8#include "TClonesArray.h"
11#include "FairRootManager.h"
12#include "FairRunAna.h"
13#include "FairRuntimeDb.h"
36using std::setprecision;
42 : FairTask(
"STS Cluster Finder", 1),
59 fLongestGoodCluster(0)
64 : FairTask(
"STSClusterFinder", iVerbose),
81 fLongestGoodCluster(0)
86 : FairTask(name, iVerbose),
103 fLongestGoodCluster(0)
108 if ( fClustersCand ) {
109 fClustersCand->Delete();
110 delete fClustersCand;
125 Bool_t warn = kFALSE;
128 cout << endl <<
"-I- " << fName <<
": executing event with " << fDigis->GetEntriesFast() <<
" digis." << endl;
129 cout <<
"----------------------------------------------" << endl;
133 if ( ! fDigiScheme ) {
134 cerr <<
"-E- " << fName <<
"::Exec: No digi scheme!" << endl;
140 fNofClustersCand = 0;
145 fClustersCand->Delete();
156 for (Int_t iStation=0; iStation<nStations; iStation++) {
158 Int_t nDigisFInStation = 0;
159 Int_t nDigisBInStation = 0;
162 for (Int_t iSector=0; iSector<nSectors; iSector++) {
166 set <Int_t> fSet, bSet;
167 if ( fDigiMapF.find(sector) == fDigiMapF.end() ) {
168 cout <<
"-E- " << fName <<
"::Exec: sector "
175 fSet = fDigiMapF[sector];
176 FindClusters(iStation+1,iSector+1,0, fSet);
178 if ( fDigiMapB.find(sector) == fDigiMapB.end() ) {
179 cout <<
"-E- " << fName <<
"::Exec: sector "
187 bSet = fDigiMapB[sector];
188 FindClusters(iStation+1,iSector+1,1, bSet);
189 Int_t nDigisFInSector = fSet.size();
190 Int_t nDigisBInSector = bSet.size();
191 nDigisFInStation += nDigisFInSector;
192 nDigisBInStation += nDigisBInSector;
195 nDigisF += nDigisFInStation;
196 nDigisB += nDigisBInStation;
206 cout <<
"-I- " << fName <<
":Event summary" << endl;
207 cout <<
" Active channels front side: " << nDigisF << endl;
208 cout <<
" Active channels back side : " << nDigisB << endl;
209 cout <<
" Real time : " << fTimer.RealTime()
213 if ( warn ) cout <<
"- ";
215 cout << setw(15) << left << fName <<
": " << setprecision(4) << setw(8)
216 << fixed << right << fTimer.RealTime()
217 <<
" s, " << fNofClustersCand
218 <<
"(" << fNofClustersGood
219 <<
"+" << fNofClustersWP
220 <<
") clusters, longest till now " << fLongestCluster << endl;
226 Int_t nClust = fClusters->GetEntriesFast();
227 for (Int_t
i = 0;
i < nClust; ++
i) {
231 for (Int_t j = 0; j < nDigis; ++j) {
232 Int_t idigi = clus->
GetDigi(j);
233 clus->AddLink(FairLink(
kStsDigi, idigi));
244void CbmStsClusterFinder::SetParContainers() {
247 FairRunAna*
run = FairRunAna::Instance();
248 if ( !
run ) Fatal(
"SetParContainers",
"No analysis run");
250 FairRuntimeDb* db =
run->GetRuntimeDb();
251 if ( ! db ) Fatal(
"SetParContainers",
"No runtime database");
254 fGeoPar = (
CbmGeoStsPar*) db->getContainer(
"CbmGeoStsPar");
257 fDigiPar = (
CbmStsDigiPar*) db->getContainer(
"CbmStsDigiPar");
266InitStatus CbmStsClusterFinder::Init() {
269 FairRootManager* ioman = FairRootManager::Instance();
270 if ( ! ioman ) Fatal(
"Init",
"No FairRootManager");
271 fDigis = (TClonesArray*) ioman->GetObject(
"StsDigi");
273 fClustersCand =
new TClonesArray(
"CbmStsCluster", 30000);
274 ioman->Register(
"StsClusterCand",
"Cluster in STS", fClustersCand, kTRUE);
276 fClusters =
new TClonesArray(
"CbmStsCluster", 30000);
277 ioman->Register(
"StsCluster",
"Cluster in STS", fClusters, kTRUE);
280 Bool_t success = fDigiScheme->
Init(fGeoPar, fDigiPar);
281 if ( ! success )
return kERROR;
287 if (fVerbose == 1 || fVerbose == 2) fDigiScheme->
Print(kFALSE);
288 else if (fVerbose > 2) fDigiScheme->
Print(kTRUE);
289 cout <<
"-I- " << fName <<
"::Init: "
290 <<
"STS digitisation scheme succesfully initialised" << endl;
292 <<
", Sectors: " << fDigiScheme->
GetNSectors() <<
", Channels: "
295 fNofClustersCand = 0;
297 fNofClustersGood = 0;
302 fLongestGoodCluster = 0;
312InitStatus CbmStsClusterFinder::ReInit() {
315 fDigiScheme->
Clear();
318 Bool_t success = fDigiScheme->
Init(fGeoPar, fDigiPar);
319 if ( ! success )
return kERROR;
325 if (fVerbose == 1 || fVerbose == 2) fDigiScheme->
Print(kFALSE);
326 else if (fVerbose > 2) fDigiScheme->
Print(kTRUE);
327 cout <<
"-I- " << fName <<
"::Init: "
328 <<
"STS digitisation scheme succesfully reinitialised" << endl;
330 <<
", Sectors: " << fDigiScheme->
GetNSectors() <<
", Channels: "
333 fNofClustersCand = 0;
335 fNofClustersGood = 0;
340 fLongestGoodCluster = 0;
350void CbmStsClusterFinder::MakeSets() {
355 for (Int_t iStation=0; iStation<nStations; iStation++) {
358 for (Int_t iSector=0; iSector<nSectors; iSector++) {
361 fDigiMapF[sector] = a;
364 fDigiMapB[sector] = b;
376void CbmStsClusterFinder::SortDigis() {
380 cout <<
"-E- " << fName <<
"::SortDigis: No input array!" << endl;
385 const Int_t nDigis = fDigis->GetEntriesFast();
388 map<CbmStsSector*, set<Int_t> >::iterator mapIt;
389 for (mapIt=fDigiMapF.begin(); mapIt!=fDigiMapF.end(); mapIt++)
390 ((*mapIt).second).clear();
391 for (mapIt=fDigiMapB.begin(); mapIt!=fDigiMapB.end(); mapIt++)
392 ((*mapIt).second).clear();
396 Int_t stationNr = -1;
401 for (Int_t iDigi=0; iDigi<nDigis; iDigi++) {
407 sector = fDigiScheme->
GetSector(stationNr, sectorNr);
410 if ( fDigiMapF.find(sector) == fDigiMapF.end() ) {
411 cerr <<
"-E- " << fName <<
"::SortDigits:: sector " << sectorNr
412 <<
" of station " << stationNr
413 <<
" not found in digi scheme (F)!" << endl;
416 fDigiMapF[sector].insert(iDigi);
418 else if (iSide == 1 ) {
419 if ( fDigiMapB.find(sector) == fDigiMapB.end() ) {
420 cerr <<
"-E- " << fName <<
"::SortDigits:: sector " << sectorNr
421 <<
" of station " << stationNr
422 <<
" not found in digi scheme (B)!" << endl;
425 fDigiMapB[sector].insert(iDigi);
432Int_t CbmStsClusterFinder::FindClusters(Int_t stationNr, Int_t sectorNr, Int_t iSide, set<Int_t>& digiSet) {
434 set<Int_t>::iterator it1;
442 Double_t digiSig = -1.;
443 Int_t lastDigiNr = -1;
444 Int_t lastDigiPos = -1;
445 Double_t lastDigiSig = 100000.;
446 Int_t clusterMaxNr = -1;
448 Double_t clusterMaxSig = -1.;
449 Bool_t clusterHasMinimum = kFALSE;
450 Bool_t clusterHasPlateau = kFALSE;
451 Int_t clusterBeginPos = 0;
452 Int_t clusterWidth = 0;
456 for (it1=digiSet.begin(); it1!=digiSet.end(); it1++) {
463 if ( lastDigiPos == -1 ) {
464 clusterCand =
new ((*fClustersCand)[fNofClustersCand++])
CbmStsCluster(digiSig, stationNr,sectorNr,iSide);
466 clusterBeginPos = digiPos;
469 if ( digiPos == lastDigiPos+1 ) {
471 if ( digiSig == lastDigiSig ) {
473 clusterHasPlateau = kTRUE;
477 if ( digiSig > lastDigiSig && lastDigiSig < clusterMaxSig && digiSig != clusterMaxSig) {
478 clusterCand->
SetMean(clusterMaxNr);
480 clusterCand =
new ((*fClustersCand)[fNofClustersCand++])
CbmStsCluster(digiSig, stationNr,sectorNr,iSide);
481 clusterCand->
AddDigi(lastDigiNr);
485 clusterWidth = lastDigiPos - clusterBeginPos + 1;
486 if ( clusterWidth > fLongestCluster )
487 fLongestCluster = clusterWidth;
488 if ( clusterHasPlateau ) {
491 if ( !clusterHasMinimum && !clusterHasPlateau ) {
493 if ( clusterWidth > fLongestGoodCluster )
494 fLongestGoodCluster = clusterWidth;
497 clusterHasPlateau = kFALSE;
500 clusterBeginPos = digiPos;
503 else if ( lastDigiPos>=0 ) {
504 clusterCand->
SetMean(clusterMaxNr);
506 clusterCand =
new ((*fClustersCand)[fNofClustersCand++])
CbmStsCluster(digiSig, stationNr,sectorNr,iSide);
509 clusterWidth = lastDigiPos - clusterBeginPos + 1;
510 if ( clusterWidth > fLongestCluster )
511 fLongestCluster = clusterWidth;
512 if ( clusterHasPlateau ) {
515 if ( !clusterHasMinimum && !clusterHasPlateau ) {
517 if ( clusterWidth > fLongestGoodCluster )
518 fLongestGoodCluster = clusterWidth;
521 clusterHasPlateau = kFALSE;
524 clusterBeginPos = digiPos;
526 if ( digiSig > clusterMaxSig ) {
527 clusterMaxNr = iDigi;
529 clusterMaxSig = digiSig;
532 clusterWidth = lastDigiPos - clusterBeginPos + 1;
533 if ( clusterWidth < 90 ) {
538 clusterCand->
SetMean(clusterMaxNr);
541 clusterCand =
new ((*fClustersCand)[fNofClustersCand++])
CbmStsCluster(digiSig, stationNr,sectorNr,iSide);
543 clusterWidth = lastDigiPos - clusterBeginPos + 1;
544 if ( clusterWidth > fLongestCluster )
545 fLongestCluster = clusterWidth;
546 if ( clusterHasPlateau ) {
549 if ( !clusterHasMinimum && !clusterHasPlateau ) {
551 if ( clusterWidth > fLongestGoodCluster )
552 fLongestGoodCluster = clusterWidth;
555 clusterHasPlateau = kFALSE;
558 clusterBeginPos = digiPos;
562 lastDigiPos = digiPos;
563 lastDigiSig = digiSig;
565 if ( digiSig > 0. ) {
566 clusterCand->
SetMean(clusterMaxNr);
569 clusterWidth = lastDigiPos - clusterBeginPos + 1;
570 if ( clusterWidth > fLongestCluster )
571 fLongestCluster = clusterWidth;
572 if ( clusterHasPlateau ) {
575 if ( lastDigiPos && !clusterHasPlateau ) {
577 if ( clusterWidth > fLongestGoodCluster )
578 fLongestGoodCluster = clusterWidth;
585 map<Int_t , Int_t> channelSorted;
586 for (it1=digiSet.begin(); it1!=digiSet.end(); it1++) {
595 for (Int_t iter=0; iter<1100; iter++) {
596 iDigi = channelSorted[iter];
597 if ( iDigi == 0 )
continue;
600 if (iFS >= channelSorted.size())
break;
625void CbmStsClusterFinder::AnalyzeClusters() {
626 for ( Int_t iclus = 0 ; iclus < fNofClustersCand ; iclus++ ) {
627 AnalyzeCluster(iclus);
633void CbmStsClusterFinder::AnalyzeCluster(Int_t iCluster) {
638 Int_t maxDigiNr = (Int_t)clusterCand->
GetMean();
640 Double_t maxDigiSig = 0.;
644 maxDigiSig = digi->
GetAdc();
653 Double_t chanADC = 0.;
658 Double_t sumWX2 = 0.0;
659 for ( Int_t itemp = 0 ; itemp < clusterCand->
GetNDigis() ; itemp++ ) {
664 sumWX += chanNr*chanADC;
666 error += ( chanADC*chanADC );
667 sumWX2 += chanADC * chanNr * chanNr;
674 for ( Int_t itemp = 0 ; itemp < clusterCand->
GetNDigis() ; itemp++ ) {
692 cluster->
SetMeanError( (1./(sumW)) * TMath::Sqrt(error) );
693 if ( sumW < maxDigiSig ) {
694 cout <<
" MAX DIGI = " << maxDigiSig <<
", while SUMW = " << sumW << endl;
695 for ( Int_t itemp = 0 ; itemp < clusterCand->
GetNDigis() ; itemp++ ) {
697 cout <<
"digi ADC = " << digi->
GetAdc() <<
" at channel# " << digi->
GetChannelNr() << endl;
702 if (fNofClusters > 1) {
709 if (chan2 == ((
CbmStsDigi*)fDigis->UncheckedAt(cluster->
GetDigi(0)))->GetChannelNr()) {
711 Double_t adcPrev = digPrev->
GetAdc();
712 Double_t qPrev = clusPrev->
GetQtot();
713 Double_t xPrev = clusPrev->
GetMean() * qPrev;
714 xPrev -= chan2 * adcPrev * 0.5;
715 xPrev /= (qPrev - adcPrev * 0.5);
717 clusPrev->
SetQtot(qPrev - adcPrev * 0.5);
718 Double_t xCor = sumWX;
719 xCor -= chan2 * adcPrev * 0.5;
720 xCor /= (sumW - adcPrev * 0.5);
722 cluster->
SetQtot(sumW - adcPrev * 0.5);
728 if (fNofClusters > 1) {
734 if (chan2 != ((
CbmStsDigi*)fDigis->UncheckedAt(cluster->
GetDigi(0)))->GetChannelNr()) chan2 = -1;
736 EvalErrors(clusPrev, chan2);
739 Double_t rms = (sumWX2 - sumWX * sumWX / sumW) / sumW;
743 if (iCluster == fNofClustersCand-1) EvalErrors(cluster, -1);
753void CbmStsClusterFinder::SplitCluster(Int_t iCluster)
757 const Int_t nDigMax = 13;
758 static Int_t first = 1, nSubs[nDigMax] = {0};
762 nSubs[6] = nSubs[7] = nSubs[8] = nSubs[9] = 2;
763 nSubs[10] = nSubs[11] = nSubs[12] = 3;
770 Int_t mult = clusterCand->
GetNDigis(), nsub = 1;
771 if (mult < nDigMax) nsub = nSubs[mult];
772 else nsub = TMath::Nint (mult * 1.0 / 4 - 0.1);
773 Int_t leng0 = TMath::Nint (mult * 1.0 / nsub);
774 Int_t i0 = 0, itemp = 0;
775 Double_t chanNr = 0.0, chanADC = 0.0, sumW = 0.0, sumWX = 0.0, sumWX2 = 0.0;
778 for (Int_t icl = 0; icl < nsub; ++icl) {
780 if (icl == 0 && mult - leng0 * nsub == 1) ++leng;
781 else if (icl == nsub - 1 && mult - leng0 * nsub == 2) ++leng;
795 sumWX += chanNr * chanADC;
796 sumWX2 += chanADC * chanNr * chanNr;
801 cluster->SetDefaultType(mult);
805 if (fNofClusters > 1) {
814 if (TMath::Abs(chan2-chan1) < 1) {
816 Double_t adcPrev = digPrev->
GetAdc();
817 Double_t qPrev = clusPrev->
GetQtot();
818 Double_t xPrev = clusPrev->
GetMean() * qPrev;
819 xPrev -= chan2 * adcPrev * 0.5;
820 xPrev /= (qPrev - adcPrev * 0.5);
822 clusPrev->
SetQtot(qPrev - adcPrev * 0.5);
823 adcPrev = digThis->
GetAdc();
824 Double_t xCor = sumWX;
825 xCor -= chan1 * adcPrev * 0.5;
826 xCor /= (sumW - adcPrev * 0.5);
828 cluster->
SetQtot(sumW - adcPrev * 0.5);
834 if (fNofClusters > 1) {
840 if (TMath::Abs(chan2-((
CbmStsDigi*)fDigis->UncheckedAt(cluster->
GetDigi(0)))->GetChannelNr()) > 0) chan2 = -1;
842 EvalErrors(clusPrev, chan2);
845 Double_t rms = (sumWX2 - sumWX * sumWX / sumW) / sumW;
849 if (iCluster == fNofClustersCand-1) EvalErrors(cluster, -1);
853 if (itemp + leng * (nsub - icl - 1) > mult) --itemp;
854 sumW = sumWX = sumWX2 = 0.0;
863void CbmStsClusterFinder::EvalErrors(
CbmStsCluster *clus, Int_t chan2) {
869 if (chan2 >= 0 && clus->
GetLeft() >= 0) {
871 if (mult <= 3) sigma = 0.0298;
872 else if (mult == 4) {
873 if (clus->GetDefaultType()) sigma = 0.0398;
876 else if (mult == 5) {
877 if (clus->GetDefaultType()) sigma = 0.0463;
882 else if (chan2 >= 0 || clus->
GetLeft() >= 0) {
890 else if (mult == 5) {
896 if (clus->GetDefaultType()) sigma = 0.0487;
899 else if (mult == 3) {
902 if (clus->GetDefaultType()) sigma = 0.0315;
905 else if (mult == 4) {
908 if (clus->GetDefaultType()) sigma = 0.0366;
911 xcor = TMath::Max (0.0, xcor);
916 if (mult == 1) sigma = 0.0122;
917 else if (mult == 2) {
918 if (rms > 0.495) sigma = 0.0071;
921 else if (mult == 3) {
922 if (clus->GetDefaultType()) sigma = 0.0255;
925 else if (mult == 4) {
926 if (clus->GetDefaultType()) sigma = 0.0337;
929 else if (mult == 5) {
931 if (rms < 1.19) sigma = 0.0038;
943 fNofClustersCand = fNofClustersGood+fNofClustersWP;
945 cout <<
"============================================================"
947 cout <<
"===== " << fName <<
": Run summary " << endl;
948 cout <<
"===== " << endl;
949 cout <<
"===== Number of clusters : "
950 << setw(8) << setprecision(2)
951 << fNofClustersCand << endl;
952 cout <<
"===== Number of good clusters : "
953 << setw(8) << setprecision(2)
954 << fNofClustersGood <<
" ("
955 << setw(8) << setprecision(2)
956 << 100.*fNofClustersGood/fNofClustersCand <<
"%)" << endl;
957 cout <<
"===== Number of plateau clusters : "
958 << setw(8) << setprecision(2)
959 << fNofClustersWP <<
" ("
960 << setw(8) << setprecision(2)
961 << 100.*fNofClustersWP/fNofClustersCand <<
"%)" << endl;
962 cout <<
"===== Number of minimum clusters : "
963 << setw(8) << setprecision(2)
964 << fNofClustersWM <<
" ("
965 << setw(8) << setprecision(2)
966 << 100.*fNofClustersWM/fNofClustersCand <<
"%)" << endl;
967 cout <<
"===== Longest cluster : "
968 << setw(8) << setprecision(2)
969 << fLongestCluster << endl;
970 cout <<
"===== Longest good cluster : "
971 << setw(8) << setprecision(2)
972 << fLongestGoodCluster << endl;
973 cout <<
"============================================================"
BmnSsdDigitizeParameters * fDigiPar
Digitisation parameters.
virtual ~CbmStsClusterFinder()
virtual void Exec(Option_t *opt)
void SetMeanError(Double_t err)
void SetMean(Double_t chan)
void SetQtot(Double_t qtot)
Int_t GetDetectorId() const
Double_t GetMeanError() const
Int_t GetDigi(Int_t inum)
void AddDigi(Int_t idigi)
void Print(Bool_t kLong=kFALSE)
CbmStsSector * GetSector(Int_t stationNr, Int_t sectorNr)
CbmStsStation * GetStation(Int_t iStation)
Int_t GetSectorNr() const
Int_t GetChannelNr() const
Int_t GetStationNr() const
Int_t GetSectorNr() const
Int_t GetNSectors() const
Int_t GetStationNr() const
CbmStsSector * GetSector(Int_t iSector)
@ error
throw a parse_error exception in case of a tag