Back to home page

EIC code displayed by LXR

 
 

    


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

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/Plugins.h>
0017 #include <DD4hep/Printout.h>
0018 
0019 #include <DDG4/Geant4Handle.h>
0020 #include <DDG4/Geant4Kernel.h>
0021 #include <DDG4/Geant4GeneratorAction.h>
0022 #include <DDG4/Geant4RunAction.h>
0023 #include <DDG4/Geant4EventAction.h>
0024 #include <DDG4/Geant4TrackingAction.h>
0025 #include <DDG4/Geant4SteppingAction.h>
0026 #include <DDG4/Geant4StackingAction.h>
0027 #include <DDG4/Geant4SensDetAction.h>
0028 #include <DDG4/Geant4PhysicsList.h>
0029 #include <DDG4/Geant4ActionPhase.h>
0030 #include <DDG4/Geant4UserInitialization.h>
0031 #include <DDG4/Geant4DetectorConstruction.h>
0032 
0033 // Geant4 include files
0034 #include <G4Threading.hh>
0035 #include <G4AutoLock.hh>
0036 
0037 using namespace dd4hep::sim;
0038 namespace {
0039   G4Mutex creation_mutex=G4MUTEX_INITIALIZER;
0040 }
0041 
0042 namespace dd4hep {
0043   namespace sim {
0044 
0045     template <typename TYPE> static inline TYPE* checked_value(TYPE* p) {
0046       if (p) {
0047         return p;
0048       }
0049       except("Geant4Handle","Attempt to access an invalid object of type:%s!",
0050              typeName(typeid(TYPE)).c_str());
0051       return 0;
0052     }
0053 
0054     template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(TYPE* typ) : value(typ)  {
0055       if (value)
0056         value->addRef();
0057     }
0058 
0059     template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(const Geant4Handle<TYPE>& handle) : value(handle.get())
0060     {
0061       if (value)
0062         value->addRef();
0063     }
0064 
0065     template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(Geant4Handle<TYPE>&& handle) : value(handle.get())
0066     {
0067       handle.value = 0;
0068     }
0069 
0070     template <typename TYPE> TYPE* _create_object(Geant4Kernel& kernel, const TypeName& typ)    {
0071       Geant4Context* ctxt = kernel.workerContext();
0072       Geant4Action* object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second);
0073       if (!object && typ.first == typ.second) {
0074         std::string _t = typeName(typeid(TYPE));
0075         printout(DEBUG, "Geant4Handle", "Object factory for %s not found. Try out %s",
0076                  typ.second.c_str(), _t.c_str());
0077         object = PluginService::Create<Geant4Action*>(_t, ctxt, typ.second);
0078         if (!object) {
0079           size_t idx = _t.rfind(':');
0080           if (idx != std::string::npos)
0081             _t = std::string(_t.substr(idx + 1));
0082           printout(DEBUG, "Geant4Handle", "Try out object factory for %s",_t.c_str());
0083           object = PluginService::Create<Geant4Action*>(_t, ctxt, typ.second);
0084         }
0085       }
0086       if (object)  {
0087         TYPE* ptr = dynamic_cast<TYPE*>(object);
0088         if (ptr)  {
0089           return ptr;
0090         }
0091         std::string _t = typeName(typeid(TYPE));
0092         except("Geant4Handle", "Failed to convert object of type '%s' with name '%s' to handle of type '%s'!",
0093                typ.first.c_str(),typ.second.c_str(),_t.c_str());
0094       }
0095       except("Geant4Handle", "Failed to create object of type %s!", typ.first.c_str());
0096       return 0;
0097     }
0098 
0099     template <typename TYPE, typename CONT> 
0100     TYPE* _create_share(Geant4Kernel& kernel,
0101                         CONT& (Geant4ActionContainer::*pmf)(), 
0102                         const std::string& type_name, 
0103                         const std::string& shared_typ, 
0104                         bool shared, TYPE*)
0105     {
0106       TypeName typ = TypeName::split(type_name);
0107       Geant4Kernel& k = shared ? kernel.master() : kernel;
0108       if ( shared && k.isMultiThreaded() )   {
0109         typedef typename TYPE::shared_type _ST;
0110         TypeName s_type = TypeName::split(shared_typ+"/"+typ.second);
0111         _ST* object = (_ST*)_create_object<TYPE>(kernel,s_type);
0112         CONT& container = (k.*pmf)();
0113         TYPE* value = 0;
0114         { // Need to protect the global action sequence!
0115           G4AutoLock protection_lock(&creation_mutex);
0116           value = container.get(typ.second);
0117           if ( !value ) {
0118             value = _create_object<TYPE>(k,typ);
0119             container.adopt(value);
0120             value->release();
0121           }
0122         }
0123         object->use(value);
0124         value->info("+++ Created shared object for %s of type %s.",
0125                     typ.second.c_str(),typeName(typeid(TYPE)).c_str());
0126         return object;
0127       }
0128       TYPE* value = _create_object<TYPE>(k,typ);
0129       return value;
0130     }
0131 
0132     template <typename TYPE> 
0133     Geant4Handle<TYPE>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool /* shared */)  {
0134       value = _create_object<TYPE>(kernel,TypeName::split(type_name));
0135     }
0136 
0137     template <typename TYPE> 
0138     Geant4Handle<TYPE>::Geant4Handle(Geant4Kernel& kernel, const char* type_name_char, bool /* shared */)  {
0139       value = _create_object<TYPE>(kernel,TypeName::split(type_name_char ? type_name_char : "????"));
0140     }
0141 
0142     template <typename TYPE> Geant4Handle<TYPE>::~Geant4Handle() {
0143       if (value)
0144         value->release();
0145       value = 0;
0146     }
0147 
0148     template <typename TYPE> TYPE* Geant4Handle<TYPE>::release() {
0149       TYPE* temp = value;
0150       value = 0;
0151       return temp;
0152     }
0153 
0154     template <typename TYPE> void Geant4Handle<TYPE>::checked_assign(TYPE* p) {
0155       if (value)
0156         value->release();
0157       value = checked_value(p);
0158       if (value)
0159         value->addRef();
0160     }
0161 
0162     template <typename TYPE> Property& Geant4Handle<TYPE>::operator[](const std::string& property_name) const {
0163       PropertyManager& pm = checked_value(value)->properties();
0164       return pm[property_name];
0165     }
0166 
0167     template <typename TYPE> Geant4Handle<TYPE>::operator TYPE*() const {
0168       return checked_value(value);
0169     }
0170 
0171     template <typename TYPE> bool Geant4Handle<TYPE>::operator!() const {
0172       return 0 == value;
0173     }
0174 
0175     template <typename TYPE> TYPE* Geant4Handle<TYPE>::get() const {
0176       return checked_value(value);
0177     }
0178 
0179     template <typename TYPE> TYPE* Geant4Handle<TYPE>::operator->() const {
0180       return checked_value(value);
0181     }
0182 
0183     template <typename TYPE> Geant4Action* Geant4Handle<TYPE>::action() const {
0184       return checked_value(value);
0185     }
0186 
0187     /// Assignment operator
0188     template <typename TYPE> Geant4Handle<TYPE>& Geant4Handle<TYPE>::operator=(const Geant4Handle& handle) {
0189       if ( &handle != this )  {
0190         TYPE* point = value;
0191         value = handle.get();
0192         if ( value ) value->addRef();
0193         if ( point ) point->release();
0194       }
0195       return *this;
0196     }
0197 
0198     /// Assignment move operator
0199     template <typename TYPE> Geant4Handle<TYPE>& Geant4Handle<TYPE>::operator=(Geant4Handle&& handle) {
0200       if ( value ) value->release();
0201       value = handle.get();
0202       handle.value = 0;
0203       return *this;
0204     }
0205 
0206     template <typename TYPE> Geant4Handle<TYPE>& Geant4Handle<TYPE>::operator=(TYPE* pointer) {
0207       if ( pointer != value )  {
0208         TYPE* point = value;
0209         value = pointer;
0210         if ( value ) value->addRef();
0211         if ( point ) point->release();
0212       }
0213       return *this;
0214     }
0215 
0216     //namespace dd4hep {
0217     //  namespace sim {
0218 
0219     KernelHandle::KernelHandle()  {
0220       value = &Geant4Kernel::instance(Detector::getInstance());
0221     }
0222     KernelHandle::KernelHandle(Geant4Kernel* k) : value(k)  {
0223     }
0224     KernelHandle KernelHandle::worker()  {
0225       Geant4Kernel* k = value ? &value->worker(Geant4Kernel::thread_self()) : 0;
0226       if ( k ) return KernelHandle(k);
0227       except("KernelHandle", "Cannot access worker context [Invalid Handle]");
0228       return KernelHandle(0);
0229     }
0230     void KernelHandle::destroy()  {
0231       if ( value ) delete value;
0232       value = 0;
0233     }
0234 
0235     template <> 
0236     Geant4Handle<Geant4RunAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared)  {
0237       value = _create_share(kernel,&Geant4ActionContainer::runAction, type_name,
0238                             "Geant4SharedRunAction", shared, null());
0239     }
0240     template <> 
0241     Geant4Handle<Geant4RunAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared)  {
0242       value = _create_share(kernel,&Geant4ActionContainer::runAction, type_name,
0243                             "Geant4SharedRunAction", shared, null());
0244     }
0245 
0246     template <> 
0247     Geant4Handle<Geant4EventAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared)  {
0248       value = _create_share(kernel,&Geant4ActionContainer::eventAction, type_name,
0249                             "Geant4SharedEventAction", shared, null());
0250     }
0251     template <> 
0252     Geant4Handle<Geant4EventAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared)  {
0253       value = _create_share(kernel,&Geant4ActionContainer::eventAction, type_name,
0254                             "Geant4SharedEventAction", shared, null());
0255     }
0256 
0257     template <> 
0258     Geant4Handle<Geant4GeneratorAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared)  {
0259       value = _create_share(kernel,&Geant4ActionContainer::generatorAction, type_name,
0260                             "Geant4SharedGeneratorAction", shared, null());
0261     }
0262     template <> 
0263     Geant4Handle<Geant4GeneratorAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared)  {
0264       value = _create_share(kernel,&Geant4ActionContainer::generatorAction, type_name,
0265                             "Geant4SharedGeneratorAction", shared, null());
0266     }
0267 
0268     template <> 
0269     Geant4Handle<Geant4TrackingAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared)  {
0270       value = _create_share(kernel,&Geant4ActionContainer::trackingAction, type_name,
0271                             "Geant4SharedTrackingAction", shared, null());
0272     }
0273     template <> 
0274     Geant4Handle<Geant4TrackingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared)  {
0275       value = _create_share(kernel,&Geant4ActionContainer::trackingAction, type_name,
0276                             "Geant4SharedTrackingAction", shared, null());
0277     }
0278 
0279     template <> 
0280     Geant4Handle<Geant4SteppingAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared)  {
0281       value = _create_share(kernel,&Geant4ActionContainer::steppingAction, type_name,
0282                             "Geant4SharedSteppingAction", shared, null());
0283     }
0284     template <> 
0285     Geant4Handle<Geant4SteppingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared)  {
0286       value = _create_share(kernel,&Geant4ActionContainer::steppingAction, type_name,
0287                             "Geant4SharedSteppingAction", shared, null());
0288     }
0289 
0290     template <> 
0291     Geant4Handle<Geant4StackingAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared)  {
0292       value = _create_share(kernel,&Geant4ActionContainer::stackingAction, type_name,
0293                             "Geant4SharedStackingAction", shared, null());
0294     }
0295     template <> 
0296     Geant4Handle<Geant4StackingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared)  {
0297       value = _create_share(kernel,&Geant4ActionContainer::stackingAction, type_name,
0298                             "Geant4SharedStackingAction", shared, null());
0299     }
0300 
0301     template <> Geant4Handle<Geant4Sensitive>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name,
0302                                                             const std::string& detector, bool /* shared */) {
0303       try {
0304         Geant4Context*  ctxt = kernel.workerContext();
0305         TypeName         typ = TypeName::split(type_name);
0306         Detector&        dsc = kernel.detectorDescription();
0307         DetElement       det = dsc.detector(detector);
0308         Geant4Sensitive* obj = PluginService::Create<Geant4Sensitive*>(typ.first, ctxt, typ.second, &det, &dsc);
0309         if ( obj ) {
0310           value = obj;
0311           return;
0312         }
0313       }
0314       catch (const std::exception& e) {
0315         printout(ERROR, "Geant4Handle<Geant4Sensitive>", "Exception: %s", e.what());
0316       }
0317       catch (...) {
0318         printout(ERROR, "Geant4Handle<Geant4Sensitive>", "Exception: Unknown exception");
0319       }
0320       except("Geant4Handle<Geant4Sensitive>", 
0321              "Failed to create sensitive object of type %s for detector %s!",
0322              type_name.c_str(), detector.c_str());
0323     }
0324   
0325 
0326     template class Geant4Handle<Geant4Action>;
0327     template class Geant4Handle<Geant4Filter>;
0328     template class Geant4Handle<Geant4Sensitive>;
0329     template class Geant4Handle<Geant4ActionPhase>;
0330     template class Geant4Handle<Geant4PhaseAction>;
0331     template class Geant4Handle<Geant4GeneratorAction>;
0332     template class Geant4Handle<Geant4RunAction>;
0333     template class Geant4Handle<Geant4EventAction>;
0334     template class Geant4Handle<Geant4TrackingAction>;
0335     template class Geant4Handle<Geant4SteppingAction>;
0336     template class Geant4Handle<Geant4StackingAction>;
0337     template class Geant4Handle<Geant4DetectorConstruction>;
0338     template class Geant4Handle<Geant4PhysicsList>;
0339     template class Geant4Handle<Geant4UserInitialization>;
0340 
0341     template class Geant4Handle<Geant4GeneratorActionSequence>;
0342     template class Geant4Handle<Geant4PhysicsListActionSequence>;
0343     template class Geant4Handle<Geant4RunActionSequence>;
0344     template class Geant4Handle<Geant4EventActionSequence>;
0345     template class Geant4Handle<Geant4TrackingActionSequence>;
0346     template class Geant4Handle<Geant4SteppingActionSequence>;
0347     template class Geant4Handle<Geant4StackingActionSequence>;
0348     template class Geant4Handle<Geant4SensDetActionSequence>;
0349     template class Geant4Handle<Geant4UserInitializationSequence>;
0350     template class Geant4Handle<Geant4DetectorConstructionSequence>;
0351   }
0352 }