CbmRoot
Loading...
Searching...
No Matches
CbmTrdGeoSetup.cxx
Go to the documentation of this file.
1/* Copyright (C) 2024 National Institute of Physics and Nuclear Engineering - Horia Hulubei, Bucharest
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Alexandru Bercuci [committer] */
4
5#include "CbmTrdGeoSetup.h"
6
7#include "CbmTrdGeoFactory.h"
8
9#include <FairParGenericSet.h> // for FairParGenericSet
10#include <FairParamList.h> // for FairParamList
11#include <FairRunAna.h> // for FairRunAna
12#include <FairRuntimeDb.h> // for FairRuntimeDb
13#include <Logger.h> // for LOG
14
15#include <TArrayI.h> // for TArrayI
16#include <TDatime.h> // for TDatime::AsString()
17#include <TGeoElement.h> // for active volume material interogation
18#include <TGeoManager.h> // for TGeoManager, gGeoManager
19#include <TGeoNode.h> // for TGeoNode
20#include <TObjArray.h> // for TObjArray
21#include <TSystem.h> // for TSystem::GetUserInfo()
22
23using namespace cbm::trd::geo;
24
25
26//__________________________________________________________________
28{
29 InitStatus stat;
30 TGeoNode* topNode = gGeoManager->GetTopNode();
31 TObjArray* nodes = topNode->GetNodes();
32 for (Int_t iNode = 0; iNode < nodes->GetEntriesFast(); iNode++) {
33 TGeoNode* trdGeo = static_cast<TGeoNode*>(nodes->At(iNode));
34 if (string(trdGeo->GetName()).find("trd") != 0) continue; // trd_vXXy top node, e.g. trd_v13a, trd_v14b
35 fGeoTag = trdGeo->GetName();
36
37 // init the setup. Collect meta info
38 string uname = "John Doe", ucontact = "not-defined", udescr = "not-defined";
39 // retrieve user name from the system
40 auto uinfo = gSystem->GetUserInfo(gSystem->GetEffectiveUid());
41 if (!uinfo)
42 LOG(warning) << "Couldn't read user_name.";
43 else
44 uname = uinfo->fRealName;
45 if (fContact.compare("") == 0)
46 LOG(warning) << "No contact info were provided for responsible " << uname;
47 else
48 ucontact = fContact;
49 if (fDescription.compare("") == 0)
50 LOG(error) << "No comments provided for setup. Please add them by SetupManager::SetDescription()";
51 else
52 udescr = fDescription;
53
54 // build setup adding all meta info
55 uname += ";";
56 uname += ucontact;
57 TDatime d;
58 uname += ";";
59 uname += d.AsString();
60 uname += ";";
61 uname += udescr;
62 Setup* setup = new Setup(fGeoTag.data(), uname.data());
63 Setup::Module modSetup;
64 //fHardwareSetup.SelectComponentIdMap(fGeometryTag);
65 TObjArray* layers = trdGeo->GetNodes();
66 for (Int_t iLayer = 0; iLayer < layers->GetEntriesFast(); iLayer++) {
67 TGeoNode* lyGeo = static_cast<TGeoNode*>(layers->At(iLayer));
68 if (string(lyGeo->GetName()).find("layer") != 0) continue; // only layers
69
70 TObjArray* modules = lyGeo->GetNodes();
71 for (Int_t iModule = 0; iModule < modules->GetEntriesFast(); iModule++) {
72 TGeoNode* modGeo = static_cast<TGeoNode*>(modules->At(iModule));
73 // skip geo elements which are not modules
74 if (string(modGeo->GetName()).find("module") != 0) continue;
75
76 LOG(info) << " Reading module " << modGeo->GetName() << " [" << lyGeo->GetName() << "].";
77 stat = modSetup.init(modGeo);
78 switch (stat) {
79 case kERROR: continue;
80 case kFATAL: LOG(fatal) << GetName() << " Couldn't process geometry file."; break;
81 case kSUCCESS: setup->addParam(new Setup::Module(modSetup)); break;
82 }
83 } // loop over TRD modules / layers
84 } // loop over TRD layers
85 break; // loop over CBM systems
86 }
87 return kSUCCESS;
88}
89
90//__________________________________________________________________
92{
93 FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb();
94 fSetup = (Setup*) (rtdb->getContainer("TrdSetup"));
95}
96
97//__________________________________________________________________
99{
100 FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb();
101 fSetup = (Setup*) (rtdb->getContainer("TrdSetup"));
102 //fSetup->Print();
103}
104
105//__________________________________________________________________
106Setup::Setup(const char* n, const char* t) : FairParGenericSet(n, t, "default")
107{
115 fMetaFields.push_back("name");
116 fMetaFields.push_back("email");
117 fMetaFields.push_back("date");
118 size_t ii(0);
119 if ((ii = Parse()) != fMetaFields.size()) {
120 Help();
121 LOG(warning) << "Number of info fields " << ii << " less than required (" << fMetaFields.size()
122 << "). Info might be spoiled. Check input.\n";
123 }
124 else {
125 for (auto info : fMeta) {
126 if (strcmp(info.second.data(), "") != 0) continue;
127 Help(info.first.data());
128 }
129 }
130}
131
132//__________________________________________________________________
133const char* Setup::GetInfo(const char* label) const
134{
135 if (fMeta.find(label) == fMeta.end()) {
136 Help(label);
137 return nullptr;
138 }
139 return fMeta.at(label).data();
140}
141
142//__________________________________________________________________
143void Setup::Help(const char* lab) const
144{
145 LOG(info) << "* meta info; list of \";\" separated information in the following order:";
146 LOG(info) << "* - \"name\" : responsible person's name";
147 LOG(info) << "* - \"email\" : responsible person's email";
148 LOG(info) << "* - \"date\" : date of creation";
149
150 if (lab) {
151 if (fMeta.find(lab) == fMeta.end())
152 LOG(error) << "Meta info \"" << lab << "\" not defined.\n";
153 else
154 LOG(warning) << "Meta info for\"" << lab << "\" not registered.\n";
155 }
156}
157
158//__________________________________________________________________
160{
161 size_t idx(0);
162 string s(GetTitle());
163 char* p = strtok(s.data(), ";");
164 while (p != nullptr && idx < fMetaFields.size()) {
165 fMeta[fMetaFields[idx++]] = p;
166 p = strtok(nullptr, ";");
167 }
168 return idx;
169}
170
171//_______________________________________________________________________________
172Setup::~Setup() { fModule.clear(); }
173
174//_______________________________________________________________________________
175int Setup::GetModuleId(int i) const
176{
177 if (i < 0 || i >= (int) GetNrOfModules()) return -1;
178 uint16_t id = fModule[i]->GetModuleId();
179 if (id == 0xffff)
180 return -1;
181 else
182 return id;
183}
184
185//_______________________________________________________________________________
186const Setup::Module* Setup::GetModulePar(int detId) const
187{
188 for (auto mod : fModule)
189 if (mod->GetModuleId() == detId) return mod;
190 return nullptr;
191}
192
193//_______________________________________________________________________________
194bool Setup::getParams(FairParamList* l)
195{
196 if (!l) return false;
197 if (!l->fill("Version", &fVersion)) {
198 LOG(error) << GetName() << "::getParams : Couldn't find \"Version\"";
199 return false;
200 }
201 int nmods(0);
202 if (!l->fill("NrOfModules", &nmods)) {
203 LOG(error) << GetName() << "::getParams : Couldn't find \"NrOfModules\"";
204 return false;
205 }
206 TArrayI modId(nmods), typId(nmods), rot(nmods);
207 if (!l->fill("Trd.Id", &modId)) {
208 LOG(error) << GetName() << "::getParams : Couldn't find \"Trd.Id\"";
209 return false;
210 }
211 if (!l->fill("Trd.Type", &typId)) {
212 LOG(error) << GetName() << "::getParams : Couldn't find \"Trd.Type\"";
213 return false;
214 }
215 if (!l->fill("Trd.Rot", &rot)) {
216 LOG(error) << GetName() << "::getParams : Couldn't find \"Trd.Rot\"";
217 return false;
218 }
219 Text_t textIn[100];
220 if (!l->fill("Trd.Gas", textIn, 100)) {
221 LOG(error) << GetName() << "::getParams : Couldn't find \"Trd.Gas\"";
222 return false;
223 }
224 if (textIn[0] == 'A' && textIn[1] == 'r')
225 fGas = eGas::kAr;
226 else
227 fGas = eGas::kXe;
228
229 for (int imod(0); imod < nmods; imod++) {
230 fModule.push_back(new Module(Form("Trd%s.%d", (modId[imod] < 0 ? "2D" : "1D"), abs(modId[imod])), GetTitle()));
231 auto mod = fModule.back();
232 mod->fType = typId[imod];
233 mod->fRot = rot[imod];
234 mod->getParams(l);
235 }
236 return true;
237}
238
239
240//_______________________________________________________________________________
241void Setup::putParams(FairParamList* l)
242{
243 if (!l) return;
244 l->add("Version", fVersion);
245 int ii(0), nmods = (int) GetNrOfModules();
246 l->add("NrOfModules", nmods);
247 TArrayI modId(nmods), typId(nmods), rot(nmods);
248 for (auto mod : fModule) {
249 modId[ii] = mod->GetModuleId() * (mod->GetFamily() == ePadPlane::k1d ? 1 : -1);
250 typId[ii] = mod->GetType();
251 rot[ii] = mod->GetRotation();
252 ii++;
253 }
254 l->add("Trd.Id", modId);
255 l->add("Trd.Type", typId);
256 l->add("Trd.Rot", rot);
257 if (fGas == eGas::kAr)
258 l->add("Trd.Gas", "ArCO2");
259 else
260 l->add("Trd.Gas", "XeCO2");
261 for (auto mod : fModule)
262 mod->putParams(l);
263}
264
265//_______________________________________________________________________________
266void Setup::addParam(Module* mod) { fModule.push_back(mod); }
267
268//_______________________________________________________________________________
269Setup::Module::Module(const char* n, const char* t) : TNamed(n, t)
270{
271 // string name = n;
272 // if (name.size() > 6) {
273 // if (name.substr(3, 2).compare("1D") == 0) fFamily = ePadPlane::k1d;
274 // else
275 // fFamily = ePadPlane::k2d;
276 // fId = stoi(name.substr(6, 10));
277 // }
278}
279
280//_______________________________________________________________________________
281Setup::Module::Module(const Module& m0) : TNamed((const TNamed&) m0)
282{
283 fId = m0.fId;
284 fFee = m0.fFee;
285 fFamily = m0.fFamily;
286 fWindow = m0.fWindow;
287 fGas = m0.fGas;
288 fType = m0.fType;
289 fFeeType = m0.fFeeType;
290 fRot = m0.fRot;
291 fDaq = m0.fDaq;
292 fFEE = m0.fFEE;
293}
294
295//_______________________________________________________________________________
296InitStatus Setup::Module::init(TGeoNode* n)
297{
298 bool hasRadiator(false);
299 info_t info;
300 if (!ReadModuleInfo(n->GetName(), info)) return kERROR;
301
302 TObjArray* components = n->GetNodes();
303 for (Int_t icomp = 0; icomp < components->GetEntriesFast(); icomp++) {
304 TGeoNode* comp = static_cast<TGeoNode*>(components->At(icomp));
305 string cname(comp->GetName());
306
308 LOG(debug4) << GetName() << " Initialize " << comp->GetName() << " with "
310 hasRadiator = true; // to be used when defining entrance window params
311 }
313 LOG(debug4) << GetName() << " Initialize " << comp->GetName() << " with "
315 if (!hasRadiator)
316 fWindow = eWindow::kNotSet;
317 else { // determine if the module have a thin (1D) or thick (2D) entrance window
318 int selectFeature(0);
319 TIter ipcs(comp->GetNodes());
320 while (auto pcs = (TGeoNode*) ipcs()) {
321 if (string(pcs->GetName()).find("winIn_C") == 0)
322 selectFeature++;
323 else if (string(pcs->GetName()).find("winIn_HC") == 0)
324 selectFeature++;
325 }
326 if (selectFeature == 2)
327 fWindow = eWindow::kThick;
328 else
329 fWindow = eWindow::kThin;
330
331 LOG(info) << GetName() << " Initialize TR absorption in " << (fWindow == eWindow::kThick ? "thick" : "thin")
332 << " entrance window.";
333 }
334 }
336 LOG(debug4) << GetName() << " Initialize " << comp->GetName() << " with "
338 // determine the active gas
339 auto gas = (TGeoNode*) comp->GetNodes()->FindObject("gas_0");
340 if (!gas)
341 LOG(error) << GetName() << " Couldn't find \"gas_0\" in " << comp->GetName();
342 else {
343 auto activeGas = gas->GetMedium()->GetMaterial();
344 for (int imat(0); imat < activeGas->GetNelements(); imat++) {
345 auto elem = activeGas->GetElement(imat);
346 switch (elem->Z()) {
347 case 6:
348 case 8: break; // do nothing for C and O
349 case 18: // found Ar
350 fGas = eGas::kAr;
351 break;
352 case 54: // found Xe
353 fGas = eGas::kXe;
354 break;
355 default:
356 elem->Print();
357 LOG(error) << GetName() << " Couldn't found element in active gas from " << comp->GetName();
358 break;
359 }
360 }
361 }
362 if (fGas == eGas::kNotSet) {
363 LOG(warning) << GetName() << " Couldn't identify active gas type. Use legacy mode.";
364 return kERROR;
365 }
366 LOG(info) << GetName() << " Initialize active gas to " << (fGas == eGas::kXe ? "XeCO2." : "ArCO2.");
367 }
369 LOG(debug4) << GetName() << " Initialize " << comp->GetName() << " with "
371 // find the type of the pad-plane and consequently the TRD family
372 TIter ibkp(comp->GetNodes());
373 while (auto bkp = (TGeoNode*) ibkp()) {
374 if (string(bkp->GetName()).find("pp_pcb2d") == 0) {
375 fFamily = ePadPlane::k2d; // 2d
376 SetName(Form("Trd2D.%d", info.address));
377 break;
378 }
379 else if (string(bkp->GetName()).find("pp_pcb1d") == 0) {
380 fFamily = ePadPlane::k1d; // 1d
381 SetName(Form("Trd1D.%d", info.address));
382 break;
383 }
384 }
385 if (fFamily == ePadPlane::kNotSet) {
386 LOG(error) << GetName() << " Couldn't identify TRD module family for " << n->GetName() << " " << n->GetTitle();
387 return kFATAL;
388 }
389 LOG(info) << GetName() << " Initialize TRD family to " << (fFamily == ePadPlane::k2d ? "2D." : "1D;");
390 }
391 else if (cname.find(ChamberBuilder::Component::fgName[(int) ChamberBuilder::eGeoPart::kFEB]) == 0) {
392 LOG(info) << GetName() << " Initialize " << comp->GetName() << " with "
394 // find the FEE family, number of ASICs / module and eventually mapping
395 if (!ReadFebInfo(comp->GetName(), info)) return kERROR;
396 }
397 else {
398 LOG(info) << GetName() << "Geometry of module " << n->GetName() << " uses legacy setup.";
399 return kERROR;
400 }
401 // if (!TString(part->GetName()).BeginsWith("gas_")) continue; // only active gas volume
402 //
403 // // Put together the full path to the interesting volume, which
404 // // is needed to navigate with the geomanager to this volume.
405 // // Extract the geometry information (size, global position)
406 // // from this volume.
407 // TString path = TString("/") + topNode->GetName() + "/" + station->GetName() + "/" + layer->GetName() + "/"
408 // + module->GetName() + "/" + part->GetName();
409 //
410 // CreateModuleParameters(path);
411 }
412 return kSUCCESS;
413}
414
415//_______________________________________________________________________________
416void Setup::Module::putParams(FairParamList* l)
417{
418 int ii(0);
419 TArrayI daqId(fDaq.size());
420 for (auto ic : fDaq)
421 daqId[ii++] = ic;
422 l->add(Form("%s.DaqInfo", GetName()), daqId);
423
424 ii = 0;
425 auto pads = fFEE[0]->GetPads();
426 TArrayI asicSetup(fFEE.size() * (pads.size() + 2));
427 for (auto asic : fFEE) {
428 asicSetup[ii++] = asic->GetId(); // asic id in the module
429 asicSetup[ii++] = asic->GetMask();
430 pads = asic->GetPads();
431 for (auto pad : pads)
432 asicSetup[ii++] = pad;
433 }
434 l->add(Form("%s.%sInfo", GetName(), (fFee == eAsic::kSpadic ? "Spadic" : "Fasp")), asicSetup);
435}
436
437//_______________________________________________________________________________
438bool Setup::Module::getParams(FairParamList* l)
439{
440 READOUT pMod = (fFamily == ePadPlane::k1d ? mod1D[fType] : mod2D[fType]);
441 FEB pFeb = faspFeb[fFeeType];
442 int ndaq = pMod.ndaq;
443 int nasic = pMod.nasic;
444 int nch = pFeb.nchannels;
445 TArrayI daqId(ndaq);
446 if (!l->fill(Form("%s.DaqInfo", GetName()), &daqId)) {
447 LOG(error) << GetName() << "::getParams : Couldn't find \"DaqInfo\"";
448 return false;
449 }
450 fDaq.assign(daqId.GetArray(), daqId.GetArray() + ndaq);
451
452 TArrayI asicInfo(nasic);
453 if (!l->fill(Form("%s.SpadicInfo", GetName()), &asicInfo)) fFee = eAsic::kSpadic;
454 if (!l->fill(Form("%s.FaspInfo", GetName()), &asicInfo))
455 fFee = eAsic::kFasp;
456 else {
457 LOG(error) << GetName() << "::getParams : Couldn't find \"AsicInfo\"";
458 return false;
459 }
460 for (int i(0), k(0); i < nasic; i++) {
461 fFEE.push_back(new Asic(Form("%s%d", (fFee == eAsic::kSpadic ? "Spadic" : "Fasp"), i), GetName()));
462 auto asic = fFEE.back();
463 asic->fUnique = asicInfo[k++];
464 asic->fMask = asicInfo[k++];
465 asic->fPad.assign(&asicInfo[k], &asicInfo[k + nch]);
466 k += nch;
467 }
468
469 return true;
470}
471
472//_______________________________________________________________________________
473Setup::Asic::Asic(const char* n, const char* t) : TNamed(n, t)
474{
475 string name = n;
476 // fFamily = eAsic::kFasp;
477 int nskip(4);
478 if (name.find("Spadic") == 0) {
479 // fFamily = eAsic::kSpadic;
480 nskip = 6;
481 }
482 fId = stoi(name.substr(nskip, 10));
483}
484
485/* clang-format off */
486// NamespaceImp(cbm::trd::geo)
491 /* clang-format on */
ClassImp(CbmConverterManager)
Double_t lab[3]
Builder class for the TRD chamber geometry.
Describing class of the TRD setup geometry, FEE, gas.
static const char * fgName[(int) eGeoPart::kNparts]
Generate setup meta info for the TRD system.
string fDescription
further description of the current setup
Setup * fSetup
the setup object
virtual void Finish()
Inherited from FairTask.
string fContact
contact info (usual email) of the responsible
virtual InitStatus Init()
Inherited from FairTask.
virtual void SetParContainers()
Inherited from FairTask.
string fGeoTag
the setup name
Meta info for one TRD ASIC.
Asic(const char *n, const char *t)
uint8_t fId
ASIC id in the chamber.
Meta info for one TRD module.
int fRot
rotation of chamber in steps of 90 deg
ePadPlane fFamily
Chamber family (1D / 2D)
virtual void putParams(FairParamList *)
Write out the setup from object to FairParamList.
int fFeeType
FEB type for each FEE version.
uint16_t fId
TRD chamber id in the setup.
virtual InitStatus init(TGeoNode *)
Read info relevant for the module from the geometry.
int fType
TRD chamber sub-type (e.g. 1, 3, 5, 7 for TRD1D)
Module(const char *n="", const char *t="")
eWindow fWindow
Entrance window type.
eAsic fFee
ASIC family (SPADIC/FASP)
virtual bool getParams(FairParamList *)
Read in the setup from FairParamList.
Setup meta info for the TRD system to supplement the geometry.
virtual const Module * GetModulePar(int detId) const
Get module par by detector id.
virtual void addParam(Module *mod)
void Help(const char *lab=nullptr) const
Help message for user.
vector< Module * > fModule
list of modules defined in the setup
Setup(const char *n, const char *t)
Setup descriptor for the TRD setup. The identification should be :
map< string, string > fMeta
meta info attached to this setup
virtual int GetModuleId(int i) const
Get module par by index.
virtual bool getParams(FairParamList *)
Read in the setup from FairParamList.
virtual void putParams(FairParamList *)
Write out the setup from object to FairParamList.
vector< string > fMetaFields
ordered list of meta info types
virtual const char * GetInfo(const char *label) const
Retrieve meta info for the setup according to label.
virtual size_t GetNrOfModules() const
Retrieve no of modules in the setup.
size_t Parse()
Parse setup description for meta info.
bool ReadModuleInfo(const char *modTxt, info_t &info)
Identify information related to the module encrypted in the geoManager path. Based on legacy function...
bool ReadFebInfo(const char *febTxt, info_t &info)
Identify information related to one FEB encrypted in the geoManager path.
static constexpr FEB faspFeb[2]
Definition CbmTrdDefs.h:158
@ kXe
XeCO2 active gas.
@ kNotSet
active gas not set / recognized
@ kAr
ArCO2 active gas.
@ kNotSet
window not set / recognized
@ kThin
1D case (Al+mylar)
@ kThick
2D case (Kapton + C + HC)
@ k1d
rectangular 1D case
@ kNotSet
pad=plane not set / recognized
@ k2d
triangular 2D case
static READOUT mod1D[9]
Definition CbmTrdDefs.h:94
static const READOUT mod2D[3]
Definition CbmTrdDefs.h:142
@ kSpadic
SPADIC type definition.
@ kFasp
FASP ASIC definition.
int nchannels
no of channels / asic
Definition CbmTrdDefs.h:79
int ndaq
no of concentrators (e.g. CROB) to read-out the pad-plane
Definition CbmTrdDefs.h:87
int nasic
no of ASICs to read-out the pad-plane
Definition CbmTrdDefs.h:86
Information to be storred in the geoManager path. Based on legacy class CbmTrdGeoHandler.