diff --git a/DDG4/src/Geant4Output2ROOT.cpp b/DDG4/src/Geant4Output2ROOT.cpp index f8119eb28..9aae89e22 100644 --- a/DDG4/src/Geant4Output2ROOT.cpp +++ b/DDG4/src/Geant4Output2ROOT.cpp @@ -29,6 +29,8 @@ #include #include #include +#include + using namespace dd4hep::sim; using namespace dd4hep; @@ -36,7 +38,7 @@ using namespace std; /// Standard constructor Geant4Output2ROOT::Geant4Output2ROOT(Geant4Context* ctxt, const string& nam) - : Geant4OutputAction(ctxt, nam), m_file(0), m_tree(0) { + : Geant4OutputAction(ctxt, nam), m_file(nullptr), m_tree(nullptr) { declareProperty("Section", m_section = "EVENT"); declareProperty("HandleMCTruth", m_handleMCTruth = true); declareProperty("DisabledCollections", m_disabledCollections); @@ -94,11 +96,21 @@ void Geant4Output2ROOT::beginRun(const G4Run* run) { } if ( !m_file && !fname.empty() ) { TDirectory::TContext ctxt(TDirectory::CurrentDirectory()); - m_file = TFile::Open(fname.c_str(), "RECREATE", "dd4hep Simulation data"); - if (m_file->IsZombie()) { + if ( !gSystem->AccessPathName(fname.c_str()) ) { + gSystem->Unlink(fname.c_str()); + } + std::unique_ptr file(TFile::Open(fname.c_str(), "RECREATE", "dd4hep Simulation data")); + if ( !file ) { + file.reset(TFile::Open((fname+".1").c_str(), "RECREATE", "dd4hep Simulation data")); + } + if ( !file ) { + except("Failed to create ROOT output file:'%s'", fname.c_str()); + } + if (file->IsZombie()) { detail::deletePtr (m_file); except("Failed to open ROOT output file:'%s'", fname.c_str()); } + m_file = file.release(); m_tree = section(m_section); } Geant4OutputAction::beginRun(run); diff --git a/examples/ClientTests/compact/FiberTubeCalorimeter.xml b/examples/ClientTests/compact/FiberTubeCalorimeter.xml index 41b322b38..94544908e 100644 --- a/examples/ClientTests/compact/FiberTubeCalorimeter.xml +++ b/examples/ClientTests/compact/FiberTubeCalorimeter.xml @@ -70,11 +70,12 @@ - + + @@ -92,18 +93,18 @@ zmin is where the dtector goes --> - - - - - + + + + + diff --git a/examples/ClientTests/scripts/FiberTubeCalorimeter.py b/examples/ClientTests/scripts/FiberTubeCalorimeter.py new file mode 100644 index 000000000..01e465bb7 --- /dev/null +++ b/examples/ClientTests/scripts/FiberTubeCalorimeter.py @@ -0,0 +1,95 @@ +# ========================================================================== +# AIDA Detector description implementation +# -------------------------------------------------------------------------- +# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +# All rights reserved. +# +# For the licensing terms see $DD4hepINSTALL/LICENSE. +# For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +# +# ========================================================================== +# +# +from __future__ import absolute_import, unicode_literals +import os +import time +import DDG4 +from DDG4 import OutputLevel as Output +from g4units import GeV, MeV, m +# +# +""" + + dd4hep simulation example setup using the python configuration + + @author M.Frank + @version 1.0 + +""" + + +def run(): + args = DDG4.CommandLine() + kernel = DDG4.Kernel() + install_dir = os.environ['DD4hepExamplesINSTALL'] + kernel.loadGeometry(str("file:" + install_dir + "/examples/ClientTests/compact/FiberTubeCalorimeter.xml")) + + DDG4.importConstants(kernel.detectorDescription(), debug=False) + geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction') + geant4.printDetectors() + # Configure UI + if args.macro: + ui = geant4.setupCshUI(macro=args.macro) + else: + ui = geant4.setupCshUI() + if args.batch: + ui.Commands = ['/run/beamOn ' + str(args.events), '/ddg4/UI/terminate'] + + # Configure field + geant4.setupTrackingField(prt=True) + # Configure Event actions + prt = DDG4.EventAction(kernel, 'Geant4ParticlePrint/ParticlePrint') + prt.OutputLevel = Output.DEBUG + prt.OutputType = 3 # Print both: table and tree + kernel.eventAction().adopt(prt) + + generator_output_level = Output.INFO + + # Configure G4 geometry setup + seq, act = geant4.addDetectorConstruction("Geant4DetectorGeometryConstruction/ConstructGeo") + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + seq, act = geant4.addDetectorConstruction("Geant4DetectorSensitivesConstruction/ConstructSD") + + # Configure I/O + geant4.setupROOTOutput('RootOutput', 'FiberTubeCalorimeter_' + time.strftime('%Y-%m-%d_%H-%M')) + + # Setup particle gun + gun = geant4.setupGun("Gun", particle='e+', energy=20 * GeV, multiplicity=1, position=(0.0, 0.0, -369.0)) + gun.OutputLevel = generator_output_level + + # And handle the simulation particles. + part = DDG4.GeneratorAction(kernel, "Geant4ParticleHandler/ParticleHandler") + kernel.generatorAction().adopt(part) + part.SaveProcesses = ['Decay'] + part.MinimalKineticEnergy = 100 * MeV + part.OutputLevel = Output.INFO # generator_output_level + part.enableUI() + user = DDG4.Action(kernel, "Geant4TCUserParticleHandler/UserParticleHandler") + user.TrackingVolume_Zmax = 3.0 * m + user.TrackingVolume_Rmax = 3.0 * m + user.enableUI() + part.adopt(user) + + geant4.setupCalorimeter('FiberTubeCalorimeter') + + # Now build the physics list: + phys = geant4.setupPhysics('QGSP_BERT') + phys.dump() + geant4.execute() + + +if __name__ == "__main__": + run() diff --git a/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp index 99e50aacb..bca02b101 100644 --- a/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp +++ b/examples/ClientTests/src/FiberTubeCalorimeter_geo.cpp @@ -68,27 +68,17 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // these refer to different fields in the xml file for this detector xml_comp_t fX_struct( x_det.child( _Unicode(structure) ) ); xml_comp_t fX_absorb( fX_struct.child( _Unicode(absorb) ) ); - xml_comp_t fX_core1( fX_struct.child( _Unicode(core1) ) ); - xml_comp_t fX_core2( fX_struct.child( _Unicode(core2) ) ); - xml_comp_t fX_hole( fX_struct.child( _Unicode(hole) ) ); + xml_comp_t fX_core1( fX_struct.child( _Unicode(core1) ) ); + xml_comp_t fX_core2( fX_struct.child( _Unicode(core2) ) ); + xml_comp_t fX_hole( fX_struct.child( _Unicode(hole) ) ); xml_comp_t fX_phdet1( fX_struct.child( _Unicode(phdet1) ) ); xml_comp_t fX_phdet2( fX_struct.child( _Unicode(phdet2) ) ); - - // detector element for entire detector. - DetElement sdet (det_name, det_id); - Volume motherVol = description.pickMotherVolume(sdet); - Box env_box ((2*Ncount+1)*(hthick+agap+tol),(2*Ncount+1)*(hthick+agap+tol), (hzlength+hzph+tol)); - Volume envelopeVol (det_name, env_box, air); - envelopeVol.setAttributes(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); Material mat; Transform3D trafo; PlacedVolume pv; Solid sol; - - pv = motherVol.placeVolume(envelopeVol, Position(0.,0.,azmin+hzlength+hzph+tol)); - pv.addPhysVolID("system", det_id); - sdet.setPlacement(pv); // associate the placed volume to the detector element + sens.setType("calorimeter"); // scint fiber @@ -182,24 +172,40 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s } // setup the volumes with the shapes and properties in one horixontal layer - Volume tube_row_vol("layer", Box(hthick,hthick,hzlength+hzph), air); + double dx = 2*(Ncount + Ncount+1)/2e0 * (hthick+agap) + tol; + double dy = hthick + tol; + double dz = hzlength+hzph + tol; + Box tube_row_box(dx, dy, dz); + Volume tube_row_vol("layer", tube_row_box, air); tube_row_vol.setVisAttributes(description, x_det.visStr()); tube_row_vol.setSensitiveDetector(sens); - + cout << tube_row_vol.name() + << " dx: " << tube_row_box.x() + << " dy: " << tube_row_box.y() + << " dz: " << tube_row_box.z() << endl; + tube_row_vol.setVisAttributes(description, "layerVis"); + for (int ijk=-Ncount; ijk