File indexing completed on 2025-01-18 09:14:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef DD4HEP_DDG4_GEANT4FIELDTRACKINGSETUP_H
0015 #define DD4HEP_DDG4_GEANT4FIELDTRACKINGSETUP_H 1
0016
0017
0018 #include <DD4hep/Detector.h>
0019 #include <DDG4/Geant4ActionPhase.h>
0020 #include <DDG4/Geant4DetectorConstruction.h>
0021
0022
0023 namespace dd4hep {
0024
0025
0026 namespace sim {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 struct Geant4FieldTrackingSetup {
0041 protected:
0042
0043
0044 std::string eq_typ;
0045
0046 std::string stepper_typ;
0047
0048 double min_chord_step;
0049
0050 double delta_chord;
0051
0052 double delta_one_step;
0053
0054 double delta_intersection;
0055
0056 double eps_min;
0057
0058 double eps_max;
0059
0060 double largest_step;
0061
0062 public:
0063
0064 Geant4FieldTrackingSetup();
0065
0066 virtual ~Geant4FieldTrackingSetup();
0067
0068 virtual int execute(Detector& description);
0069 };
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 class Geant4FieldTrackingSetupAction :
0081 public Geant4PhaseAction,
0082 public Geant4FieldTrackingSetup
0083 {
0084 protected:
0085 public:
0086
0087 Geant4FieldTrackingSetupAction(Geant4Context* context, const std::string& nam);
0088
0089 virtual ~Geant4FieldTrackingSetupAction() {}
0090
0091 void operator()();
0092 };
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 class Geant4FieldTrackingConstruction :
0104 public Geant4DetectorConstruction,
0105 public Geant4FieldTrackingSetup
0106 {
0107 protected:
0108 public:
0109
0110 Geant4FieldTrackingConstruction(Geant4Context* context, const std::string& nam);
0111
0112
0113 virtual ~Geant4FieldTrackingConstruction() {}
0114
0115
0116 void constructField(Geant4DetectorConstructionContext *ctxt);
0117
0118 };
0119 }
0120 }
0121 #endif
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
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
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
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
0186 Geant4FieldTrackingSetup::~Geant4FieldTrackingSetup() {
0187 }
0188
0189
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& ,
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
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
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
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
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)