File indexing completed on 2025-09-17 08:59:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifndef G4THitsMap_h
0041 #define G4THitsMap_h 1
0042
0043 #include "G4THitsCollection.hh"
0044 #include "globals.hh"
0045
0046 #include <map>
0047 #include <unordered_map>
0048 #include <type_traits>
0049
0050 template <typename T, typename Map_t = std::map<G4int, T*>>
0051 class G4VTHitsMap : public G4HitsCollection
0052 {
0053 private:
0054
0055 using mmap_t = std::multimap<G4int, T *>;
0056 using pair_t = std::pair<G4int, T *>;
0057 using uommap_t = std::unordered_multimap<G4int, T *>;
0058
0059 #define is_same_t(_Tp, _Up) std::is_same<_Tp, _Up>::value
0060 #define is_multimap_t(_Mp) std::is_same<_Mp, mmap_t>::value
0061 #define is_uommap_t(_Mp) std::is_same<_Mp, uommap_t>::value
0062 #define is_mmap_t(_Mp) (is_multimap_t(_Mp) || is_uommap_t(_Mp))
0063 #define is_fundamental_t(_Tp) std::is_fundamental<_Tp>::value
0064
0065 template <bool _Bp, typename _Tp = void>
0066 using enable_if_t = typename std::enable_if<_Bp, _Tp>::type;
0067
0068
0069 template <typename U = T, enable_if_t<is_fundamental_t(U), G4int> = 0>
0070 T* allocate() const
0071 {
0072 return new T(0.);
0073 }
0074
0075
0076
0077 template <typename U = T, enable_if_t<! is_fundamental_t(U), G4int> = 0>
0078 T* allocate() const
0079 {
0080 return new T();
0081 }
0082
0083 public:
0084 using this_type = G4VTHitsMap<T, Map_t>;
0085 using value_type = T;
0086 using map_type = Map_t;
0087 using iterator = typename map_type::iterator;
0088 using const_iterator = typename map_type::const_iterator;
0089
0090
0091 G4VTHitsMap();
0092
0093 G4VTHitsMap(const G4String& detName, const G4String& colNam);
0094
0095 ~G4VTHitsMap() override;
0096
0097 G4bool operator==(const G4VTHitsMap<T, Map_t>& right) const;
0098
0099
0100
0101
0102
0103 template <typename U, typename MapU_t>
0104 this_type& operator+=(const G4VTHitsMap<U, MapU_t>& right) const
0105 {
0106 MapU_t* aHitsMap = right.GetMap();
0107 for (auto itr = aHitsMap->begin(); itr != aHitsMap->end(); ++itr)
0108 add<U, map_type>(itr->first, *(itr->second));
0109 return (this_type&)(*this);
0110 }
0111
0112
0113 void DrawAllHits() override;
0114 void PrintAllHits() override;
0115
0116
0117
0118
0119 inline Map_t* GetContainer() const { return (Map_t*)theCollection; }
0120
0121 inline typename Map_t::size_type size() { return GetContainer()->size(); }
0122
0123 inline typename Map_t::size_type GetIndex(iterator itr) { return itr->first; }
0124
0125 inline typename Map_t::size_type GetIndex(const_iterator itr) const { return itr->first; }
0126
0127 template <typename MapU_t = Map_t, enable_if_t<! is_mmap_t(MapU_t), G4int> = 0>
0128 inline T* GetObject(G4int idx) const
0129 {
0130 return (GetContainer()->count(idx) != 0) ? (*GetContainer())[idx] : nullptr;
0131 }
0132
0133 template <typename MapU_t = Map_t, enable_if_t<is_mmap_t(MapU_t), G4int> = 0>
0134 inline T* GetObject(G4int idx) const
0135 {
0136 return (GetContainer()->count(idx) != 0) ? GetContainer()->find(idx)->second : nullptr;
0137 }
0138
0139 inline T* GetObject(iterator itr) const { return itr->second; }
0140
0141 inline const T* GetObject(const_iterator itr) const { return itr->second; }
0142
0143 iterator begin() { return GetContainer()->begin(); }
0144 iterator end() { return GetContainer()->end(); }
0145 const_iterator begin() const { return GetContainer()->begin(); }
0146 const_iterator end() const { return GetContainer()->end(); }
0147 const_iterator cbegin() const { return GetContainer()->cbegin(); }
0148 const_iterator cend() const { return GetContainer()->cend(); }
0149
0150
0151 inline Map_t* GetMap() const { return (Map_t*)theCollection; }
0152
0153
0154 inline std::size_t entries() const { return ((Map_t*)theCollection)->size(); }
0155
0156 inline void clear();
0157
0158 G4VHit* GetHit(std::size_t) const override { return nullptr; }
0159 std::size_t GetSize() const override { return ((Map_t*)theCollection)->size(); }
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 template <typename U = T, typename MapU_t = Map_t,
0170 enable_if_t<is_same_t(U, T) && ! is_mmap_t(MapU_t), G4int> = 0>
0171 std::size_t add(const G4int& key, U*& aHit) const
0172 {
0173 map_type* theHitsMap = GetMap();
0174 if (theHitsMap->find(key) == theHitsMap->end())
0175 theHitsMap->insert(pair_t(key, new T(*aHit)));
0176 else
0177 *theHitsMap->find(key)->second += *aHit;
0178 return theHitsMap->size();
0179 }
0180
0181
0182
0183 template <typename U = T, typename MapU_t = Map_t,
0184 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0185 std::size_t add(const G4int& key, U*& aHit) const
0186 {
0187 map_type* theHitsMap = GetMap();
0188 theHitsMap->insert(pair_t(key, aHit));
0189 return theHitsMap->size();
0190 }
0191
0192
0193
0194
0195 template <typename U = T, typename MapU_t = Map_t,
0196 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0197 std::size_t add(const G4int& key, U*& aHit) const
0198 {
0199 map_type* theHitsMap = GetMap();
0200 T* hit = allocate();
0201 *hit += *aHit;
0202 theHitsMap->insert(pair_t(key, hit));
0203 return theHitsMap->size();
0204 }
0205
0206
0207
0208
0209
0210
0211
0212 template <typename U = T, typename MapU_t = Map_t,
0213 enable_if_t<(is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0214 std::size_t add(const G4int& key, U& aHit) const
0215 {
0216 map_type* theHitsMap = GetMap();
0217 if (theHitsMap->find(key) == theHitsMap->end())
0218 theHitsMap->insert(pair_t(key, new T(aHit)));
0219 else
0220 *theHitsMap->find(key)->second += aHit;
0221 return theHitsMap->size();
0222 }
0223
0224
0225
0226
0227 template <typename U = T, typename MapU_t = Map_t,
0228 enable_if_t<(! is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0229 std::size_t add(const G4int& key, U& aHit) const
0230 {
0231 map_type* theHitsMap = GetMap();
0232 if (theHitsMap->find(key) == theHitsMap->end()) theHitsMap->insert(pair_t(key, allocate()));
0233 *theHitsMap->find(key)->second += aHit;
0234 return theHitsMap->size();
0235 }
0236
0237
0238
0239 template <typename U = T, typename MapU_t = Map_t,
0240 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0241 std::size_t add(const G4int& key, U& aHit) const
0242 {
0243 map_type* theHitsMap = GetMap();
0244 theHitsMap->insert(pair_t(key, new T(aHit)));
0245 return theHitsMap->size();
0246 }
0247
0248
0249
0250
0251 template <typename U = T, typename MapU_t = Map_t,
0252 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0253 std::size_t add(const G4int& key, U& aHit) const
0254 {
0255 map_type* theHitsMap = GetMap();
0256 T* hit = allocate();
0257 *hit += aHit;
0258 theHitsMap->insert(pair_t(key, hit));
0259 return theHitsMap->size();
0260 }
0261
0262
0263
0264
0265
0266
0267
0268 template <typename U = T, typename MapU_t = Map_t,
0269 enable_if_t<(is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0270 inline std::size_t set(const G4int& key, U*& aHit) const
0271 {
0272 map_type* theHitsMap = GetMap();
0273 if (theHitsMap->find(key) != theHitsMap->end()) delete theHitsMap->find(key)->second;
0274 theHitsMap->find(key)->second = aHit;
0275 return theHitsMap->size();
0276 }
0277
0278
0279
0280 template <typename U = T, typename MapU_t = Map_t,
0281 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0282 inline std::size_t set(const G4int& key, U*& aHit) const
0283 {
0284 map_type* theHitsMap = GetMap();
0285 if (theHitsMap->find(key) != theHitsMap->end())
0286 theHitsMap->insert(pair_t(key, aHit));
0287 else {
0288 delete theHitsMap->find(key)->second;
0289 theHitsMap->find(key)->second = aHit;
0290 }
0291 return theHitsMap->size();
0292 }
0293
0294
0295
0296 template <typename U = T, typename MapU_t = Map_t,
0297 enable_if_t<(! is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0298 inline std::size_t set(const G4int& key, U*& aHit) const
0299 {
0300 map_type* theHitsMap = GetMap();
0301 T* hit = nullptr;
0302 if (theHitsMap->find(key) == theHitsMap->end())
0303 theHitsMap->insert(std::make_pair(key, hit = allocate()));
0304 else
0305 hit = theHitsMap->find(key)->second;
0306 *hit += *aHit;
0307 return theHitsMap->size();
0308 }
0309
0310
0311
0312 template <typename U = T, typename MapU_t = Map_t,
0313 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0314 inline std::size_t set(const G4int& key, U*& aHit) const
0315 {
0316 map_type* theHitsMap = GetMap();
0317 T* hit = allocate();
0318 *hit += *aHit;
0319 if (theHitsMap->find(key) != theHitsMap->end())
0320 theHitsMap->insert(pair_t(key, hit));
0321 else {
0322 delete theHitsMap->find(key)->second;
0323 theHitsMap->find(key)->second = hit;
0324 }
0325 return theHitsMap->size();
0326 }
0327
0328
0329
0330
0331
0332
0333
0334 template <typename U = T, typename MapU_t = Map_t,
0335 enable_if_t<(is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0336 inline std::size_t set(const G4int& key, U& aHit) const
0337 {
0338 map_type* theHitsMap = GetMap();
0339 T* hit = nullptr;
0340 if (theHitsMap->find(key) != theHitsMap->end())
0341 hit = theHitsMap->find(key)->second;
0342 else
0343 theHitsMap->insert(pair_t(key, hit = allocate()));
0344 *hit = aHit;
0345 return theHitsMap->size();
0346 }
0347
0348
0349
0350 template <typename U = T, typename MapU_t = Map_t,
0351 enable_if_t<(is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0352 inline std::size_t set(const G4int& key, U& aHit) const
0353 {
0354 map_type* theHitsMap = GetMap();
0355 if (theHitsMap->find(key) != theHitsMap->end())
0356 *theHitsMap->find(key)->second = aHit;
0357 else
0358 theHitsMap->insert(pair_t(key, new T(aHit)));
0359 return theHitsMap->size();
0360 }
0361
0362
0363
0364 template <typename U = T, typename MapU_t = Map_t,
0365 enable_if_t<(! is_same_t(U, T) && ! is_mmap_t(MapU_t)), G4int> = 0>
0366 inline std::size_t set(const G4int& key, U& aHit) const
0367 {
0368 map_type* theHitsMap = GetMap();
0369 T* hit = nullptr;
0370 if (theHitsMap->find(key) == theHitsMap->end())
0371 theHitsMap->insert(std::make_pair(key, hit = allocate()));
0372 else
0373 hit = theHitsMap->find(key)->second;
0374 *hit += aHit;
0375 return theHitsMap->size();
0376 }
0377
0378
0379
0380 template <typename U = T, typename MapU_t = Map_t,
0381 enable_if_t<(! is_same_t(U, T) && is_mmap_t(MapU_t)), G4int> = 0>
0382 inline std::size_t set(const G4int& key, U& aHit) const
0383 {
0384 map_type* theHitsMap = GetMap();
0385 T* hit = allocate();
0386 *hit += aHit;
0387 if (theHitsMap->find(key) != theHitsMap->end())
0388 *theHitsMap->find(key)->second = *hit;
0389 else
0390 theHitsMap->insert(pair_t(key, hit));
0391 return theHitsMap->size();
0392 }
0393
0394
0395
0396
0397
0398
0399 template <typename MapU_t = Map_t, enable_if_t<! is_mmap_t(MapU_t), G4int> = 0>
0400 T* operator[](G4int key) const
0401 {
0402 map_type* theHitsMap = GetMap();
0403 if (theHitsMap->find(key) != theHitsMap->end()) return theHitsMap->find(key)->second;
0404 return nullptr;
0405 }
0406
0407 template <typename MapU_t = Map_t, enable_if_t<is_mmap_t(MapU_t), G4int> = 0>
0408 T* operator[](G4int key) const
0409 {
0410 #ifdef G4VERBOSE
0411 static G4bool _first = true;
0412 if (_first) {
0413 _first = false;
0414 G4Exception("G4THitsMap operator[]", "calling [] on multimap", JustWarning,
0415 "Returning the last matching entry");
0416 }
0417 #endif
0418 map_type* theHitsMap = GetMap();
0419 iterator itr = theHitsMap->find(key);
0420 if (itr != theHitsMap->end()) {
0421 std::advance(itr, theHitsMap->count(key) - 1);
0422 return itr->second;
0423 }
0424 return nullptr;
0425 }
0426
0427
0428 #undef is_same_t
0429 #undef is_multimap_t
0430 #undef is_uommap_t
0431 #undef is_mmap_t
0432 #undef is_fundamental_t
0433 };
0434
0435
0436
0437 template <typename T, typename Map_t>
0438 G4VTHitsMap<T, Map_t>::G4VTHitsMap()
0439 {
0440 theCollection = (void*)new Map_t;
0441 }
0442
0443
0444
0445 template <typename T, typename Map_t>
0446 G4VTHitsMap<T, Map_t>::G4VTHitsMap(const G4String& detName, const G4String& colNam)
0447 : G4HitsCollection(detName, colNam)
0448 {
0449 theCollection = (void*)new Map_t;
0450 }
0451
0452
0453
0454 template <typename T, typename Map_t>
0455 G4VTHitsMap<T, Map_t>::~G4VTHitsMap()
0456 {
0457 map_type* theHitsMap = GetMap();
0458 for (auto itr = theHitsMap->begin(); itr != theHitsMap->end(); ++itr)
0459 delete itr->second;
0460 delete theHitsMap;
0461 }
0462
0463
0464
0465 template <typename T, typename Map_t>
0466 G4bool G4VTHitsMap<T, Map_t>::operator==(const G4VTHitsMap<T, Map_t>& right) const
0467 {
0468 return (collectionName == right.collectionName);
0469 }
0470
0471
0472
0473 template <typename T, typename Map_t>
0474 void G4VTHitsMap<T, Map_t>::DrawAllHits()
0475 {
0476 ;
0477 }
0478
0479
0480
0481 template <typename T, typename Map_t>
0482 void G4VTHitsMap<T, Map_t>::PrintAllHits()
0483 {
0484 G4cout << "G4THitsMap " << SDname << " / " << collectionName << " --- " << entries() << " entries"
0485 << G4endl;
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 }
0499
0500
0501
0502 template <typename T, typename Map_t>
0503 void G4VTHitsMap<T, Map_t>::clear()
0504 {
0505 Map_t* theHitsMap = GetMap();
0506 for (iterator itr = theHitsMap->begin(); itr != theHitsMap->end(); ++itr)
0507 delete itr->second;
0508 theHitsMap->clear();
0509 }
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519 template <typename _Tp>
0520 class G4THitsMap : public G4VTHitsMap<_Tp, std::map<G4int, _Tp*>>
0521 {
0522 public:
0523 using parent_type = G4VTHitsMap<_Tp, std::map<G4int, _Tp *>>;
0524
0525 public:
0526 G4THitsMap() : parent_type() {}
0527 G4THitsMap(G4String detName, G4String colName) : parent_type(detName, colName) {}
0528
0529 using parent_type::operator+=;
0530 using parent_type::operator==;
0531 using parent_type::operator[];
0532 using parent_type::add;
0533 using parent_type::begin;
0534 using parent_type::cbegin;
0535 using parent_type::cend;
0536 using parent_type::clear;
0537 using parent_type::DrawAllHits;
0538 using parent_type::end;
0539 using parent_type::entries;
0540 using parent_type::GetHit;
0541 using parent_type::GetMap;
0542 using parent_type::GetSize;
0543 using parent_type::PrintAllHits;
0544 using parent_type::set;
0545 };
0546
0547
0548
0549 template <typename _Tp>
0550 class G4THitsMultiMap : public G4VTHitsMap<_Tp, std::multimap<G4int, _Tp*>>
0551 {
0552 public:
0553 using parent_type = G4VTHitsMap<_Tp, std::multimap<G4int, _Tp *>>;
0554
0555 public:
0556 G4THitsMultiMap() : parent_type() {}
0557 G4THitsMultiMap(const G4String& detName, const G4String& colName)
0558 : parent_type(detName, colName) {}
0559
0560 using parent_type::operator+=;
0561 using parent_type::operator==;
0562 using parent_type::operator[];
0563 using parent_type::add;
0564 using parent_type::begin;
0565 using parent_type::cbegin;
0566 using parent_type::cend;
0567 using parent_type::clear;
0568 using parent_type::DrawAllHits;
0569 using parent_type::end;
0570 using parent_type::entries;
0571 using parent_type::GetHit;
0572 using parent_type::GetMap;
0573 using parent_type::GetSize;
0574 using parent_type::PrintAllHits;
0575 using parent_type::set;
0576 };
0577
0578
0579
0580 template <typename _Tp>
0581 class G4THitsUnorderedMap : public G4VTHitsMap<_Tp, std::unordered_map<G4int, _Tp*>>
0582 {
0583 public:
0584 using parent_type = G4VTHitsMap<_Tp, std::unordered_map<G4int, _Tp *>>;
0585
0586 public:
0587 G4THitsUnorderedMap() : parent_type() {}
0588 G4THitsUnorderedMap(const G4String& detName, const G4String& colName)
0589 : parent_type(detName, colName) {}
0590
0591 using parent_type::operator+=;
0592 using parent_type::operator==;
0593 using parent_type::operator[];
0594 using parent_type::add;
0595 using parent_type::begin;
0596 using parent_type::cbegin;
0597 using parent_type::cend;
0598 using parent_type::clear;
0599 using parent_type::DrawAllHits;
0600 using parent_type::end;
0601 using parent_type::entries;
0602 using parent_type::GetHit;
0603 using parent_type::GetMap;
0604 using parent_type::GetSize;
0605 using parent_type::PrintAllHits;
0606 using parent_type::set;
0607 };
0608
0609
0610
0611 template <typename _Tp>
0612 class G4THitsUnorderedMultiMap : public G4VTHitsMap<_Tp, std::unordered_multimap<G4int, _Tp*>>
0613 {
0614 public:
0615 using parent_type = G4VTHitsMap<_Tp, std::unordered_multimap<G4int, _Tp *>>;
0616
0617 public:
0618 G4THitsUnorderedMultiMap() : parent_type() {}
0619 G4THitsUnorderedMultiMap(const G4String& detName, const G4String& colName)
0620 : parent_type(detName, colName) {}
0621
0622 using parent_type::operator+=;
0623 using parent_type::operator==;
0624 using parent_type::operator[];
0625 using parent_type::add;
0626 using parent_type::begin;
0627 using parent_type::cbegin;
0628 using parent_type::cend;
0629 using parent_type::clear;
0630 using parent_type::DrawAllHits;
0631 using parent_type::end;
0632 using parent_type::entries;
0633 using parent_type::GetHit;
0634 using parent_type::GetMap;
0635 using parent_type::GetSize;
0636 using parent_type::PrintAllHits;
0637 using parent_type::set;
0638 };
0639
0640
0641
0642 #endif