DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
Geant4Handle.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
15 #include <DD4hep/Detector.h>
16 #include <DD4hep/Plugins.h>
17 #include <DD4hep/Printout.h>
18 
19 #include <DDG4/Geant4Handle.h>
20 #include <DDG4/Geant4Kernel.h>
22 #include <DDG4/Geant4RunAction.h>
23 #include <DDG4/Geant4EventAction.h>
28 #include <DDG4/Geant4PhysicsList.h>
29 #include <DDG4/Geant4ActionPhase.h>
32 
33 // Geant4 include files
34 #include <G4Threading.hh>
35 #include <G4AutoLock.hh>
36 
37 using namespace dd4hep::sim;
38 namespace {
39  G4Mutex creation_mutex=G4MUTEX_INITIALIZER;
40 }
41 
42 namespace dd4hep {
43  namespace sim {
44 
45  template <typename TYPE> static inline TYPE* checked_value(TYPE* p) {
46  if (p) {
47  return p;
48  }
49  except("Geant4Handle","Attempt to access an invalid object of type:%s!",
50  typeName(typeid(TYPE)).c_str());
51  return 0;
52  }
53 
54  template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(TYPE* typ) : value(typ) {
55  if (value)
56  value->addRef();
57  }
58 
59  template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(const Geant4Handle<TYPE>& handle) : value(handle.get())
60  {
61  if (value)
62  value->addRef();
63  }
64 
65  template <typename TYPE> Geant4Handle<TYPE>::Geant4Handle(Geant4Handle<TYPE>&& handle) : value(handle.get())
66  {
67  handle.value = 0;
68  }
69 
70  template <typename TYPE> TYPE* _create_object(Geant4Kernel& kernel, const TypeName& typ) {
71  Geant4Context* ctxt = kernel.workerContext();
72  Geant4Action* object = PluginService::Create<Geant4Action*>(typ.first, ctxt, typ.second);
73  if (!object && typ.first == typ.second) {
74  std::string _t = typeName(typeid(TYPE));
75  printout(DEBUG, "Geant4Handle", "Object factory for %s not found. Try out %s",
76  typ.second.c_str(), _t.c_str());
77  object = PluginService::Create<Geant4Action*>(_t, ctxt, typ.second);
78  if (!object) {
79  size_t idx = _t.rfind(':');
80  if (idx != std::string::npos)
81  _t = std::string(_t.substr(idx + 1));
82  printout(DEBUG, "Geant4Handle", "Try out object factory for %s",_t.c_str());
83  object = PluginService::Create<Geant4Action*>(_t, ctxt, typ.second);
84  }
85  }
86  if (object) {
87  TYPE* ptr = dynamic_cast<TYPE*>(object);
88  if (ptr) {
89  return ptr;
90  }
91  std::string _t = typeName(typeid(TYPE));
92  except("Geant4Handle", "Failed to convert object of type '%s' with name '%s' to handle of type '%s'!",
93  typ.first.c_str(),typ.second.c_str(),_t.c_str());
94  }
95  except("Geant4Handle", "Failed to create object of type %s!", typ.first.c_str());
96  return 0;
97  }
98 
99  template <typename TYPE, typename CONT>
101  CONT& (Geant4ActionContainer::*pmf)(),
102  const std::string& type_name,
103  const std::string& shared_typ,
104  bool shared, TYPE*)
105  {
106  TypeName typ = TypeName::split(type_name);
107  Geant4Kernel& k = shared ? kernel.master() : kernel;
108  if ( shared && k.isMultiThreaded() ) {
109  typedef typename TYPE::shared_type _ST;
110  TypeName s_type = TypeName::split(shared_typ+"/"+typ.second);
111  _ST* object = (_ST*)_create_object<TYPE>(kernel,s_type);
112  CONT& container = (k.*pmf)();
113  TYPE* value = 0;
114  { // Need to protect the global action sequence!
115  G4AutoLock protection_lock(&creation_mutex);
116  value = container.get(typ.second);
117  if ( !value ) {
118  value = _create_object<TYPE>(k,typ);
119  container.adopt(value);
120  value->release();
121  }
122  }
123  object->use(value);
124  value->info("+++ Created shared object for %s of type %s.",
125  typ.second.c_str(),typeName(typeid(TYPE)).c_str());
126  return object;
127  }
128  TYPE* value = _create_object<TYPE>(k,typ);
129  return value;
130  }
131 
132  template <typename TYPE>
133  Geant4Handle<TYPE>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool /* shared */) {
134  value = _create_object<TYPE>(kernel,TypeName::split(type_name));
135  }
136 
137  template <typename TYPE>
138  Geant4Handle<TYPE>::Geant4Handle(Geant4Kernel& kernel, const char* type_name_char, bool /* shared */) {
139  value = _create_object<TYPE>(kernel,TypeName::split(type_name_char ? type_name_char : "????"));
140  }
141 
142  template <typename TYPE> Geant4Handle<TYPE>::~Geant4Handle() {
143  if (value)
144  value->release();
145  value = 0;
146  }
147 
148  template <typename TYPE> TYPE* Geant4Handle<TYPE>::release() {
149  TYPE* temp = value;
150  value = 0;
151  return temp;
152  }
153 
154  template <typename TYPE> void Geant4Handle<TYPE>::checked_assign(TYPE* p) {
155  if (value)
156  value->release();
157  value = checked_value(p);
158  if (value)
159  value->addRef();
160  }
161 
162  template <typename TYPE> Property& Geant4Handle<TYPE>::operator[](const std::string& property_name) const {
163  PropertyManager& pm = checked_value(value)->properties();
164  return pm[property_name];
165  }
166 
167  template <typename TYPE> Geant4Handle<TYPE>::operator TYPE*() const {
168  return checked_value(value);
169  }
170 
171  template <typename TYPE> bool Geant4Handle<TYPE>::operator!() const {
172  return 0 == value;
173  }
174 
175  template <typename TYPE> TYPE* Geant4Handle<TYPE>::get() const {
176  return checked_value(value);
177  }
178 
179  template <typename TYPE> TYPE* Geant4Handle<TYPE>::operator->() const {
180  return checked_value(value);
181  }
182 
183  template <typename TYPE> Geant4Action* Geant4Handle<TYPE>::action() const {
184  return checked_value(value);
185  }
186 
189  if ( &handle != this ) {
190  TYPE* point = value;
191  value = handle.get();
192  if ( value ) value->addRef();
193  if ( point ) point->release();
194  }
195  return *this;
196  }
197 
200  if ( value ) value->release();
201  value = handle.get();
202  handle.value = 0;
203  return *this;
204  }
205 
206  template <typename TYPE> Geant4Handle<TYPE>& Geant4Handle<TYPE>::operator=(TYPE* pointer) {
207  if ( pointer != value ) {
208  TYPE* point = value;
209  value = pointer;
210  if ( value ) value->addRef();
211  if ( point ) point->release();
212  }
213  return *this;
214  }
215 
216  //namespace dd4hep {
217  // namespace sim {
218 
221  }
223  }
226  if ( k ) return KernelHandle(k);
227  except("KernelHandle", "Cannot access worker context [Invalid Handle]");
228  return KernelHandle(0);
229  }
231  if ( value ) delete value;
232  value = 0;
233  }
234 
235  template <>
236  Geant4Handle<Geant4RunAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared) {
237  value = _create_share(kernel,&Geant4ActionContainer::runAction, type_name,
238  "Geant4SharedRunAction", shared, null());
239  }
240  template <>
241  Geant4Handle<Geant4RunAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) {
242  value = _create_share(kernel,&Geant4ActionContainer::runAction, type_name,
243  "Geant4SharedRunAction", shared, null());
244  }
245 
246  template <>
247  Geant4Handle<Geant4EventAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared) {
248  value = _create_share(kernel,&Geant4ActionContainer::eventAction, type_name,
249  "Geant4SharedEventAction", shared, null());
250  }
251  template <>
252  Geant4Handle<Geant4EventAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) {
253  value = _create_share(kernel,&Geant4ActionContainer::eventAction, type_name,
254  "Geant4SharedEventAction", shared, null());
255  }
256 
257  template <>
258  Geant4Handle<Geant4GeneratorAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared) {
259  value = _create_share(kernel,&Geant4ActionContainer::generatorAction, type_name,
260  "Geant4SharedGeneratorAction", shared, null());
261  }
262  template <>
263  Geant4Handle<Geant4GeneratorAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) {
264  value = _create_share(kernel,&Geant4ActionContainer::generatorAction, type_name,
265  "Geant4SharedGeneratorAction", shared, null());
266  }
267 
268  template <>
269  Geant4Handle<Geant4TrackingAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared) {
270  value = _create_share(kernel,&Geant4ActionContainer::trackingAction, type_name,
271  "Geant4SharedTrackingAction", shared, null());
272  }
273  template <>
274  Geant4Handle<Geant4TrackingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) {
275  value = _create_share(kernel,&Geant4ActionContainer::trackingAction, type_name,
276  "Geant4SharedTrackingAction", shared, null());
277  }
278 
279  template <>
280  Geant4Handle<Geant4SteppingAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared) {
281  value = _create_share(kernel,&Geant4ActionContainer::steppingAction, type_name,
282  "Geant4SharedSteppingAction", shared, null());
283  }
284  template <>
285  Geant4Handle<Geant4SteppingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) {
286  value = _create_share(kernel,&Geant4ActionContainer::steppingAction, type_name,
287  "Geant4SharedSteppingAction", shared, null());
288  }
289 
290  template <>
291  Geant4Handle<Geant4StackingAction>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name, bool shared) {
292  value = _create_share(kernel,&Geant4ActionContainer::stackingAction, type_name,
293  "Geant4SharedStackingAction", shared, null());
294  }
295  template <>
296  Geant4Handle<Geant4StackingAction>::Geant4Handle(Geant4Kernel& kernel, const char* type_name, bool shared) {
297  value = _create_share(kernel,&Geant4ActionContainer::stackingAction, type_name,
298  "Geant4SharedStackingAction", shared, null());
299  }
300 
301  template <> Geant4Handle<Geant4Sensitive>::Geant4Handle(Geant4Kernel& kernel, const std::string& type_name,
302  const std::string& detector, bool /* shared */) {
303  try {
304  Geant4Context* ctxt = kernel.workerContext();
305  TypeName typ = TypeName::split(type_name);
306  Detector& dsc = kernel.detectorDescription();
307  DetElement det = dsc.detector(detector);
308  Geant4Sensitive* obj = PluginService::Create<Geant4Sensitive*>(typ.first, ctxt, typ.second, &det, &dsc);
309  if ( obj ) {
310  value = obj;
311  return;
312  }
313  }
314  catch (const std::exception& e) {
315  printout(ERROR, "Geant4Handle<Geant4Sensitive>", "Exception: %s", e.what());
316  }
317  catch (...) {
318  printout(ERROR, "Geant4Handle<Geant4Sensitive>", "Exception: Unknown exception");
319  }
320  except("Geant4Handle<Geant4Sensitive>",
321  "Failed to create sensitive object of type %s for detector %s!",
322  type_name.c_str(), detector.c_str());
323  }
324 
325 
326  template class Geant4Handle<Geant4Action>;
327  template class Geant4Handle<Geant4Filter>;
328  template class Geant4Handle<Geant4Sensitive>;
329  template class Geant4Handle<Geant4ActionPhase>;
330  template class Geant4Handle<Geant4PhaseAction>;
332  template class Geant4Handle<Geant4RunAction>;
333  template class Geant4Handle<Geant4EventAction>;
334  template class Geant4Handle<Geant4TrackingAction>;
335  template class Geant4Handle<Geant4SteppingAction>;
336  template class Geant4Handle<Geant4StackingAction>;
338  template class Geant4Handle<Geant4PhysicsList>;
340 
351  }
352 }
Geant4DetectorConstruction.h
dd4hep::sim::Geant4Handle::value
TYPE * value
Pointer to referenced object.
Definition: Geant4Handle.h:47
dd4hep::Property
The property class to assign options to actions.
Definition: ComponentProperties.h:48
dd4hep::Detector::detector
virtual DetElement detector(const std::string &name) const =0
Retrieve a subdetector element by its name from the detector description.
Detector.h
dd4hep::exception
void exception(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:69
Geant4Handle.h
dd4hep::sim::Geant4Handle::operator[]
Property & operator[](const std::string &property_name) const
Property accessor.
Definition: Geant4Handle.cpp:162
Geant4SensDetAction.h
Geant4TrackingAction.h
Geant4RunAction.h
Geant4EventAction.h
dd4hep::sim::Geant4Kernel
Class, which allows all Geant4Action derivatives to access the DDG4 kernel structures.
Definition: Geant4Kernel.h:64
dd4hep::sim::KernelHandle
Handle to Geant4 actions with built-in creation mechanism.
Definition: Geant4Handle.h:96
dd4hep::sim::KernelHandle::worker
KernelHandle worker()
Access to worker thread.
Definition: Geant4Handle.cpp:224
dd4hep::sim::TypeName::second
std::string second
Definition: Geant4Action.h:85
Geant4PhysicsList.h
dd4hep::sim::Geant4ActionContainer::workerContext
Geant4Context * workerContext()
Thread's Geant4 execution context.
Definition: Geant4ActionContainer.cpp:65
Geant4SteppingAction.h
dd4hep::sim::Geant4Kernel::detectorDescription
Detector & detectorDescription() const
Access to detector description.
Definition: Geant4Kernel.h:201
dd4hep::sim::Geant4Kernel::worker
Geant4Kernel & worker(unsigned long thread_identifier, bool create_if=false)
Access worker instance by its identifier.
Definition: Geant4Kernel.cpp:230
dd4hep::sim::_create_object
TYPE * _create_object(Geant4Kernel &kernel, const TypeName &typ)
Definition: Geant4Handle.cpp:70
dd4hep::sim::Geant4ActionContainer::stackingAction
Geant4StackingActionSequence & stackingAction()
Access stacking action sequence.
Definition: Geant4ActionContainer.h:145
dd4hep::sim::Geant4Handle::~Geant4Handle
~Geant4Handle()
Default destructor.
Definition: Geant4Handle.cpp:142
dd4hep::Detector::getInstance
static Detector & getInstance(const std::string &name="default")
—Factory method----—
Definition: DetectorImp.cpp:150
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::sim::Geant4ActionContainer::eventAction
Geant4EventActionSequence & eventAction()
Access run action sequence.
Definition: Geant4ActionContainer.h:124
Geant4GeneratorAction.h
dd4hep::sim::KernelHandle::value
Geant4Kernel * value
Pointer to referenced object.
Definition: Geant4Handle.h:99
Geant4StackingAction.h
dd4hep::sim::Geant4ActionContainer::trackingAction
Geant4TrackingActionSequence & trackingAction()
Access tracking action sequence.
Definition: Geant4ActionContainer.h:138
dd4hep::sim::Geant4Handle::operator=
Geant4Handle & operator=(const Geant4Handle &handle)
Assignment operator.
Definition: Geant4Handle.cpp:188
Plugins.h
dd4hep::sim::TypeName::first
std::string first
Definition: Geant4Action.h:84
dd4hep::sim::Geant4ActionContainer::runAction
Geant4RunActionSequence & runAction()
Access run action sequence.
Definition: Geant4ActionContainer.h:117
dd4hep::sim::Geant4Action
Default base class for all Geant 4 actions and derivates thereof.
Definition: Geant4Action.h:113
dd4hep::sim::Geant4Kernel::thread_self
static unsigned long int thread_self()
Access thread identifier.
Definition: Geant4Kernel.cpp:211
dd4hep::sim::Geant4Handle::release
TYPE * release()
Release the underlying object.
Definition: Geant4Handle.cpp:148
dd4hep::sim::Geant4Handle::operator->
TYPE * operator->() const
Access to the underlying object.
Definition: Geant4Handle.cpp:179
dd4hep::sim::Geant4ActionContainer::steppingAction
Geant4SteppingActionSequence & steppingAction()
Access stepping action sequence.
Definition: Geant4ActionContainer.h:131
dd4hep::sim::TypeName::split
static TypeName split(const std::string &type_name)
Split string pair according to default delimiter ('/')
Definition: Geant4Action.cpp:40
dd4hep::sim::Geant4Handle::Geant4Handle
Geant4Handle()=default
Default constructor.
dd4hep::sim::KernelHandle::destroy
void destroy()
Destroy referenced object (program termination)
Definition: Geant4Handle.cpp:230
dd4hep::sim::Geant4Handle
Handle to Geant4 actions with built-in creation mechanism.
Definition: Geant4Config.h:28
dd4hep::sim::Geant4Handle::operator!
bool operator!() const
Validity check.
Definition: Geant4Handle.cpp:171
dd4hep::sim::KernelHandle::KernelHandle
KernelHandle()
Default constructor.
Definition: Geant4Handle.cpp:219
dd4hep::sim::Geant4Kernel::isMultiThreaded
bool isMultiThreaded() const
Definition: Geant4Kernel.h:161
dd4hep::sim::Geant4Kernel::instance
static Geant4Kernel & instance(Detector &description)
Instance accessor.
Definition: Geant4Kernel.cpp:163
dd4hep::sim
Namespace for the Geant4 based simulation part of the AIDA detector description toolkit.
Definition: Geant4Output2EDM4hep.cpp:49
dd4hep::PropertyManager
Manager to ease the handling of groups of properties.
Definition: ComponentProperties.h:174
dd4hep::sim::Geant4ActionContainer
Class, which allows all Geant4Action to be stored.
Definition: Geant4ActionContainer.h:60
dd4hep::sim::Geant4Handle::get
TYPE * get() const
Access to the underlying object.
Definition: Geant4Handle.cpp:175
dd4hep::sim::_create_share
TYPE * _create_share(Geant4Kernel &kernel, CONT &(Geant4ActionContainer::*pmf)(), const std::string &type_name, const std::string &shared_typ, bool shared, TYPE *)
Definition: Geant4Handle.cpp:100
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
Geant4UserInitialization.h
dd4hep::sim::TypeName
Helper class to handle strings of the format "type/name".
Definition: Geant4Action.h:82
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::sim::Geant4ActionContainer::generatorAction
Geant4GeneratorActionSequence & generatorAction()
Access generator action sequence.
Definition: Geant4ActionContainer.h:110
Geant4Kernel.h
dd4hep::sim::Geant4Sensitive
The base class for Geant4 sensitive detector actions implemented by users.
Definition: Geant4SensDetAction.h:121
dd4hep::sim::Geant4Handle::checked_assign
void checked_assign(TYPE *p)
Definition: Geant4Handle.cpp:154
Geant4ActionPhase.h
dd4hep::sim::Geant4Kernel::master
Geant4Kernel & master() const
Thread's master context.
Definition: Geant4Kernel.h:158
Printout.h
handle
void handle(const O *o, const C &c, F pmf)
Definition: LCDDConverter.cpp:1105
dd4hep::sim::Geant4Handle::action
Geant4Action * action() const
Access to the underlying object.
Definition: Geant4Handle.cpp:183
dd4hep::sim::Geant4Context
Generic context to extend user, run and event information.
Definition: Geant4Context.h:201