File indexing completed on 2025-01-18 10:13:58
0001
0002
0003
0004
0005 #ifndef VECGEOM_NAVIGATION_NAVSTATEPATH_H_
0006 #define VECGEOM_NAVIGATION_NAVSTATEPATH_H_
0007
0008 #include "VecGeom/base/Config.h"
0009
0010 #include "VecGeom/base/VariableSizeObj.h"
0011 #include "VecGeom/base/Transformation3D.h"
0012 #include "VecGeom/volumes/PlacedVolume.h"
0013 #include "VecGeom/management/GeoManager.h"
0014 #ifdef VECGEOM_ENABLE_CUDA
0015 #include "VecGeom/management/CudaManager.h"
0016 #endif
0017 #include "VecGeom/base/Global.h"
0018
0019 #include <iostream>
0020 #include <string>
0021
0022 class TGeoBranchArray;
0023
0024
0025
0026
0027 #if __GNUC__ < 3 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)
0028
0029 #pragma GCC diagnostic push
0030 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
0031 #pragma GCC diagnostic ignored "-Weffc++"
0032 #define GCC_DIAG_POP_NEEDED
0033 #endif
0034
0035 namespace vecgeom {
0036 inline namespace VECGEOM_IMPL_NAMESPACE {
0037
0038
0039
0040
0041
0042
0043 #ifdef VECGEOM_USE_INDEXEDNAVSTATES
0044
0045 typedef unsigned long NavStateIndex_t;
0046 #else
0047 typedef VPlacedVolume const *NavStateIndex_t;
0048 #endif
0049
0050
0051
0052
0053
0054 template <typename T>
0055 struct Index2PVolumeConverter {
0056 VECCORE_ATT_HOST_DEVICE
0057 VECGEOM_FORCE_INLINE
0058 static VPlacedVolume const *ToPlacedVolume(T index)
0059 {
0060 #ifdef VECCORE_CUDA_DEVICE_COMPILATION
0061
0062
0063 assert(vecgeom::globaldevicegeomdata::gCompactPlacedVolBuffer != nullptr);
0064 return &vecgeom::globaldevicegeomdata::gCompactPlacedVolBuffer[index];
0065 #else
0066 #ifndef VECCORE_CUDA
0067 assert(vecgeom::GeoManager::gCompactPlacedVolBuffer == nullptr ||
0068 vecgeom::GeoManager::gCompactPlacedVolBuffer[index].id() == index);
0069 return &vecgeom::GeoManager::gCompactPlacedVolBuffer[index];
0070 #else
0071
0072
0073 assert(false && "reached unimplement code");
0074 (void)index;
0075 return nullptr;
0076 #endif
0077 #endif
0078 }
0079
0080 VECCORE_ATT_HOST_DEVICE
0081 VECGEOM_FORCE_INLINE
0082 static T ToIndex(VPlacedVolume const *pvol) { return pvol->id(); }
0083 };
0084
0085
0086 template <>
0087 struct Index2PVolumeConverter<VPlacedVolume const *> {
0088 VECCORE_ATT_HOST_DEVICE
0089 VECGEOM_FORCE_INLINE
0090 static VPlacedVolume const *ToPlacedVolume(VPlacedVolume const *pvol) { return pvol; }
0091 VECCORE_ATT_HOST_DEVICE
0092 VECGEOM_FORCE_INLINE
0093 static VPlacedVolume const *ToIndex(VPlacedVolume const *pvol) { return pvol; }
0094 };
0095
0096
0097
0098
0099
0100 class NavStatePath : protected VariableSizeObjectInterface<NavStatePath, NavStateIndex_t>,
0101 private Index2PVolumeConverter<NavStateIndex_t> {
0102 public:
0103 using Value_t = NavStateIndex_t;
0104 using Base_t = VariableSizeObjectInterface<NavStatePath, Value_t>;
0105 using VariableData_t = VariableSizeObj<Value_t>;
0106
0107 private:
0108 friend Base_t;
0109
0110
0111 VECCORE_ATT_HOST_DEVICE
0112 VariableData_t &GetVariableData() { return fPath; }
0113 VECCORE_ATT_HOST_DEVICE
0114 const VariableData_t &GetVariableData() const { return fPath; }
0115
0116 unsigned char
0117 fCurrentLevel;
0118
0119
0120
0121
0122
0123 short fCache;
0124
0125 bool fOnBoundary;
0126
0127 #ifdef VECGEOM_CACHED_TRANS
0128
0129 bool fCacheM = true;
0130 Transformation3D fTopTrans;
0131 #endif
0132
0133
0134 VariableSizeObj<Value_t> fPath;
0135
0136
0137
0138 VECGEOM_FORCE_INLINE
0139 VECCORE_ATT_HOST_DEVICE
0140 NavStatePath(size_t nvalues);
0141
0142 VECGEOM_FORCE_INLINE
0143 VECCORE_ATT_HOST_DEVICE
0144 NavStatePath(size_t new_size, NavStatePath &other)
0145 : fCurrentLevel(other.fCurrentLevel), fCache(-1), fOnBoundary(other.fOnBoundary),
0146 #ifdef VECGEOM_CACHED_TRANS
0147 fCacheM(other.fCacheM), fTopTrans(other.fTopTrans),
0148 #endif
0149 fPath(new_size, other.fPath)
0150 {
0151
0152
0153
0154
0155
0156 if (new_size > other.fPath.fN) {
0157 memset(fPath.GetValues() + other.fPath.fN, 0, new_size - other.fPath.fN);
0158 }
0159 }
0160
0161
0162 VECGEOM_FORCE_INLINE
0163 VECCORE_ATT_HOST_DEVICE
0164 void InitInternalStorage();
0165
0166 private:
0167
0168
0169
0170 const void *DataStart() const { return (const void *)&fCurrentLevel; }
0171 const void *ObjectStart() const { return (const void *)this; }
0172 void *DataStart() { return (void *)&fCurrentLevel; }
0173 void *ObjectStart() { return (void *)this; }
0174
0175
0176 size_t DataSize() const { return SizeOf() + (size_t)ObjectStart() - (size_t)DataStart(); }
0177
0178 public:
0179
0180
0181
0182 void ConvertToGPUPointers();
0183
0184
0185
0186
0187 void ConvertToCPUPointers();
0188
0189
0190 using Base_t::MakeCopy;
0191 using Base_t::MakeCopyAt;
0192 using Base_t::ReleaseInstance;
0193 using Base_t::SizeOf;
0194 using Base_t::SizeOfAlignAware;
0195
0196
0197
0198 using Index2PVolumeConverter<NavStateIndex_t>::ToIndex;
0199 using Index2PVolumeConverter<NavStateIndex_t>::ToPlacedVolume;
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 VECCORE_ATT_HOST_DEVICE
0211 static NavStatePath *MakeInstance(int maxlevel)
0212 {
0213
0214 return Base_t::MakeInstance(maxlevel + 1);
0215 }
0216
0217 VECCORE_ATT_HOST_DEVICE
0218 static NavStatePath *MakeInstanceAt(int maxlevel, void *addr)
0219 {
0220
0221 return Base_t::MakeInstanceAt(maxlevel + 1, addr);
0222 }
0223
0224
0225
0226 VECCORE_ATT_HOST_DEVICE
0227 static size_t SizeOfInstance(int maxlevel)
0228 {
0229
0230 return VariableSizeObjectInterface::SizeOf(maxlevel + 1);
0231 }
0232
0233
0234
0235
0236 VECCORE_ATT_HOST_DEVICE
0237 static size_t SizeOfInstanceAlignAware(int maxlevel)
0238 {
0239
0240 return VariableSizeObjectInterface::SizeOfAlignAware(maxlevel + 1);
0241 }
0242
0243 VECCORE_ATT_HOST_DEVICE
0244 int GetObjectSize() const { return SizeOf(GetMaxLevel()); }
0245
0246 VECCORE_ATT_HOST_DEVICE
0247 int SizeOf() const { return NavStatePath::SizeOfInstance(GetMaxLevel()); }
0248
0249 VECGEOM_FORCE_INLINE
0250 VECCORE_ATT_HOST_DEVICE
0251 NavStatePath &operator=(NavStatePath const &rhs);
0252
0253
0254
0255
0256 void GetPathAsListOfIndices(std::list<uint> &indices) const;
0257 void ResetPathFromListOfIndices(VPlacedVolume const *world, std::list<uint> const &indices);
0258
0259 VECCORE_ATT_HOST_DEVICE
0260 void CopyTo(NavStatePath *other) const
0261 {
0262
0263
0264
0265
0266 bool alloc = other->fPath.fSelfAlloc;
0267
0268
0269
0270
0271
0272 std::memcpy(static_cast<void *>(other), this, NavStatePath::SizeOfInstance(this->GetCurrentLevel()));
0273
0274 other->fPath.fSelfAlloc = alloc;
0275 }
0276
0277
0278
0279
0280 template <size_t N>
0281 void CopyToFixedSize(NavStatePath *other) const
0282 {
0283 bool alloc = other->fPath.fSelfAlloc;
0284 for (size_t i = 0; i < N; ++i) {
0285 ((char *)other)[i] = ((char *)this)[i];
0286 }
0287 other->fPath.fSelfAlloc = alloc;
0288 }
0289
0290 VECGEOM_FORCE_INLINE
0291 VECCORE_ATT_HOST_DEVICE
0292 ~NavStatePath();
0293
0294
0295
0296 VECGEOM_FORCE_INLINE
0297 VECCORE_ATT_HOST_DEVICE
0298 unsigned char GetMaxLevel() const { return fPath.fN - 1; }
0299
0300 VECGEOM_FORCE_INLINE
0301 VECCORE_ATT_HOST_DEVICE
0302 unsigned char GetCurrentLevel() const { return fCurrentLevel; }
0303
0304 VECGEOM_FORCE_INLINE
0305 VECCORE_ATT_HOST_DEVICE
0306 VPlacedVolume const *GetLastExited() const
0307 {
0308 return (fCurrentLevel < GetMaxLevel() - 1) ? ToPlacedVolume(fPath[fCurrentLevel]) : nullptr;
0309 }
0310
0311 VECGEOM_FORCE_INLINE
0312 VECCORE_ATT_HOST_DEVICE
0313 void SetLastExited() {}
0314
0315
0316 VECGEOM_FORCE_INLINE
0317 VECCORE_ATT_HOST_DEVICE
0318 void Push(VPlacedVolume const *);
0319
0320
0321 VECGEOM_FORCE_INLINE
0322 VECCORE_ATT_HOST_DEVICE
0323 void Push(unsigned short);
0324
0325
0326 VECGEOM_FORCE_INLINE
0327 VECCORE_ATT_HOST_DEVICE
0328 void PushIndexType(NavStateIndex_t);
0329
0330 VECGEOM_FORCE_INLINE
0331 VECCORE_ATT_HOST_DEVICE
0332 VPlacedVolume const *Top() const;
0333
0334 VECGEOM_FORCE_INLINE
0335 VECCORE_ATT_HOST_DEVICE
0336 VPlacedVolume const *At(int level) const { return ToPlacedVolume(fPath[level]); }
0337
0338 VECGEOM_FORCE_INLINE
0339 VECCORE_ATT_HOST_DEVICE
0340 Value_t ValueAt(int level) const { return fPath[level]; }
0341
0342
0343
0344
0345 VECGEOM_FORCE_INLINE
0346 VECCORE_ATT_HOST_DEVICE
0347 void SetValueAt(int level, Value_t v) { fPath[level] = v; }
0348
0349 VECGEOM_FORCE_INLINE
0350 VECCORE_ATT_HOST_DEVICE
0351 void TopMatrix(Transformation3D &) const;
0352
0353 #ifdef VECGEOM_CACHED_TRANS
0354
0355 VECGEOM_FORCE_INLINE
0356 VECCORE_ATT_HOST_DEVICE
0357 void UpdateTopMatrix(Transformation3D *top_matrix = nullptr);
0358 #endif
0359
0360
0361
0362
0363 VECCORE_ATT_HOST_DEVICE
0364 void DeltaTransformation(NavStatePath const &other, Transformation3D & ) const;
0365
0366
0367 VECCORE_ATT_HOST_DEVICE
0368 Vector3D<Precision> GlobalToLocal(Vector3D<Precision> const &) const;
0369
0370 VECCORE_ATT_HOST_DEVICE
0371 Vector3D<Precision> GlobalToLocal(Vector3D<Precision> const &, int tolevel) const;
0372
0373 VECCORE_ATT_HOST_DEVICE
0374 void TopMatrix(int tolevel, Transformation3D &) const;
0375
0376 VECGEOM_FORCE_INLINE
0377 VECCORE_ATT_HOST_DEVICE
0378 void Pop();
0379
0380 VECGEOM_FORCE_INLINE
0381 VECCORE_ATT_HOST_DEVICE
0382 int Distance(NavStatePath const &) const;
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396 std::string RelativePath(NavStatePath const & ) const;
0397
0398
0399 VECGEOM_FORCE_INLINE
0400 VECCORE_ATT_HOST_DEVICE
0401 void Clear();
0402
0403 VECCORE_ATT_HOST_DEVICE
0404 void Print() const;
0405
0406 VECGEOM_FORCE_INLINE
0407 VECCORE_ATT_HOST_DEVICE
0408 void Dump() const;
0409
0410 VECGEOM_FORCE_INLINE
0411 VECCORE_ATT_HOST_DEVICE
0412 bool HasSamePathAsOther(NavStatePath const &other) const
0413 {
0414 if (other.fCurrentLevel != fCurrentLevel) return false;
0415 for (int i = fCurrentLevel - 1; i >= 0; --i) {
0416 if (fPath[i] != other.fPath[i]) return false;
0417 }
0418 return true;
0419 }
0420
0421 void printValueSequence(std::ostream & = std::cerr) const;
0422
0423
0424
0425 unsigned long getCheckSum() const
0426 {
0427 unsigned long s = 0;
0428 for (int i = 0; i < fCurrentLevel; ++i) {
0429 s += (unsigned long)(ValueAt(i) + 1);
0430 }
0431 return s;
0432 }
0433
0434
0435
0436
0437
0438 VECGEOM_FORCE_INLINE
0439 VECCORE_ATT_HOST_DEVICE
0440 unsigned char GetLevel() const { return fCurrentLevel - 1; }
0441
0442
0443
0444
0445 VECGEOM_FORCE_INLINE
0446 VECCORE_ATT_HOST_DEVICE
0447 bool IsOutside() const { return !(fCurrentLevel > 0); }
0448
0449 VECGEOM_FORCE_INLINE
0450 VECCORE_ATT_HOST_DEVICE
0451 bool IsOnBoundary() const { return fOnBoundary; }
0452
0453 #ifdef VECGEOM_CACHED_TRANS
0454 VECGEOM_FORCE_INLINE
0455 VECCORE_ATT_HOST_DEVICE
0456 bool IsMatrixCached() const { return fCacheM; }
0457 #endif
0458
0459 VECGEOM_FORCE_INLINE
0460 VECCORE_ATT_HOST_DEVICE
0461 void SetBoundaryState(bool b) { fOnBoundary = b; }
0462
0463 VECGEOM_FORCE_INLINE
0464 VECCORE_ATT_HOST_DEVICE
0465 short GetCacheValue() const { return fCache; }
0466
0467 VECGEOM_FORCE_INLINE
0468 VECCORE_ATT_HOST_DEVICE
0469 void SetCacheValue(short v) { fCache = v; }
0470
0471 };
0472
0473 VECCORE_ATT_HOST_DEVICE
0474 NavStatePath &NavStatePath::operator=(NavStatePath const &rhs)
0475 {
0476 if (this != &rhs) {
0477 fCurrentLevel = rhs.fCurrentLevel;
0478 fCache = rhs.fCache;
0479 fOnBoundary = rhs.fOnBoundary;
0480 #ifdef VECGEOM_CACHED_TRANS
0481 fCacheM = rhs.fCacheM;
0482 fTopTrans = rhs.fTopTrans;
0483 #endif
0484
0485 fPath = rhs.fPath;
0486 }
0487 return *this;
0488 }
0489
0490
0491 VECCORE_ATT_HOST_DEVICE
0492 NavStatePath::NavStatePath(size_t nvalues) : fCurrentLevel(0), fCache(-1), fOnBoundary(false), fPath(nvalues)
0493 {
0494
0495 std::memset(fPath.GetValues(), 0, nvalues * sizeof(NavStateIndex_t));
0496 }
0497
0498 VECCORE_ATT_HOST_DEVICE
0499 NavStatePath::~NavStatePath() {}
0500
0501 VECCORE_ATT_HOST_DEVICE
0502 void NavStatePath::Pop()
0503 {
0504 if (fCurrentLevel > 0) {
0505 fCurrentLevel--;
0506
0507
0508 fCache = -1;
0509 #ifdef VECGEOM_CACHED_TRANS
0510 fCacheM = false;
0511 #endif
0512 }
0513 }
0514
0515 VECCORE_ATT_HOST_DEVICE
0516 void NavStatePath::Clear()
0517 {
0518 fCurrentLevel = 0;
0519 fOnBoundary = false;
0520 fCache = -1;
0521 #ifdef VECGEOM_CACHED_TRANS
0522 fCacheM = true;
0523 #endif
0524 }
0525
0526 VECCORE_ATT_HOST_DEVICE
0527 void NavStatePath::Push(VPlacedVolume const *v)
0528 {
0529 #ifdef DEBUG
0530 assert(fCurrentLevel < GetMaxLevel());
0531 #endif
0532 fPath[fCurrentLevel++] = ToIndex(v);
0533 #ifdef VECGEOM_CACHED_TRANS
0534 fCacheM = false;
0535 #endif
0536 }
0537
0538
0539 VECCORE_ATT_HOST_DEVICE
0540 void NavStatePath::Push(unsigned short child)
0541 {
0542 if (fCurrentLevel > 0) {
0543 auto top = ToPlacedVolume(fPath[fCurrentLevel - 1]);
0544 #ifdef DEBUG
0545 assert(child < top->GetDaughters().size());
0546 #endif
0547 fPath[fCurrentLevel++] = ToIndex(top->GetDaughters().operator[](child));
0548 #ifdef VECGEOM_CACHED_TRANS
0549 fCacheM = false;
0550 #endif
0551 }
0552 }
0553
0554 VECCORE_ATT_HOST_DEVICE
0555 void NavStatePath::PushIndexType(NavStateIndex_t v)
0556 {
0557 #ifdef DEBUG
0558 assert(fCurrentLevel < GetMaxLevel());
0559 #endif
0560 fPath[fCurrentLevel++] = v;
0561 #ifdef VECGEOM_CACHED_TRANS
0562 fCacheM = false;
0563 #endif
0564 }
0565
0566 VECCORE_ATT_HOST_DEVICE
0567 VPlacedVolume const *NavStatePath::Top() const
0568 {
0569 return (fCurrentLevel > 0) ? ToPlacedVolume(fPath[fCurrentLevel - 1]) : nullptr;
0570 }
0571
0572
0573
0574
0575 VECGEOM_FORCE_INLINE
0576 VECCORE_ATT_HOST_DEVICE
0577 void NavStatePath::TopMatrix(Transformation3D &global_matrix) const
0578 {
0579
0580 #ifdef VECGEOM_CACHED_TRANS
0581 if (fCacheM) {
0582 global_matrix = fTopTrans;
0583 return;
0584 }
0585 #endif
0586 for (int i = 1; i < fCurrentLevel; ++i) {
0587 global_matrix.MultiplyFromRight(*(ToPlacedVolume(fPath[i])->GetTransformation()));
0588 }
0589 }
0590
0591 #ifdef VECGEOM_CACHED_TRANS
0592
0593 VECGEOM_FORCE_INLINE
0594 VECCORE_ATT_HOST_DEVICE
0595 void NavStatePath::UpdateTopMatrix(Transformation3D *top_matrix)
0596 {
0597
0598 if (fCacheM) return;
0599 if (top_matrix) {
0600 fTopTrans = *top_matrix;
0601 } else {
0602
0603 fTopTrans.Clear();
0604 TopMatrix(fTopTrans);
0605 }
0606
0607 fCacheM = true;
0608 }
0609 #endif
0610
0611 VECGEOM_FORCE_INLINE
0612 VECCORE_ATT_HOST_DEVICE
0613 void NavStatePath::Dump() const
0614 {
0615 const unsigned int *ptr = (const unsigned int *)this;
0616 #pragma GCC diagnostic push
0617 #pragma GCC diagnostic ignored "-Wcast-qual"
0618 printf("NavState::Dump(): data: %p(%zu) : %p(%zu) : %p(%zu)\n", (void *)&fCurrentLevel, sizeof(fCurrentLevel),
0619 (void *)&fOnBoundary, sizeof(fOnBoundary), (void *)&fPath, sizeof(fPath));
0620 for (unsigned int i = 0; i < 20; ++i) {
0621 printf("%p: ", (void *)ptr);
0622 for (unsigned int j = 0; j < 8; ++j) {
0623 printf(" %08x ", *ptr);
0624 ptr++;
0625 }
0626 printf("\n");
0627 }
0628 #pragma GCC diagnostic pop
0629 }
0630
0631
0632
0633
0634 inline void NavStatePath::printValueSequence(std::ostream &stream) const
0635 {
0636 for (int i = 0; i < fCurrentLevel; ++i) {
0637 stream << "/" << fPath[i] << "(" << At(i)->GetLabel() << ")";
0638 }
0639 }
0640
0641
0642
0643
0644
0645 VECGEOM_FORCE_INLINE
0646 VECCORE_ATT_HOST_DEVICE
0647 int NavStatePath::Distance(NavStatePath const &other) const
0648 {
0649 int lastcommonlevel = -1;
0650 int maxlevel = Min(GetCurrentLevel(), other.GetCurrentLevel());
0651
0652
0653 for (int i = 0; i < maxlevel; i++) {
0654 if (this->At(i) == other.At(i)) {
0655 lastcommonlevel = i;
0656 } else {
0657 break;
0658 }
0659 }
0660
0661 return (GetCurrentLevel() - lastcommonlevel) + (other.GetCurrentLevel() - lastcommonlevel) - 2;
0662 }
0663
0664 inline void NavStatePath::ConvertToGPUPointers()
0665 {
0666 #if !defined(VECCORE_CUDA) && defined(VECGEOM_ENABLE_CUDA) && !defined(VECGEOM_USE_INDEXEDNAVSTATES)
0667 for (int i = 0; i < fCurrentLevel; ++i) {
0668 auto *pvol = vecgeom::CudaManager::Instance().LookupPlaced(ToPlacedVolume(fPath[i])).GetPtr();
0669 fPath[i] = ToIndex(pvol);
0670 }
0671 #endif
0672 }
0673
0674 inline void NavStatePath::ConvertToCPUPointers()
0675 {
0676 #if !defined(VECCORE_CUDA) && defined(VECGEOM_ENABLE_CUDA) && !defined(VECGEOM_USE_INDEXEDNAVSTATES)
0677 for (int i = 0; i < fCurrentLevel; ++i)
0678 fPath[i] = ToIndex(vecgeom::CudaManager::Instance().LookupPlacedCPUPtr((const void *)ToPlacedVolume(fPath[i])));
0679 #endif
0680 }
0681 }
0682 }
0683
0684 #if defined(GCC_DIAG_POP_NEEDED)
0685 #pragma GCC diagnostic pop
0686 #undef GCC_DIAG_POP_NEEDED
0687 #endif
0688
0689 #endif