CbmRoot
Loading...
Searching...
No Matches
CbmTrdHitProducer.cxx
Go to the documentation of this file.
1/* Copyright (C) 2018-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pascal Raisig, Florian Uhlig [committer], Alexandru Bercuci */
4
5#include "CbmTrdHitProducer.h"
6
7#include "CbmDefs.h"
8#include "CbmDigiManager.h"
9#include "CbmTrdAddress.h"
10#include "CbmTrdClusterFinder.h"
11#include "CbmTrdDigi.h"
12#include "CbmTrdGeoHandler.h"
13#include "CbmTrdHit.h"
14#include "CbmTrdModuleRec.h"
15#include "CbmTrdModuleRec2D.h"
16#include "CbmTrdModuleRecR.h"
17#include "CbmTrdParAsic.h"
18#include "CbmTrdParModDigi.h"
19#include "CbmTrdParModGain.h"
20#include "CbmTrdParModGas.h"
21#include "CbmTrdParSetAsic.h"
22#include "CbmTrdParSetDigi.h"
23#include "CbmTrdParSetGain.h"
24#include "CbmTrdParSetGas.h"
25#include "CbmTrdParSetGeo.h"
26
27#include <FairRootManager.h>
28#include <FairRunAna.h>
29#include <FairRuntimeDb.h>
30#include <Logger.h>
31
32#include <TGeoManager.h>
33#include <TGeoPhysicalNode.h>
34#include <TStopwatch.h>
35#include <TVector3.h>
36
37#include <iomanip>
38#include <iostream>
39#include <map>
40
41using std::fixed;
42using std::left;
43using std::right;
44using std::setprecision;
45using std::setw;
46using std::stringstream;
47
48//____________________________________________________________________________________
49CbmTrdHitProducer::CbmTrdHitProducer() : FairTask("TrdHitProducer") {}
50
51//____________________________________________________________________________________
53{
54 fHits->Clear();
55 delete fHits;
56 //if (fGeoPar) delete fGeoPar;
57}
58
59//____________________________________________________________________________________
61{
62
67 if (!mod) return 0;
68
69 auto hits = mod->GetHits();
70
71 if (!hits) return 0;
72
73 std::uint32_t numModuleHits = hits->GetEntriesFast();
74 if (!numModuleHits) return 0;
75 if (event) {
76 uint32_t nHitsTs = fNrHitsCall;
77 int32_t nHitsEv = event->GetNofData(ECbmDataType::kTrdHit);
78 if (nHitsEv > 0) nHitsTs += nHitsEv;
79 for (std::uint32_t iHit = 0; iHit < numModuleHits; ++iHit)
80 event->AddData(ECbmDataType::kTrdHit, nHitsTs + iHit);
81 }
82 fHits->AbsorbObjects(hits);
83 fNrHits += numModuleHits;
84 return numModuleHits;
85}
86
87//____________________________________________________________________________________
89{
90 CbmTrdGeoHandler geoHandler;
91 Int_t moduleAddress = geoHandler.GetModuleAddress(pg->GetTitle()),
92 moduleType = geoHandler.GetModuleType(pg->GetTitle()), lyId = CbmTrdAddress::GetLayerId(address);
93 if (moduleAddress != address) {
94 LOG(error) << "CbmTrdHitProducer::AddModule: Module ID " << address << " does not match geometry definition "
95 << moduleAddress << ". Module init failed!";
96 return nullptr;
97 }
98 // try to load read-out parameters for module
99 const CbmTrdParModDigi* pDigi(NULL);
100 if (!fDigiPar || !(pDigi = (const CbmTrdParModDigi*) fDigiPar->GetModulePar(address))) {
101 LOG(error) << GetName() << "::AddModule : No Read-Out params for module " << address << " @ " << pg->GetTitle()
102 << ". Module init failed!";
103 return nullptr;
104 }
105
106 // find the type of TRD detector was hit. Temporary until a new scheme of setup parameters will be but in place. TODO
107 bool trd2d(false);
108 if (pDigi->GetPadPlaneType() >= 0)
109 trd2d = pDigi->IsPadPlane2D();
110 else
111 trd2d = (moduleType >= 9); // legacy support for old pad-plane addresing
112 LOG(info) << GetName() << "::AddModule(" << pg->GetName() << " " << (trd2d ? '2' : '1') << "D] mod[" << moduleAddress
113 << "] ly[" << lyId << "] det[" << moduleAddress << "]";
114
115 CbmTrdModuleRec* module(nullptr);
116 if (trd2d) {
117 module = fModules[address] = new CbmTrdModuleRec2D(address);
118 ((CbmTrdModuleRec2D*) module)->SetUseHelpers(CbmTrdClusterFinder::UseRecoHelpers());
119 ((CbmTrdModuleRec2D*) module)->SetHitTimeOffset(fHitTimeOffset);
120 }
121 else {
122 module = fModules[address] = new CbmTrdModuleRecR(address);
123 }
124
125 // Load geometry parameters for the module
126 module->SetGeoPar(pg);
127 module->SetDigiPar(pDigi);
128
129 // try to load ASIC parameters for module
130 CbmTrdParModAsic* pAsic(NULL);
131 if (!fAsicPar || !(pAsic = (CbmTrdParModAsic*) fAsicPar->GetModulePar(address))) {
132 LOG(warn) << GetName() << "::AddModule : No ASIC params for modAddress " << address << ". Using default.";
133 // module->SetAsicPar(); // map ASIC channels to read-out channels - need ParModDigi already loaded
134 }
135 else
136 module->SetAsicPar(pAsic);
137
138 // try to load Chamber parameters for module
139 const CbmTrdParModGas* pChmb(NULL);
140 if (!fGasPar || !(pChmb = (const CbmTrdParModGas*) fGasPar->GetModulePar(address))) {
141 LOG(warn) << GetName() << "::AddModule : No Gas params for modAddress " << address << ". Using default.";
142 }
143 else
144 module->SetChmbPar(pChmb);
145
146 // try to load Gain parameters for module
147 if (trd2d) {
148 const CbmTrdParModGain* pGain(NULL);
149 if (!fGainPar || !(pGain = (const CbmTrdParModGain*) fGainPar->GetModulePar(address))) {
150 //LOG(warn) << GetName() << "::AddModule : No Gain params for modAddress "<< address <<". Using default.";
151 }
152 else
153 module->SetGainPar(pGain);
154 }
155 return module;
156}
157
158
159// ---- processCluster ----
161{
162 Int_t nclusters = fClusters->GetEntriesFast();
163
164 for (Int_t icluster = 0; icluster < nclusters; icluster++) {
165 processCluster(icluster);
166 }
167 auto nhits = addHits();
169 LOG(info) << GetName() << "::processClusters: "
170 << " Clusters : " << nclusters;
171 LOG(info) << GetName() << "::processClusters: "
172 << " Hits : " << nhits;
173 }
174 return nhits;
175}
176
177// ---- processCluster ----
179{
180 Int_t nclusters = event->GetNofData(ECbmDataType::kTrdCluster);
181
182 for (Int_t icluster = 0; icluster < nclusters; icluster++) {
183 auto clusterIdx = event->GetIndex(ECbmDataType::kTrdCluster, icluster);
184 processCluster(clusterIdx);
185 }
186 auto nhits = addHits(event);
187
189 LOG(info) << GetName() << "::processClusters: "
190 << " Clusters : " << nclusters;
191 LOG(info) << GetName() << "::processClusters: "
192 << " Hits : " << nhits;
193 }
194 return nhits;
195}
196
197
198// ---- processCluster ----
199void CbmTrdHitProducer::processCluster(const Int_t clusterIdx)
200{
201 auto cluster = static_cast<const CbmTrdCluster*>(fClusters->At(clusterIdx));
202 if (!cluster) return;
203
204 // get/build module for current cluster
205 auto imod = fModules.find(cluster->GetAddress());
206 auto mod = imod->second;
207
208 std::vector<const CbmTrdDigi*> digivec = {};
209
210 // get digis for current cluster
211 for (Int_t iDigi = 0; iDigi < cluster->GetNofDigis(); iDigi++) {
212 const CbmTrdDigi* digi = CbmDigiManager::Instance()->Get<CbmTrdDigi>(cluster->GetDigi(iDigi));
213
214 if (digi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kSPADIC && digi->GetCharge() <= 0) continue;
215 digivec.emplace_back(digi);
216 }
217 mod->MakeHit(clusterIdx, cluster, &digivec);
218
219 fNrClusters++;
220}
221
222// ---- addHits ----
224{
225 Int_t hitCounter(0);
226 for (std::map<Int_t, CbmTrdModuleRec*>::iterator imod = fModules.begin(); imod != fModules.end(); imod++) {
227 auto mod = imod->second;
228 mod->PreProcessHits();
229 mod->PostProcessHits();
230 hitCounter += addModuleHits(mod, event);
231 }
232
233 // AbsorberObjects takes care of cleaning up.
234 // Hence, remove local data from all modules is not needed
235 return hitCounter;
236}
237
238//____________________________________________________________________________________
240{
241 FairRootManager* ioman = FairRootManager::Instance();
242 if (NULL == ioman) {
243 LOG(error) << GetName() << "::Init: "
244 << "ROOT manager is not instantiated!";
245 return kFATAL;
246 }
247
249 if (!CbmDigiManager::Instance()->IsPresent(ECbmModuleId::kTrd)) LOG(fatal) << GetName() << "Missing Trd digi branch.";
250
251 fClusters = (TClonesArray*) ioman->GetObject("TrdCluster");
252 if (!fClusters) {
253 LOG(error) << GetName() << "::Init: "
254 << "no TrdCluster array!";
255 return kFATAL;
256 }
257
258 fHits = new TClonesArray("CbmTrdHit", 100);
259 ioman->Register("TrdHit", "TRD", fHits, IsOutputBranchPersistent("TrdHit"));
260
261 // If not deactivated by the user, the hitproducer will look for the CbmEvent branch, to only use Digis connected to a CbmEvent. If no CbmEvent branch is found all digis in the TrdDigi branch are automatically used.
263 fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent"));
264 if (fEvents == nullptr) {
266 }
267 }
268
269 // Get the full geometry information of the detector gas layers and store
270 // them with the CbmTrdModuleRec. This information can then be used for
271 // transformation calculations
272 if (!fGeoPar->LoadAlignVolumes()) {
273 LOG(error) << GetName() << "::Init: "
274 << "GEO info for modules unavailable !";
275 return kFATAL;
276 }
277
278 Int_t nrModules = fDigiPar->GetNrOfModules();
279 Int_t nrNodes = fGeoPar->GetNrOfModules();
280 if (nrModules != nrNodes)
281 LOG(fatal) << "CbmTrdHitProducer::Init() - Geometry(" << nrNodes << ") and parameter files(" << nrModules
282 << ") have different number of modules.";
283 for (Int_t loop = 0; loop < nrModules; ++loop) {
284 int address = fGeoPar->GetModuleId(loop);
285 const CbmTrdParModGeo* par = (const CbmTrdParModGeo*) fGeoPar->GetModulePar(address);
286 AddModule(address, par);
287 }
288 return kSUCCESS;
289}
290
291//____________________________________________________________________________________
293{
294 fHits->Delete();
295
296 TStopwatch timer;
297 TStopwatch timerTs;
298 timerTs.Start();
299
300 Long64_t nClusters = fClusters->GetEntriesFast();
301 UInt_t nEvents = 0;
302 fNrHitsCall = 0;
303
305 for (auto eventobj : *fEvents) {
306 timer.Start();
307 auto event = static_cast<CbmEvent*>(eventobj);
308 if (!event) continue;
310 fNrEvents++;
311 nEvents++;
312 timer.Stop();
314 LOG(info) << GetName() << "::Exec : Event Nr: " << fNrEvents;
315 LOG(info) << GetName() << "::Exec : real time=" << timer.RealTime() << " CPU time=" << timer.CpuTime();
316 }
317 fProcessTime += timer.RealTime();
318 timer.Reset();
319 }
320 }
321
323 timer.Start();
325 fNrEvents++;
326 timer.Stop();
328 LOG(info) << GetName() << "::Exec : Event Nr: " << fNrEvents;
329 LOG(info) << GetName() << "::Exec : real time=" << timer.RealTime() << " CPU time=" << timer.CpuTime();
330 }
331 fProcessTime += timer.RealTime();
332 timer.Reset();
333 }
334
335
336 timer.Stop();
337 timerTs.Stop();
339 LOG(info) << GetName() << "::Exec: real time=" << timer.RealTime() << " CPU time=" << timer.CpuTime();
340 fProcessTime += timer.RealTime();
341
342 stringstream logOut;
343 logOut << setw(20) << left << GetName() << " [";
344 logOut << fixed << setw(8) << setprecision(1) << right << timerTs.RealTime() * 1000. << " ms] ";
345 logOut << "TS " << fNrTs;
346 if (CbmTrdClusterFinder::UseOnlyEventDigis()) logOut << ", events " << nEvents;
347 logOut << ", clusters " << nClusters << ", hits " << fNrHitsCall << ", time/1k-hit " << setprecision(4)
348 << timerTs.RealTime() * 1e6 / fNrHitsCall << " [ms]";
349 LOG(info) << logOut.str();
350 fNrTs++;
351}
352
353//____________________________________________________________________________________
355{
356 std::cout << std::endl;
357 LOG(info) << "=====================================";
358 LOG(info) << GetName() << ": Finish run";
359 LOG(info) << GetName() << ": Run summary ";
360 LOG(info) << GetName() << ": Processing time : " << std::fixed << std::setprecision(3) << fProcessTime;
361 LOG(info) << GetName() << ": Nr of events : " << fNrEvents;
362 LOG(info) << GetName() << ": Nr of input clusters : " << fNrClusters;
363 LOG(info) << GetName() << ": Nr of produced hits : " << fNrHits;
364 LOG(info) << GetName() << ": Nr of hits / event : " << std::fixed << std::setprecision(2)
365 << (fNrEvents > 0 ? fNrHits / (Double_t) fNrEvents : 0);
366 LOG(info) << GetName() << ": Nr of hits / clusters: " << std::fixed << std::setprecision(2)
367 << (fNrClusters > 0 ? fNrHits / (Double_t) fNrClusters : 0);
368 LOG(info) << "=====================================";
369 std::cout << std::endl;
370}
371
372//________________________________________________________________________________________
374{
375 FairRuntimeDb* rtdb = FairRunAna::Instance()->GetRuntimeDb();
376 fAsicPar = static_cast<CbmTrdParSetAsic*>(rtdb->getContainer("CbmTrdParSetAsic"));
377 fGasPar = static_cast<CbmTrdParSetGas*>(rtdb->getContainer("CbmTrdParSetGas"));
378 fDigiPar = static_cast<CbmTrdParSetDigi*>(rtdb->getContainer("CbmTrdParSetDigi"));
379 fGainPar = static_cast<CbmTrdParSetGain*>(rtdb->getContainer("CbmTrdParSetGain"));
380 fGeoPar = static_cast<CbmTrdParSetGeo*>(rtdb->getContainer("CbmTrdParSetGeo"));
381}
382
383
@ kTrd
Transition Radiation Detector.
static vector< vector< QAHit > > hits
Helper class to convert unique channel ID back and forth.
FairTask to produce TrdCluster objects from TrdHit objects.
Helper class to extract information from the GeoManager.
ClassImp(CbmTrdHitProducer)
FairTask to produce TrdHit objects from TrdCluster objects.
Class for hits in TRD detector.
InitStatus Init()
Initialisation.
const Digi * Get(Int_t index) const
Get a digi object.
static CbmDigiManager * Instance()
Static instance.
Class characterising one event by a collection of links (indices) to data objects,...
Definition CbmEvent.h:34
void AddData(ECbmDataType type, uint32_t index)
Definition CbmEvent.cxx:33
static uint32_t GetLayerId(uint32_t address)
Return layer ID from address.
static void SetUseOnlyEventDigis(Bool_t set=kTRUE)
Set the Use Only Event Digis Per default this is activated on construction, such that the user can tu...
static Bool_t UseRecoHelpers()
static Bool_t UseOnlyEventDigis()
If true only digis connected ro a CbmEvent are processed Per default this is activated on constructio...
static Bool_t DoDebugPrintouts()
Data Container for TRD clusters.
eCbmTrdAsicType GetType() const
Channel FEE SPADIC/FASP according to CbmTrdAsicType.
Definition CbmTrdDigi.h:173
double GetCharge() const
Common purpose charge getter.
Int_t GetModuleType(const TString &path)
Int_t GetModuleAddress()
Return module address calculated based on the current node in the TGeoManager.
UInt_t fNrClusters
Number of clusters as input for the hit production.
CbmTrdParSetGain * fGainPar
parameter list for keV->ADC gain conversion
UInt_t addModuleHits(CbmTrdModuleRec *mod, CbmEvent *event)
Pass all hits produced by the given module to the TrdHit branch. In case of event not nullptr only th...
UInt_t fNrHits
Number of produced hits.
CbmTrdParSetGeo * fGeoPar
parameter list for modules geometry
UInt_t processClusters()
Process all clusters found in the TrdClusters branch.
UInt_t fNrTs
Number of processed time slices.
void processCluster(const Int_t clusterIdx)
Produce a hit from the cluster found at clusterIdx in fClusters.
std::map< Int_t, CbmTrdModuleRec * > fModules
list of modules being processed
CbmTrdHitProducer()
Constructor.
virtual void SetParContainers()
UInt_t fNrHitsCall
Number of produced hits per call of Exec, i.e. Event(EbyE) or TimeSlice(TB).
CbmTrdParSetAsic * fAsicPar
parameter list for ASIC characterization
virtual void Exec(Option_t *option="")
Inherited from FairTask.
CbmTrdParSetDigi * fDigiPar
parameter list for read-out geometry
virtual ~CbmTrdHitProducer()
Destructor.
int fHitTimeOffset
hit time correction for synchronization
CbmTrdParSetGas * fGasPar
parameter list for HV status
virtual InitStatus Init()
Inherited form FairTask.
TClonesArray * fClusters
Input array of CbmTrdCluster.
Int_t addHits(CbmEvent *event=nullptr)
Loop over all modules in the given geometry and call addModuleHits(imodule)
UInt_t fNrEvents
Number of processed events (without CbmEvent corresponds to nr of exec calls)
virtual void Finish()
Inherited from FairTask.
CbmTrdModuleRec * AddModule(Int_t address, const CbmTrdParModGeo *pg)
Float_t fProcessTime
Total processing time [RealTime].
TClonesArray * fEvents
Array connected to the CbmEvent branch.
TClonesArray * fHits
Output array of CbmTrdHit.
Cluster finding and hit reconstruction algorithms for the TRD(2D) module.
Abstract class for module wise cluster finding and hit reconstruction.
virtual TClonesArray * GetHits()
Describe TRD module ASIC settings (electronic gain, delays, etc)
Definition of chamber gain conversion for one TRD module.
int GetPadPlaneType() const
Access the basic type of pad plane topology. For convenience also specific accessors are added for ea...
bool IsPadPlane2D() const
Definition of gain parameters for one TRD module.
Definition of gas parameters for one TRD module.
Definition of geometry for one TRD module.
Describe TRD module ASIC settings (electronic gain, delays, etc)
Describe TRD module working settings (HV, etc)
bool LoadAlignVolumes()
Trigger loading alignment information for all nodes registered.
virtual Int_t GetNrOfModules() const
virtual Int_t GetModuleId(Int_t i) const
virtual const CbmTrdParMod * GetModulePar(Int_t detId) const