File indexing completed on 2025-01-30 09:17:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
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 {
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 ) {
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 ) {
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
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
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
0217
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 ) {
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 }