File indexing completed on 2025-01-18 09:55:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DDG4_GEANT4HITCOLLECTION_H
0014 #define DDG4_GEANT4HITCOLLECTION_H
0015
0016
0017 #include <DD4hep/Handle.h>
0018 #include <DDG4/ComponentUtils.h>
0019 #include <G4VHitsCollection.hh>
0020 #include <G4VHit.hh>
0021
0022
0023 #include <vector>
0024 #include <string>
0025 #include <climits>
0026 #include <typeinfo>
0027 #include <stdexcept>
0028
0029
0030 namespace dd4hep {
0031
0032
0033 namespace sim {
0034
0035
0036 class Geant4Sensitive;
0037 class Geant4HitCollection;
0038 class Geant4HitWrapper;
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 class Geant4HitWrapper: public G4VHit {
0051 private:
0052 public:
0053
0054 class InvalidHit {
0055 public:
0056 virtual ~InvalidHit();
0057 };
0058
0059
0060
0061
0062
0063
0064
0065 class HitManipulator {
0066 public:
0067 typedef std::pair<void*, HitManipulator*> Wrapper;
0068 #ifdef __CINT__
0069 const ComponentCast* cast;
0070 const ComponentCast* vec_type;
0071 #else
0072 const ComponentCast& cast;
0073 const ComponentCast& vec_type;
0074 #endif
0075
0076 HitManipulator(const ComponentCast& c, const ComponentCast& v);
0077
0078 ~HitManipulator();
0079
0080 template <typename TYPE> Wrapper castHit(TYPE* obj) {
0081 if (obj) {
0082 ComponentCast& me = ComponentCast::instance<TYPE>();
0083 Wrapper wrap(obj, this);
0084 if (&cast == &me) {
0085 return wrap;
0086 }
0087
0088 wrap.first = me.apply_dynCast(cast, obj);
0089 return wrap;
0090 }
0091 throw std::runtime_error("Invalid hit pointer passed to collection!");
0092 }
0093
0094 template <typename TYPE> static void deleteHit(Wrapper& obj) {
0095 TYPE* p = (TYPE*) obj.first;
0096 if (p)
0097 delete p;
0098 obj.first = 0;
0099 }
0100 template <typename TYPE> static HitManipulator* instance() {
0101 static HitManipulator hm(ComponentCast::instance<TYPE>(), ComponentCast::instance<std::vector<TYPE*> >());
0102 return &hm;
0103 }
0104 };
0105
0106 typedef HitManipulator::Wrapper Wrapper;
0107 protected:
0108
0109 mutable Wrapper m_data;
0110
0111 public:
0112
0113
0114 Geant4HitWrapper() : G4VHit() {
0115 m_data.second = manipulator<InvalidHit>();
0116 m_data.first = 0;
0117 }
0118
0119 Geant4HitWrapper(const Geant4HitWrapper& v) : G4VHit() {
0120 m_data = v.m_data;
0121 v.m_data.first = 0;
0122
0123 }
0124
0125 Geant4HitWrapper(const Wrapper& v) : G4VHit() {
0126 m_data = v;
0127 }
0128
0129 virtual ~Geant4HitWrapper();
0130
0131 void *operator new(size_t);
0132
0133 void operator delete(void *ptr);
0134
0135 void* release();
0136
0137 Wrapper releaseData();
0138
0139 HitManipulator* manip() const {
0140 return m_data.second;
0141 }
0142
0143 void* data() {
0144 return m_data.first;
0145 }
0146
0147 void* data() const {
0148 return m_data.first;
0149 }
0150
0151 template <typename TYPE> static HitManipulator* manipulator() {
0152 return HitManipulator::instance<TYPE>();
0153 }
0154
0155 Geant4HitWrapper& operator=(const Geant4HitWrapper& v) {
0156 if ( this != & v ) {
0157 m_data = v.m_data;
0158 v.m_data.first = 0;
0159
0160 }
0161 return *this;
0162 }
0163
0164 template <typename TYPE> operator TYPE*() const {
0165 return (TYPE*) m_data.second->
0166 cast.apply_dynCast(ComponentCast::instance<TYPE>(),m_data.first);
0167
0168 }
0169 };
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 class Geant4HitCollection : public G4VHitsCollection {
0202 public:
0203
0204
0205 typedef std::vector<Geant4HitWrapper> WrappedHits;
0206
0207 typedef Geant4HitWrapper::HitManipulator Manip;
0208
0209 typedef std::map<VolumeID, size_t> Keys;
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 class Compare {
0221 public:
0222
0223 virtual ~Compare();
0224
0225 virtual void* operator()(const Geant4HitWrapper& w) const = 0;
0226 };
0227
0228
0229 union CollectionFlags {
0230
0231 unsigned long value;
0232
0233 struct BitItems {
0234 unsigned repeatedLookup:1;
0235 unsigned mappedLookup:1;
0236 } bits;
0237 };
0238
0239 protected:
0240
0241 WrappedHits m_hits;
0242
0243 Geant4Sensitive* m_detector;
0244
0245 Manip* m_manipulator;
0246
0247 size_t m_lastHit;
0248
0249 Keys m_keys;
0250
0251 CollectionFlags m_flags;
0252
0253 protected:
0254
0255 void newInstance();
0256
0257 void* findHit(const Compare& cmp);
0258
0259 Geant4HitWrapper* findHitByKey(VolumeID key);
0260
0261 void releaseData(const ComponentCast& cast, std::vector<void*>* result);
0262
0263 void getData(const ComponentCast& cast, std::vector<void*>* result);
0264
0265 public:
0266
0267 enum OptimizationFlags {
0268 OPTIMIZE_NONE = 0,
0269 OPTIMIZE_REPEATEDLOOKUP = 1<<0,
0270 OPTIMIZE_MAPPEDLOOKUP = 1<<1,
0271 OPTIMIZE_LAST
0272 };
0273
0274
0275 template <typename TYPE>
0276 Geant4HitCollection(const std::string& det, const std::string& coll, Geant4Sensitive* sd)
0277 : G4VHitsCollection(det, coll), m_detector(sd),
0278 m_manipulator(Geant4HitWrapper::manipulator<TYPE>()),
0279 m_lastHit(ULONG_MAX)
0280 {
0281 newInstance();
0282 m_hits.reserve(200);
0283 m_flags.value = OPTIMIZE_REPEATEDLOOKUP;
0284 }
0285
0286 template <typename TYPE>
0287 Geant4HitCollection(const std::string& det, const std::string& coll, Geant4Sensitive* sd, const TYPE*)
0288 : G4VHitsCollection(det, coll), m_detector(sd),
0289 m_manipulator(Geant4HitWrapper::manipulator<TYPE>()),
0290 m_lastHit(ULONG_MAX)
0291 {
0292 newInstance();
0293 m_hits.reserve(200);
0294 m_flags.value = OPTIMIZE_NONE;
0295 }
0296
0297 virtual ~Geant4HitCollection();
0298
0299 const ComponentCast& type() const;
0300
0301 const ComponentCast& vector_type() const;
0302
0303 virtual void clear();
0304
0305 void setOptimize(int flag) {
0306 m_flags.value |= flag;
0307 }
0308
0309 void setSensitive(Geant4Sensitive* detector) {
0310 m_detector = detector;
0311 }
0312
0313 Geant4Sensitive* sensitive() const {
0314 return m_detector;
0315 }
0316
0317 virtual G4VHit* GetHit(size_t which) const {
0318 return (G4VHit*) &m_hits.at(which);
0319 }
0320
0321 virtual size_t GetSize() const {
0322 return m_hits.size();
0323 }
0324
0325 Geant4HitWrapper& hit(size_t which) {
0326 return m_hits.at(which);
0327 }
0328
0329 const Geant4HitWrapper& hit(size_t which) const {
0330 return m_hits.at(which);
0331 }
0332
0333 template <typename TYPE> void add(TYPE* hit_pointer) {
0334 Geant4HitWrapper w(m_manipulator->castHit(hit_pointer));
0335 m_lastHit = m_hits.size();
0336 m_hits.emplace_back(w);
0337 }
0338
0339 template <typename TYPE> void add(VolumeID key, TYPE* hit_pointer) {
0340 m_lastHit = m_hits.size();
0341 std::pair<Keys::iterator,bool> ret = m_keys.emplace(key,m_lastHit);
0342 if ( ret.second ) {
0343 Geant4HitWrapper w(m_manipulator->castHit(hit_pointer));
0344 m_hits.emplace_back(w);
0345 return;
0346 }
0347 throw std::runtime_error("Attempt to insert hit with same key to G4 hit-collection "+GetName());
0348 }
0349
0350 template <typename TYPE> TYPE* find(const Compare& cmp) {
0351 return (TYPE*) findHit(cmp);
0352 }
0353
0354 template <typename TYPE> TYPE* findByKey(VolumeID key) {
0355 Keys::const_iterator i=m_keys.find(key);
0356 if ( i == m_keys.end() ) return 0;
0357 m_lastHit = (*i).second;
0358 TYPE* obj = m_hits.at(m_lastHit);
0359 return obj;
0360 }
0361
0362 template <typename TYPE> std::vector<TYPE*> releaseHits() {
0363 std::vector<TYPE*> vec;
0364 if (m_hits.size() != 0) {
0365 releaseData(ComponentCast::instance<TYPE>(), (std::vector<void*>*) &vec);
0366 }
0367 m_lastHit = ULONG_MAX;
0368 m_keys.clear();
0369 return vec;
0370 }
0371
0372 void releaseHitsUnchecked(std::vector<void*>& result);
0373
0374
0375 template <typename TYPE> std::vector<TYPE*> getHits() {
0376 std::vector<TYPE*> vec;
0377 if (m_hits.size() != 0) {
0378 getData(ComponentCast::instance<TYPE>(), (std::vector<void*>*) &vec);
0379 }
0380 return vec;
0381 }
0382
0383 void getHitsUnchecked(std::vector<void*>& result);
0384 };
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395 template<typename TYPE, typename POS> class PositionCompare : public Geant4HitCollection::Compare {
0396 public:
0397 const POS& pos;
0398
0399 PositionCompare(const POS& p) : pos(p) { }
0400
0401 virtual void* operator()(const Geant4HitWrapper& w) const;
0402 };
0403
0404 template <typename TYPE, typename POS>
0405 void* PositionCompare<TYPE,POS>::operator()(const Geant4HitWrapper& w) const {
0406 TYPE* h = w;
0407 return pos == h->position ? h : 0;
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418 template<typename TYPE> class CellIDCompare : public Geant4HitCollection::Compare {
0419 public:
0420 long long int id;
0421
0422 CellIDCompare(long long int i) : id(i) { }
0423
0424 virtual void* operator()(const Geant4HitWrapper& w) const;
0425 };
0426
0427 template <typename TYPE>
0428 void* CellIDCompare<TYPE>::operator()(const Geant4HitWrapper& w) const {
0429 TYPE* h = w;
0430 if ( id == h->cellID )
0431 return h;
0432 return 0;
0433 }
0434
0435 }
0436 }
0437
0438 #endif