diff --git a/DDG4/src/Geant4CalorimeterSD.cpp b/DDG4/src/Geant4CalorimeterSD.cpp index a6edbda5f5a294bc71ccef0d608bf99abd1f9417..a1da7a7bead01067a90811a0bf9da58bd91ba127 100644 --- a/DDG4/src/Geant4CalorimeterSD.cpp +++ b/DDG4/src/Geant4CalorimeterSD.cpp @@ -49,8 +49,7 @@ namespace DD4hep { namespace Simulation { return true; } - //typedef Geant4GenericSD<Calorimeter> Geant4Calorimeter; - typedef SimpleG4SDFactory< Geant4GenericSD<Calorimeter> > Geant4Calorimeter; + typedef Geant4GenericSD<Calorimeter> Geant4Calorimeter; }} // End namespace DD4hep::Simulation DECLARE_GEANT4SENSITIVEDETECTOR(Geant4Calorimeter) @@ -105,8 +104,7 @@ namespace DD4hep { namespace Simulation { } } }; - //typedef Geant4GenericSD<OpticalCalorimeter> Geant4OpticalCalorimeter; - typedef SimpleG4SDFactory< Geant4GenericSD<OpticalCalorimeter> > Geant4OpticalCalorimeter; + typedef Geant4GenericSD<OpticalCalorimeter> Geant4OpticalCalorimeter; }} // End namespace DD4hep::Simulation DECLARE_GEANT4SENSITIVEDETECTOR(Geant4OpticalCalorimeter) diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index 003c426abb14797df25a26564d7465ff3dd60306..82ea256e651f7cf7e625eeff4b68de9c21f56679 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -8,11 +8,12 @@ //==================================================================== #include "DD4hep/LCDD.h" +#include "DD4hep/Plugins.h" #include "DD4hep/Volumes.h" #include "DD4hep/Printout.h" #include "DDG4/Geant4Field.h" #include "DDG4/Geant4Converter.h" -#include "DDG4/G4SDFactory.h" +#include "DDG4/Factories.h" #include "DDG4/Geant4SensitiveDetector.h" // ROOT includes @@ -36,8 +37,8 @@ #include "TGeoShapeAssembly.h" #include "TClass.h" #include "TMath.h" -#include "Reflex/PluginService.h" +#include "G4VSensitiveDetector.hh" #include "G4VisAttributes.hh" #include "G4ProductionCuts.hh" #include "G4VUserRegionInformation.hh" @@ -465,7 +466,8 @@ void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume bool assembly = s->IsA() == TGeoShapeAssembly::Class(); SensitiveDetector det = _v.sensitiveDetector(); - G4VSensitiveDetector* sd = 0; + G4VSensitiveDetector* sd = 0; + if ( det.isValid() ) { sd = info.g4SensDets[det.ptr()]; if ( !sd ) { @@ -704,34 +706,6 @@ void* Geant4Converter::handleLimitSet(const TNamed* limitset, const set<const TG return g4; } -// /// Convert the geometry type SensitiveDetector into the corresponding Geant4 object(s). -// void* Geant4Converter::handleSensitive(const TNamed* sens_det, const set<const TGeoVolume*>& /* volumes */) const { -// Geant4GeometryInfo& info = data(); -// G4VSensitiveDetector* g4 = info.g4SensDets[sens_det]; -// if ( !g4 ) { -// SensitiveDetector sd = Ref_t(sens_det); -// string type = sd.type(), name = sd.name(); - -// g4 = ROOT::Reflex::PluginService::Create<G4VSensitiveDetector*>(type,name,&m_lcdd); -// if ( !g4 ) { -// string tmp = type; -// tmp[0] = ::toupper(tmp[0]); -// type = "Geant4"+tmp; -// g4 = ROOT::Reflex::PluginService::Create<G4VSensitiveDetector*>(type,name,&m_lcdd); -// if ( !g4 ) { -// throw runtime_error("Geant4Converter<SensitiveDetector>: FATAL Failed to " -// "create Geant4 sensitive detector "+name+" of type "+type+"."); -// } -// } -// g4->Activate(true); -// g4->defineCollection(sd.hitsCollection()); -// G4SDManager::GetSDMpointer()->AddNewDetector(g4); -// info.g4SensDets[sens_det] = g4; -// } -// return g4; -// } - - /// Convert the geometry type SensitiveDetector into the corresponding Geant4 object(s). void* Geant4Converter::handleSensitive(const TNamed* sens_det, const set<const TGeoVolume*>& /* volumes */) const { Geant4GeometryInfo& info = data(); @@ -739,38 +713,20 @@ void* Geant4Converter::handleSensitive(const TNamed* sens_det, const set<const T if ( !g4 ) { SensitiveDetector sd = Ref_t(sens_det); string type = sd.type(), name = sd.name(); - - // g4 = ROOT::Reflex::PluginService::Create<G4VSensitiveDetector*>(type,name,&m_lcdd); - G4SDFactory* sdf = ROOT::Reflex::PluginService::Create<G4SDFactory*>(type) ; - - if ( !sdf ) { + g4 = PluginService::Create<G4VSensitiveDetector*>(type,name,&m_lcdd); + if ( !g4 ) { string tmp = type; tmp[0] = ::toupper(tmp[0]); type = "Geant4"+tmp; - - // g4 = ROOT::Reflex::PluginService::Create<G4VSensitiveDetector*>(type,name,&m_lcdd); - sdf = ROOT::Reflex::PluginService::Create<G4SDFactory*>(type) ; - - if ( !sdf ) { + g4 = PluginService::Create<G4VSensitiveDetector*>(type,name,&m_lcdd); + if ( !g4 ) { + PluginDebug dbg; + g4 = ROOT::Reflex::PluginService::Create<G4VSensitiveDetector*>(type,name,&m_lcdd); throw runtime_error("Geant4Converter<SensitiveDetector>: FATAL Failed to " "create Geant4 sensitive detector factory "+name+" of type "+type+"."); } } - g4 = sdf->createSD( name , m_lcdd ) ; - - if ( !g4 ) { - throw runtime_error("Geant4Converter<SensitiveDetector>: FATAL Failed to " - "create SD from factory "+name+" of type "+type+"."); - } - g4->Activate(true); - - // fg: don't know if this is needed ... - Geant4SensitiveDetector* g4sd = dynamic_cast<Geant4SensitiveDetector*>( g4 ) ; - if( g4sd) - g4sd->defineCollection(sd.hitsCollection()); - // ...but to be save we treat old Geant4SensitiveDetectors as before ... - G4SDManager::GetSDMpointer()->AddNewDetector(g4); info.g4SensDets[sens_det] = g4; } @@ -847,8 +803,8 @@ void Geant4Converter::handleProperties(LCDD::Properties& prp) const { /// Convert the geometry type SensitiveDetector into the corresponding Geant4 object(s). void* Geant4Converter::printSensitive(const TNamed* sens_det, const set<const TGeoVolume*>& /* volumes */) const { - Geant4GeometryInfo& info = data(); - G4VSensitiveDetector* g4 = info.g4SensDets[sens_det]; + Geant4GeometryInfo& info = data(); + G4VSensitiveDetector* g4 = info.g4SensDets[sens_det]; ConstVolumeSet& volset = info.sensitives[sens_det]; SensitiveDetector sd = Ref_t(sens_det); stringstream str; diff --git a/DDG4/src/Geant4SensitiveDetector.cpp b/DDG4/src/Geant4SensitiveDetector.cpp index bc411403ae387aba98bcae507ce361e284e73d57..fc669bffb9486f273567f07898d28420619cbdbe 100644 --- a/DDG4/src/Geant4SensitiveDetector.cpp +++ b/DDG4/src/Geant4SensitiveDetector.cpp @@ -174,7 +174,7 @@ void Geant4SensitiveDetector::dumpStep(G4Step* st, G4TouchableHistory* /* histor long long Geant4SensitiveDetector::getVolumeID(G4Step* aStep ){ - Geant4Mapping& mapping = Geant4Mapping::instance(); + //Geant4Mapping& mapping = Geant4Mapping::instance(); Geant4StepHandler step(aStep); diff --git a/DDG4/src/Geant4Setup.cpp b/DDG4/src/Geant4Setup.cpp index 8928d38c7d07e8eed808eb9f12825350c2a6fedb..6aae7297b07ba262f6eaa35d7a9ee4a780c51cf4 100644 --- a/DDG4/src/Geant4Setup.cpp +++ b/DDG4/src/Geant4Setup.cpp @@ -6,88 +6,188 @@ // Author : M.Frank // //==================================================================== + // Framework include files -#include "DDG4/Factories.h" -#include "DDG4/Geant4Field.h" -#include "DDG4/Geant4Converter.h" -#include "DD4hep/Fields.h" +#include "DD4hep/LCDD.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/Printout.h" +#include "DDG4/Geant4Setup.h" +#include "DDG4/Geant4Kernel.h" +#include "DDG4/Geant4GeneratorAction.h" +#include "DDG4/Geant4RunAction.h" +#include "DDG4/Geant4EventAction.h" +#include "DDG4/Geant4TrackingAction.h" +#include "DDG4/Geant4SteppingAction.h" +#include "DDG4/Geant4StackingAction.h" +#include "DDG4/Geant4SensDetAction.h" +#include "DDG4/Geant4ActionPhase.h" -#include "G4TransportationManager.hh" -#include "G4MagIntegratorStepper.hh" -#include "G4Mag_EqRhs.hh" -#include "G4ChordFinder.hh" -#include "G4PropagatorInField.hh" -using namespace DD4hep::Simulation; -using namespace DD4hep::Geometry; -using namespace std; -typedef DD4hep::Geometry::LCDD lcdd_t; +// C/C++ include files +#include <stdexcept> -struct PropertyMap { - const map<string,string>& vals; - PropertyMap(const map<string,string>& v) : vals(v) {} - string value(const string& key) const; - double toDouble(const string& key) const; - bool operator[](const string& key) const { return vals.find(key) != vals.end(); } -}; +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Simulation; -string PropertyMap::value(const string& key) const { - lcdd_t::PropertyValues::const_iterator iV = vals.find(key); - return iV == vals.end() ? "" : (*iV).second; +/// Standard constructor +Geant4SetupFactory<CINT>::Geant4SetupFactory(Geometry::LCDD& lcdd) : m_lcdd(lcdd) { } -double PropertyMap::toDouble(const string& key) const { - return _toDouble(value(key)); +/// Default destructor +Geant4SetupFactory<CINT>::~Geant4SetupFactory() { } -static long setup_fields(lcdd_t& lcdd, const Geant4Converter& /* cnv */, const map<string,string>& vals) { - PropertyMap pm(vals); - DD4hep::Geometry::OverlayedField fld = lcdd.field(); - G4MagIntegratorStepper* stepper = 0; - G4MagneticField* field = 0; - G4FieldManager* fieldMgr = 0; - G4TransportationManager* tr = 0; - G4PropagatorInField* propagator = 0; - G4ChordFinder* chordFinder = 0; - - lcdd_t::PropertyValues::const_iterator iV; +/// Create the Geant4 Kernel object +Geant4Kernel& Geant4SetupFactory<CINT>::kernel() { + static Geant4Kernel* k = new Geant4Kernel(m_lcdd); + return *k; +} - string eq_typ = pm.value("equation"); - string stepper_typ = pm.value("stepper"); - double value; +typedef pair<string,string> TypeName; +static TypeName splitName(const string& type_name) { + size_t idx = type_name.find("/"); + string typ=type_name, nam=type_name; + if ( idx != string::npos ) { + typ = type_name.substr(0,idx); + nam = type_name.substr(idx+1); + } + return make_pair(typ,nam); +} - field = new Geant4Field(fld); - tr = G4TransportationManager::GetTransportationManager(); - fieldMgr = tr->GetFieldManager(); +template <typename TYPE> static inline TYPE* checked_value(TYPE* p) { + if ( p ) { + return p; + } + throw runtime_error(format("Geant4Handle","Attempt to access an invalid object of type:%s!", + typeinfoName(typeid(TYPE)).c_str())); +} - fieldMgr->SetFieldChangesEnergy(fld.changesEnergy()); - fieldMgr->SetDetectorField(field); +template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle() : value(0) +{ +} - G4Mag_EqRhs* equation = ROOT::Reflex::PluginService::Create<G4Mag_EqRhs*>(eq_typ,field); - stepper = ROOT::Reflex::PluginService::Create<G4MagIntegratorStepper*>(stepper_typ,equation); +template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(TYPE* typ) : value(typ) +{ +} - iV = vals.find("min_chord_step"); - value = _toDouble((iV == vals.end()) ? string("1.0e-2 * mm") : (*iV).second); - chordFinder = new G4ChordFinder(field,value,stepper); - propagator = tr->GetPropagatorInField(); - fieldMgr->SetChordFinder(chordFinder); +template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(Geant4Handle<TYPE>& handle) +: value(0) +{ + value = handle.release(); +} - if ( pm["delta_chord"] ) { - chordFinder->SetDeltaChord(pm.toDouble("delta_chord")); - } - if ( pm["delta_one_step"] ) { - fieldMgr->SetAccuraciesWithDeltaOneStep(pm.toDouble("delta_one_step")); +template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(const Geant4Kernel& kernel,const string& type_name) +: value(0) +{ + TypeName typ = splitName(type_name); + Geant4Context* ctxt = kernel.context(); + Geant4Action* object = PluginService::Create<Geant4Action*>(typ.first,ctxt,typ.second); + if ( !object && typ.first == typ.second ) { + typ.first = typeinfoName(typeid(TYPE)); + printout(DEBUG,"Geant4Handle<Geant4Sensitive>", + "Object factory for %s not found. Try out %s", + typ.second.c_str(),typ.first.c_str()); + object = PluginService::Create<Geant4Action*>(typ.first,ctxt,typ.second); + if ( !object ) { + size_t idx = typ.first.rfind(':'); + if ( idx != string::npos ) typ.first = string(typ.first.substr(idx+1)); + printout(DEBUG,"Geant4Handle<Geant4Sensitive>", + "Try out object factory for %s",typ.first.c_str()); + object = PluginService::Create<Geant4Action*>(typ.first,ctxt,typ.second); + } } - if ( pm["delta_intersection"] ) { - fieldMgr->SetDeltaIntersection(pm.toDouble("delta_intersection")); + if ( object ) { + TYPE* ptr = dynamic_cast<TYPE*>(object); + if ( ptr ) { + value = ptr; + return; + } + throw runtime_error(format("Geant4Handle", + "Failed to convert object of type %s to handle of type %s!", + type_name.c_str(),typeinfoName(typeid(TYPE)).c_str())); } - if ( pm["eps_min"] ) { - propagator->SetMinimumEpsilonStep(pm.toDouble("eps_min")); - } - if ( pm["eps_max"] ) { - propagator->SetMaximumEpsilonStep(pm.toDouble("eps_max")); - } - return 1; + throw runtime_error(format("Geant4Handle","Failed to create object of type %s!",type_name.c_str())); +} + +template <typename TYPE> Geant4Handle<TYPE>::~Geant4Handle() { + value = 0; } -DECLARE_GEANT4_SETUP(Geant4FieldSetup,setup_fields) + +template <typename TYPE> Property& Geant4Handle<TYPE>::operator[](const string& property_name) const { + PropertyManager& pm = checked_value(value)->properties(); + return pm[property_name]; +} + +template <typename TYPE> Geant4Handle<TYPE>::operator TYPE*() const { + return checked_value(value); +} + +template <typename TYPE> TYPE* Geant4Handle<TYPE>::release() { + TYPE* ptr = checked_value(value); + value = 0; + return ptr; +} + +template <typename TYPE> TYPE* Geant4Handle<TYPE>::get() const { + return checked_value(value); +} +template <typename TYPE> TYPE* Geant4Handle<TYPE>::operator->() const { + return checked_value(value); +} + + +template <typename TYPE> Geant4Handle<TYPE>& Geant4Handle<TYPE>::operator=(Geant4Handle& handle) { + value = handle.release(); + return *this; +} + +template <typename TYPE> Geant4Handle<TYPE>& Geant4Handle<TYPE>::operator=(TYPE* typ) { + value = typ; + return *this; +} + +namespace DD4hep { namespace Simulation { + + template <> Geant4Handle<Geant4Sensitive>::Geant4Handle(const Geant4Kernel& kernel, const string& type_name, const string& detector) { + try { + Geant4Context* ctxt = kernel.context(); + TypeName typ = splitName(type_name); + Geometry::LCDD& lcdd = kernel.lcdd(); + Geometry::DetElement det = lcdd.detector(detector); + Geant4Sensitive* object = PluginService::Create<Geant4Sensitive*>(typ.first,ctxt,typ.second,&det,&lcdd); + if ( object ) { + value = object; + return; + } + } + catch(const std::exception& e) { + printout(ERROR,"Geant4Handle<Geant4Sensitive>","Exception: %s",e.what()); + } + catch(...) { + printout(ERROR,"Geant4Handle<Geant4Sensitive>","Exception: Unknown exception"); + } + throw runtime_error(format("Geant4Handle<Geant4Sensitive>", + "Failed to create sensitive object of type %s for detector %s!", + type_name.c_str(),detector.c_str())); + } + }} + +template class Geant4Handle<Geant4Action>; +template class Geant4Handle<Geant4Sensitive>; +template class Geant4Handle<Geant4ActionPhase>; +template class Geant4Handle<Geant4GeneratorAction>; +template class Geant4Handle<Geant4RunAction>; +template class Geant4Handle<Geant4EventAction>; +template class Geant4Handle<Geant4TrackingAction>; +template class Geant4Handle<Geant4SteppingAction>; +template class Geant4Handle<Geant4StackingAction>; + +template class Geant4Handle<Geant4GeneratorActionSequence>; +template class Geant4Handle<Geant4RunActionSequence>; +template class Geant4Handle<Geant4EventActionSequence>; +template class Geant4Handle<Geant4TrackingActionSequence>; +template class Geant4Handle<Geant4SteppingActionSequence>; +template class Geant4Handle<Geant4StackingActionSequence>; +template class Geant4Handle<Geant4SensDetActionSequence>; diff --git a/DDG4/src/Geant4TrackerCombineSD.cpp b/DDG4/src/Geant4TrackerCombineSD.cpp index 51c1dbc416dc4a1ce293ff2ed11127c4c4ddfc56..573f1814b65df46c9e05513d6231847b252c74e3 100644 --- a/DDG4/src/Geant4TrackerCombineSD.cpp +++ b/DDG4/src/Geant4TrackerCombineSD.cpp @@ -107,8 +107,7 @@ namespace DD4hep { namespace Simulation { } return return_code; } - // typedef Geant4GenericSD<TrackerCombine> Geant4TrackerCombine; - typedef SimpleG4SDFactory< Geant4GenericSD<TrackerCombine> > Geant4TrackerCombine; + typedef Geant4GenericSD<TrackerCombine> Geant4TrackerCombine; }} // End namespace DD4hep::Simulation DECLARE_GEANT4SENSITIVEDETECTOR(Geant4TrackerCombine) diff --git a/DDG4/src/Geant4TrackerSD.cpp b/DDG4/src/Geant4TrackerSD.cpp index a0884980871e8dde4b4a43b25fb8abcd22ae3f64..91b0de3ff96648d1c338664ef251e5c03d39f39d 100644 --- a/DDG4/src/Geant4TrackerSD.cpp +++ b/DDG4/src/Geant4TrackerSD.cpp @@ -56,8 +56,7 @@ namespace DD4hep { namespace Simulation { collection(0)->insert(hit); return hit != 0; } - //typedef Geant4GenericSD<Tracker> Geant4Tracker; - typedef SimpleG4SDFactory< Geant4GenericSD<Tracker> > Geant4Tracker; + typedef Geant4GenericSD<Tracker> Geant4Tracker; }} // End namespace DD4hep::Simulation DECLARE_GEANT4SENSITIVEDETECTOR(Geant4Tracker) diff --git a/DDG4/src/Geant4VolumeManager.cpp b/DDG4/src/Geant4VolumeManager.cpp index 57fdb518a3dbe642c23f28e15c1da11b875cac39..53cdbd35daba2412b912c231991e73790a17a748 100644 --- a/DDG4/src/Geant4VolumeManager.cpp +++ b/DDG4/src/Geant4VolumeManager.cpp @@ -80,7 +80,7 @@ namespace { } else { printout(WARNING,"VolumeManager", - "Strange constellation volume %s is sensitive, but has no readout! sd:%p", + "populate: Strange constellation volume %s is sensitive, but has no readout! sd:%p", pv.volume().name(), sd.ptr()); } } @@ -109,13 +109,13 @@ namespace { } } if ( m_geo.g4Paths.find(path) != m_geo.g4Paths.end() ) { - cout << "Severe error: Duplicated Geant4 path!!!!" << endl; + printout(ERROR,"VolumeManager","populate: Severe error: Duplicated Geant4 path!!!!"); } m_geo.g4Paths[path] = code; m_entries.insert(code); } else { - cout << "Severe error: Duplicated Volume entry:" << (void*)code << endl; + printout(ERROR,"VolumeManager","populate: Severe error: Duplicated Volume entry: %X",code); } } };