BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
CbmStsClusterFinder.cxx
Go to the documentation of this file.
1//* $Id: */
2
3// -------------------------------------------------------------------------
4// ----- CbmStsClusterFinder source fil -----
5// ----- Created 26/06/2008 by R. Karabowicz -----
6// -------------------------------------------------------------------------
7// -------------------------------------------------------------------------
9
10#include "CbmGeoStsPar.h"
11#include "CbmStsCluster.h"
12#include "CbmStsDigi.h"
13#include "CbmStsDigiPar.h"
14#include "CbmStsDigiScheme.h"
15#include "CbmStsHit.h"
16#include "CbmStsSector.h"
17#include "CbmStsStation.h"
18#include "FairRootManager.h"
19#include "FairRunAna.h"
20#include "FairRuntimeDb.h"
21#include "TClonesArray.h"
22#include "TH1S.h"
23#include "TMath.h"
24
25#include <iomanip>
26
27using std::cerr;
28using std::cout;
29using std::endl;
30using std::fixed;
31using std::flush;
32using std::left;
33using std::map;
34using std::right;
35using std::set;
36using std::setprecision;
37using std::setw;
38
39// ----- Default constructor ------------------------------------------
41 : FairTask("STS Cluster Finder", 1)
42 , fGeoPar(NULL)
43 , fDigiPar(NULL)
44 , fDigiScheme(CbmStsDigiScheme::Instance())
45 , fDigis(NULL)
46 , fClustersCand(NULL)
47 , fClusters(NULL)
48 , fNofDigis(0)
49 , fDigiMapF()
50 , fDigiMapB()
51 , fTimer()
53 , fNofClusters(0)
59{}
60
61// ----- Standard constructor ------------------------------------------
63 : FairTask("STSClusterFinder", iVerbose)
64 , fGeoPar(NULL)
65 , fDigiPar(NULL)
66 , fDigiScheme(CbmStsDigiScheme::Instance())
67 , fDigis(NULL)
68 , fClustersCand(NULL)
69 , fClusters(NULL)
70 , fNofDigis(0)
71 , fDigiMapF()
72 , fDigiMapB()
73 , fTimer()
75 , fNofClusters(0)
81{}
82
83// ----- Constructor with name -----------------------------------------
85 : FairTask(name, iVerbose)
86 , fGeoPar(NULL)
87 , fDigiPar(NULL)
88 , fDigiScheme(CbmStsDigiScheme::Instance())
89 , fDigis(NULL)
90 , fClustersCand(NULL)
91 , fClusters(NULL)
92 , fNofDigis(0)
93 , fDigiMapF()
94 , fDigiMapB()
95 , fTimer()
97 , fNofClusters(0)
100 , fNofClustersWM(0)
101 , fLongestCluster(0)
103{}
104
105// ----- Destructor ----------------------------------------------------
107{
108 if (fClustersCand) {
109 fClustersCand->Delete();
110 delete fClustersCand;
111 }
112 if (fClusters) {
113 fClusters->Delete();
114 delete fClusters;
115 }
116}
117// -------------------------------------------------------------------------
118
119// ----- Public method Exec --------------------------------------------
121{
122
123 fTimer.Start();
124 Bool_t warn = kFALSE;
125
126 if (fVerbose) {
127 cout << endl << "-I- " << fName << ": executing event with " << fDigis->GetEntriesFast() << " digis." << endl;
128 cout << "----------------------------------------------" << endl;
129 }
130
131 // Check for digi scheme
132 if (!fDigiScheme) {
133 cerr << "-E- " << fName << "::Exec: No digi scheme!" << endl;
134 return;
135 }
136
137 // Clear output array
138 // cout << "before clear: " << fClusters->GetEntriesFast() << endl;
140 fNofClusters = 0;
141 // fClustersCand->Clear();
142 // fClusters->Clear();
143 fClusters->Delete();
144 fClustersCand->Delete();
145 // cout << " after clear: " << fClusters->GetEntriesFast() << endl;
146
147 // Sort STS digis with respect to sectors
148 SortDigis();
149
150 // Find hits in sectors
151 Int_t nDigisF = 0;
152 Int_t nDigisB = 0;
153 Int_t nStations = fDigiScheme->GetNStations();
154 CbmStsStation* station = NULL;
155 for (Int_t iStation = 0; iStation < nStations; iStation++) {
156 station = fDigiScheme->GetStation(iStation);
157 Int_t nDigisFInStation = 0;
158 Int_t nDigisBInStation = 0;
159 Int_t nSectors = station->GetNSectors();
160
161 for (Int_t iSector = 0; iSector < nSectors; iSector++) {
162 CbmStsSector* sector = station->GetSector(iSector);
163 // cout << "=============================================================================" << endl;
164 // cout << "station " << iStation+1 << " sector " << iSector+1 << " " << endl;
165 set<Int_t> fSet, bSet;
166 if (fDigiMapF.find(sector) == fDigiMapF.end()) {
167 cout << "-E- " << fName << "::Exec: sector " << sector->GetSectorNr() << " of station "
168 << station->GetStationNr() << "not found in front map!" << endl;
169 warn = kTRUE;
170 continue;
171 }
172 fSet = fDigiMapF[sector];
173 FindClusters(iStation + 1, iSector + 1, 0, fSet);
174 if (sector->GetType() == 2 || sector->GetType() == 3) {
175 if (fDigiMapB.find(sector) == fDigiMapB.end()) {
176 cout << "-E- " << fName << "::Exec: sector " << sector->GetSectorNr() << " of station "
177 << station->GetStationNr() << "not found in back map!" << endl;
178 warn = kTRUE;
179 continue;
180 }
181 }
182 bSet = fDigiMapB[sector];
183 FindClusters(iStation + 1, iSector + 1, 1, bSet);
184 Int_t nDigisFInSector = fSet.size();
185 Int_t nDigisBInSector = bSet.size();
186 nDigisFInStation += nDigisFInSector;
187 nDigisBInStation += nDigisBInSector;
188 } // Sector loop
189
190 nDigisF += nDigisFInStation;
191 nDigisB += nDigisBInStation;
192
193 } // Station loop
194
195 // analyze clusters...
197
198 fTimer.Stop();
199 if (fVerbose) {
200 cout << endl;
201 cout << "-I- " << fName << ":Event summary" << endl;
202 cout << " Active channels front side: " << nDigisF << endl;
203 cout << " Active channels back side : " << nDigisB << endl;
204 cout << " Real time : " << fTimer.RealTime() << endl;
205 } else {
206 if (warn)
207 cout << "- ";
208 else
209 cout << "+ ";
210 cout << setw(15) << left << fName << ": " << setprecision(4) << setw(8) << fixed << right << fTimer.RealTime()
211 << " s, " << fNofClustersCand << "(" << fNofClustersGood << "+" << fNofClustersWP
212 << ") clusters, longest till now " << fLongestCluster << endl;
213 // cout << fDigis->GetEntriesFast() << " vs " << fClusters->GetEntriesFast() << endl;
214 }
215
216 // AZ - add links to clusters (digits)
217 Int_t nClust = fClusters->GetEntriesFast();
218 for (Int_t i = 0; i < nClust; ++i) {
219 CbmStsCluster* clus = (CbmStsCluster*)fClusters->UncheckedAt(i);
220
221 Int_t nDigis = clus->GetNDigis();
222 for (Int_t j = 0; j < nDigis; ++j) {
223 Int_t idigi = clus->GetDigi(j);
224 clus->AddLink(FairLink(kStsDigi, idigi));
225 }
226 }
227}
228// -------------------------------------------------------------------------
229
230// ----- Private method SetParContainers -------------------------------
232{
233
234 // Get run and runtime database
235 FairRunAna* run = FairRunAna::Instance();
236 if (!run)
237 Fatal("SetParContainers", "No analysis run");
238
239 FairRuntimeDb* db = run->GetRuntimeDb();
240 if (!db)
241 Fatal("SetParContainers", "No runtime database");
242
243 // Get STS geometry parameter container
244 fGeoPar = (CbmGeoStsPar*)db->getContainer("CbmGeoStsPar");
245
246 // Get STS digitisation parameter container
247 fDigiPar = (CbmStsDigiPar*)db->getContainer("CbmStsDigiPar");
248}
249// -------------------------------------------------------------------------
250
251// ----- Private method Init -------------------------------------------
253{
254
255 // Get input array
256 FairRootManager* ioman = FairRootManager::Instance();
257 if (!ioman)
258 Fatal("Init", "No FairRootManager");
259 fDigis = (TClonesArray*)ioman->GetObject("StsDigi");
260
261 fClustersCand = new TClonesArray("CbmStsCluster", 30000);
262 ioman->Register("StsClusterCand", "Cluster in STS", fClustersCand, kTRUE);
263
264 fClusters = new TClonesArray("CbmStsCluster", 30000);
265 ioman->Register("StsCluster", "Cluster in STS", fClusters, kTRUE);
266
267 // Build digitisation scheme
268 Bool_t success = fDigiScheme->Init(fGeoPar, fDigiPar);
269 if (!success)
270 return kERROR;
271
272 // Create sectorwise digi sets
273 MakeSets();
274
275 // Control output
276 if (fVerbose == 1 || fVerbose == 2)
277 fDigiScheme->Print(kFALSE);
278 else if (fVerbose > 2)
279 fDigiScheme->Print(kTRUE);
280 cout << "-I- " << fName << "::Init: "
281 << "STS digitisation scheme succesfully initialised" << endl;
282 cout << " Stations: " << fDigiScheme->GetNStations() << ", Sectors: " << fDigiScheme->GetNSectors()
283 << ", Channels: " << fDigiScheme->GetNChannels() << endl;
284
286 fNofClusters = 0;
288 fNofClustersWP = 0;
289 fNofClustersWM = 0;
290
291 fLongestCluster = 0;
293
294 return kSUCCESS;
295}
296// -------------------------------------------------------------------------
297
298// ----- Private method ReInit -----------------------------------------
300{
301
302 // Clear digitisation scheme
303 fDigiScheme->Clear();
304
305 // Build new digitisation scheme
306 Bool_t success = fDigiScheme->Init(fGeoPar, fDigiPar);
307 if (!success)
308 return kERROR;
309
310 // Create sectorwise digi sets
311 MakeSets();
312
313 // Control output
314 if (fVerbose == 1 || fVerbose == 2)
315 fDigiScheme->Print(kFALSE);
316 else if (fVerbose > 2)
317 fDigiScheme->Print(kTRUE);
318 cout << "-I- " << fName << "::Init: "
319 << "STS digitisation scheme succesfully reinitialised" << endl;
320 cout << " Stations: " << fDigiScheme->GetNStations() << ", Sectors: " << fDigiScheme->GetNSectors()
321 << ", Channels: " << fDigiScheme->GetNChannels() << endl;
322
324 fNofClusters = 0;
326 fNofClustersWP = 0;
327 fNofClustersWM = 0;
328
329 fLongestCluster = 0;
331
332 return kSUCCESS;
333}
334// -------------------------------------------------------------------------
335
336// ----- Private method MakeSets ---------------------------------------
338{
339
340 fDigiMapF.clear();
341 fDigiMapB.clear();
342 Int_t nStations = fDigiScheme->GetNStations();
343 for (Int_t iStation = 0; iStation < nStations; iStation++) {
344 CbmStsStation* station = fDigiScheme->GetStation(iStation);
345 Int_t nSectors = station->GetNSectors();
346 for (Int_t iSector = 0; iSector < nSectors; iSector++) {
347 CbmStsSector* sector = station->GetSector(iSector);
348 set<Int_t> a;
349 fDigiMapF[sector] = a;
350 if (sector->GetType() == 2 || sector->GetType() == 3) {
351 set<Int_t> b;
352 fDigiMapB[sector] = b;
353 }
354 }
355 }
356}
357// -------------------------------------------------------------------------
358
359// ----- Private method SortDigis --------------------------------------
361{
362
363 // Check input array
364 if (!fDigis) {
365 cout << "-E- " << fName << "::SortDigis: No input array!" << endl;
366 return;
367 }
368
369 CbmStsDigi* digi = NULL;
370 const Int_t nDigis = fDigis->GetEntriesFast();
371
372 // Clear sector digi sets
373 map<CbmStsSector*, set<Int_t>>::iterator mapIt;
374 for (mapIt = fDigiMapF.begin(); mapIt != fDigiMapF.end(); mapIt++)
375 ((*mapIt).second).clear();
376 for (mapIt = fDigiMapB.begin(); mapIt != fDigiMapB.end(); mapIt++)
377 ((*mapIt).second).clear();
378
379 // Fill digis into sets
380 CbmStsSector* sector = NULL;
381 Int_t stationNr = -1;
382 Int_t sectorNr = -1;
383 Int_t iSide = -1;
384 // Int_t channelNr = -1;
385
386 for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
387 digi = (CbmStsDigi*)fDigis->At(iDigi);
388
389 stationNr = digi->GetStationNr();
390 sectorNr = digi->GetSectorNr();
391 iSide = digi->GetSide();
392 sector = fDigiScheme->GetSector(stationNr, sectorNr);
393
394 if (iSide == 0) {
395 if (fDigiMapF.find(sector) == fDigiMapF.end()) {
396 cerr << "-E- " << fName << "::SortDigits:: sector " << sectorNr << " of station " << stationNr
397 << " not found in digi scheme (F)!" << endl;
398 continue;
399 }
400 fDigiMapF[sector].insert(iDigi);
401 } else if (iSide == 1) {
402 if (fDigiMapB.find(sector) == fDigiMapB.end()) {
403 cerr << "-E- " << fName << "::SortDigits:: sector " << sectorNr << " of station " << stationNr
404 << " not found in digi scheme (B)!" << endl;
405 continue;
406 }
407 fDigiMapB[sector].insert(iDigi);
408 }
409 }
410}
411// -------------------------------------------------------------------------
412
413// ----- Private method RealisticResponse ------------------------------
414Int_t CbmStsClusterFinder::FindClusters(Int_t stationNr, Int_t sectorNr, Int_t iSide, set<Int_t>& digiSet)
415{
416
417 set<Int_t>::iterator it1;
418
419 Int_t iDigi = -1;
420 CbmStsDigi* digi = NULL;
421 CbmStsCluster* clusterCand = NULL;
422 // CbmStsCluster* cluster = NULL;
423
424 Int_t digiPos = -1;
425 Double_t digiSig = -1.;
426 Int_t lastDigiNr = -1;
427 Int_t lastDigiPos = -1;
428 Double_t lastDigiSig = 100000.;
429 Int_t clusterMaxNr = -1;
430 // Int_t clusterMaxPos = -1;
431 Double_t clusterMaxSig = -1.;
432 Bool_t clusterHasMinimum = kFALSE;
433 Bool_t clusterHasPlateau = kFALSE;
434 Int_t clusterBeginPos = 0;
435 Int_t clusterWidth = 0;
436 // cout << "====================================================================" << digiSet.size() << endl;
437 // cout << " cluster " << flush;
438 // if ( fNofClusters != fNofClustersGood+fNofClustersWP ) cout << fNofClusters-(fNofClustersGood+fNofClustersWP)
439 // << " -> " << fNofClusters <<"!="<< fNofClustersGood<<"+"<<fNofClustersWP<<endl;
440 for (it1 = digiSet.begin(); it1 != digiSet.end(); it1++) {
441 iDigi = (*it1);
442 digi = (CbmStsDigi*)fDigis->At(iDigi);
443
444 digiPos = digi->GetChannelNr();
445 digiSig = digi->GetAdc();
446
447 if (lastDigiPos == -1) {
448 clusterCand = new ((*fClustersCand)[fNofClustersCand++]) CbmStsCluster(digiSig, stationNr, sectorNr, iSide);
449 // cout << "first cluster ADC " << digiSig << endl;
450 clusterBeginPos = digiPos;
451 }
452
453 if (digiPos == lastDigiPos + 1) {
454
455 if (digiSig == lastDigiSig) {
456 clusterCand->SetMeanError(digiSig);
457 clusterHasPlateau = kTRUE;
458 }
459
460 // if the signal is larger that last one and the previous one is smaller than maximum
461 if (digiSig > lastDigiSig && lastDigiSig < clusterMaxSig && digiSig != clusterMaxSig) {
462 clusterCand->SetMean(clusterMaxNr);
463 // cluster->SetMeanError(clusterMaxSig);
464 clusterCand =
465 new ((*fClustersCand)[fNofClustersCand++]) CbmStsCluster(digiSig, stationNr, sectorNr, iSide);
466 clusterCand->AddDigi(lastDigiNr);
467 // cout << " +end cluster " << lastDigiPos << endl;
468
469 // cout << "+new cluster " << digiPos << endl;
470 clusterWidth = lastDigiPos - clusterBeginPos + 1;
471 if (clusterWidth > fLongestCluster)
472 fLongestCluster = clusterWidth;
473 if (clusterHasPlateau) {
475 }
476 if (!clusterHasMinimum && !clusterHasPlateau) {
478 if (clusterWidth > fLongestGoodCluster)
479 fLongestGoodCluster = clusterWidth;
480 }
481
482 clusterHasPlateau = kFALSE;
483 // clusterMaxPos = -1;
484 clusterMaxSig = -1.;
485 clusterBeginPos = digiPos;
486 }
487 } else if (lastDigiPos >= 0) {
488 clusterCand->SetMean(clusterMaxNr);
489 // cluster->SetMeanError(clusterMaxSig);
490 clusterCand = new ((*fClustersCand)[fNofClustersCand++]) CbmStsCluster(digiSig, stationNr, sectorNr, iSide);
491 // cout << " end cluster " << lastDigiPos << endl;
492 // cout << "new cluster " << digiPos << endl;
493 clusterWidth = lastDigiPos - clusterBeginPos + 1;
494 if (clusterWidth > fLongestCluster)
495 fLongestCluster = clusterWidth;
496 if (clusterHasPlateau) {
498 }
499 if (!clusterHasMinimum && !clusterHasPlateau) {
501 if (clusterWidth > fLongestGoodCluster)
502 fLongestGoodCluster = clusterWidth;
503 }
504
505 clusterHasPlateau = kFALSE;
506 // clusterMaxPos = -1;
507 clusterMaxSig = -1.;
508 clusterBeginPos = digiPos;
509 }
510 if (digiSig > clusterMaxSig) {
511 clusterMaxNr = iDigi;
512 // clusterMaxPos = digiPos;
513 clusterMaxSig = digiSig;
514 }
515
516 clusterWidth = lastDigiPos - clusterBeginPos + 1;
517 if (clusterWidth < 90) {
518 clusterCand->AddDigi(iDigi);
519 }
520 // clusterCand->AddIndex(iDigi,digiSig);}
521 else
522 {
523 // return 1;
524 clusterCand->SetMean(clusterMaxNr);
525 // cluster->SetMeanError(clusterMaxSig);
526
527 clusterCand = new ((*fClustersCand)[fNofClustersCand++]) CbmStsCluster(digiSig, stationNr, sectorNr, iSide);
528 clusterCand->AddDigi(iDigi);
529 clusterWidth = lastDigiPos - clusterBeginPos + 1;
530 if (clusterWidth > fLongestCluster)
531 fLongestCluster = clusterWidth;
532 if (clusterHasPlateau) {
534 }
535 if (!clusterHasMinimum && !clusterHasPlateau) {
537 if (clusterWidth > fLongestGoodCluster)
538 fLongestGoodCluster = clusterWidth;
539 }
540
541 clusterHasPlateau = kFALSE;
542 // clusterMaxPos = -1;
543 clusterMaxSig = -1.;
544 clusterBeginPos = digiPos;
545 }
546
547 lastDigiNr = iDigi;
548 lastDigiPos = digiPos;
549 lastDigiSig = digiSig;
550 }
551 if (digiSig > 0.) {
552 clusterCand->SetMean(clusterMaxNr);
553
554 // cout << " last cluster " << lastDigiPos << endl;
555 clusterWidth = lastDigiPos - clusterBeginPos + 1;
556 if (clusterWidth > fLongestCluster)
557 fLongestCluster = clusterWidth;
558 if (clusterHasPlateau) {
560 }
561 if (lastDigiPos && !clusterHasPlateau) {
563 if (clusterWidth > fLongestGoodCluster)
564 fLongestGoodCluster = clusterWidth;
565 }
566 }
567 // delete clusterCand;
568
569 return 1;
570
571 map<Int_t, Int_t> channelSorted;
572 for (it1 = digiSet.begin(); it1 != digiSet.end(); it1++) {
573 iDigi = (*it1);
574 digi = (CbmStsDigi*)fDigis->At(iDigi);
575 cout << digi->GetChannelNr() << " " << flush;
576 channelSorted[digi->GetChannelNr()] = iDigi + 1;
577 }
578 cout << endl;
579 // print channels/signals
580 size_t iFS = 0;
581 for (Int_t iter = 0; iter < 1100; iter++) {
582 iDigi = channelSorted[iter];
583 if (iDigi == 0)
584 continue;
585 iFS++;
586 digi = (CbmStsDigi*)fDigis->At(iDigi - 1);
587 if (iFS >= channelSorted.size())
588 break;
589 }
590 // cout << endl;
591
592 // cout << "size = " << channelSorted.size() << endl;
593 /* Int_t iFS = 0;
594 Float_t lastSignal = 0.;
595 for (Int_t iter=0; iter<1100; iter++) {
596 iDigi = channelSorted[iter];
597 if ( iDigi == 0 ) {lastSignal=0.;continue;}
598 iFS++;
599 digi = (CbmStsDigi*) fDigis->At(iDigi-1);
600 Float_t signal = digi->GetADC();
601 if ( signal <= lastSignal ) { lastSignal = signal; continue; }
602
603 if ( iFS >= channelSorted.size() ) break;
604
605
606 }*/
607 // cout << endl << "=============================================" << endl;
608}
609// -------------------------------------------------------------------------
610
611// ----- Method AnalyzeClusters ----------------------------------------
613{
614 for (Int_t iclus = 0; iclus < fNofClustersCand; iclus++) {
615 AnalyzeCluster(iclus);
616 }
617}
618// -------------------------------------------------------------------------
619
620// ----- Method AnalyzeClusters ----------------------------------------
622{
623
624 CbmStsCluster* clusterCand = (CbmStsCluster*)fClustersCand->At(iCluster);
625 CbmStsCluster* cluster = (CbmStsCluster*)fClusters->At(iCluster);
626 // CbmStsSector* sector = NULL;
627 Int_t maxDigiNr = (Int_t)clusterCand->GetMean();
628 // Double_t plateau = clusterCand->GetMeanError();
629 Double_t maxDigiSig = 0.;
630 CbmStsDigi* digi = NULL;
631 digi = (CbmStsDigi*)fDigis->At(maxDigiNr);
632 // Int_t maxDigiPos = digi->GetChannelNr();
633 maxDigiSig = digi->GetAdc();
634
635 if (clusterCand->GetNDigis() > 5) {
636 // AZ - split large clusters
637 // SplitCluster(iCluster);
638 // return;
639 }
640 // cout << "Cluster " << iCluster+1 << " has " << cluster->GetNDigis() << " digis, max at " << maxDigiNr << endl;
641 Double_t chanNr = 0;
642 Double_t chanADC = 0.;
643 Double_t sumW = 0;
644 Double_t sumWX = 0;
645 Double_t sumCh = 0;
646 Double_t error = 0;
647 Double_t sumWX2 = 0.0;
648 for (Int_t itemp = 0; itemp < clusterCand->GetNDigis(); itemp++) {
649 digi = (CbmStsDigi*)fDigis->At(clusterCand->GetDigi(itemp));
650 chanNr = (Double_t)digi->GetChannelNr();
651 chanADC = digi->GetAdc();
652 sumW += chanADC;
653 sumWX += chanNr * chanADC;
654 sumCh += chanNr;
655 error += (chanADC * chanADC);
656 sumWX2 += chanADC * chanNr * chanNr; // AZ
657 // cout << chanADC << " + " << flush;
658 // cout << "channel " << digi->GetChannelNr() << " with signal = " << digi->GetADC() << " (" << sumWX << "/"
659 // << sumW << ") - plateau = " << plateau << endl;
660 }
661
662 if (sumW > 50.) {
663 // Int_t imean = TMath::Nint (sumWX/sumW); //AZ
664 for (Int_t itemp = 0; itemp < clusterCand->GetNDigis(); itemp++) {
665
666 digi = (CbmStsDigi*)fDigis->At(clusterCand->GetDigi(itemp));
667 if (itemp == 0) {
668 cluster = new ((*fClusters)[fNofClusters++])
669 CbmStsCluster(digi->GetAdc(), digi->GetStationNr(), digi->GetSectorNr(), digi->GetSide());
670 // AZ cluster->AddDigi(itemp);
671 cluster->AddDigi(clusterCand->GetDigi(itemp));
672 // if (digi->GetChannelNr() == imean) cluster->AddDigi(clusterCand->GetDigi(itemp));
673 } else if (itemp > 0) {
674 // AZ cluster->AddDigi(itemp);
675 cluster->AddDigi(clusterCand->GetDigi(itemp));
676 // if (digi->GetChannelNr() == imean) cluster->AddDigi(clusterCand->GetDigi(itemp));
677 }
678 }
679 // cout << " mean at = " << sumWX/sumW << endl;
680 cluster->SetMean(sumWX / sumW);
681 cluster->SetQtot(sumW); // AZ
682 cluster->SetMeanError((1. / (sumW)) * TMath::Sqrt(error));
683 if (sumW < maxDigiSig) {
684 cout << " MAX DIGI = " << maxDigiSig << ", while SUMW = " << sumW << endl;
685 for (Int_t itemp = 0; itemp < clusterCand->GetNDigis(); itemp++) {
686 digi = (CbmStsDigi*)fDigis->At(clusterCand->GetDigi(itemp));
687 cout << "digi ADC = " << digi->GetAdc() << " at channel# " << digi->GetChannelNr() << endl;
688 }
689 }
690 // AZ - correct coordinate for 2 adjacent clusters, i.e. the ones sharing 1 channel
691 // if (0) {
692 if (fNofClusters > 1) {
693 CbmStsCluster* clusPrev = (CbmStsCluster*)fClusters->UncheckedAt(fNofClusters - 2);
694 if (clusPrev->GetDetectorId() == cluster->GetDetectorId()) {
695
696 Int_t nDigis = clusPrev->GetNDigis();
697 CbmStsDigi* digPrev = (CbmStsDigi*)fDigis->UncheckedAt(clusPrev->GetDigi(nDigis - 1));
698 Int_t chan2 = digPrev->GetChannelNr();
699 if (chan2 == ((CbmStsDigi*)fDigis->UncheckedAt(cluster->GetDigi(0)))->GetChannelNr()) {
700
701 Double_t adcPrev = digPrev->GetAdc();
702 Double_t qPrev = clusPrev->GetQtot();
703 Double_t xPrev = clusPrev->GetMean() * qPrev;
704 xPrev -= chan2 * adcPrev * 0.5;
705 xPrev /= (qPrev - adcPrev * 0.5);
706 clusPrev->SetMean(xPrev);
707 clusPrev->SetQtot(qPrev - adcPrev * 0.5);
708 Double_t xCor = sumWX;
709 xCor -= chan2 * adcPrev * 0.5;
710 xCor /= (sumW - adcPrev * 0.5);
711 cluster->SetMean(xCor);
712 cluster->SetQtot(sumW - adcPrev * 0.5);
713 }
714 }
715 }
716 //* AZ - correct coordinate and choose error estimate for previous cluster
717 Int_t chan2 = -1;
718 if (fNofClusters > 1) {
719 CbmStsCluster* clusPrev = (CbmStsCluster*)fClusters->UncheckedAt(fNofClusters - 2);
720 if (clusPrev->GetDetectorId() == cluster->GetDetectorId()) {
721 Int_t nDigis = clusPrev->GetNDigis();
722 CbmStsDigi* digPrev = (CbmStsDigi*)fDigis->UncheckedAt(clusPrev->GetDigi(nDigis - 1));
723 chan2 = digPrev->GetChannelNr();
724 if (chan2 != ((CbmStsDigi*)fDigis->UncheckedAt(cluster->GetDigi(0)))->GetChannelNr())
725 chan2 = -1;
726 }
727 EvalErrors(clusPrev, chan2);
728 }
729 // Double_t rms = sumWX2 / sumW - cluster->GetMean() * cluster->GetMean();
730 Double_t rms = (sumWX2 - sumWX * sumWX / sumW) / sumW;
731 cluster->SetMeanError(TMath::Sqrt(rms));
732 // cluster->SetMeanError(0.04/TMath::Sqrt(12.)); //rms);
733 cluster->SetLeft(chan2); // if > 0 - there is a left neighbour
734 if (iCluster == fNofClustersCand - 1)
735 EvalErrors(cluster, -1); // last cluster
736 // AZ
737 //*/
738 } // if (sumW>50.)
739 // cout << sumWE/sumW << " mean at " << endl;
740 // cout << "error = " << sumW/maxDigiSig << endl;
741}
742// -------------------------------------------------------------------------
743
744// AZ -----------------------------------------------------------------------
746{
747 // Split large cluster into subclusters
748
749 const Int_t nDigMax = 13;
750 static Int_t first = 1, nSubs[nDigMax] = {0};
751
752 if (first) {
753 first = 0;
754 nSubs[6] = nSubs[7] = nSubs[8] = nSubs[9] = 2; // number of subclusters
755 nSubs[10] = nSubs[11] = nSubs[12] = 3;
756 }
757
758 CbmStsCluster* clusterCand = (CbmStsCluster*)fClustersCand->At(iCluster);
759 CbmStsCluster* cluster = NULL;
760 CbmStsDigi* digi = NULL;
761
762 Int_t mult = clusterCand->GetNDigis(), nsub = 1;
763 if (mult < nDigMax)
764 nsub = nSubs[mult];
765 else
766 nsub = TMath::Nint(mult * 1.0 / 4 - 0.1);
767 Int_t leng0 = TMath::Nint(mult * 1.0 / nsub);
768 Int_t i0 = 0, itemp = 0;
769 Double_t chanNr = 0.0, chanADC = 0.0, sumW = 0.0, sumWX = 0.0, sumWX2 = 0.0;
770
771 // for ( Int_t itemp = 0; itemp < mult; itemp++ ) {
772 for (Int_t icl = 0; icl < nsub; ++icl) {
773 Int_t leng = leng0;
774 if (icl == 0 && mult - leng0 * nsub == 1)
775 ++leng; // add extra digi to first subcluster
776 else if (icl == nsub - 1 && mult - leng0 * nsub == 2)
777 ++leng; // add extra digi to last subclus.
778 while (1) {
779 digi = (CbmStsDigi*)fDigis->UncheckedAt(clusterCand->GetDigi(itemp));
780 if (i0 == 0) {
781 cluster = new ((*fClusters)[fNofClusters++])
782 CbmStsCluster(digi->GetAdc(), digi->GetStationNr(), digi->GetSectorNr(), digi->GetSide());
783 cluster->AddDigi(clusterCand->GetDigi(itemp));
784 } else {
785 cluster->AddDigi(clusterCand->GetDigi(itemp));
786 }
787 ++i0;
788 ++itemp;
789 chanNr = digi->GetChannelNr();
790 chanADC = digi->GetAdc();
791 sumW += chanADC;
792 sumWX += chanNr * chanADC;
793 sumWX2 += chanADC * chanNr * chanNr;
794 if (i0 == leng) {
795 // Subcluster
796 cluster->SetMean(sumWX / sumW);
797 cluster->SetQtot(sumW); // AZ
798 cluster->SetDefaultType(mult);
799
800 // AZ - correct coordinate for 2 adjacent clusters, i.e. the ones sharing 1 channel or back to back
801 // if (0) {
802 if (fNofClusters > 1) {
803 CbmStsCluster* clusPrev = (CbmStsCluster*)fClusters->UncheckedAt(fNofClusters - 2);
804 if (clusPrev->GetDetectorId() == cluster->GetDetectorId()) {
805
806 Int_t nDigis = clusPrev->GetNDigis();
807 CbmStsDigi* digPrev = (CbmStsDigi*)fDigis->UncheckedAt(clusPrev->GetDigi(nDigis - 1));
808 Int_t chan2 = digPrev->GetChannelNr();
809 CbmStsDigi* digThis = (CbmStsDigi*)fDigis->UncheckedAt(cluster->GetDigi(0));
810 Int_t chan1 = digThis->GetChannelNr();
811 if (TMath::Abs(chan2 - chan1) < 1) {
812 // Adjacent clusters
813 Double_t adcPrev = digPrev->GetAdc();
814 Double_t qPrev = clusPrev->GetQtot();
815 Double_t xPrev = clusPrev->GetMean() * qPrev;
816 xPrev -= chan2 * adcPrev * 0.5;
817 xPrev /= (qPrev - adcPrev * 0.5);
818 clusPrev->SetMean(xPrev);
819 clusPrev->SetQtot(qPrev - adcPrev * 0.5);
820 adcPrev = digThis->GetAdc();
821 Double_t xCor = sumWX;
822 xCor -= chan1 * adcPrev * 0.5;
823 xCor /= (sumW - adcPrev * 0.5);
824 cluster->SetMean(xCor);
825 cluster->SetQtot(sumW - adcPrev * 0.5);
826 }
827 }
828 }
829 //* AZ - correct coordinate and choose error estimate for previous cluster
830 Int_t chan2 = -1;
831 if (fNofClusters > 1) {
832 CbmStsCluster* clusPrev = (CbmStsCluster*)fClusters->UncheckedAt(fNofClusters - 2);
833 if (clusPrev->GetDetectorId() == cluster->GetDetectorId()) {
834 Int_t nDigis = clusPrev->GetNDigis();
835 CbmStsDigi* digPrev = (CbmStsDigi*)fDigis->UncheckedAt(clusPrev->GetDigi(nDigis - 1));
836 chan2 = digPrev->GetChannelNr();
837 if (TMath::Abs(chan2 - ((CbmStsDigi*)fDigis->UncheckedAt(cluster->GetDigi(0)))->GetChannelNr())
838 > 0)
839 chan2 = -1;
840 }
841 EvalErrors(clusPrev, chan2);
842 }
843 // Double_t rms = sumWX2 / sumW - cluster->GetMean() * cluster->GetMean();
844 Double_t rms = (sumWX2 - sumWX * sumWX / sumW) / sumW;
845 cluster->SetMeanError(TMath::Sqrt(rms));
846 // cluster->SetMeanError(0.04/TMath::Sqrt(12.)); //rms);
847 cluster->SetLeft(chan2); // if > 0 - there is a left neighbour
848 if (iCluster == fNofClustersCand - 1)
849 EvalErrors(cluster, -1); // last cluster
850
851 // cluster->SetMeanError( (1./(sumW)) * TMath::Sqrt(error) );
852 i0 = 0;
853 if (itemp + leng * (nsub - icl - 1) > mult)
854 --itemp; // move one digi backward
855 sumW = sumWX = sumWX2 = 0.0;
856 break;
857 }
858 }
859 }
860}
861// -------------------------------------------------------------------------
862
863// AZ -----------------------------------------------------------------------
865{
866 // Evaluate errors and correct coordinate if necessary
867
868 Int_t mult = clus->GetNDigis();
869 Double_t sigma = 0.0, xcor = clus->GetMean(), rms = clus->GetMeanError();
870
871 if (chan2 >= 0 && clus->GetLeft() >= 0) {
872 // Cluster has 2 neighbours
873 if (mult <= 3)
874 sigma = 0.0298;
875 else if (mult == 4) {
876 if (clus->GetDefaultType())
877 sigma = 0.0398; // split cluster - check that !
878 else
879 sigma = 0.0135; // fit
880 } else if (mult == 5) {
881 if (clus->GetDefaultType())
882 sigma = 0.0463; // split cluster - check that !
883 else
884 sigma = 0.0109; // fit
885 }
886 }
887
888 else if (chan2 >= 0 || clus->GetLeft() >= 0)
889 {
890 // 1 neighbour
891 // Int_t ishft = 1;
892 // if (chan2 >= 0) ishft = -1;
893 if (mult <= 2) {
894 sigma = 0.0220;
895 // xcor = xcor - ishft * 0.0122 / 0.0400;
896 } else if (mult == 5) {
897 ////if (rms < 1.2) sigma = 0.0075;
898 ////else sigma = 0.0121;
899 ////sigma = 0.0105;
900 // sigma = 0.0055; // fit
901 // xcor = xcor + ishft * (0.0070 / 0.0400 + (rms - 1.234) * 0.44 / 4.5 / 0.0400);
902 if (clus->GetDefaultType())
903 sigma = 0.0487; // split cluster - check that !
904 else
905 sigma = 0.0118; // fit
906 } else if (mult == 3) {
907 // sigma = 0.0080;
908 // xcor = xcor + ishft * (-0.0025 / 0.0400 + (rms - 0.776) * 0.54 / 2.5 / 0.0400);
909 if (clus->GetDefaultType())
910 sigma = 0.0315; // split cluster - check that !
911 else
912 sigma = 0.0098; // fit
913 } else if (mult == 4) {
914 // sigma = 0.0065;
915 // xcor = xcor + ishft * (0.0045 / 0.0400 + (rms - 1.028) * 0.62 / 3.5 / 0.0400);
916 if (clus->GetDefaultType())
917 sigma = 0.0366; // split cluster - check that !
918 else
919 sigma = 0.0100; // fit
920 }
921 xcor = TMath::Max(0.0, xcor);
922 }
923
924 else
925 {
926 // No neighbours
927 if (mult == 1)
928 sigma = 0.0122;
929 else if (mult == 2) {
930 if (rms > 0.495)
931 sigma = 0.0071; // RMS
932 else
933 sigma = 0.0224; // edge effect - fix !
934 } else if (mult == 3) {
935 if (clus->GetDefaultType())
936 sigma = 0.0255; // split cluster - check that !
937 else
938 sigma = 0.0064; // fit
939 } else if (mult == 4) {
940 if (clus->GetDefaultType())
941 sigma = 0.0337; // split cluster - check that !
942 sigma = 0.0048; // fit
943 } else if (mult == 5) {
944 // if (rms < 1.19) sigma = 0.0108;
945 if (rms < 1.19)
946 sigma = 0.0038; // fit
947 else
948 sigma = 0.0415; // should be split also !
949 }
950 }
951
952 clus->SetMean(xcor);
953 clus->SetMeanError(sigma);
954}
955// AZ -----------------------------------------------------------------------
956
957// ----- Virtual method Finish -----------------------------------------
959{
961 cout << endl;
962 cout << "============================================================" << endl;
963 cout << "===== " << fName << ": Run summary " << endl;
964 cout << "===== " << endl;
965 cout << "===== Number of clusters : " << setw(8) << setprecision(2) << fNofClustersCand << endl;
966 cout << "===== Number of good clusters : " << setw(8) << setprecision(2) << fNofClustersGood << " ("
967 << setw(8) << setprecision(2) << 100. * fNofClustersGood / fNofClustersCand << "%)" << endl;
968 cout << "===== Number of plateau clusters : " << setw(8) << setprecision(2) << fNofClustersWP << " ("
969 << setw(8) << setprecision(2) << 100. * fNofClustersWP / fNofClustersCand << "%)" << endl;
970 cout << "===== Number of minimum clusters : " << setw(8) << setprecision(2) << fNofClustersWM << " ("
971 << setw(8) << setprecision(2) << 100. * fNofClustersWM / fNofClustersCand << "%)" << endl;
972 cout << "===== Longest cluster : " << setw(8) << setprecision(2) << fLongestCluster << endl;
973 cout << "===== Longest good cluster : " << setw(8) << setprecision(2) << fLongestGoodCluster << endl;
974 cout << "============================================================" << endl;
975}
976// -------------------------------------------------------------------------
int i
Definition P4_F32vec4.h:22
bool Bool_t
int Int_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
void Fatal(const char *location, const char *msgfmt,...)
@ kStsDigi
virtual ~CbmStsClusterFinder()
Destructor.
void MakeSets()
Make sectorwise sets for sigis.
CbmStsClusterFinder()
Default constructor.
TClonesArray * fClusters
Input array of CbmStsCluster.
TStopwatch fTimer
sector digis (back)
virtual InitStatus Init()
Intialisation.
virtual InitStatus ReInit()
Reinitialisation.
void EvalErrors(CbmStsCluster *clus, Int_t chan2)
virtual void SetParContainers()
Get parameter containers.
void AnalyzeCluster(Int_t iclus)
Int_t fNofDigis
Input array of CbmStsCluster.
virtual void Exec(Option_t *opt)
Execution.
CbmStsDigiPar * fDigiPar
Geometry parameters.
void SortDigis()
Sort digis sectorwise.
map< CbmStsSector *, set< Int_t > > fDigiMapF
map< CbmStsSector *, set< Int_t > > fDigiMapB
sector digis (front)
TClonesArray * fDigis
Digitisation scheme.
virtual void Finish()
Virtual method Finish.
CbmStsDigiScheme * fDigiScheme
Digitisation parameters.
void SplitCluster(Int_t iclus)
TClonesArray * fClustersCand
Input array of CbmStsDigi.
Int_t FindClusters(Int_t stationNr, Int_t sectorNr, Int_t iSide, set< Int_t > &digiSet)
Find hits in one sector.
CbmStsCluster.h.
void SetMeanError(Double_t err)
Int_t GetLeft() const
void SetMean(Double_t chan)
Double_t GetMean() const
void SetQtot(Double_t qtot)
Int_t GetNDigis() const
Int_t GetDetectorId() const
Accessors.
Double_t GetMeanError() const
Double_t GetQtot() const
Int_t GetDigi(Int_t inum)
void SetLeft(Int_t left)
void AddDigi(Int_t idigi)
CbmStsDigi.h.
Definition CbmStsDigi.h:32
Int_t GetSide() const
Side ( 0 = front, 1 = back ).
Definition CbmStsDigi.h:73
Int_t GetAdc() const
Charge.
Definition CbmStsDigi.h:79
Int_t GetSectorNr() const
Sector number.
Definition CbmStsDigi.h:70
Int_t GetChannelNr() const
Channel number.
Definition CbmStsDigi.h:76
Int_t GetStationNr() const
Station number.
Definition CbmStsDigi.h:67
Int_t GetType() const
Int_t GetSectorNr() const
Int_t GetNSectors() const
Int_t GetStationNr() const
CbmStsSector * GetSector(Int_t iSector)
Int_t Nint(T x)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)