CbmRoot
Loading...
Searching...
No Matches
CbmTofGeoHandler.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] */
4
5// -------------------------------------------------------------------------
6// ----- CbmTofGeoHandler source file -----
7// ----- Created 13/08/10 by F. Uhlig -----
8// -------------------------------------------------------------------------
9#include "CbmTofGeoHandler.h"
10
11#include "CbmDefs.h" // for kTof
12#include "CbmTofDetectorId_v07a.h" // for CbmTofDetectorId_v07a
13#include "CbmTofDetectorId_v12b.h" // for CbmTofDetectorId_v12b
14#include "CbmTofDetectorId_v14a.h" // for CbmTofDetectorId_v14a
15#include "CbmTofDetectorId_v21a.h" // for CbmTofDetectorId_v21a
16
17#include <Logger.h> // for Logger, LOG
18
19#include <TGeoBBox.h> // for TGeoBBox
20#include <TGeoManager.h> // for gGeoManager, TGeoManager
21#include <TGeoNode.h> // for TGeoNode
22#include <TGeoVolume.h> // for TGeoVolume
23#include <TObjArray.h> // for TObjArray
24#include <TObject.h> // for TObject
25#include <TVirtualMC.h> // for TVirtualMC, gMC
26
27#include <string.h> // for strlen, strncpy
28
30 : TObject()
31 , fTofId(nullptr)
32 , fGeoVersion(-1)
33 , fIsSimulation(kFALSE)
34 , fMCVersion(-1)
35 , fUseNodeName(kFALSE)
36 , fLastUsedDetectorID(0)
37 , fDetectorInfoArray()
38 , fGeoPathHash(0)
39 , fCurrentVolume(nullptr)
40 , fVolumeShape(nullptr)
41 , fGlobal()
42 , fGlobalMatrix(nullptr)
43{
44}
45
46Int_t CbmTofGeoHandler::Init(Bool_t isSimulation)
47{
48 fIsSimulation = isSimulation;
49
50 if (fIsSimulation) {
51 TString tVirtualMCName = gMC->GetName();
52
53 if (tVirtualMCName == "TGeant3TGeo") {
54 fMCVersion = 0;
55 }
56 else if (tVirtualMCName == "TGeant4") {
57 fMCVersion = 1;
58 }
59 else if (tVirtualMCName == "TFluka") {
60 fMCVersion = 2;
61 }
62 else {
63 fMCVersion = 3; // GEANE
64 }
65 }
66
67 Int_t geoVersion = CheckGeometryVersion();
68
69 return geoVersion;
70}
71
73{
74 // Check which geometry version is used. In the moment there are 3
75 // possible geometry versions.
76 // v07a:
77 // Old TOF geometry at 10 m from target
78 // v12a:
79 // Old TOF geometry at 6 m from target. Beside the z position
80 // the geometry is the same as v07a, so it is handled in the same way
81 // v12b:
82 // New version of the tof geometrie developed by Norbert Herrmann
83 // including also a support structure
84 // v14a:
85 // test beam tof geometrie developed by Norbert Herrmann
86 // v20a:
87 // tof geometrie with MRPC and Module types developed by Norbert Herrmann
88
89 if (nullptr == gGeoManager) LOG(fatal) << "No GeoManager";
90
91 TObjArray* nodes = gGeoManager->GetTopNode()->GetNodes();
92 for (Int_t iNode = 0; iNode < nodes->GetEntriesFast(); iNode++) {
93 TGeoNode* node = (TGeoNode*) nodes->At(iNode);
94 LOG(info) << "Inspect node " << iNode << " " << node->GetName();
95 if (TString(node->GetName()).Contains("tof")) {
96 // Since there is only one tof top node we check for full node name
97 // In the old geometries v07a and v12a the name of this node is tof1_0
98 // In new geometries the node name is tof_v<year><version> eg. tof_v12b
99 // With this naming scheme the geometry version is completely qualified
100 LOG(info) << "Found TOF geometry " << TString(node->GetName());
101 if (TString(node->GetName()).EqualTo("tof1_0")) {
102 LOG(info) << "Found TOF geometry v07a";
105 return fGeoVersion;
106 }
107 else if (TString(node->GetName()).EqualTo("tof_v12b_0")) {
108 LOG(info) << "Found TOF geometry v12b.";
111 return fGeoVersion;
112 }
113 else if (TString(node->GetName()).Contains("v13")) {
114 //TString(node->GetName()).EqualTo("tof_v13-3a_0")) {
115 LOG(info) << "Found TOF geometry " << TString(node->GetName()) << ", treat as Id 12b ";
118 return fGeoVersion;
119 }
120 else if ((TString(node->GetName()).Contains("v14")) || (TString(node->GetName()).Contains("v16a"))
121 || (TString(node->GetName()).Contains("v16c")) || (TString(node->GetName()).Contains("v16d"))
122 || (TString(node->GetName()).Contains("v16e")) || (TString(node->GetName()).Contains("v17a"))
123 || (TString(node->GetName()).Contains("v17c")) || (TString(node->GetName()).Contains("v19"))) {
124 LOG(info) << "CbmTofGeoHandler::CheckGeometryVersion: Found TOF geometry " << TString(node->GetName())
125 << ", treat as Id 14a ";
126 // if(nullptr!=fTofId) fTofId->Delete();
129
130 if (TString(node->GetName()).Contains("v14a_n")) {
131 if (fIsSimulation && 0 != fMCVersion) {
132 LOG(fatal) << "Using node names instead of volume names to extract "
133 "the module type "
134 << "in a MC simulation only works with GEANT3 VMC!";
135 }
136
137 fUseNodeName = kTRUE;
138 }
139 return fGeoVersion;
140 }
141 else if ((TString(node->GetName()).Contains("v21")) || (TString(node->GetName()).Contains("v18"))
142 || (TString(node->GetName()).Contains("v20")) || (TString(node->GetName()).Contains("v22"))
143 || (TString(node->GetName()).Contains("v24"))) {
144 LOG(info) << "CbmTofGeoHandler::CheckGeometryVersion: Found TOF geometry " << TString(node->GetName())
145 << ", treat as Id 21a ";
146 // if(nullptr!=fTofId) fTofId->Delete();
149 return fGeoVersion;
150 }
151 else {
152 LOG(fatal) << "Found an unknown TOF geometry.";
153 fGeoVersion = -1;
154 return fGeoVersion;
155 }
156 }
157 }
158 LOG(fatal) << "No TOF geometry found!";
159 fGeoVersion = -1;
160 return fGeoVersion;
161}
162
164{
165 if (fGeoPathHash != volName.Hash()) {
166 NavigateTo(volName);
167 }
168 return GetUniqueDetectorId();
169}
170
171
173{
174
175 Int_t smtype = 0;
176 Int_t smodule = 0;
177 Int_t counter = 0;
178 Int_t countertype = 0;
179 Int_t gap = 0;
180 Int_t cell = 0;
181 TString Volname;
182
183
184 if (fGeoVersion == k07a) {
185 Volname = CurrentVolName();
186 smtype = Volname[5] - '0';
188 CurrentVolOffID(1, cell);
189 CurrentVolID(gap);
190 }
191 else if (fGeoVersion == k12b) {
192 Volname = CurrentVolOffName(4);
193 smtype = Volname[7] - '0';
194 CurrentVolOffID(4, smodule);
196 CurrentVolOffID(1, gap);
197 CurrentVolID(cell);
198 }
199 else if (fGeoVersion == k14a) { // test beam
200 if (fUseNodeName) {
201 Volname = CurrentNodeOffName(4);
202 }
203 else {
204 Volname = CurrentVolOffName(4);
205 }
206 smtype = Volname[7] - '0';
207 CurrentVolOffID(4, smodule);
209 CurrentVolOffID(1, gap);
210 CurrentVolID(cell);
211 // counter=smodule; // necessary for plastics
212 // smodule=smtype; // for test beam setup
213 gap = 0;
214 cell--;
215 }
216 else if (fGeoVersion == k21a) { // test beam
217 if (fUseNodeName) {
218 Volname = CurrentNodeOffName(4);
219 }
220 else {
221 Volname = CurrentVolOffName(4);
222 }
223 //smtype = Volname[7] - '0';
224 TString csmtype = Volname(7, Volname.Length());
225 smtype = csmtype.Atoi();
226 CurrentVolOffID(4, smodule);
228 CurrentVolOffID(1, gap);
229 CurrentVolID(cell);
230 // counter=smodule; // necessary for plastics
231 // smodule=smtype; // for test beam setup
232 gap = 0;
233 cell--;
234 }
235
236 LOG(debug1) << "GetUniqueDetectorId: ";
237 LOG(debug1) << " Volname: " << Volname << ", " << CurrentVolOffName(3) << ", " << CurrentVolOffName(2) << ", "
238 << CurrentVolOffName(1) << ", " << CurrentVolOffName(0);
239
240 TString cTemp = CurrentVolOffName(2);
241 TString cType = cTemp(8, 2); // 1 character only
242 countertype = cType.Atoi();
243
244 if (fGeoVersion == k21a) {
245 LOG(debug1) << " SMtype: " << smtype << " SModule: " << smodule << " CounterType: " << countertype
246 << " Counter: " << counter << " Gap: " << gap << " Cell: " << cell;
247 }
248 else {
249 LOG(debug1) << " SMtype: " << smtype << " SModule: " << smodule << " Counter: " << counter << " Gap: " << gap
250 << " Cell: " << cell;
251 }
252
253 CbmTofDetectorInfo detInfo(ECbmModuleId::kTof, smtype, smodule, counter, gap, cell, countertype);
254
255 Int_t result = fTofId->SetDetectorInfo(detInfo);
256 LOG(debug1) << " Unique ID: " << Form("0x%08x", result);
257 // return fTofId->SetDetectorInfo(detInfo);
258 return result;
259}
260
261
263{
264
265 Int_t smtype = 0;
266 Int_t smodule = 0;
267 Int_t countertype = 0;
268 Int_t counter = 0;
269 Int_t gap = 0;
270 Int_t cell = 0;
271 TString Volname;
272
273
274 if (fGeoVersion == k07a) {
275 Volname = CurrentVolName();
276 smtype = Volname[5] - '0';
278 CurrentVolOffID(1, cell);
279 CurrentVolID(gap);
280 }
281 else if (fGeoVersion == k12b) {
282 Volname = CurrentVolOffName(4);
283 smtype = Volname[7] - '0';
284 CurrentVolOffID(4, smodule);
286 CurrentVolOffID(1, gap);
287 CurrentVolID(cell);
288 }
289 else if (fGeoVersion == k14a) { // test beam
290 if (fUseNodeName) {
291 Volname = CurrentNodeOffName(4);
292 }
293 else {
294 Volname = CurrentVolOffName(4);
295 }
296 //smtype = Volname[7] - '0';
297 TString csmtype = Volname(7, Volname.Length());
298 smtype = csmtype.Atoi();
299 CurrentVolOffID(4, smodule);
301 CurrentVolOffID(1, gap);
302 CurrentVolID(cell);
303 // counter=smodule; // necessary for plastics
304 // smodule=smtype; // for test beam setup
305 }
306 else if (fGeoVersion == k21a) { // test beam
307 if (fUseNodeName) {
308 Volname = CurrentNodeOffName(4);
309 }
310 else {
311 Volname = CurrentVolOffName(4);
312 }
313 smtype = Volname[7] - '0';
314 CurrentVolOffID(4, smodule);
315 TString cTemp = CurrentVolOffName(2);
316 TString cType = cTemp(8, 2); // 1 character only
317 countertype = cType.Atoi();
319 CurrentVolOffID(1, gap);
320 CurrentVolID(cell);
321 }
322
323 cell = 0;
324
325 fDetectorInfoArray = CbmTofDetectorInfo(ECbmModuleId::kTof, smtype, smodule, counter, gap, cell, countertype);
326
327 gap = 0;
328
329 LOG(debug1) << "GetUniqueCounterId: ";
330 LOG(debug1) << " Volname: " << Volname << ", " << CurrentVolOffName(3) << ", " << CurrentVolOffName(2) << ", "
331 << CurrentVolOffName(1) << ", " << CurrentVolOffName(0);
332 if (fGeoVersion == k21a) {
333 LOG(debug1) << " SMtype: " << smtype << " SModule: " << smodule << " CounterType: " << countertype
334 << " Counter: " << counter << " Gap: " << gap << " Cell: " << cell;
335 }
336 else {
337 LOG(debug1) << " SMtype: " << smtype << " SModule: " << smodule << " Counter: " << counter << " Gap: " << gap
338 << " Cell: " << cell;
339 }
340
341 CbmTofDetectorInfo detInfo(ECbmModuleId::kTof, smtype, smodule, counter, gap, cell, countertype);
342
343 Int_t result = fTofId->SetDetectorInfo(detInfo);
344 fLastUsedDetectorID = result;
345 LOG(debug1) << " Unique ID: " << Form("0x%08x", result);
346 // return fTofId->SetDetectorInfo(detInfo);
347 return result;
348}
349
350/*
351void CbmTofGeoHandler::FillInternalStructures()
352{
353 // Extract geometry information from Virtual MC.
354 // All geometry handling should be done now in the
355 // separate utility class CbmTofGeoHandler
356
357 Int_t stationNr = 1;
358 char volumeName[10];
359 Bool_t result;
360 Int_t MCid;
361
362 fStationMap.clear();
363 fModuleTypeMap.clear();
364
365 if (fGeoVersion == kNewMonolithic) {
366
367 do {
368 sprintf(volumeName, "trd%dgas", stationNr);
369 MCid = VolId(volumeName);
370 if ( 0 != MCid) {
371 fStationMap.insert(pair<Int_t,Int_t>(MCid,stationNr));
372 }
373 stationNr++;
374 } while ( 0 != MCid);
375
376 } else {
377
378 do {
379 sprintf(volumeName, "trd%d", stationNr);
380 MCid = VolId(volumeName);
381 if ( 0 != MCid) {
382 fStationMap.insert(pair<Int_t,Int_t>(MCid,stationNr));
383 }
384 stationNr++;
385 }
386 while ( 0 != MCid);
387
388 Int_t maxStationNr = --stationNr;
389
390 Int_t maxModuleTypes;
391 if (fGeoVersion == kSegmentedSquaredOneKeepingVolume) {
392 maxModuleTypes = 8;
393 } else {
394 maxModuleTypes = 3;
395 }
396
397 for (Int_t iStation = 1; iStation < maxStationNr; iStation++) {
398 for (Int_t iModule = 1; iModule <= maxModuleTypes; iModule++) {
399 sprintf(volumeName, "trd%dmod%d", iStation, iModule);
400 MCid = VolId(volumeName);
401 if ( 0 != MCid ) {
402 fModuleTypeMap.insert(pair<Int_t,Int_t>(MCid,iModule));
403 }
404 }
405 }
406 }
407}
408*/
409
410Int_t CbmTofGeoHandler::VolIdGeo(const char* name) const
411{
412 //
413 // Return the unique numeric identifier for volume name
414 //
415
416 Int_t uid = gGeoManager->GetUID(name);
417 if (uid < 0) {
418 LOG(info) << "VolId: Volume " << name << " not found";
419 return 0;
420 }
421 return uid;
422}
423
424Int_t CbmTofGeoHandler::VolId(const Text_t* name) const
425{
426 if (fIsSimulation) {
427 return gMC->VolId(name);
428 }
429 else {
430 //
431 // Return the unique numeric identifier for volume name
432 //
433 Int_t len = strlen(name) - 1;
434 if (name[len] != ' ') {
435 return VolIdGeo(name);
436 }
437 char sname[len + 1];
438 memcpy(sname, name, len);
439 sname[len] = 0;
440 return VolIdGeo(sname);
441 }
442}
443
444Int_t CbmTofGeoHandler::CurrentVolID(Int_t& copy) const
445{
446 if (fIsSimulation) {
447 return gMC->CurrentVolID(copy);
448 }
449 else {
450 //
451 // Returns the current volume ID and copy number
452 //
453 if (gGeoManager->IsOutside()) {
454 return 0;
455 }
456 TGeoNode* node = gGeoManager->GetCurrentNode();
457 copy = node->GetNumber();
458 Int_t id = node->GetVolume()->GetNumber();
459 return id;
460 }
461}
462
463//_____________________________________________________________________________
464Int_t CbmTofGeoHandler::CurrentVolOffID(Int_t off, Int_t& copy) const
465{
466 if (fIsSimulation) {
467 return gMC->CurrentVolOffID(off, copy);
468 }
469 else {
470 //
471 // Return the current volume "off" upward in the geometrical tree
472 // ID and copy number
473 //
474 if (off < 0 || off > gGeoManager->GetLevel()) {
475 return 0;
476 }
477 if (off == 0) {
478 return CurrentVolID(copy);
479 }
480 TGeoNode* node = gGeoManager->GetMother(off);
481 if (!node) {
482 return 0;
483 }
484 copy = node->GetNumber();
485 return node->GetVolume()->GetNumber();
486 }
487}
488
489//_____________________________________________________________________________
491{
492 if (fIsSimulation) {
493 return gMC->CurrentVolName();
494 }
495 else {
496 //
497 // Returns the current volume name
498 //
499 if (gGeoManager->IsOutside()) return gGeoManager->GetTopVolume()->GetName();
500 return gGeoManager->GetCurrentVolume()->GetName();
501 }
502}
503
504//_____________________________________________________________________________
505const char* CbmTofGeoHandler::CurrentVolOffName(Int_t off) const
506{
507 if (fIsSimulation) {
508 return gMC->CurrentVolOffName(off);
509 }
510 else {
511 //
512 // Return the current volume "off" upward in the geometrical tree
513 // ID, name and copy number
514 // if name=0 no name is returned
515 //
516 if (off < 0 || off > gGeoManager->GetLevel()) return 0;
517 if (off == 0) return CurrentVolName();
518 TGeoNode* node = gGeoManager->GetMother(off);
519 if (!node) return 0;
520 return node->GetVolume()->GetName();
521 }
522}
523
524//_____________________________________________________________________________
526{
527 //
528 // Returns the current node name
529 //
530 if (gGeoManager->IsOutside()) return gGeoManager->GetTopNode()->GetName();
531 return gGeoManager->GetCurrentNode()->GetName();
532}
533
534//_____________________________________________________________________________
535const char* CbmTofGeoHandler::CurrentNodeOffName(Int_t off) const
536{
537 //
538 // Return the current node "off" upward in the geometrical tree
539 // if name=0 no name is returned
540 //
541 if (off < 0 || off > gGeoManager->GetLevel()) return 0;
542 if (off == 0) return CurrentNodeName();
543 TGeoNode* node = gGeoManager->GetMother(off);
544 if (!node) return 0;
545 return node->GetName();
546}
547
549{
551 fLastUsedDetectorID = uniqueId;
552}
553
555{
556 if (fLastUsedDetectorID != uniqueId) {
557 FillDetectorInfoArray(uniqueId);
558 }
560}
561
562Int_t CbmTofGeoHandler::GetSMType(Int_t uniqueId)
563{
564 if (fLastUsedDetectorID != uniqueId) {
565 FillDetectorInfoArray(uniqueId);
566 }
568}
569
570Int_t CbmTofGeoHandler::GetSModule(Int_t uniqueId)
571{
572 if (fLastUsedDetectorID != uniqueId) {
573 FillDetectorInfoArray(uniqueId);
574 }
576}
577
578Int_t CbmTofGeoHandler::GetCounter(Int_t uniqueId)
579{
580 if (fLastUsedDetectorID != uniqueId) {
581 FillDetectorInfoArray(uniqueId);
582 }
584}
585
586Int_t CbmTofGeoHandler::GetGap(Int_t uniqueId)
587{
588 if (fLastUsedDetectorID != uniqueId) {
589 FillDetectorInfoArray(uniqueId);
590 }
592}
593
594Int_t CbmTofGeoHandler::GetCell(Int_t uniqueId)
595{
596 if (fLastUsedDetectorID != uniqueId) {
597 FillDetectorInfoArray(uniqueId);
598 }
600}
601
602Int_t CbmTofGeoHandler::GetRegion(Int_t uniqueId)
603{
604 /*
605 if (fLastUsedDetectorID != uniqueId) {
606 FillDetectorInfoArray(uniqueId);
607 }
608*/
609 return GetSMType(uniqueId);
610}
611
612Int_t CbmTofGeoHandler::GetCellId(Int_t uniqueId) { return fTofId->GetCellId(uniqueId); }
613
614Float_t CbmTofGeoHandler::GetSizeX(TString volName)
615{
616 if (fGeoPathHash != volName.Hash()) {
617 NavigateTo(volName);
618 }
619 Float_t sizex = fVolumeShape->GetDX();
620 return sizex;
621}
622
623Float_t CbmTofGeoHandler::GetSizeY(TString volName)
624{
625 if (fGeoPathHash != volName.Hash()) {
626 NavigateTo(volName);
627 }
628 Float_t sizey = fVolumeShape->GetDY();
629 return sizey;
630}
631
632Float_t CbmTofGeoHandler::GetSizeZ(TString volName)
633{
634 if (fGeoPathHash != volName.Hash()) {
635 NavigateTo(volName);
636 }
637 Float_t sizez = fVolumeShape->GetDZ();
638 return sizez;
639}
640
641Float_t CbmTofGeoHandler::GetZ(TString volName)
642{
643 if (fGeoPathHash != volName.Hash()) {
644 NavigateTo(volName);
645 }
646 return fGlobal[2];
647}
648
649Float_t CbmTofGeoHandler::GetY(TString volName)
650{
651 if (fGeoPathHash != volName.Hash()) {
652 NavigateTo(volName);
653 }
654 return fGlobal[1];
655}
656
657Float_t CbmTofGeoHandler::GetX(TString volName)
658{
659 if (fGeoPathHash != volName.Hash()) {
660 NavigateTo(volName);
661 }
662 return fGlobal[0];
663}
664
665void CbmTofGeoHandler::NavigateTo(TString volName)
666{
667 if (fIsSimulation) {
668 LOG(fatal) << "This methode is not supported in simulation mode";
669 }
670 else {
671 gGeoManager->cd(volName.Data());
672 fGeoPathHash = volName.Hash();
673 fCurrentVolume = gGeoManager->GetCurrentVolume();
674 fVolumeShape = (TGeoBBox*) fCurrentVolume->GetShape();
675 Double_t local[3] = {0., 0., 0.}; // Local centre of volume
676 gGeoManager->LocalToMaster(local, fGlobal);
677 LOG(debug2) << "GeoNav: Pos: " << fGlobal[0] << " , " << fGlobal[1] << " , " << fGlobal[2];
678 // fGlobalMatrix = gGeoManager->GetCurrentMatrix();
679 }
680}
681
682
ClassImp(CbmConverterManager)
@ kTof
Time-of-flight Detector.
@ k12b
@ k21a
@ k14a
@ k07a
virtual int32_t GetCellId(const int32_t detectorId)=0
virtual int32_t SetDetectorInfo(const CbmTofDetectorInfo detectorInfo)=0
virtual CbmTofDetectorInfo GetDetectorInfo(const int32_t detectorId)=0
Int_t VolIdGeo(const char *name) const
Int_t GetCell(Int_t uniqueId)
Int_t Init(Bool_t isSimulation=kFALSE)
void NavigateTo(TString volName)
Float_t GetZ(TString volName)
Float_t GetX(TString volName)
Int_t GetSModule(Int_t uniqueId)
const char * CurrentVolOffName(Int_t off) const
Int_t VolId(const Text_t *name) const
Int_t GetCounter(Int_t uniqueId)
Int_t CurrentVolOffID(Int_t off, Int_t &copy) const
Int_t GetSMType(Int_t uniqueId)
Float_t GetSizeX(TString volName)
void FillDetectorInfoArray(Int_t uniqueId)
const char * CurrentVolName() const
Float_t GetSizeY(TString volName)
Int_t GetRegion(Int_t uniqueId)
Float_t GetSizeZ(TString volName)
CbmTofDetectorId * fTofId
const char * CurrentNodeOffName(Int_t off) const
CbmTofDetectorInfo fDetectorInfoArray
const char * CurrentNodeName() const
Int_t CurrentVolID(Int_t &copy) const
TGeoVolume * fCurrentVolume
Int_t GetDetSystemId(Int_t uniqueId)
Int_t GetCellId(Int_t uniqueId)
Float_t GetY(TString volName)
Int_t GetGap(Int_t uniqueId)