DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Geant4HitCollection.h
Go to the documentation of this file.
1 // $Id: $
2 //==========================================================================
3 // AIDA Detector description implementation for LCD
4 //--------------------------------------------------------------------------
5 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
6 // All rights reserved.
7 //
8 // For the licensing terms see $DD4hepINSTALL/LICENSE.
9 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
10 //
11 // Author : M.Frank
12 //
13 //==========================================================================
14 #ifndef DD4HEP_DDG4_GEANT4HITCOLLECTION_H
15 #define DD4HEP_DDG4_GEANT4HITCOLLECTION_H
16 
17 // Framework include files
18 #include "DD4hep/Handle.h"
19 #include "DDG4/ComponentUtils.h"
20 #include "G4VHitsCollection.hh"
21 #include "G4VHit.hh"
22 
23 // C/C++ include files
24 #include <vector>
25 #include <string>
26 #include <climits>
27 #include <typeinfo>
28 #include <stdexcept>
29 
31 namespace DD4hep {
32 
34  namespace Simulation {
35 
36  // Forward declarations
37  class Geant4Sensitive;
38  class Geant4HitCollection;
39  class Geant4HitWrapper;
40 
42 
51  class Geant4HitWrapper: public G4VHit {
52  private:
53  public:
55  class InvalidHit {
56  public:
57  virtual ~InvalidHit();
58  };
59 
61 
67  public:
68  typedef std::pair<void*, HitManipulator*> Wrapper;
69 #ifdef __CINT__
70  const ComponentCast* cast;
71  const ComponentCast* vec_type;
72 #else
75 #endif
76  HitManipulator(const ComponentCast& c, const ComponentCast& v);
81  template <typename TYPE> Wrapper castHit(TYPE* obj) {
82  if (obj) {
83  ComponentCast& me = ComponentCast::instance<TYPE>();
84  Wrapper wrap(obj, this);
85  if (&cast == &me) {
86  return wrap;
87  }
88  // Need to ensure that the container types are the same!
89  wrap.first = me.apply_dynCast(cast, obj);
90  return wrap;
91  }
92  throw std::runtime_error("Invalid hit pointer passed to collection!");
93  }
95  template <typename TYPE> static void deleteHit(Wrapper& obj) {
96  TYPE* p = (TYPE*) obj.first;
97  if (p)
98  delete p;
99  obj.first = 0;
100  }
101  template <typename TYPE> static HitManipulator* instance() {
102  static HitManipulator hm(ComponentCast::instance<TYPE>(), ComponentCast::instance<std::vector<TYPE*> >());
103  return &hm;
104  }
105  };
106 
108  protected:
109  mutable Wrapper m_data;
110 
111  public:
112 
115  m_data.second = manipulator<InvalidHit>();
116  m_data.first = 0;
117  }
120  m_data = v.m_data;
121  v.m_data.first = 0;
122  //v.release();
123  }
126  m_data = v;
127  }
129  virtual ~Geant4HitWrapper();
131  void *operator new(size_t);
133  void operator delete(void *ptr);
135  void* release();
140  return m_data.second;
141  }
143  void* data() {
144  return m_data.first;
145  }
147  void* data() const {
148  return m_data.first;
149  }
151  template <typename TYPE> static HitManipulator* manipulator() {
152  return HitManipulator::instance<TYPE>();
153  }
156  if ( this != & v ) {
157  m_data = v.m_data;
158  v.m_data.first = 0;
159  //v.release();
160  }
161  return *this;
162  }
164  template <typename TYPE> operator TYPE*() const {
165  return (TYPE*) m_data.second->
166  cast.apply_dynCast(ComponentCast::instance<TYPE>(),m_data.first);
167  //cast.apply_downCast(ComponentCast::instance<TYPE>(),m_data.first);
168  }
169  };
170 
172 
202  public:
204  typedef std::vector<Geant4HitWrapper> WrappedHits;
209  typedef std::map<VolumeID, size_t> Keys;
210 
212 
220  class Compare {
221  public:
223  virtual ~Compare();
225  virtual void* operator()(const Geant4HitWrapper& w) const = 0;
226  };
227 
229  unsigned long value;
230  struct BitItems {
231  unsigned repeatedLookup:1;
232  unsigned mappedLookup:1;
233  } bits;
234  };
235 
236  protected:
244  size_t m_lastHit;
249 
250  protected:
252  void newInstance();
254  void* findHit(const Compare& cmp);
258  void releaseData(const ComponentCast& cast, std::vector<void*>* result);
260  void getData(const ComponentCast& cast, std::vector<void*>* result);
261 
262  public:
263  enum {
269 
271  template <typename TYPE>
272  Geant4HitCollection(const std::string& det, const std::string& coll, Geant4Sensitive* sd)
273  : G4VHitsCollection(det, coll), m_detector(sd),
274  m_manipulator(Geant4HitWrapper::manipulator<TYPE>()),
275  m_lastHit(ULONG_MAX)
276  {
277  newInstance();
278  m_hits.reserve(200);
280  }
282  template <typename TYPE>
283  Geant4HitCollection(const std::string& det, const std::string& coll, Geant4Sensitive* sd, const TYPE*)
284  : G4VHitsCollection(det, coll), m_detector(sd),
285  m_manipulator(Geant4HitWrapper::manipulator<TYPE>()),
286  m_lastHit(ULONG_MAX)
287  {
288  newInstance();
289  m_hits.reserve(200);
290  m_flags.value = 0;//OPTIMIZE_REPEATEDLOOKUP;
291  }
293  virtual ~Geant4HitCollection();
295  const ComponentCast& type() const;
297  const ComponentCast& vector_type() const;
299  virtual void clear();
301  void setOptimize(int flag) {
302  m_flags.value |= flag;
303  }
305  void setSensitive(Geant4Sensitive* detector) {
306  m_detector = detector;
307  }
310  return m_detector;
311  }
313  virtual G4VHit* GetHit(size_t which) const {
314  return (G4VHit*) &m_hits.at(which);
315  }
317  virtual size_t GetSize() const {
318  return m_hits.size();
319  }
321  Geant4HitWrapper& hit(size_t which) {
322  return m_hits.at(which);
323  }
325  const Geant4HitWrapper& hit(size_t which) const {
326  return m_hits.at(which);
327  }
329  template <typename TYPE> void add(TYPE* hit_pointer) {
330  Geant4HitWrapper w(m_manipulator->castHit(hit_pointer));
331  m_lastHit = m_hits.size();
332  m_hits.push_back(w);
333  }
335  template <typename TYPE> void add(VolumeID key, TYPE* hit_pointer) {
336  m_lastHit = m_hits.size();
337  std::pair<Keys::iterator,bool> ret = m_keys.insert(std::make_pair(key,m_lastHit));
338  if ( ret.second ) {
339  Geant4HitWrapper w(m_manipulator->castHit(hit_pointer));
340  m_hits.push_back(w);
341  return;
342  }
343  throw std::runtime_error("Attempt to insert hit with same key to G4 hit-collection "+GetName());
344  }
346  template <typename TYPE> TYPE* find(const Compare& cmp) {
347  return (TYPE*) findHit(cmp);
348  }
350  template <typename TYPE> TYPE* findByKey(VolumeID key) {
351  Keys::const_iterator i=m_keys.find(key);
352  if ( i == m_keys.end() ) return 0;
353  m_lastHit = (*i).second;
354  TYPE* obj = m_hits.at(m_lastHit);
355  return obj;
356  }
358  template <typename TYPE> std::vector<TYPE*> releaseHits() {
359  std::vector<TYPE*> vec;
360  if (m_hits.size() != 0) {
361  releaseData(ComponentCast::instance<TYPE>(), (std::vector<void*>*) &vec);
362  }
363  m_lastHit = ULONG_MAX;
364  m_keys.clear();
365  return vec;
366  }
368  void releaseHitsUnchecked(std::vector<void*>& result);
369 
371  template <typename TYPE> std::vector<TYPE*> getHits() {
372  std::vector<TYPE*> vec;
373  if (m_hits.size() != 0) {
374  getData(ComponentCast::instance<TYPE>(), (std::vector<void*>*) &vec);
375  }
376  return vec;
377  }
379  void getHitsUnchecked(std::vector<void*>& result);
380  };
381 
382 
384 
391  template<typename TYPE, typename POS> class PositionCompare : public Geant4HitCollection::Compare {
392  public:
393  const POS& pos;
395  PositionCompare(const POS& p) : pos(p) { }
397  virtual void* operator()(const Geant4HitWrapper& w) const;
398  };
399 
400  template <typename TYPE, typename POS>
402  TYPE* h = w;
403  return pos == h->position ? h : 0;
404  }
405 
407 
414  template<typename TYPE> class CellIDCompare : public Geant4HitCollection::Compare {
415  public:
416  long long int id;
418  CellIDCompare(long long int i) : id(i) { }
420  virtual void* operator()(const Geant4HitWrapper& w) const;
421  };
422 
423  template <typename TYPE>
425  TYPE* h = w;
426  if ( id == h->cellID )
427  return h;
428  return 0;
429  }
430 
431  } // End namespace Simulation
432 } // End namespace DD4hep
433 
434 #endif // DD4HEP_DDG4_GEANT4HITCOLLECTION_H
void releaseData(const ComponentCast &cast, std::vector< void * > *result)
Release all hits from the Geant4 container and pass ownership to the caller.
Geant4HitWrapper(const Wrapper &v)
Copy constructor.
struct DD4hep::Simulation::Geant4HitCollection::CollectionFlags::BitItems bits
virtual void * operator()(const Geant4HitWrapper &w) const =0
Comparison function.
void * findHit(const Compare &cmp)
Find hit in a collection by comparison of attributes.
std::vector< Geant4HitWrapper > WrappedHits
Hit wrapper.
Geant4HitCollection(const std::string &det, const std::string &coll, Geant4Sensitive *sd, const TYPE *)
Initializing constructor.
void setSensitive(Geant4Sensitive *detector)
Set the sensitive detector.
size_t m_lastHit
Memorize for speedup the last searched hit.
void * data() const
Pointer/Object access (CONST)
Helper class to indicate invalid hit wrappers or containers.
Specialized hit selector based on the hit's position.
TYPE * findByKey(VolumeID key)
Find hits in a collection by comparison of key value.
Geant4HitWrapper & hit(size_t which)
Access the hit wrapper.
static HitManipulator * manipulator()
Generate manipulator object.
Geant4HitWrapper * findHitByKey(VolumeID key)
Find hit in a collection by comparison of the key.
CollectionFlags m_flags
Optimization flags.
Class of the Geant4 toolkit. See http://www-geant4.kek.jp/Reference.
Definition: Geant4Classes.h:36
std::pair< void *, HitManipulator * > Wrapper
void * release()
Pointer/Object release.
Class of the Geant4 toolkit. See http://www-geant4.kek.jp/Reference.
Definition: Geant4Classes.h:40
std::vector< TYPE * > getHits()
Release all hits from the Geant4 container. Ownership stays with the container.
const ComponentCast & vector_type() const
Type information of the vector type for extracting data.
virtual void * operator()(const Geant4HitWrapper &w) const
Comparison function.
virtual G4VHit * GetHit(size_t which) const
Access individual hits.
void newInstance()
Notification to increase the instance counter.
void add(VolumeID key, TYPE *hit_pointer)
Add a new hit with a check, that the hit is of the same type.
HitManipulator(const ComponentCast &c, const ComponentCast &v)
Initializing Constructor.
Generic wrapper class for hit structures created in Geant4 sensitive detectors.
virtual void * operator()(const Geant4HitWrapper &w) const
Comparison function.
Geant4HitCollection(const std::string &det, const std::string &coll, Geant4Sensitive *sd)
Initializing constructor (C++ version)
Specialized hit selector based on the hit's cell identifier.
Geant4HitWrapper & operator=(const Geant4HitWrapper &v)
Assignment transfers the pointer ownership.
const Geant4HitWrapper & hit(size_t which) const
Access the hit wrapper (CONST)
The base class for Geant4 sensitive detector actions implemented by users.
void getData(const ComponentCast &cast, std::vector< void * > *result)
Release all hits from the Geant4 container. Ownership stays with the container.
const char * GetName(T *p)
Definition: Utilities.h:45
Geant4HitWrapper::HitManipulator Manip
Hit manipulator.
std::map< VolumeID, size_t > Keys
Hit key map for fast random lookup.
WrappedHits m_hits
The collection of hit pointers in the wrapped format.
void * apply_dynCast(const ComponentCast &to, const void *ptr) const
Apply cast using typeinfo instead of dynamic_cast.
Definition: Primitives.cpp:318
Generic class template to compare/select hits in Geant4HitCollection objects.
void add(TYPE *hit_pointer)
Add a new hit with a check, that the hit is of the same type.
Keys m_keys
Hit key map for fast random lookup.
Geant4Sensitive * m_detector
Handle to the sensitive detector.
virtual ~Geant4HitWrapper()
Default destructor.
void releaseHitsUnchecked(std::vector< void * > &result)
Release all hits from the Geant4 container and pass ownership to the caller.
Generic hit container class using Geant4HitWrapper objects.
TYPE * find(const Compare &cmp)
Find hits in a collection by comparison of attributes.
Geant4Sensitive * sensitive() const
Access the sensitive detector.
Class to perform dynamic casts using unknown pointers.
Definition: Primitives.h:168
CellIDCompare(long long int i)
Constructor.
static void deleteHit(Wrapper &obj)
Static function to delete contained hits.
virtual ~Geant4HitCollection()
Default destructor.
void setOptimize(int flag)
Set optimization flags.
static ComponentCast & instance()
Definition: Primitives.h:197
View * v
Definition: MultiView.cpp:30
Wrapper castHit(TYPE *obj)
Check pointer to be of proper type.
long long int VolumeID
Definition: Primitives.h:35
enum DD4hep::Simulation::Geant4HitCollection::@10 OptimizationFlags
virtual size_t GetSize() const
Access the collection size.
HitManipulator * manip() const
Access to cast grammar.
Manip * m_manipulator
The type of the objects in this collection. Set by the constructor.
void * data()
Pointer/Object access.
PositionCompare(const POS &p)
Constructor.
const ComponentCast & type() const
Type information of the object stored.
void getHitsUnchecked(std::vector< void * > &result)
Release all hits from the Geant4 container. Ownership stays with the container.
Wrapper releaseData()
Release data for copy.
Generic type manipulation class for generic hit structures created in Geant4 sensitive detectors...
std::vector< TYPE * > releaseHits()
Release all hits from the Geant4 container and pass ownership to the caller.
Geant4HitWrapper(const Geant4HitWrapper &v)
Copy constructor.
virtual void clear()
Clear the collection (Deletes all valid references to real hits)