Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:27

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
0015 #include <DD4hep/Detector.h>
0016 #include <DD4hep/Printout.h>
0017 #include <DD4hep/DetFactoryHelper.h>
0018 #include <XML/Conversions.h>
0019 #include <DDG4/Geant4Config.h>
0020 
0021 /// Namespace for the AIDA detector description toolkit
0022 namespace dd4hep {
0023 
0024   // Forward declarations
0025   class ActionSequence;
0026   using namespace dd4hep::sim;
0027   using namespace dd4hep::sim::Setup;
0028 
0029   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0030   namespace sim {
0031 
0032     // Forward declarations
0033     class XMLSetup;
0034 
0035     /// Action cast
0036     template <typename TYPE, typename PTR> TYPE* _action(PTR* in)  {
0037       return dynamic_cast<TYPE*>(in);
0038     }
0039 
0040     /// Install Geant4 mesenger to action objects
0041     template <typename T> static void installMessenger(const T& handle)  {
0042       handle->installMessengers();
0043     }
0044 
0045     /// Set the properties of a Geant4 Action object from XML object attributes
0046     template <typename T> static void _setAttributes(const T& handle, xml_h& e)  {
0047       xml::Handle_t props(e);
0048       // Now we set the object properties
0049       std::vector<xml::Attribute> attrs = props.attributes();
0050       for(std::vector<xml::Attribute>::iterator i=attrs.begin(); i!=attrs.end(); ++i)   {
0051         xml::Attribute a = *i;
0052         handle[xml::_toString(props.attr_name(a))].str(props.attr<std::string>(a));
0053       }
0054     }
0055 
0056     /// Set the properties of a Geant4 Action object from \<properties/\> XML subsection
0057     template <typename T> static void _setProperties(const T& handle, xml_h& e)  {
0058       xml_comp_t action(e);
0059       // Now we set the object properties
0060       xml::Handle_t  props = action.child(_Unicode(properties),false);
0061       if ( props )  {
0062         _setAttributes(handle, props);
0063       }
0064       if ( action.hasAttr(_Unicode(Control)) )   {
0065         handle["Control"].str(props.attr<std::string>(_Unicode(Control)));
0066       }
0067     }
0068 
0069     /// Create/Configure Geant4 sensitive action object from XML
0070     static Action _convertSensitive(Detector& description, xml_h e, const std::string& detector)  {
0071       xml_comp_t action(e);
0072       Kernel& kernel = Kernel::instance(description);
0073       TypeName tn = TypeName::split(action.attr<std::string>(_U(name)));
0074       // Create the object using the factory method
0075       Sensitive handle(kernel,action.attr<std::string>(_U(name)),detector);
0076       _setProperties(Action(handle.get()),e);
0077       for(xml_coll_t f(e,_Unicode(filter)); f; ++f)  {
0078         std::string nam = f.attr<std::string>(_U(name));
0079         Filter filter(kernel.globalFilter(nam,false));
0080         handle->adopt(filter);
0081       }
0082       installMessenger(handle);
0083       printout(INFO,"Geant4Setup","+++ Added sensitive element %s of type %s",
0084                tn.second.c_str(),tn.first.c_str());
0085       return Action(handle);
0086     }
0087 
0088     /// Create/Configure Action object from XML
0089     static Action _convertAction(Detector& description, xml_h e)  {
0090       xml_comp_t action(e);
0091       Kernel& kernel = Kernel::instance(description);
0092       TypeName tn = TypeName::split(action.attr<std::string>(_U(name)));
0093       // Create the object using the factory method
0094       Action handle(kernel,action.attr<std::string>(_U(name)));
0095       _setProperties(handle,e);
0096       printout(INFO,"Geant4Setup","+++ Added action %s of type %s",tn.second.c_str(),tn.first.c_str());
0097       installMessenger(handle);
0098 
0099       if ( action.hasChild(_Unicode(adopt)) )  {
0100         xml_comp_t   child = action.child(_Unicode(adopt));
0101         Geant4Action* user = kernel.globalAction(child.nameStr());
0102         Geant4ParticleHandler* ph = dynamic_cast<Geant4ParticleHandler*>(handle.get());
0103         if ( ph )  {
0104           ph->adopt(user);
0105         }
0106       }
0107       return handle;
0108     }
0109 
0110     enum { SENSITIVE, ACTION, FILTER };
0111     /// Create/Configure Action object from XML
0112     Action _createAction(Detector& description, xml_h a, const std::string& seqType, int what)  {
0113       std::string nam = a.attr<std::string>(_U(name));
0114       TypeName typ    = TypeName::split(nam);
0115       Kernel&  kernel = Kernel::instance(description);
0116       Action action((what==FILTER) ? (Geant4Action*)kernel.globalFilter(typ.second,false)
0117                     : (what==ACTION) ? kernel.globalAction(typ.second,false)
0118                     ///  : (what==FILTER) ? kernel.globalAction(typ.second,false)
0119                     : 0);
0120       // Create the object using the factory method
0121       if ( !action )  {
0122         action = (what == SENSITIVE) ? Action(_convertSensitive(description, a, seqType))
0123           : (what==ACTION) ? _convertAction(description, a)
0124           : (what==FILTER) ? _convertAction(description, a)
0125           : Action();
0126         if ( !action )  {
0127           except("Geant4ActionSequence",
0128                  "DDG4: The action '%s' cannot be created. [Action-Missing]",nam.c_str());
0129       }
0130     }
0131     return action;
0132   }
0133 }
0134 
0135 /// Convert Geant4Action objects
0136 /**
0137  *  <actions>
0138  *    <action name="Geant4PostTrackingAction/PostTrackAction"
0139  *      <properties
0140  *         NAME1="Value1"
0141  *         NAME2="Value2" />
0142  *    </action>
0143  *  </actions>
0144  */
0145 template <> void Converter<Action>::operator()(xml_h e)  const  {
0146   Action a = _convertAction(description, e);
0147   Kernel::instance(description).registerGlobalAction(a);
0148 }
0149 
0150 /// Convert Sensitive detector filters
0151 /**
0152  *  Note: Filters are Geant4Actions and - if global - may also receive properties!
0153  *
0154  *  <filters>
0155  *    <filter name="GeantinoRejector"/>
0156  *    <filter name="EnergyDepositMinimumCut">
0157  *      <properties cut="10*MeV"/>
0158  *    </filter>
0159  *  </filters>
0160  */
0161 template <> void Converter<Filter>::operator()(xml_h e)  const  {
0162   Action a = _convertAction(description, e);
0163   Kernel::instance(description).registerGlobalFilter(a);
0164 }
0165 
0166 /// Convert Geant4Phase objects
0167 /**
0168  *  <phases>
0169  *    <phase name="Geant4PostTrackingPhase/PostTrackPhase"
0170  *      <properties
0171  *         NAME1="Value1"
0172  *         NAME2="Value2" />
0173  *    </phase>
0174  *  </phases>
0175  */
0176 template <> void Converter<Phase>::operator()(xml_h e)  const  {
0177   xml_comp_t x_phase(e);
0178   Kernel&  kernel = Kernel::instance(description);
0179   std::string nam = x_phase.attr<std::string>(_U(type));
0180   typedef Geant4ActionPhase PH;
0181   Phase p;
0182 
0183   if ( nam == "RunAction/begin" )  {
0184     void (Geant4ActionPhase::*func)(const G4Run*) = &Geant4ActionPhase::call;
0185     kernel.runAction().callAtBegin((p=kernel.addPhase<const G4Run*>(nam)).get(),func);
0186     //&Geant4ActionPhase::call<const G4Run*>);
0187   }
0188   else if ( nam == "RunAction/end" )  {
0189     void (Geant4ActionPhase::*func)(const G4Run*) = &Geant4ActionPhase::call;
0190     kernel.runAction().callAtEnd((p=kernel.addPhase<const G4Run*>(nam)).get(),func);
0191     //&PH::call<const G4Run*>);
0192   }
0193   else if ( nam == "EventAction/begin" )  {
0194     void (Geant4ActionPhase::*func)(const G4Event*) = &Geant4ActionPhase::call;
0195     kernel.eventAction().callAtBegin((p=kernel.addPhase<const G4Event*>(nam)).get(),func);
0196     //&PH::call<const G4Event*>);
0197   }
0198   else if ( nam == "EventAction/end" )  {
0199     void (Geant4ActionPhase::*func)(const G4Event*) = &Geant4ActionPhase::call;
0200     kernel.eventAction().callAtEnd((p=kernel.addPhase<const G4Event*>(nam)).get(),func);
0201     //&PH::call<const G4Event*>);
0202   }
0203   else if ( nam == "TrackingAction/begin" )  {
0204     void (Geant4ActionPhase::*func)(const G4Track*) = &Geant4ActionPhase::call;
0205     kernel.trackingAction().callAtBegin((p=kernel.addPhase<const G4Track*>(nam)).get(),func);
0206     //&PH::call<const G4Track*>);
0207   }
0208   else if ( nam == "TrackingAction/end" )  {
0209     void (Geant4ActionPhase::*func)(const G4Track*) = &Geant4ActionPhase::call;
0210     kernel.trackingAction().callAtEnd((p=kernel.addPhase<const G4Track*>(nam,false)).get(),func);
0211     //&PH::call<const G4Track*>);
0212   }
0213   else if ( nam == "StackingAction/newStage" )  {
0214     kernel.stackingAction().callAtNewStage((p=kernel.addPhase<void>(nam,false)).get(),&PH::call);
0215   }
0216   else if ( nam == "StackingAction/prepare" )  {
0217     kernel.stackingAction().callAtPrepare((p=kernel.addPhase<void>(nam,false)).get(),&PH::call);
0218   }
0219   else if ( nam == "SteppingAction" )  {
0220     void (Geant4ActionPhase::*func)(const G4Step*,G4SteppingManager*) = &Geant4ActionPhase::call;
0221     kernel.steppingAction().call((p=kernel.addPhase<const G4Step*>(nam)).get(),func);
0222     //&PH::call<const G4Step*,G4SteppingManager*>);
0223   }
0224   else if ( nam == "GeneratorAction/primaries" )  {
0225     void (Geant4ActionPhase::*func)(G4Event*) = &Geant4ActionPhase::call;
0226     kernel.generatorAction().call((p=kernel.addPhase<G4Event*>(nam)).get(),func);
0227     //&PH::call<G4Event*>);
0228   }
0229   else   {
0230     TypeName tn = TypeName::split(nam);
0231     DetElement det = description.detector(tn.first);
0232     if ( !det.isValid() )   {
0233       except("Phase","DDG4: The phase '%s' of type SensitiveSeq"
0234              " cannot be attached to a non-existing detector"
0235              " [Detector-Missing]",nam.c_str());
0236     }
0237 
0238     SensitiveDetector sd = description.sensitiveDetector(tn.first);
0239     if ( !sd.isValid() )  {
0240       except("Phase","DDG4: The phase '%s' of type SensitiveSeq"
0241              " cannot be attached to a non-existing sensitive detector"
0242              " [Sensitive-Missing]",nam.c_str());
0243     }
0244     SensitiveSeq sdSeq = SensitiveSeq(kernel,tn.first);
0245     if ( tn.second == "begin" )
0246       sdSeq->callAtBegin((p=kernel.addPhase<G4HCofThisEvent*>(tn.second)).get(),
0247                          &PH::call<G4HCofThisEvent*>);
0248     else if ( tn.second == "end" )
0249       sdSeq->callAtEnd((p=kernel.addPhase<G4HCofThisEvent*>(tn.second)).get(),
0250                        &PH::call<G4HCofThisEvent*>);
0251     else if ( tn.second == "clear" )
0252       sdSeq->callAtClear((p=kernel.addPhase<G4HCofThisEvent*>(tn.second)).get(),
0253                          &PH::call<G4HCofThisEvent*>);
0254     else if ( tn.second == "process" )
0255       sdSeq->callAtProcess((p=kernel.addPhase<G4Step*>(tn.second)).get(),
0256                            &PH::call<G4Step*,G4TouchableHistory*>);
0257     else
0258       except("Phase","DDG4: The phase '%s' of type SensitiveSeq"
0259              " cannot be attached to the call '%s'."
0260              " [Callback-Missing]",tn.first.c_str(), tn.second.c_str());
0261   }
0262 }
0263 
0264 /// Convert Action sequences into objects
0265 /**
0266  *  <sequences>
0267  *    <sequence name="Geant4EventActionSequence/EventAction"
0268  *      <member name="" type="Geant4TrackerEventMonitor/TrackerEvtAction"/>
0269  *    </sequence>
0270  *    <sequence name="Geant4SensdetActionSequence/SiVertexBarrel"
0271  *      <member type="Geant4TrackerSensitiveMonitor/TrackerHitMonitor">
0272  *        <properties
0273  *           NAME1="Value1"
0274  *           NAME2="Value2" />
0275  *      </member>
0276  *    </sequence>
0277  *  </sequences>
0278  */
0279 template <> void Converter<ActionSequence>::operator()(xml_h e)  const  {
0280   xml_comp_t   seq(e);
0281   SensitiveSeq sdSeq;
0282   std::string  seqNam;
0283   TypeName     seqType;
0284   int          what = ACTION;
0285   Kernel&      kernel = Kernel::instance(description);
0286 
0287   if ( seq.hasAttr(_U(sd)) )   {
0288     std::string sd_nam = seq.attr<std::string>(_U(sd));
0289     SensitiveDetector sensitive = description.sensitiveDetector(sd_nam);
0290     seqNam  = seq.attr<std::string>(_U(type))+"/"+sd_nam;
0291     if ( !sensitive.isValid() )  {
0292       printout(ALWAYS,"Geant4Setup","+++ ActionSequence %s is defined, "
0293                "but no sensitive detector present.",seqNam.c_str());
0294       printout(ALWAYS,"Geant4Setup","+++ ---> Sequence for detector %s IGNORED on popular request!",
0295                sd_nam.c_str());
0296       return;
0297     }
0298     seqType = TypeName::split(seqNam);
0299     sdSeq   = SensitiveSeq(kernel,seqNam);
0300     what    = SENSITIVE;
0301   }
0302   else {
0303     seqNam = seq.attr<std::string>(_U(name));
0304     seqType = TypeName::split(seqNam);
0305   }
0306   printout(INFO,"Geant4Setup","+++ ActionSequence %s of type %s added.",
0307            seqType.second.c_str(),seqType.first.c_str());
0308 
0309   if ( seqType.second == "PhysicsList" )  {
0310     PhysicsActionSeq pl(&kernel.physicsList());
0311     PropertyManager& props = kernel.physicsList().properties();
0312     props.dump();
0313     _setAttributes(pl,e);
0314     props.dump();
0315   }
0316 
0317   for(xml_coll_t a(seq,_Unicode(action)); a; ++a)  {
0318     std::string  nam = a.attr<std::string>(_U(name));
0319     Action action(_createAction(description,a,seqType.second,what));
0320     if ( seqType.second == "RunAction" )
0321       kernel.runAction().adopt(_action<Geant4RunAction>(action.get()));
0322     else if ( seqType.second == "EventAction" )
0323       kernel.eventAction().adopt(_action<Geant4EventAction>(action.get()));
0324     else if ( seqType.second == "GeneratorAction" )
0325       kernel.generatorAction().adopt(_action<Geant4GeneratorAction>(action.get()));
0326     else if ( seqType.second == "TrackingAction" )
0327       kernel.trackingAction().adopt(_action<Geant4TrackingAction>(action.get()));
0328     else if ( seqType.second == "StackingAction" )
0329       kernel.stackingAction().adopt(_action<Geant4StackingAction>(action.get()));
0330     else if ( seqType.second == "SteppingAction" )
0331       kernel.steppingAction().adopt(_action<Geant4SteppingAction>(action.get()));
0332     else if ( seqType.second == "PhysicsList" )
0333       kernel.physicsList().adopt(_action<Geant4PhysicsList>(action.get()));
0334     else if ( sdSeq.get() )
0335       sdSeq->adopt(_action<Geant4Sensitive>(action.get()));
0336     else   {
0337       except("ActionSequence","DDG4: The action '%s'"
0338              " cannot be attached to any sequence '%s'."
0339              " [Sequence-Missing]",nam.c_str(), seqNam.c_str());
0340     }
0341     printout(INFO,"Geant4Setup","+++ ActionSequence %s added filter object:%s",
0342              seqType.second.c_str(),action->name().c_str());
0343   }
0344   if ( what == SENSITIVE )  {
0345     for(xml_coll_t a(seq,_Unicode(filter)); a; ++a)  {
0346       std::string  nam = a.attr<std::string>(_U(name));
0347       Action action(_createAction(description,a,"",FILTER));
0348       installMessenger(action);
0349       printout(INFO,"Geant4Setup","+++ ActionSequence %s added filter object:%s",
0350                seqType.second.c_str(),action->name().c_str());
0351       if ( sdSeq.get() )
0352         sdSeq->adopt(_action<Geant4Filter>(action.get()));
0353       else   {
0354         except("ActionSequence","DDG4: The action '%s'"
0355                " cannot be attached to any sequence '%s'."
0356                " [Sequence-Missing]",nam.c_str(), seqNam.c_str());
0357       }
0358     }
0359   }
0360 }
0361 
0362 /// Create/Configure PhysicsList objects
0363 /**
0364  *  <physicslist>
0365  *    <processes>
0366  *      <particle name="'e-'">
0367  *        <process name="G4eMultipleScattering" ordAtRestDoIt="-1" ordAlongSteptDoIt="1" ordPostStepDoIt="1"/>
0368  *        <process name="G4eIonisation"         ordAtRestDoIt="-1" ordAlongSteptDoIt="2" ordPostStepDoIt="2"/>
0369  *      </particle>
0370  *    </processes>
0371  *  </physicslist>
0372  */
0373 template <> void Converter<Geant4PhysicsList::ParticleProcesses>::operator()(xml_h e) const {
0374   xml_comp_t part(e);
0375   std::string part_name = part.nameStr();
0376   Geant4PhysicsList::ParticleProcesses& procs =
0377     _object<Geant4PhysicsList>().processes(part_name);
0378   for(xml_coll_t q(part,_Unicode(process)); q; ++q)  {
0379     xml_comp_t proc(q);
0380     Geant4PhysicsList::Process p;
0381     p.name = proc.nameStr();
0382     p.ordAtRestDoIt     = proc.attr<int>(_Unicode(ordAtRestDoIt));
0383     p.ordAlongSteptDoIt = proc.attr<int>(_Unicode(ordAlongSteptDoIt));
0384     p.ordPostStepDoIt   = proc.attr<int>(_Unicode(ordPostStepDoIt));
0385     procs.emplace_back(p);
0386     printout(INFO,"Geant4Setup","+++ Converter<ParticleProcesses: Particle:%s add process %s %d %d %d",
0387              part_name.c_str(),p.name.c_str(),p.ordAtRestDoIt,p.ordAlongSteptDoIt,p.ordPostStepDoIt);
0388   }
0389 }
0390 
0391 /// Create/Configure PhysicsList objects: Particle constructors
0392 /**
0393  *  <physicslist>
0394  *    <particles>
0395  *      <construct name="G4Electron"/>
0396  *      <construct name="G4Gamma"/>
0397  *      <construct name="G4BosonConstructor"/>
0398  *      <construct name="G4LeptonConstructor"/>
0399  *      <construct name="G4BaryonConstructor"/>
0400  *    </particles>
0401  *  </physicslist>
0402  */
0403 template <> void Converter<Geant4PhysicsList::ParticleConstructor>::operator()(xml_h e) const {
0404   Geant4PhysicsList::ParticleConstructors& parts = _object<Geant4PhysicsList>().particles();
0405   xml_comp_t  part(e);
0406   std::string n = part.nameStr();
0407   parts.emplace_back(n);
0408   printout(INFO,"Geant4Setup","+++ ParticleConstructor: Add Geant4 particle constructor '%s'",n.c_str());
0409 }
0410 
0411 /// Create/Configure PhysicsList objects: Physics constructors
0412 /**
0413  *  <physicslist>
0414  *    <physics>
0415  *      <construct name="G4EmStandardPhysics"/>
0416  *      <construct name="HadronPhysicsQGSP"/>
0417  *    </physics>
0418  *  </physicslist>
0419  */
0420 template <> void Converter<Geant4PhysicsList::PhysicsConstructor>::operator()(xml_h e) const {
0421   Geant4PhysicsList::PhysicsConstructors& parts = _object<Geant4PhysicsList>().physics();
0422   xml_comp_t  part(e);
0423   std::string n = part.nameStr();
0424   parts.emplace_back(n);
0425   printout(INFO,"Geant4Setup","+++ PhysicsConstructor: Add Geant4 physics constructor '%s'",n.c_str());
0426 }
0427 
0428 /// Create/Configure PhysicsList extension objects: Predefined Geant4 Physics lists
0429 /**
0430  *  <physicslist>
0431  *    <list name="TQGSP_FTFP_BERT_95"/>
0432  *  </physicslist>
0433  *  Note: list items are Geant4Actions and - if global - may receive properties!
0434  */
0435 struct PhysicsListExtension;
0436 template <> void Converter<PhysicsListExtension>::operator()(xml_h e) const {
0437   Kernel& kernel = Kernel::instance(description);
0438   std::string ext = xml_comp_t(e).nameStr();
0439   kernel.physicsList().properties()["extends"].str(ext);
0440   printout(INFO,"Geant4Setup","+++ PhysicsListExtension: Set predefined Geant4 physics list to '%s'",ext.c_str());
0441 }
0442 
0443 /// Create/Configure PhysicsList objects: Predefined Geant4 Physics lists
0444 template <> void Converter<PhysicsList>::operator()(xml_h e)  const  {
0445   std::string name = e.attr<std::string>(_U(name));
0446   Kernel& kernel = Kernel::instance(description);
0447   PhysicsList handle(kernel,name);
0448   _setAttributes(handle,e);
0449   xml_coll_t(e,_Unicode(particles)).for_each(_Unicode(construct),Converter<Geant4PhysicsList::ParticleConstructor>(description,handle.get()));
0450   xml_coll_t(e,_Unicode(processes)).for_each(_Unicode(particle),Converter<Geant4PhysicsList::ParticleProcesses>(description,handle.get()));
0451   xml_coll_t(e,_Unicode(physics)).for_each(_Unicode(construct),Converter<Geant4PhysicsList::PhysicsConstructor>(description,handle.get()));
0452   xml_coll_t(e,_Unicode(extends)).for_each(Converter<PhysicsListExtension>(description,handle.get()));
0453   kernel.physicsList().adopt(handle);
0454 }
0455 
0456 /// Create/Configure Geant4Kernel objects
0457 template <> void Converter<Kernel>::operator()(xml_h e) const {
0458   Kernel& kernel = Kernel::instance(description);
0459   xml_comp_t k(e);
0460   if ( k.hasAttr(_Unicode(NumEvents)) )
0461     kernel.property("NumEvents").str(k.attr<std::string>(_Unicode(NumEvents)));
0462   if ( k.hasAttr(_Unicode(UI)) )
0463     kernel.property("UI").str(k.attr<std::string>(_Unicode(UI)));
0464 }
0465 
0466 /// Main entry point to configure Geant4 with XML
0467 template <> void Converter<XMLSetup>::operator()(xml_h seq)  const  {
0468   xml_elt_t compact(seq);
0469   // First execute the basic setup from the plugins module
0470   long result = PluginService::Create<long>("geant4_XML_reader",&description,&seq);
0471   if ( 0 == result )  {
0472     except("PhysicsList", "dd4hep: Failed to locate plugin to interprete files of type"
0473            " \"" + seq.tag() + "\" - no factory of type geant4_XML_reader.");
0474   }
0475   result = *(long*) result;
0476   if (result != 1) {
0477     except("PhysicsList", "dd4hep: Failed to parse the XML tag %s with the plugin geant4_XML_reader", seq.tag().c_str());
0478   }
0479   xml_coll_t(compact,_Unicode(kernel)).for_each(Converter<Kernel>(description,param));
0480   // Now deal with the new stuff.....
0481   xml_coll_t(compact,_Unicode(actions) ).for_each(_Unicode(action),Converter<Action>(description,param));
0482   xml_coll_t(compact,_Unicode(filters) ).for_each(_Unicode(filter),Converter<Filter>(description,param));
0483   xml_coll_t(compact,_Unicode(sequences) ).for_each(_Unicode(sequence),Converter<ActionSequence>(description,param));
0484   xml_coll_t(compact,_Unicode(phases) ).for_each(_Unicode(phase),Converter<Phase>(description,param));
0485   xml_coll_t(compact,_Unicode(physicslist)).for_each(Converter<PhysicsList>(description,param));
0486 }
0487 }
0488 
0489 /// Factory method
0490 static long setup_Geant4(dd4hep::Detector& description, const xml_h& element) {
0491   (dd4hep::Converter<dd4hep::sim::XMLSetup>(description))(element);
0492   return 1;
0493 }
0494 // Factory declaration
0495 DECLARE_XML_DOC_READER(geant4_setup,setup_Geant4)