BmnRoot
Loading...
Searching...
No Matches
BmnGeoTemplate.h
Go to the documentation of this file.
1#ifndef BMNGEOTEMPLATE_H
2#define BMNGEOTEMPLATE_H
3
4#include "BmnEnums.h"
5#include "FairGeoSet.h"
6#include "FairLogger.h"
7#include "TFile.h"
8#include "TGeoBBox.h"
9#include "TGeoManager.h"
10#include "TGeoNavigator.h"
11#include "TGeoNode.h"
12#include "TGeoVolume.h"
13#include "TString.h"
14#include "TVector3.h"
15
16#include <memory>
17#include <string>
18#include <unordered_map>
19
20// -----------------------------------------------------------------------------
21// CRTP base: loads geometry from either an existing TGeoManager or a ROOT file,
22// then delegates to Derived::ListNodesImpl() to fill fPositionMap.
23// -----------------------------------------------------------------------------
24template<class Derived>
26{
27 public:
28 BmnGeoTemplate() = default;
29 virtual ~BmnGeoTemplate() = default;
30
31 // Load via existing gGeoManager
32 BmnStatus ReadGeometryFromGeoManager(bool getGlobalPosition = true)
33 {
34 if (!gGeoManager) {
35 LOG(error) << Name() << ": no GeoManager!";
36 return kBMNERROR;
37 }
38 gGeoManager->GetCache()->BuildIdArray();
39 auto* saveTop = gGeoManager->GetTopVolume();
40 if (!getGlobalPosition) {
41 gGeoManager->CdTop();
42 if (gGeoManager->CheckPath(Derived::PathBeforeLocalSystem())) {
43 gGeoManager->cd(Derived::PathBeforeLocalSystem());
44 gGeoManager->SetTopVolume(gGeoManager->GetCurrentNode()->GetVolume());
45 } else {
46 LOG(error) << Name() << ": wrong path " << Derived::PathBeforeLocalSystem();
47 }
48 }
49
50 ListNodes();
51
52 if (!getGlobalPosition) {
53 gGeoManager->SetTopVolume(saveTop);
54 }
55 return kBMNSUCCESS;
56 }
57
58 // Load standalone from ROOT file (with VMCWORKDIR fallback)
59 BmnStatus ReadGeometryFromFile(const std::string& path, bool getGlobalPosition = true)
60 {
61 TString full = Form("%s/geometry/%s", getenv("VMCWORKDIR"), path.c_str());
62 LOG(info) << Name() << ": ReadGeometryFromFile " << full;
63 if (gGeoManager) {
64 LOG(warn) << Name() << ": GeoManager exists. Delegating to GeoManager";
65 return ReadGeometryFromGeoManager(getGlobalPosition);
66 } else {
67 TFile f(full.Data(), "READONLY");
68 auto* top = dynamic_cast<TGeoVolume*>(f.Get(Derived::TopVolumeName()));
69 if (!top) {
70 LOG(error) << Name() << ": no TOP volume in file " << full;
71 return kBMNERROR;
72 }
73 gGeoManager->SetTopVolume(top);
74 gGeoManager->CloseGeometry();
75 if (ReadGeometryFromGeoManager(getGlobalPosition) == kBMNSUCCESS) {
76 delete gGeoManager;
77 gGeoManager = nullptr;
78 }
79 }
80 return kBMNSUCCESS;
81 }
82
83 // Public entry‐point: clear maps & dispatch to impl, using gGeoManager
84 void ListNodes()
85 {
86 fPositionMap.clear();
87 if (!gGeoManager) {
88 LOG(error) << Name() << ": ListNodes called without a GeoManager";
89 return;
90 }
91 // call detector‐specific implementation
92 static_cast<Derived*>(this)->ListNodesImpl();
93
94 if (FairLogger::GetLogger()->IsLogNeeded(fair::Severity::debug)) {
95 for (const auto& kv : fPositionMap) {
96 uint32_t address = kv.first;
97 const auto& pos = kv.second.first;
98 const auto& err = kv.second.second;
99 LOG(debug) << Form("%s: addr=0x%08X pos=(%.2f, %.2f, %.2f) err=(%.2f, %.2f, %.2f)", Name(), address,
100 pos.X(), pos.Y(), pos.Z(), err.X(), err.Y(), err.Z());
101 }
102 }
103 }
104
105 // IsPointInside just delegates to Derived’s volume name
106 bool IsPointInside(const TVector3& p) const
107 {
108 if (!gGeoManager)
109 return false;
110 auto* nav = gGeoManager->GetCurrentNavigator();
111 if (!nav)
112 return false;
113 nav->SetCurrentPoint(p.X(), p.Y(), p.Z());
114 nav->FindNode();
115 return TString(nav->GetPath()).Contains(Derived::DetectorVolumeName());
116 }
117
118 // Accessors
119 const auto& GetPositionMap() const { return fPositionMap; }
120
121 protected:
123 const char* Name() const { return static_cast<Derived*>(const_cast<BmnGeoTemplate*>(this))->GetName(); }
124
125 // --- default implementation: one node to one entry ---
127 {
128 int n = gGeoManager->CountNodes();
129 for (int i = 0; i < n; ++i) {
130 gGeoManager->CdNode(i);
131 auto* node = gGeoManager->GetCurrentNode();
132 if (!node)
133 continue;
134 if (!Derived::CheckIfSensitive(node->GetVolume()->GetName()))
135 continue;
136
137 // address from path
138 uint32_t addr = static_cast<Derived*>(this)->GetAddressFromPath(gGeoManager->GetPath());
139
140 // position
141 double loc[3] = {0}, glb[3];
142 gGeoManager->LocalToMaster(loc, glb);
143 fPositionMap[addr] =
144 std::make_pair(TVector3(glb[0], glb[1], glb[2]), static_cast<Derived*>(this)->GetPosError(node));
145 }
146 }
147
149 TVector3 GetPosError(TGeoNode* node) const
150 {
151 if (auto* box = dynamic_cast<TGeoBBox*>(node->GetVolume()->GetShape())) {
152 return TVector3(box->GetDX(), box->GetDY(), box->GetDZ());
153 }
154 return TVector3(0, 0, 0);
155 }
156
157 std::map<uint32_t, std::pair<TVector3, TVector3>> fPositionMap;
158
159 ClassDef(BmnGeoTemplate, 1)
160};
161
162#endif // BMNGEOTEMPLATE_H
int i
Definition P4_F32vec4.h:22
float f
Definition P4_F32vec4.h:21
BmnStatus
Definition BmnEnums.h:24
@ kBMNERROR
Definition BmnEnums.h:26
@ kBMNSUCCESS
Definition BmnEnums.h:25
bool IsPointInside(const TVector3 &p) const
BmnStatus ReadGeometryFromFile(const std::string &path, bool getGlobalPosition=true)
TVector3 GetPosError(TGeoNode *node) const
by default: box‐half‐sizes
const char * Name() const
Helper to call the FairGeoSet::GetName() on the actual object.
BmnGeoTemplate()=default
const auto & GetPositionMap() const
BmnStatus ReadGeometryFromGeoManager(bool getGlobalPosition=true)
virtual ~BmnGeoTemplate()=default
std::map< uint32_t, std::pair< TVector3, TVector3 > > fPositionMap
Define enumerations used in tracking.