CbmRoot
Loading...
Searching...
No Matches
CbmTrdGeoHandler.cxx
Go to the documentation of this file.
1/* Copyright (C) 2010-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Florian Uhlig [committer], David Emschermann, Andrey Lebedev */
4
9#include "CbmTrdGeoHandler.h"
10
11#include "CbmTrdAddress.h" // for CbmTrdAddress
12
13#include <Logger.h> // for LOG, Logger
14
15#include <TGenericClassInfo.h> // for TGenericClassInfo
16#include <TGeoBBox.h> // for TGeoBBox
17#include <TGeoManager.h> // for TGeoManager, gGeoManager
18#include <TGeoNode.h> // for TGeoNode
19#include <TGeoPhysicalNode.h> // for TGeoPhysicalNode
20#include <TGeoVolume.h> // for TGeoVolume
21#include <TObjArray.h> // for TObjArray
22#include <TObject.h> // for TObject
23#include <TVirtualMC.h> // for TVirtualMC, gMC
24
25#include <cstdlib> // for atoi
26#include <iostream> // for string
27
28using std::atoi;
29using std::string;
30
32 : TObject()
33 , fIsSimulation(kFALSE)
34 , fGeoPathHash(0)
35 , fCurrentVolume(nullptr)
36 , fVolumeShape(nullptr)
37 , fGlobal()
38 , fGlobalMatrix(nullptr)
39 , fLayerId(0)
40 , fModuleId(0)
41 , fModuleType(0)
42 , fRadiatorType(-1)
43 , fRotation(0)
44 , fStation(0)
45 , fLayer(0)
46 , fModuleCopy(0)
47{
48}
49
51
52void CbmTrdGeoHandler::Init(Bool_t isSimulation) { fIsSimulation = isSimulation; }
53
55{
56
57 // In the simulation we can not rely on the TGeoManager information
58 // In the simulation we get the correct information only from gMC
59 Int_t copyNr;
60 if (fIsSimulation) {
61 // get the copy number of the mother volume (1 volume up in hierarchy)
62 gMC->CurrentVolOffID(1, copyNr);
63 // Check if the geometry is legacy version
64 string s(gMC->CurrentVolPath());
65 if (s.find("Volume") < s.size()) { // new geometry format
66 LOG(debug4) << "New geo " << gMC->CurrentVolPath();
67 // get the copy number of the mother volume (2 volume up in hierarchy)
68 gMC->CurrentVolOffID(2, copyNr);
69 }
70 else
71 LOG(debug4) << "Legacy geo " << gMC->CurrentVolPath();
72 }
73 else {
74 // Check if the geometry is legacy version
75 int nodeIdx(1);
76 string s(gGeoManager->GetPath());
77 if (s.find("Volume") < s.size()) { // new geometry format
78 LOG(debug4) << "New geo " << s;
79 nodeIdx++;
80 }
81 else
82 LOG(debug4) << "Legacy geo " << s;
83 // We take the mother node (module) of the current node we are in (gas).
84 TGeoNode* node = gGeoManager->GetMother(nodeIdx);
85 // Get the module copy number to get the information about layerId and moduleId.
86 copyNr = node->GetNumber();
87 }
88 LOG(debug4) << "CopyNr: " << copyNr;
89
90 Int_t layerId = 0;
91 Int_t moduleId = 0;
92
93 if ((copyNr / 100000000) > 0) // has 9 digits => 2014 format
94 {
95 // In TGeoManager numbering starts with 1, so we have to subtract 1.
96 layerId = ((copyNr / 1000) % 100) - 1;
97 moduleId = (copyNr % 1000) - 1;
98 LOG(debug4) << "2014 ";
99 }
100 else // 2013 and earlier
101 {
102 // In TGeoManager numbering starts with 1, so we have to subtract 1.
103 layerId = ((copyNr / 100) % 100) - 1;
104 moduleId = (copyNr % 100) - 1;
105 LOG(debug4) << "2013 ";
106 }
107
108 LOG(debug4) << copyNr / 100000000 << " copy " << copyNr << " layerID " << layerId << " moduleId " << moduleId;
109 // Form the module address.
110 return CbmTrdAddress::GetAddress(layerId, moduleId, 0, 0, 0);
111}
112
113Int_t CbmTrdGeoHandler::GetModuleAddress(const TString& path)
114{
115 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
116 return GetModuleAddress();
117}
118
119//Int_t CbmTrdGeoHandler::GetModuleOrientation()
120//{
121// // We take the mother node (module) of the current node we are in (gas).
122// TGeoNode* modulenode = gGeoManager->GetMother();
123// // Get the module copy number to get the information about layerId and moduleId.
124// Int_t modulecopyNr = modulenode->GetNumber();
125// // In TGeoManager numbering starts with 1, so we have to subtract 1.
126// fRotation = ((modulecopyNr / 10000) % 10); // from module copy number
127// // LOG(info) << "fRotation: " << modulecopyNr << " " << fRotation;
128// return fRotation;
129//}
130
132{
133 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
134 return fRotation;
135}
136
137Double_t CbmTrdGeoHandler::GetSizeX(const TString& path)
138{
139 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
140 return fVolumeShape->GetDX();
141}
142
143Double_t CbmTrdGeoHandler::GetSizeY(const TString& path)
144{
145 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
146 return fVolumeShape->GetDY();
147}
148
149Double_t CbmTrdGeoHandler::GetSizeZ(const TString& path)
150{
151 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
152 return fVolumeShape->GetDZ();
153}
154
155Double_t CbmTrdGeoHandler::GetZ(const TString& path)
156{
157 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
158 return fGlobal[2];
159}
160
161Double_t CbmTrdGeoHandler::GetY(const TString& path)
162{
163 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
164 return fGlobal[1];
165}
166
167Double_t CbmTrdGeoHandler::GetX(const TString& path)
168{
169 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
170 return fGlobal[0];
171}
172
173Int_t CbmTrdGeoHandler::GetModuleType(const TString& path)
174{
175 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
176 return fModuleType;
177}
178
179Int_t CbmTrdGeoHandler::GetRadiatorType(const TString& path)
180{
181 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
182 return fRadiatorType;
183}
184
185Int_t CbmTrdGeoHandler::GetStation(const TString& path)
186{
187 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
188 return fStation;
189}
190
191Int_t CbmTrdGeoHandler::GetLayer(const TString& path)
192{
193 if (fGeoPathHash != path.Hash()) {
194 // LOG(info) << "path : " << path.Data();
195 NavigateTo(path);
196 }
197 return fLayer;
198}
199
200Int_t CbmTrdGeoHandler::GetModuleCopyNr(const TString& path)
201{
202 if (fGeoPathHash != path.Hash()) { NavigateTo(path); }
203 return fModuleCopy;
204}
205
206void CbmTrdGeoHandler::NavigateTo(const TString& path)
207{
208 LOG(debug) << "CbmTrdGeoHandler::NavigateTo(" << path.Data() << ")";
209 if (fIsSimulation) { LOG(fatal) << "This method is not supported in simulation mode"; }
210 else {
211 gGeoManager->cd(path.Data());
212 fGeoPathHash = path.Hash();
213 fCurrentVolume = gGeoManager->GetCurrentVolume();
214 fVolumeShape = (TGeoBBox*) fCurrentVolume->GetShape();
215 Double_t local[3] = {0., 0., 0.}; // Local center of volume
216 gGeoManager->LocalToMaster(local, fGlobal);
217 fGlobalMatrix = gGeoManager->GetCurrentMatrix();
218 int nodeIdx(1);
219 string s(gGeoManager->GetPath());
220 if (s.find("Volume") < s.size()) { // new geometry format
221 LOG(debug) << "CbmTrdGeoHandler::NavigateTo(new geo)";
222 nodeIdx++;
223 }
224 // We take the mother node (module) of the current node we are in (gas).
225 TGeoNode* modulenode = gGeoManager->GetMother(nodeIdx);
226 // We take the mother of the mother node (layer) of the current node we are in (gas).
227 TGeoNode* layernode = gGeoManager->GetMother(nodeIdx + 1); // get layer
228 // Get module type information which is decoded in copy number.
229 std::string moduleName = modulenode->GetName();
230 auto typeposstart = moduleName.find("module") + 6;
231 uint ndigits = 0;
232 auto partoftype = moduleName.at(typeposstart);
233 while (std::isdigit(partoftype) && (ndigits + typeposstart) < moduleName.size()) {
234 partoftype = moduleName.at(typeposstart + ndigits);
235 ++ndigits;
236 }
237 fModuleType = std::atoi(moduleName.substr(typeposstart, ndigits).data()); // 6th element+ module type
238 // TODO hybrid semaphore for TRD2D
239 if (nodeIdx == 2 && fModuleType == 1) fModuleType = 9;
240 Int_t layercopyNr = layernode->GetNumber();
241 // fIsRotated is the 4th digit from the back
242 fStation = ((layercopyNr / 10000) % 10); // from layer copy number
243 // LOG(info) << "DE fStation: " << fStation << " ";
244 fLayer = ((layercopyNr / 100) % 10); // from layer copy number
245
246 // Get the module copy number to get the information about layerId and moduleId.
247 Int_t modulecopyNr = modulenode->GetNumber();
248
249 if ((modulecopyNr / 100000000) > 0) // has 9 digits => 2014 format
250 {
251 // In TGeoManager numbering starts with 1, so we have to subtract 1.
252 fModuleCopy = ((modulecopyNr / 1000000) % 100); // from module copy number
253 fRotation = ((modulecopyNr / 100000) % 10); // from module copy number
254 fRadiatorType = -1;
255 for (int i = 0; i < modulenode->GetNdaughters(); i++) {
256 TString nDaughter(modulenode->GetDaughter(i)->GetName());
257 if (!nDaughter.BeginsWith("radiator") && !nDaughter.BeginsWith("Radiator")) continue;
258 fRadiatorType = 0;
259 // TODO define radiator (+ entrance window) types according to the naming convention
260 }
261 }
262 else // 2013 and earlier
263 {
264 // In TGeoManager numbering starts with 1, so we have to subtract 1.
265 fModuleCopy = ((modulecopyNr / 100000) % 100); // from module copy number
266 fRotation = ((modulecopyNr / 10000) % 10); // from module copy number
267 }
268
269 // LOG(info) << "fRotation: " << modulecopyNr << " " << fRotation;
270 // fLayerId = ((modulecopyNr / 100) % 100) - 1;
271 // fModuleId = ((modulecopyNr / 1) % 100) - 1;
272 }
273}
274
275std::map<Int_t, TGeoPhysicalNode*> CbmTrdGeoHandler::FillModuleMap()
276{
277 // The geometry structure is treelike with cave as
278 // the top node. For the TRD there are keeping volumes with names
279 // like trd_vXXy_1 which are only a container for the different layers.
280 // The trd layer is again only a container for all volumes of this layer.
281 // Loop over all nodes below the top node (cave). If one of
282 // the nodes contains a string trd it must be TRD detector.
283 // Now loop over the layers and then over all modules of the layer
284 // to extract the node information for each detector module
285 // all active regions (gas) of the complete TRD.
286
287 std::map<Int_t, TGeoPhysicalNode*> moduleMap;
288
289 TGeoNode* topNode = gGeoManager->GetTopNode();
290 TObjArray* nodes = topNode->GetNodes();
291 for (Int_t iNode = 0; iNode < nodes->GetEntriesFast(); iNode++) {
292 TGeoNode* node = static_cast<TGeoNode*>(nodes->At(iNode));
293 if (!TString(node->GetName()).Contains("trd", TString::kIgnoreCase))
294 continue; // trd_vXXy top node, e.g. trd_v13a, trd_v14b
295 TGeoNode* station = node;
296
297 TObjArray* layers = station->GetNodes();
298 for (Int_t iLayer = 0; iLayer < layers->GetEntriesFast(); iLayer++) {
299 TGeoNode* layer = static_cast<TGeoNode*>(layers->At(iLayer));
300 if (!TString(layer->GetName()).Contains("layer", TString::kIgnoreCase)) continue; // only layers
301
302 TObjArray* modules = layer->GetNodes();
303 for (Int_t iModule = 0; iModule < modules->GetEntriesFast(); iModule++) {
304 TGeoNode* module = static_cast<TGeoNode*>(modules->At(iModule));
305 TObjArray* parts = module->GetNodes();
306 for (Int_t iPart = 0; iPart < parts->GetEntriesFast(); iPart++) {
307 TGeoNode* part = static_cast<TGeoNode*>(parts->At(iPart));
308 if (!TString(part->GetName()).Contains("gas", TString::kIgnoreCase)) continue; // only active gas volume
309
310 // Put together the full path to the interesting volume, which
311 // is needed to navigate with the geomanager to this volume.
312 // Extract the geometry information (size, global position)
313 // from this volume.
314 TString path = TString("/") + topNode->GetName() + "/" + station->GetName() + "/" + layer->GetName() + "/"
315 + module->GetName() + "/" + part->GetName();
316
317 LOG(debug) << "Adding detector with path " << path;
318 // Generate a physical node which has all needed information
319 TGeoPhysicalNode* pNode = new TGeoPhysicalNode(path.Data());
320 Int_t address = GetModuleAddress();
321 moduleMap[address] = pNode;
322 }
323 }
324 }
325 }
326 return moduleMap;
327}
328
329
ClassImp(CbmConverterManager)
Helper class to convert unique channel ID back and forth.
Helper class to extract information from the GeoManager.
static uint32_t GetAddress(int32_t layerId, int32_t moduleId, int32_t sectorId, int32_t rowId, int32_t columnId)
Return address from system ID, layer, module, sector, column and row IDs.
Int_t fModuleCopy
LayerID within station, 1..4.
Double_t GetY(const TString &path)
void NavigateTo(const TString &path)
Int_t GetModuleCopyNr(const TString &path)
Int_t GetLayer(const TString &path)
Int_t GetModuleType(const TString &path)
Int_t GetRadiatorType(const TString &path)
Navigate to node and return the radiator type build in the geometry based on the naming convention.
void Init(Bool_t isSimulation=kFALSE)
TGeoVolume * fCurrentVolume
Int_t fStation
rotation angle 0,1,2,3
Int_t GetStation(const TString &path)
CbmTrdGeoHandler()
Constructor.
Double_t GetSizeX(const TString &path)
Double_t GetSizeZ(const TString &path)
Double_t GetSizeY(const TString &path)
Double_t GetZ(const TString &path)
Double_t GetX(const TString &path)
Int_t fLayer
StationTypeID, 1..3.
std::map< Int_t, TGeoPhysicalNode * > FillModuleMap()
Fill map with information of the gas volumes for each detector.
TGeoHMatrix * fGlobalMatrix
Global center of volume.
Int_t fRotation
radiator + chamber entrance window type
~CbmTrdGeoHandler()
Destructor.
Int_t GetModuleOrientation(const TString &path)
Return pad orientation of the current node in the TGeoManager.
Int_t GetModuleAddress()
Return module address calculated based on the current node in the TGeoManager.