Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:20

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 #ifndef DD4HEP_DDG4_GEANT4FIELDTRACKINGSETUP_H
0015 #define DD4HEP_DDG4_GEANT4FIELDTRACKINGSETUP_H 1
0016 
0017 // Framework include files
0018 #include <DD4hep/Detector.h>
0019 #include <DDG4/Geant4ActionPhase.h>
0020 #include <DDG4/Geant4DetectorConstruction.h>
0021 
0022 /// Namespace for the AIDA detector description toolkit
0023 namespace dd4hep {
0024 
0025   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0026   namespace sim {
0027 
0028     /// Generic Setup component to perform the magnetic field tracking in Geant4
0029     /** Geant4FieldTrackingSetup.
0030      *
0031      *  This base class is use jointly between the XML setup and the 
0032      *  phase action used by the python setup.
0033      *
0034      *  Note:
0035      *  Negative parameters are not passed to Geant4 objects, but ignored -- if possible.
0036      *
0037      * @author  M.Frank
0038      * @version 1.0
0039      */
0040     struct Geant4FieldTrackingSetup  {
0041     protected:
0042       /** Variables to be filled before calling execute */
0043       /// Name of the G4Mag_EqRhs class
0044       std::string eq_typ;
0045       /// Name of the G4MagIntegratorStepper class
0046       std::string stepper_typ;
0047       /// G4ChordFinder parameter: min_chord_step
0048       double      min_chord_step;
0049       /// G4ChordFinder parameter: delta
0050       double      delta_chord;
0051       /// G4FieldManager parameter: delta_one_step
0052       double      delta_one_step;
0053       /// G4FieldManager parameter: delta_intersection
0054       double      delta_intersection;
0055       /// G4PropagatorInField parameter: eps_min
0056       double      eps_min;
0057       /// G4PropagatorInField parameter: eps_min
0058       double      eps_max;
0059       /// G4PropagatorInField parameter: LargestAcceptableStep
0060       double      largest_step;
0061 
0062     public:
0063       /// Default constructor
0064       Geant4FieldTrackingSetup();
0065       /// Default destructor
0066       virtual ~Geant4FieldTrackingSetup();
0067       /// Perform the setup of the magnetic field tracking in Geant4
0068       virtual int execute(Detector& description);
0069     };
0070 
0071     /// Phase action to perform the setup of the Geant4 tracking in magnetic fields
0072     /** Geant4FieldTrackingSetupAction.
0073      *
0074      *  The phase action configures the Geant4FieldTrackingSetup base class using properties
0075      *  and then configures the Geant4 tracking in magnetic fields.
0076      *
0077      * @author  M.Frank
0078      * @version 1.0
0079      */
0080     class Geant4FieldTrackingSetupAction :
0081       public Geant4PhaseAction,
0082       public Geant4FieldTrackingSetup
0083     {
0084     protected:
0085     public:
0086       /// Standard constructor
0087       Geant4FieldTrackingSetupAction(Geant4Context* context, const std::string& nam);
0088       /// Default destructor
0089       virtual ~Geant4FieldTrackingSetupAction() {}
0090       /// Phase action callback
0091       void operator()();
0092     };
0093 
0094     /// Detector construction action to perform the setup of the Geant4 tracking in magnetic fields
0095     /** Geant4FieldTrackingSetupAction.
0096      *
0097      *  The phase action configures the Geant4FieldTrackingSetup base class using properties
0098      *  and then configures the Geant4 tracking in magnetic fields.
0099      *
0100      * @author  M.Frank
0101      * @version 1.0
0102      */
0103     class Geant4FieldTrackingConstruction : 
0104       public Geant4DetectorConstruction,
0105       public Geant4FieldTrackingSetup
0106     {
0107     protected:
0108     public:
0109       /// Standard constructor
0110       Geant4FieldTrackingConstruction(Geant4Context* context, const std::string& nam);
0111 
0112       /// Default destructor
0113       virtual ~Geant4FieldTrackingConstruction() {}
0114 
0115       /// Detector construction callback
0116       void constructField(Geant4DetectorConstructionContext *ctxt);
0117 
0118     };
0119   }    // End namespace sim
0120 }      // End namespace dd4hep
0121 #endif // DD4HEP_DDG4_GEANT4FIELDTRACKINGSETUP_H
0122 
0123 //==========================================================================
0124 //  AIDA Detector description implementation 
0125 //--------------------------------------------------------------------------
0126 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0127 // All rights reserved.
0128 //
0129 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0130 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0131 //
0132 // Author     : M.Frank
0133 //
0134 //==========================================================================
0135 
0136 // Framework include files
0137 #include <DD4hep/Handle.h>
0138 #include <DD4hep/Fields.h>
0139 #include <DDG4/Factories.h>
0140 #include <DDG4/Geant4Field.h>
0141 #include <DDG4/Geant4Converter.h>
0142 
0143 #include <G4TransportationManager.hh>
0144 #include <G4MagIntegratorStepper.hh>
0145 #include <G4Mag_EqRhs.hh>
0146 #include <G4ChordFinder.hh>
0147 #include <G4PropagatorInField.hh>
0148 #include <limits>
0149 
0150 using namespace dd4hep::sim;
0151 
0152 /// Local declaration in anonymous namespace
0153 namespace {
0154 
0155   struct Geant4SetupPropertyMap {
0156     const std::map<std::string,std::string>& vals;
0157     Geant4SetupPropertyMap(const std::map<std::string,std::string>& v) : vals(v) {}
0158     std::string value(const std::string& key) const;
0159     double toDouble(const std::string& key) const;
0160     bool operator[](const std::string& key) const  { return vals.find(key) != vals.end(); }
0161   };
0162   
0163   std::string Geant4SetupPropertyMap::value(const std::string& key) const {
0164     dd4hep::Detector::PropertyValues::const_iterator iV = vals.find(key);
0165     return iV == vals.end() ? "" : (*iV).second;
0166   }
0167 
0168   double Geant4SetupPropertyMap::toDouble(const std::string& key) const {
0169     return dd4hep::_toDouble(this->value(key));
0170   }
0171 
0172 }
0173 
0174 /// Default constructor
0175 Geant4FieldTrackingSetup::Geant4FieldTrackingSetup() : eq_typ(), stepper_typ() {
0176   eps_min            = -1.0;
0177   eps_max            = -1.0;
0178   min_chord_step     =  1.0e-2 *CLHEP::mm;
0179   delta_chord        = -1.0;
0180   delta_one_step     = -1.0;
0181   delta_intersection = -1.0;
0182   largest_step       = -1.0;
0183 }
0184 
0185 /// Default destructor
0186 Geant4FieldTrackingSetup::~Geant4FieldTrackingSetup()   {
0187 }
0188 
0189 /// Perform the setup of the magnetic field tracking in Geant4
0190 int Geant4FieldTrackingSetup::execute(Detector& description)   {
0191   OverlayedField fld  = description.field();
0192   G4ChordFinder*           chordFinder;
0193   G4TransportationManager* transportMgr;
0194   G4PropagatorInField*     propagator;
0195   G4FieldManager*          fieldManager;
0196   G4MagneticField*         mag_field    = new sim::Geant4Field(fld);
0197   G4Mag_EqRhs*             mag_equation = PluginService::Create<G4Mag_EqRhs*>(eq_typ,mag_field);
0198   G4EquationOfMotion*      mag_eq       = mag_equation;
0199   if ( nullptr == mag_eq )   {
0200     mag_eq = PluginService::Create<G4EquationOfMotion*>(eq_typ,mag_field);
0201     if ( nullptr == mag_eq )   {
0202       except("FieldSetup", "Cannot create G4EquationOfMotion of type: %s.",eq_typ.c_str());
0203     }
0204   }
0205   G4MagIntegratorStepper* fld_stepper = PluginService::Create<G4MagIntegratorStepper*>(stepper_typ,mag_eq);
0206   if ( nullptr == fld_stepper )   {
0207     fld_stepper  = PluginService::Create<G4MagIntegratorStepper*>(stepper_typ,mag_equation);
0208     if ( nullptr == fld_stepper )   {
0209       except("FieldSetup", "Cannot create stepper of type: %s.",stepper_typ.c_str());
0210     }
0211   }
0212   chordFinder  = new G4ChordFinder(mag_field,min_chord_step,fld_stepper);
0213   transportMgr = G4TransportationManager::GetTransportationManager();
0214   propagator   = transportMgr->GetPropagatorInField();
0215   fieldManager = transportMgr->GetFieldManager();
0216 
0217   fieldManager->SetFieldChangesEnergy(fld.changesEnergy());
0218   fieldManager->SetDetectorField(mag_field);
0219   fieldManager->SetChordFinder(chordFinder);
0220 
0221   if ( delta_chord >= 0e0 )
0222     chordFinder->SetDeltaChord(delta_chord);
0223   if ( delta_one_step >= 0e0 )
0224     fieldManager->SetAccuraciesWithDeltaOneStep(delta_one_step);
0225   if ( delta_intersection >= 0e0 )
0226     fieldManager->SetDeltaIntersection(delta_intersection);
0227   if ( eps_min >= 0e0 )
0228     propagator->SetMinimumEpsilonStep(eps_min);
0229   if ( eps_max >= 0e0 )
0230     propagator->SetMaximumEpsilonStep(eps_max);
0231   if ( largest_step >= 0e0 ) {
0232     propagator->SetLargestAcceptableStep(largest_step);
0233   } else {
0234     largest_step = propagator->GetLargestAcceptableStep();
0235   }
0236   return 1;
0237 }
0238 
0239 static long setup_fields(dd4hep::Detector& description,
0240                          const dd4hep::detail::GeoHandler& /* cnv */,
0241                          const std::map<std::string,std::string>& vals)
0242 {
0243   struct XMLFieldTrackingSetup : public Geant4FieldTrackingSetup {
0244     XMLFieldTrackingSetup(const std::map<std::string,std::string>& values) : Geant4FieldTrackingSetup() {
0245       Geant4SetupPropertyMap pm(values);
0246       dd4hep::Detector::PropertyValues::const_iterator iV = values.find("min_chord_step");
0247       eq_typ      = pm.value("equation");
0248       stepper_typ = pm.value("stepper");
0249       min_chord_step = dd4hep::_toDouble((iV==values.end()) ? std::string("1e-2 * mm") : (*iV).second);
0250       if ( pm["eps_min"] ) eps_min = pm.toDouble("eps_min");
0251       if ( pm["eps_max"] ) eps_max = pm.toDouble("eps_max");
0252       if ( pm["delta_chord"] ) delta_chord = pm.toDouble("delta_chord");
0253       if ( pm["delta_one_step"] ) delta_one_step = pm.toDouble("delta_one_step");
0254       if ( pm["delta_intersection"] ) delta_intersection = pm.toDouble("delta_intersection");
0255       if ( pm["largest_step"] ) largest_step = pm.toDouble("largest_step");
0256     }
0257     virtual ~XMLFieldTrackingSetup() {}
0258   } setup(vals);
0259   return setup.execute(description);
0260 }
0261 
0262 /// Standard constructor
0263 Geant4FieldTrackingSetupAction::Geant4FieldTrackingSetupAction(Geant4Context* ctxt, const std::string& nam)
0264   : Geant4PhaseAction(ctxt,nam), Geant4FieldTrackingSetup()
0265 {
0266   declareProperty("equation",           eq_typ);
0267   declareProperty("stepper",            stepper_typ);
0268   declareProperty("min_chord_step",     min_chord_step = 1.0e-2);
0269   declareProperty("delta_chord",        delta_chord = -1.0);
0270   declareProperty("delta_one_step",     delta_one_step = -1.0);
0271   declareProperty("delta_intersection", delta_intersection = -1.0);
0272   declareProperty("eps_min",            eps_min = -1.0);
0273   declareProperty("eps_max",            eps_max = -1.0);
0274   declareProperty("largest_step",       largest_step = -1.0);
0275 }
0276 
0277 /// Post-track action callback
0278 void Geant4FieldTrackingSetupAction::operator()()   {
0279   execute(context()->detectorDescription());
0280   printout( INFO, "FieldSetup", "Geant4 magnetic field tracking configured.");
0281   printout( INFO, "FieldSetup", "G4MagIntegratorStepper:%s G4Mag_EqRhs:%s",
0282         stepper_typ.c_str(), eq_typ.c_str());
0283   printout( INFO, "FieldSetup", "Epsilon:[min:%f mm max:%f mm]", eps_min, eps_max);
0284   printout( INFO, "FieldSetup", "Delta:[chord:%f 1-step:%f intersect:%f] LargestStep %f mm",
0285         delta_chord, delta_one_step, delta_intersection, largest_step);
0286 }
0287 
0288 
0289 /// Standard constructor
0290 Geant4FieldTrackingConstruction::Geant4FieldTrackingConstruction(Geant4Context* ctxt, const std::string& nam)
0291   : Geant4DetectorConstruction(ctxt,nam), Geant4FieldTrackingSetup()
0292 {
0293   declareProperty("equation",           eq_typ);
0294   declareProperty("stepper",            stepper_typ);
0295   declareProperty("min_chord_step",     min_chord_step = 1.0e-2);
0296   declareProperty("delta_chord",        delta_chord = -1.0);
0297   declareProperty("delta_one_step",     delta_one_step = -1.0);
0298   declareProperty("delta_intersection", delta_intersection = -1.0);
0299   declareProperty("eps_min",            eps_min = -1.0);
0300   declareProperty("eps_max",            eps_max = -1.0);
0301   declareProperty("largest_step",       largest_step = -1.0);
0302 }
0303 
0304 /// Detector construction callback
0305 void Geant4FieldTrackingConstruction::constructField(Geant4DetectorConstructionContext *) {
0306   execute(context()->detectorDescription());
0307   printout( INFO, "FieldSetup", "Geant4 magnetic field tracking configured.");
0308   printout( INFO, "FieldSetup", "G4MagIntegratorStepper:%s G4Mag_EqRhs:%s",
0309         stepper_typ.c_str(), eq_typ.c_str());
0310   printout( INFO, "FieldSetup", "Epsilon:[min:%f mm max:%f mm]", eps_min, eps_max);
0311   printout( INFO, "FieldSetup", "Delta:[chord:%f 1-step:%f intersect:%f] LargestStep %f mm",
0312         delta_chord, delta_one_step, delta_intersection, largest_step);
0313 }
0314 
0315 DECLARE_GEANT4_SETUP(Geant4FieldSetup,setup_fields)
0316 DECLARE_GEANT4ACTION(Geant4FieldTrackingSetupAction)
0317 DECLARE_GEANT4ACTION(Geant4FieldTrackingConstruction)