BmnRoot 26.10.0-210-gc52d34b0
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
CbmStsRealDigitize.cxx
Go to the documentation of this file.
1//* $Id: */
2
3// -------------------------------------------------------------------------
4// ----- CbmStsRealDigitize source file -----
5// ----- Created 08/07/2008 by R. Karabowicz -----
6// -------------------------------------------------------------------------
7
8// Includes from ROOT
9#include "TClonesArray.h"
10#include "TF1.h"
11#include "TGeoManager.h"
12#include "TGeoNode.h"
13#include "TMath.h"
14#include "TObjArray.h"
15#include "TRandom3.h"
16
17// Includes from base
18#include "FairRootManager.h"
19#include "FairRunAna.h"
20#include "FairRuntimeDb.h"
21
22// Includes from STS
23#include "CbmGeoStsPar.h"
24#include "CbmStsDigi.h"
25#include "CbmStsDigiMatch.h"
26#include "CbmStsDigiPar.h"
27#include "CbmStsDigiScheme.h"
28#include "CbmStsPoint.h"
29#include "CbmStsRealDigitize.h"
30#include "CbmStsSector.h"
31#include "CbmStsSensor.h"
32#include "CbmStsStation.h"
33
34#include <iomanip>
35#include <iostream>
36#include <map>
37
38using std::cerr;
39using std::cout;
40using std::endl;
41using std::fixed;
42using std::flush;
43using std::ios_base;
44using std::left;
45using std::map;
46using std::pair;
47using std::right;
48using std::set;
49using std::setprecision;
50using std::setw;
51
52// ----- Default constructor ------------------------------------------
54 : FairTask("STS Digitizer", 1)
55{
56 fGeoPar = NULL;
57 fDigiPar = NULL;
58 fPoints = NULL;
59 fDigis = NULL;
60 fDigiMatches = NULL;
63 Reset();
64
65 fStep = 0.001;
66
67 fFThreshold = 0.001;
68 fBThreshold = 0.001;
69 fFNoiseWidth = 0.0;
70 fBNoiseWidth = 0.0;
71
72 fFNofBits = 20;
73 fBNofBits = 20;
74 fFMinStep = 0.01;
75 fBMinStep = 0.01;
76
77 fNEvents = 0.;
78}
79// -------------------------------------------------------------------------
80
81// ----- Standard constructor ------------------------------------------
83 : FairTask("STSDigitize", iVerbose)
84{
85 fGeoPar = NULL;
86 fDigiPar = NULL;
87 fPoints = NULL;
88 fDigis = NULL;
89 fDigiMatches = NULL;
92 Reset();
93
94 fStep = 0.001;
95
96 fFThreshold = 0.001;
97 fBThreshold = 0.001;
98 fFNoiseWidth = 0.0;
99 fBNoiseWidth = 0.0;
100
101 fFNofBits = 20;
102 fBNofBits = 20;
103 fFMinStep = 0.01;
104 fBMinStep = 0.01;
105
106 fNEvents = 0.;
107}
108// -------------------------------------------------------------------------
109
110// ----- Constructor with name -----------------------------------------
112 : FairTask(name, iVerbose)
113{
114 fGeoPar = NULL;
115 fDigiPar = NULL;
116 fPoints = NULL;
117 fDigis = NULL;
118 fDigiMatches = NULL;
121 Reset();
122
123 fStep = 0.001;
124
125 fFThreshold = 0.001;
126 fBThreshold = 0.001;
127 fFNoiseWidth = 0.0;
128 fBNoiseWidth = 0.0;
129
130 fFNofBits = 20;
131 fBNofBits = 20;
132 fFMinStep = 0.01;
133 fBMinStep = 0.01;
134
135 fNEvents = 0.;
136}
137// -------------------------------------------------------------------------
138
139// ----- Destructor ----------------------------------------------------
141{
142 if (fGeoPar)
143 delete fGeoPar;
144 if (fDigiPar)
145 delete fDigiPar;
146 if (fDigis) {
147 fDigis->Delete();
148 delete fDigis;
149 }
150 if (fDigiMatches) {
151 fDigiMatches->Delete();
152 delete fDigiMatches;
153 }
154 if (fDigiScheme)
155 delete fDigiScheme;
156 Reset();
157}
158// -------------------------------------------------------------------------
159
160// ----- Public method Exec --------------------------------------------
162{
163
164 // cout << "threshold = " << fFThreshold << endl;
165
166 // Reset all eventwise counters
167 fTimer.Start();
168 Reset();
169 TF1* digiGausDist = new TF1("digiGausDist", "gaus", -5., 5.);
170
171 // Verbose screen output
172 if (fVerbose > 2) {
173 cout << endl << "-I- " << fName << ": executing event" << endl;
174 cout << "----------------------------------------------" << endl;
175 }
176
177 Double_t nPoints = 0.;
178 Double_t nOutside = 0.;
179 Double_t nDigisF = 0.;
180 Double_t nDigisB = 0.;
181
182 // Loop over all StsPoints
183 if (!fPoints) {
184 cerr << "-W- " << fName << "::Exec: No input array (STSPoint) " << endl;
185 cout << "- " << fName << endl;
186 return;
187 }
188
189 map<CbmStsSensor*, set<Int_t>>::iterator mapIt;
190 for (mapIt = fPointMap.begin(); mapIt != fPointMap.end(); mapIt++)
191 ((*mapIt).second).clear();
192
193 for (Int_t iPoint = 0; iPoint < fPoints->GetEntriesFast(); iPoint++) {
194 CbmStsPoint* point = (CbmStsPoint*)fPoints->At(iPoint);
195
196 Double_t xin = point->GetXIn();
197 Double_t yin = point->GetYIn();
198 Double_t zin = point->GetZIn();
199 gGeoManager->FindNode(xin, yin, zin);
200 TGeoNode* curNode = gGeoManager->GetCurrentNode();
201
202 CbmStsSensor* sensor = fDigiScheme->GetSensorByName(curNode->GetName());
203
204 if (fPointMap.find(sensor) == fPointMap.end()) {
205 cerr << "-E- " << fName << "::Exec:: sensor " << curNode->GetName() << " not found in digi scheme!" << endl;
206 continue;
207 }
208 fPointMap[sensor].insert(iPoint);
209 }
210
211 for (Int_t iStation = fDigiScheme->GetNStations(); iStation > 0;) {
212 CbmStsStation* station = fDigiScheme->GetStation(--iStation);
213 for (Int_t iSector = station->GetNSectors(); iSector > 0;) {
214 CbmStsSector* sector = station->GetSector(--iSector);
215
216 map<Int_t, set<Int_t>>::iterator mapCh;
217
218 for (mapCh = fFChannelPointsMap.begin(); mapCh != fFChannelPointsMap.end(); mapCh++)
219 ((*mapCh).second).clear();
220 for (mapCh = fBChannelPointsMap.begin(); mapCh != fBChannelPointsMap.end(); mapCh++)
221 ((*mapCh).second).clear();
222
223 // simulating detector+cables+electronics noise
224 // should be more sophisticated...
225 // the question is: sectorwise or sensorwise???
226 Int_t nChannels = sector->GetNChannelsFront();
227 for (Int_t iChannel = nChannels; iChannel > 0;) {
228 // fStripSignalF[--iChannel] = fGen->Landau(.1,.02);
229 // fStripSignalB[ iChannel] = fGen->Landau(.1,.02);
230 // fStripSignalF[--iChannel] = 0.;
231 // fStripSignalB[ iChannel] = 0.;
232 fStripSignalF[--iChannel] = TMath::Abs(gRandom->Gaus(0., fFNoiseWidth));
233 fStripSignalB[iChannel] = TMath::Abs(gRandom->Gaus(0., fBNoiseWidth));
234 }
235
236 for (Int_t iSensor = sector->GetNSensors(); iSensor > 0;) {
237 CbmStsSensor* sensor = sector->GetSensor(--iSensor);
238
239 ProduceHitResponse(sensor);
240 }
241
242 Int_t stationNr = sector->GetStationNr();
243 Int_t sectorNr = sector->GetSectorNr();
244 Int_t sectorDetId = sector->GetDetectorId();
245
246 for (Int_t ifstr = 0; ifstr < nChannels; ifstr++) {
247 if (fStripSignalF[ifstr] < fFThreshold)
248 continue;
249 // cout << "digi#" << fNDigis << " -> making fdigi at " << stationNr << "," << sectorNr
250 // << " at channel " << ifstr << " with signal " << fStripSignalF[ifstr] << endl;
251 Int_t digiFSignal = 1 + (Int_t)((fStripSignalF[ifstr] - fFThreshold) / fFMinStep);
252 if (digiFSignal >= fFNofSteps)
253 digiFSignal = fFNofSteps - 1;
254 new ((*fDigis)[fNDigis]) CbmStsDigi(0, stationNr, sectorNr, 0, ifstr, digiFSignal, 0);
255 // fStripSignalF[ifstr], 0);
256 set<Int_t>::iterator it1;
257 set<Int_t> chPnt = fFChannelPointsMap[ifstr];
258 Int_t pnt;
260 if (chPnt.size() == 0) {
261 // cout << "digi#" << fNDigis << " -> making fdigi at " << stationNr << "," << sectorNr
262 // << " at channel " << ifstr << " with signal " << fStripSignalF[ifstr] << endl;
263 new ((*fDigiMatches)[fNDigis]) CbmStsDigiMatch(-666);
264 } else {
265 for (it1 = chPnt.begin(); it1 != chPnt.end(); it1++) {
266 pnt = (*it1);
267 if (it1 == chPnt.begin())
268 match = new ((*fDigiMatches)[fNDigis]) CbmStsDigiMatch(pnt);
269 else {
270 match->AddPoint(pnt);
271 fNMulti++;
272 }
273 }
274 }
275 fNDigis++;
276 }
277
278 for (Int_t ibstr = 0; ibstr < nChannels; ibstr++) {
279 if (fStripSignalB[ibstr] < fBThreshold)
280 continue;
281 Int_t digiBSignal = 1 + (Int_t)((fStripSignalB[ibstr] - fBThreshold) / fBMinStep);
282 if (digiBSignal >= fBNofSteps)
283 digiBSignal = fBNofSteps - 1;
284 new ((*fDigis)[fNDigis]) CbmStsDigi(0, stationNr, sectorNr, 1, ibstr, digiBSignal, 0);
285 // fStripSignalB[ibstr], 0);
286 set<Int_t>::iterator it1;
287 set<Int_t> chPnt = fBChannelPointsMap[ibstr];
288 Int_t pnt;
290 if (chPnt.size() == 0) {
291 // cout << "digi#" << fNDigis << " -> making fdigi at " << stationNr << "," << sectorNr
292 // << " at channel " << ifstr << " with signal " << fStripSignalF[ifstr] << endl;
293 new ((*fDigiMatches)[fNDigis]) CbmStsDigiMatch(-666);
294 } else {
295 for (it1 = chPnt.begin(); it1 != chPnt.end(); it1++) {
296 pnt = (*it1);
297 if (it1 == chPnt.begin())
298 match = new ((*fDigiMatches)[fNDigis]) CbmStsDigiMatch(pnt);
299 else {
300 match->AddPoint(pnt);
301 fNMulti++;
302 }
303 }
304 }
305 fNDigis++;
306 }
307 }
308 }
309
310 fTimer.Stop();
311 cout << "+ " << flush;
312 cout << setw(15) << left << fName << ": " << setprecision(4) << setw(8) << fixed << right << fTimer.RealTime()
313 << " s, digis " << nDigisF << " / " << nDigisB << endl;
314
315 fNEvents += 1.;
316 fNPoints += Double_t(nPoints);
317 fNOutside += Double_t(nOutside);
318 fNDigisFront += Double_t(nDigisF);
319 fNDigisBack += Double_t(nDigisB);
320 fTime += fTimer.RealTime();
321}
322// -------------------------------------------------------------------------
323
324// ----- Private method ProduceHitResponse --------------------------------
326{
327 set<Int_t> pSet;
328 if (fPointMap.find(sensor) == fPointMap.end()) {
329 cerr << "-E- " << fName << "::Exec:: sensor"
330 << " not found in digi scheme!" << endl;
331 return;
332 }
333 pSet = fPointMap[sensor];
334
335 Int_t iPoint = -1;
336 CbmStsPoint* point = NULL;
337
338 set<Int_t>::iterator it1;
339
340 for (it1 = pSet.begin(); it1 != pSet.end(); it1++) {
341 iPoint = (*it1);
342 point = (CbmStsPoint*)fPoints->At(iPoint);
343
344 Double_t xin = point->GetXIn();
345 Double_t yin = point->GetYIn();
346 Double_t zin = point->GetZIn();
347
348 Double_t xvec = point->GetXOut() - xin;
349 Double_t yvec = point->GetYOut() - yin;
350 Double_t zvec = point->GetZOut() - zin;
351
352 Int_t nofSteps = (Int_t)(TMath::Sqrt(xvec * xvec + yvec * yvec + zvec * zvec) / fStep + 1);
353
354 Double_t stepEL = fEnergyLossToSignal * point->GetEnergyLoss() / (nofSteps + 1);
355
356 xvec = xvec / ((Double_t)nofSteps);
357 yvec = yvec / ((Double_t)nofSteps);
358 zvec = zvec / ((Double_t)nofSteps);
359
360 for (Int_t istep = 0; istep <= nofSteps; istep++) {
361 // Float_t iFChan = sensor->GetChannelPlus(xin, yin, 0);
362 Int_t iIChan = sensor->GetFrontChannel(xin, yin, zin);
363 //(Int_t)iFChan;
364
365 if (iIChan != -1) {
366 fStripSignalF[iIChan] += stepEL;
367 fFChannelPointsMap[iIChan].insert(iPoint);
368 }
369
370 // iFChan = sensor->GetChannelPlus(xin, yin, 1);
371 // iIChan = (Int_t)iFChan;
372 iIChan = sensor->GetBackChannel(xin, yin, zin);
373
374 if (iIChan != -1) {
375 fStripSignalB[iIChan] += stepEL;
376 fBChannelPointsMap[iIChan].insert(iPoint);
377 }
378
379 xin += xvec;
380 yin += yvec;
381 zin += zvec;
382 }
383 }
384}
385// -------------------------------------------------------------------------
386
387// ----- Private method FindFiredStrips --------------------------------
389 Int_t& nofStr,
390 Int_t*& strips,
391 Double_t*& signals,
392 Int_t side)
393{
394
395 nofStr = 0;
396
397 Double_t xin = pnt->GetXIn();
398 Double_t yin = pnt->GetYIn();
399 Double_t zin = pnt->GetZIn();
400
401 gGeoManager->FindNode(xin, yin, zin);
402 TGeoNode* curNode = gGeoManager->GetCurrentNode();
403
404 CbmStsSensor* sensor = fDigiScheme->GetSensorByName(curNode->GetName());
405
406 Double_t xvec = pnt->GetXOut() - xin;
407 Double_t yvec = pnt->GetYOut() - yin;
408 Double_t zvec = pnt->GetZOut() - zin;
409
410 Int_t nofSteps = (Int_t)(TMath::Sqrt(xvec * xvec + yvec * yvec + zvec * zvec) / fStep + 1);
411
412 Double_t stepEL = fEnergyLossToSignal * pnt->GetEnergyLoss() / (nofSteps + 1);
413
414 xvec = xvec / ((Double_t)nofSteps);
415 yvec = yvec / ((Double_t)nofSteps);
416 zvec = zvec / ((Double_t)nofSteps);
417
418 for (Int_t istep = 0; istep <= nofSteps; istep++) {
419 Float_t iFChan = sensor->GetChannelPlus(xin, yin, side);
420 Int_t iIChan = (Int_t)iFChan;
421
422 xin += xvec;
423 yin += yvec;
424 zin += zvec;
425
426 if (iIChan == -1)
427 continue;
428
429 for (Int_t ifstr = 0; ifstr < nofStr; ifstr++) {
430 if (strips[ifstr] == iIChan) {
431 signals[ifstr] += stepEL;
432 iIChan = -1;
433 break;
434 }
435 }
436 if (iIChan == -1)
437 continue;
438
439 strips[nofStr] = iIChan;
440 signals[nofStr] = stepEL;
441
442 nofStr++;
443 }
444}
445// -------------------------------------------------------------------------
446
447// ----- Private method SetParContainers -------------------------------
449{
450
451 // Get run and runtime database
452 FairRunAna* run = FairRunAna::Instance();
453 if (!run)
454 Fatal("SetParContainers", "No analysis run");
455
456 FairRuntimeDb* db = run->GetRuntimeDb();
457 if (!db)
458 Fatal("SetParContainers", "No runtime database");
459
460 // Get STS geometry parameter container
461 fGeoPar = (CbmGeoStsPar*)db->getContainer("CbmGeoStsPar");
462
463 // Get STS digitisation parameter container
464 fDigiPar = (CbmStsDigiPar*)db->getContainer("CbmStsDigiPar");
465}
466// -------------------------------------------------------------------------
467
468// ----- Private method Init -------------------------------------------
470{
471
472 // Get input array
473 FairRootManager* ioman = FairRootManager::Instance();
474 if (!ioman)
475 Fatal("Init", "No FairRootManager");
476 fPoints = (TClonesArray*)ioman->GetObject("StsPoint");
477
478 // Register output array StsDigi
479 fDigis = new TClonesArray("CbmStsDigi", 1000);
480 ioman->Register("StsDigi", "Digital response in STS", fDigis, kTRUE);
481
482 // Register output array StsDigiMatches
483 fDigiMatches = new TClonesArray("CbmStsDigiMatch", 1000);
484 ioman->Register("StsDigiMatch", "Digi Match in STS", fDigiMatches, kTRUE);
485
486 // fGen = new TRandom3();
487 // time_t curtime;
488 // time(&curtime);
489 // fGen->SetSeed(curtime);
490
491 fStripSignalF = new Double_t[2000];
492 fStripSignalB = new Double_t[2000];
493
494 fEnergyLossToSignal = 200000.;
495
498
499 // Build digitisation scheme
500 if (fDigiScheme->Init(fGeoPar, fDigiPar)) {
501 MakeSets();
502
503 if (fVerbose == 1 || fVerbose == 2)
504 fDigiScheme->Print(kFALSE);
505 else if (fVerbose > 2)
506 fDigiScheme->Print(kTRUE);
507 cout << "-I- " << fName << "::Init: "
508 << "STS digitisation scheme succesfully initialised" << endl;
509 cout << " Stations: " << fDigiScheme->GetNStations() << ", Sectors: " << fDigiScheme->GetNSectors()
510 << ", Channels: " << fDigiScheme->GetNChannels() << endl;
511 return kSUCCESS;
512 }
513
514 return kERROR;
515}
516// -------------------------------------------------------------------------
517
518// ----- Private method ReInit -----------------------------------------
520{
521
522 // Clear digitisation scheme
523 fDigiScheme->Clear();
524
525 // Build new digitisation scheme
526 if (fDigiScheme->Init(fGeoPar, fDigiPar)) {
527 MakeSets();
528 return kSUCCESS;
529 }
530
531 return kERROR;
532}
533// -------------------------------------------------------------------------
534
535// ----- Private method MakeSets ---------------------------------------
537{
538
539 fPointMap.clear();
540 Int_t nStations = fDigiScheme->GetNStations();
541 for (Int_t iStation = 0; iStation < nStations; iStation++) {
542 CbmStsStation* station = fDigiScheme->GetStation(iStation);
543 Int_t nSectors = station->GetNSectors();
544 for (Int_t iSector = 0; iSector < nSectors; iSector++) {
545 CbmStsSector* sector = station->GetSector(iSector);
546 Int_t nSensors = sector->GetNSensors();
547 for (Int_t iSensor = 0; iSensor < nSensors; iSensor++) {
548 CbmStsSensor* sensor = sector->GetSensor(iSensor);
549 set<Int_t> a;
550 fPointMap[sensor] = a;
551 }
552 }
553 }
554 fFChannelPointsMap.clear();
555 fBChannelPointsMap.clear();
556 for (Int_t ichan = 2000; ichan > 0;) {
557 set<Int_t> a;
558 fFChannelPointsMap[--ichan] = a;
559 set<Int_t> b;
560 fBChannelPointsMap[ichan] = b;
561 }
562}
563// -------------------------------------------------------------------------
564
565// ----- Private method Reset ------------------------------------------
567{
568 // fNPoints = fNOutside = fNDigisFront = fNDigisBack = fTime = 0.;
569 fNDigis = fNMulti = 0;
570 fFChannelPointsMap.clear();
571 fBChannelPointsMap.clear();
572 // if ( fDigis ) fDigis->Clear();
573 // if ( fDigiMatches ) fDigiMatches->Clear();
574 if (fDigis)
575 fDigis->Delete();
576 if (fDigiMatches)
577 fDigiMatches->Delete();
578}
579// -------------------------------------------------------------------------
580
581// ----- Virtual method Finish -----------------------------------------
583{
584 cout << endl;
585 cout << "============================================================" << endl;
586 cout << "===== " << fName << ": Run summary " << endl;
587 cout << "===== " << endl;
588 cout << "===== Events processed : " << setw(8) << fNEvents << endl;
589 cout.setf(ios_base::fixed, ios_base::floatfield);
590 cout << "===== Real time per event : " << setw(8) << setprecision(4) << fTime / fNEvents << " s" << endl;
591 cout << "===== StsPoints per event : " << setw(8) << setprecision(2) << fNPoints / fNEvents << endl;
592 cout << "===== Outside hits per event : " << setw(8) << setprecision(2) << fNOutside / fNEvents << " = "
593 << setw(6) << setprecision(2) << fNOutside / fNPoints * 100. << " %" << endl;
594 cout << "===== Front digis per point : " << setw(8) << setprecision(2) << fNDigisFront / (fNPoints - fNOutside)
595 << endl;
596 cout << "===== Back digis per point : " << setw(8) << setprecision(2) << fNDigisBack / (fNPoints - fNOutside)
597 << endl;
598 cout << "============================================================" << endl;
599}
600// -------------------------------------------------------------------------
int Int_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
void Fatal(const char *location, const char *msgfmt,...)
R__EXTERN TGeoManager * gGeoManager
R__EXTERN TRandom * gRandom
CbmStsDigiMatch.h.
CbmStsDigi.h.
Definition CbmStsDigi.h:32
Double_t GetXIn() const
Accessors.
Definition CbmStsPoint.h:64
Double_t GetZOut() const
Definition CbmStsPoint.h:69
Double_t GetYOut() const
Definition CbmStsPoint.h:68
Double_t GetZIn() const
Definition CbmStsPoint.h:66
Double_t GetYIn() const
Definition CbmStsPoint.h:65
Double_t GetXOut() const
Definition CbmStsPoint.h:67
CbmStsDigiScheme * fDigiScheme
Digitisation parameter container.
virtual ~CbmStsRealDigitize()
Destructor.
map< CbmStsSensor *, set< Int_t > > fPointMap
void Reset()
Reset eventwise counters.
virtual InitStatus ReInit()
Reinitialisation.
virtual InitStatus Init()
Intialisation.
CbmStsRealDigitize()
Default constructor.
map< Int_t, set< Int_t > > fBChannelPointsMap
TClonesArray * fDigiMatches
Output array of CbmStsDigi.
CbmStsDigiPar * fDigiPar
Geometry parameter container.
void ProduceHitResponse(CbmStsSensor *sensor)
TClonesArray * fPoints
Digitisation scheme.
virtual void Exec(Option_t *opt)
Execution.
virtual void SetParContainers()
Get parameter containers.
void MakeSets()
Make sensorwise set for points.
virtual void Finish()
Virtual method Finish.
Int_t fNDigis
Output array of CbmStsDigiMatches.
void FindFiredStrips(CbmStsPoint *pnt, Int_t &nofStr, Int_t *&strips, Double_t *&signals, Int_t side)
TClonesArray * fDigis
Input array of CbmStsPoint.
map< Int_t, set< Int_t > > fFChannelPointsMap
Int_t GetSectorNr() const
Int_t GetStationNr() const
Int_t GetDetectorId() const
Int_t GetNChannelsFront() const
CbmStsSensor * GetSensor(Int_t iSensor)
Int_t GetNSensors() const
Float_t GetChannelPlus(Double_t x, Double_t y, Int_t iSide)
Int_t GetFrontChannel(Double_t x, Double_t y, Double_t z, Double_t &dPitch)
Int_t GetBackChannel(Double_t x, Double_t y, Double_t z, Double_t &dPitch)
Int_t GetNSectors() const
CbmStsSector * GetSector(Int_t iSector)
const char * GetName() const override
Double_t Power(Double_t x, Double_t y)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)