11 #include "CbmTofHit.h"
13 #include "FairEventHeader.h"
14 #include "FairLogger.h"
15 #include "FairMCEventHeader.h"
16 #include "FairRunAna.h"
17 #include "FairRunSim.h"
18 #include "FairRuntimeDb.h"
19 #include "TClonesArray.h"
20 #include "TGeoManager.h"
24 #include <mach/mach_time.h>
26 #ifndef CLOCK_REALTIME
27 #define CLOCK_REALTIME 0
29 #ifndef CLOCK_MONOTONIC
30 #define CLOCK_MONOTONIC 0
32 inline int clock_gettime(
int clk_id,
struct timespec* t) {
33 mach_timebase_info_data_t timebase;
34 mach_timebase_info(&timebase);
36 time = mach_absolute_time();
38 ((double) time * (
double) timebase.numer) / ((
double) timebase.denom);
40 ((double) time * (
double) timebase.numer) / ((
double) timebase.denom * 1e9);
42 t->tv_nsec = nseconds;
82 , fOutTimeFactor(1) {}
90 for (Int_t iT = 0; iT < iNbSmTypes; iT++) {
93 for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++)
105 for (Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++) {
108 fvCPTOff[iSmType].resize(iNbSm * iNbRpc);
110 fvCPWalk[iSmType].resize(iNbSm * iNbRpc);
112 for (Int_t iSm = 0; iSm < iNbSm; iSm++) {
113 for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++) {
120 for (Int_t iTrg = 0; iTrg <
iNTrg; iTrg++)
121 fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx][iTrg] =
126 fvCPTOff[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
127 fvCPTotGain[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
128 fvCPWalk[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
130 for (Int_t iCh = 0; iCh < iNbChan; iCh++) {
131 fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
132 fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
133 fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
134 for (Int_t iSide = 0; iSide < nbSide; iSide++) {
135 fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] =
137 fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] =
139 fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][iSide].resize(
142 fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][iSide][iWx] = 0.;
150 LOG(info) <<
"CbmTofSimpClusterizer::InitCalibParameter: defaults set";
160 LOG(info) <<
"CbmTofSimpClusterizer::InitCalibParameter: read histos from "
161 <<
"file " << fCalParFileName ;
164 if(fCalParFileName.IsNull())
return kTRUE;
166 fCalParFile =
new TFile(fCalParFileName,
"");
167 if(NULL == fCalParFile) {
168 LOG(error) <<
"CbmTofSimpClusterizer::InitCalibParameter: "
169 <<
"file " << fCalParFileName <<
" does not exist!" ;
178 for( Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++ )
182 for( Int_t iSm = 0; iSm < iNbSm; iSm++ )
183 for( Int_t iRpc = 0; iRpc < iNbRpc; iRpc++ )
185 TH2F *htempPos_pfx =(TH2F*) gDirectory->FindObjectAny( Form(
"cl_CorSmT%01d_sm%03d_rpc%03d_Pos_pfx",iSmType,iSm,iRpc));
186 TH2F *htempTOff_pfx=(TH2F*) gDirectory->FindObjectAny( Form(
"cl_CorSmT%01d_sm%03d_rpc%03d_TOff_pfx",iSmType,iSm,iRpc));
187 TH2F *htempTot_pfx =(TH2F*) gDirectory->FindObjectAny( Form(
"cl_CorSmT%01d_sm%03d_rpc%03d_Tot_pfx",iSmType,iSm,iRpc));
188 if(NULL != htempPos_pfx && NULL != htempTOff_pfx && NULL != htempTot_pfx)
191 Int_t iNbinTot = htempTot_pfx->GetNbinsX();
192 for( Int_t iCh = 0; iCh < iNbCh; iCh++ )
194 Double_t YMean=((TProfile *)htempPos_pfx)->GetBinContent(iCh+1);
195 Double_t TMean=((TProfile *)htempTOff_pfx)->GetBinContent(iCh+1);
197 fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][0] += -dTYOff + TMean ;
198 fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][1] += +dTYOff + TMean ;
200 Double_t TotMean=((TProfile *)htempTot_pfx)->GetBinContent(iCh+1);
205 LOG(debug1)<<
"CbmTofSimpClusterizer::InitCalibParameter:"
206 <<
" SmT "<< iSmType<<
" Sm "<<iSm<<
" Rpc "<<iRpc<<
" Ch "<<iCh
207 <<
": YMean "<<YMean<<
", TMean "<< TMean
208 <<
" -> " <<
fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][0]
209 <<
", " <<
fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][1]
210 <<
", " <<
fvCPTotGain[iSmType][iSm*iNbRpc+iRpc][iCh][0]
211 <<
", NbinTot "<< iNbinTot
214 TH1D *htempWalk0=(TH1D*)gDirectory->FindObjectAny(
215 Form(
"Cor_SmT%01d_sm%03d_rpc%03d_Ch%03d_S0_Walk_px", iSmType, iSm, iRpc, iCh ));
216 TH1D *htempWalk1=(TH1D*)gDirectory->FindObjectAny(
217 Form(
"Cor_SmT%01d_sm%03d_rpc%03d_Ch%03d_S1_Walk_px", iSmType, iSm, iRpc, iCh ));
218 if(NULL != htempWalk0 && NULL != htempWalk1 ) {
219 LOG(info)<<
"Initialize Walk correction for "
220 <<Form(
" SmT%01d_sm%03d_rpc%03d_Ch%03d",iSmType, iSm, iRpc, iCh)
223 LOG(error)<<
"CbmTofSimpClusterizer::InitCalibParameter: Inconsistent Walk histograms"
227 fvCPWalk[iSmType][iSm*iNbRpc+iRpc][iCh][0][iBin]=htempWalk0->GetBinContent(iBin+1);
228 fvCPWalk[iSmType][iSm*iNbRpc+iRpc][iCh][1][iBin]=htempWalk1->GetBinContent(iBin+1);
229 LOG(debug1)<<Form(
" SmT%01d_sm%03d_rpc%03d_Ch%03d bin %d walk %f ",iSmType, iSm, iRpc, iCh, iBin,
230 fvCPWalk[iSmType][iSm*iNbRpc+iRpc][iCh][0][iBin])
238 LOG(error)<<
" Histos " << Form(
"cl_SmT%01d_sm%03d_rpc%03d_XXX", iSmType, iSm, iRpc) <<
" not found. "
241 for(Int_t iTrg=0; iTrg<
iNTrg; iTrg++){
242 TH1D *htmpDelTof =(TH1D*) gDirectory->FindObjectAny( Form(
"cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof",iSmType,iSm,iRpc,iTrg));
243 if (NULL==htmpDelTof) {
244 LOG(info)<<
" Histos " << Form(
"cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof", iSmType, iSm, iRpc, iTrg) <<
" not found. "
248 LOG(info)<<
" Load DelTof from histos "<< Form(
"cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof",iSmType,iSm,iRpc,iTrg)<<
"."
251 fvCPDelTof[iSmType][iSm*iNbRpc+iRpc][iBx][iTrg] += htmpDelTof->GetBinContent(iBx+1);
255 TDirectory * curdir = gDirectory;
256 gDirectory->cd( oldir->GetPath() );
257 TH1D *h1DelTof=(TH1D *)htmpDelTof->Clone(Form(
"cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof",iSmType,iSm,iRpc,iTrg));
259 LOG(info)<<
" copy histo "
260 <<h1DelTof->GetName()
265 gDirectory->cd( curdir->GetPath() );
275 LOG(info) <<
"CbmTofSimpClusterizer::InitCalibParameter: initialization done";
285 if (0 ==
fDigiBdfPar) LOG(fatal) <<
"No CbmTofDigiBdfPar found";
287 FairRootManager* ioman = FairRootManager::Instance();
289 if (0 == ioman) LOG(fatal) <<
"No FairRootManager";
291 fTofDigis =
static_cast<TClonesArray*
>(ioman->GetObject(
"TofDigiExp"));
293 if (0 ==
fTofDigis) LOG(fatal) <<
"No TofDigi array found";
296 Bool_t isSimulation = kFALSE;
299 switch (iGeoVersion) {
304 default: LOG(fatal) <<
"Invalid geometry!!";
310 for (Int_t icell = 0; icell < iNrOfCells; ++icell) {
331 LOG(info) <<
"Number of supermodule types is " << iNbSmTypes;
333 for (Int_t iSmType = 0; iSmType < iNbSmTypes; ++iSmType) {
337 LOG(info) <<
"For the supermodule with the type: " << iSmType
338 <<
", the number of such supermodules is: " << iNbSm
339 <<
", and the number of Rpc is: " << iNbRpc;
341 for (Int_t iSm = 0; iSm < iNbSm; ++iSm) {
342 for (Int_t iRpc = 0; iRpc < iNbRpc; ++iRpc) {
344 fStorDigiExp[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
350 new TH1F(
"deltaChannelTHisto",
"deltaChannelTHisto", 100, 0., 10.);
352 new TH1F(
"deltaPointTHisto",
"deltaPointTHisto", 100, 0., 1.);
354 new TH1F(
"nofChannelsTHisto",
"nofChannelsTHisto", 20, 0., 20.);
356 new TH1F(
"digiTimeHisto",
"digiTimeHisto", 10100, -100., 10000.);
358 fTofHits =
new TClonesArray(
"CbmTofHit");
360 "TofHit",
"Tof",
fTofHits, IsOutputBranchPersistent(
"TofHit"));
362 ioman->Register(
"TofDigiMatch",
365 IsOutputBranchPersistent(
"TofDigiMatch"));
371 FairRunAna* ana = FairRunAna::Instance();
372 FairRuntimeDb* rtdb = ana->GetRuntimeDb();
379 static void AddPts(set<pair<Int_t, Int_t>>& sPtsRef,
380 const CbmTofDigiExp* digi) {
385 for (
int i = 0;
i < nofLinks; ++
i) {
396 clock_gettime(CLOCK_REALTIME, &ts);
397 long beginTime = ts.tv_sec * 1000000000 + ts.tv_nsec;
401 Double_t dEventTime = 0.;
403 LOG(debug) << GetName() <<
": Input " << iInputNr <<
", event " << iEventNr
404 <<
", event time " << dEventTime <<
" ns";
411 Double_t dMaxPairTimeDist = 3.2;
412 Double_t dMaxClustTimeDist = 0.2;
414 Int_t iNbTofDigi =
fTofDigis->GetEntries();
416 LOG(debug) << GetName() <<
": Input " << iInputNr <<
", event " << iEventNr
417 <<
", event time " << dEventTime <<
" ns"
418 <<
", TOF digis: " << iNbTofDigi;
488 for (Int_t iDigInd = 0; iDigInd < iNbTofDigi; ++iDigInd) {
489 CbmTofDigiExp* pDigi =
static_cast<CbmTofDigiExp*
>(
fTofDigis->At(iDigInd));
490 LOG(debug) << GetName() <<
": digi " << iDigInd <<
" pointer " << pDigi;
493 if (0 == pDigi->GetSide()) {
494 LOG(debug) <<
"top side";
495 LOG(debug) <<
"Type" << pDigi->GetType();
496 LOG(debug) <<
"RPC" << pDigi->GetRpc();
497 LOG(debug) <<
"Channel" << pDigi->GetChannel();
498 LOG(debug) <<
"Time" << pDigi->GetTime();
499 LOG(debug) <<
"SM " << pDigi->GetSm();
501 Int_t type = pDigi->GetType();
502 Int_t superModule = pDigi->GetSm();
503 Int_t rpc = pDigi->GetRpc();
505 Int_t channel = pDigi->GetChannel();
506 Double_t time = pDigi->GetTime();
508 Int_t index2 = superModule * nofRpc;
509 Int_t index3 = channel;
510 LOG(debug) <<
"Index 1 " << index1;
511 LOG(debug) <<
"Index 2 " << index2;
512 LOG(debug) <<
"Index 2 " << index3;
516 LOG(debug) <<
"Size 3 " <<
fStorDigiExp[index1][index2].size();
521 + pDigi->GetRpc()][pDigi->GetChannel()]
522 .topDigis[pDigi->GetTime()] = {pDigi, iDigInd};
523 LOG(debug) <<
"done";
525 LOG(debug) <<
"bottom side";
528 + pDigi->GetRpc()][pDigi->GetChannel()]
529 .bottomDigis[pDigi->GetTime()] = {pDigi, iDigInd};
592 LOG(debug) << GetName() <<
": TOF digis sorted";
594 Double_t hitpos_local[3];
599 for (Int_t iSmType = 0; iSmType < iNbSmTypes; ++iSmType) {
600 vector<vector<ChannelDigis>>& digisOfType =
fStorDigiExp[iSmType];
604 for (Int_t iSm = 0; iSm < iNbSm; ++iSm) {
605 for (Int_t iRpc = 0; iRpc < iNbRpc; ++iRpc) {
606 vector<ChannelDigis>& digisOfRpc =
611 for (Int_t iCh = 0; iCh < iNbCh; ++iCh) {
613 map<Double_t, ChannelDigis::DigiDesc>& topDigis =
615 map<Double_t, ChannelDigis::DigiDesc>& bottomDigis =
618 if (bottomDigis.empty()) {
623 map<Double_t, ChannelDigis::DigiPair>& digiPairs =
626 for (map<Double_t, ChannelDigis::DigiDesc>::iterator topDigiIter =
628 topDigiIter != topDigis.end();
630 Double_t topTime = topDigiIter->first;
631 map<Double_t, ChannelDigis::DigiDesc>::iterator bottomDigiIter =
632 bottomDigis.lower_bound(topTime);
634 if (bottomDigiIter == bottomDigis.end())
636 else if (bottomDigiIter->first > topTime) {
637 Double_t deltaT = bottomDigiIter->first - topTime;
639 if (deltaT > dMaxPairTimeDist
640 && bottomDigiIter != bottomDigis.begin())
643 map<Double_t, ChannelDigis::DigiDesc>::iterator
644 bottomDigiIter2 = bottomDigiIter;
647 Double_t deltaT2 = topTime - bottomDigiIter2->first;
649 if (deltaT2 < deltaT) bottomDigiIter = bottomDigiIter2;
653 if (TMath::Abs(bottomDigiIter->first - topTime) > dMaxPairTimeDist)
657 * (bottomDigiIter->first - topTime) / 2;
667 Double_t digiPairTime = (topTime + bottomDigiIter->first) / 2;
668 digiPairs[digiPairTime] = {
669 y, topDigiIter->second, bottomDigiIter->second};
676 gGeoManager->FindNode(
678 gGeoManager->GetCurrentMatrix();
680 gGeoManager->GetCurrentMatrix();
682 for (Int_t iCh = 0; iCh < iNbCh; ++iCh)
684 map<Double_t, ChannelDigis::DigiPair>& digiPairs =
685 digisOfRpc[iCh].digiPairs;
687 for (map<Double_t, ChannelDigis::DigiPair>::iterator chIter =
689 chIter != digiPairs.end();
691 Double_t chTime = chIter->first;
692 Double_t chY = chIter->second.y;
693 Double_t dTotS = chIter->second.topDigi.pDigi->GetTot()
694 + chIter->second.bottomDigi.pDigi->GetTot();
695 Double_t dWeightedTime = chTime * dTotS;
696 Double_t dWeightedPosY = chY * dTotS;
697 Double_t dWeightedPosX =
699 Double_t dWeightedTimeErrorS =
700 chIter->second.topDigi.pDigi->GetTot()
701 * chIter->second.topDigi.pDigi->GetTot()
702 + chIter->second.bottomDigi.pDigi->GetTot()
703 * chIter->second.bottomDigi.pDigi->GetTot();
704 Double_t dWeightsSum = dTotS;
707 CbmLink(0., chIter->second.topDigi.digiInd, iEventNr, iInputNr));
709 0., chIter->second.bottomDigi.digiInd, iEventNr, iInputNr));
710 set<pair<Int_t, Int_t>> sPtsRef;
711 AddPts(sPtsRef, chIter->second.topDigi.pDigi);
712 AddPts(sPtsRef, chIter->second.bottomDigi.pDigi);
714 for (Int_t iNeighCh = iCh + 1;
717 map<Double_t, ChannelDigis::DigiPair>& neighDigiPairs =
718 digisOfRpc[iNeighCh].digiPairs;
720 if (neighDigiPairs.empty())
break;
722 map<Double_t, ChannelDigis::DigiPair>::iterator neighIter =
723 neighDigiPairs.lower_bound(chTime);
725 if (neighIter == neighDigiPairs.end())
727 else if (neighIter->first > chTime
728 && neighIter != neighDigiPairs.begin()) {
729 Double_t deltaTHigh = neighIter->first - chTime;
730 map<Double_t, ChannelDigis::DigiPair>::iterator neighIter_1 =
733 Double_t deltaTLow = chTime - neighIter_1->first;
735 if (deltaTLow < deltaTHigh) neighIter = neighIter_1;
738 if (TMath::Abs(neighIter->first - chTime) > dMaxClustTimeDist
739 || TMath::Abs(neighIter->second.y - chY) > dMaxSpaceDist)
742 Double_t dTotNeighS =
743 neighIter->second.topDigi.pDigi->GetTot()
744 + neighIter->second.bottomDigi.pDigi->GetTot();
745 dWeightedTimeErrorS +=
746 neighIter->second.topDigi.pDigi->GetTot()
747 * neighIter->second.topDigi.pDigi->GetTot()
748 + neighIter->second.bottomDigi.pDigi->GetTot()
749 * neighIter->second.bottomDigi.pDigi->GetTot();
750 dWeightedTime += neighIter->first * dTotNeighS;
751 dWeightedPosY += neighIter->second.y * dTotNeighS;
752 dWeightedPosX += (iNeighCh - Double_t(iNbCh) / 2)
754 dWeightsSum += dTotNeighS;
757 0., neighIter->second.topDigi.digiInd, iEventNr, iInputNr));
759 0., neighIter->second.bottomDigi.digiInd, iEventNr, iInputNr));
760 AddPts(sPtsRef, neighIter->second.topDigi.pDigi);
761 AddPts(sPtsRef, neighIter->second.bottomDigi.pDigi);
762 neighDigiPairs.erase(neighIter);
765 Double_t clusterTime = dWeightedTime / dWeightsSum;
767 Double_t clusterTimeError =
768 TMath::Sqrt(dWeightedTimeErrorS) * timeRes / dWeightsSum;
769 Double_t clusterY = dWeightedPosY / dWeightsSum;
770 Double_t clusterX = dWeightedPosX / dWeightsSum;
771 hitpos_local[0] = clusterX;
772 hitpos_local[1] = clusterY;
777 gGeoManager->LocalToMaster(hitpos_local, hitpos);
778 TVector3 hitPos(hitpos[0], hitpos[1], hitpos[2]);
792 Int_t iChm = floor((clusterX + Double_t(iNbCh) / 2)
806 ->SetTimeError(clusterTimeError);
807 new ((*fTofDigiMatchs)[fiNbHits])
CbmMatch(*digiMatch);
819 clock_gettime(CLOCK_REALTIME, &ts);
820 long endTime = ts.tv_sec * 1000000000 + ts.tv_nsec;
825 TFile* curFile = TFile::CurrentFile();
826 TString histoName = histo->GetName();
827 histoName +=
".root";
828 TFile fh(histoName.Data(),
"RECREATE");
832 TFile::CurrentFile() = curFile;
840 cout <<
"ToF Time Based clustering runtime: " <<
fullDuration << endl;
845 Double_t& eventTime) {
848 if (FairRunAna::Instance()) {
849 FairEventHeader*
event = FairRunAna::Instance()->GetEventHeader();
850 inputNr =
event->GetInputFileId();
851 eventNr =
event->GetMCEntryNumber();
852 eventTime =
event->GetEventTime();
858 if (!FairRunSim::Instance())
859 LOG(fatal) << GetName() <<
": neither SIM nor ANA run.";
860 FairMCEventHeader*
event = FairRunSim::Instance()->GetMCEventHeader();
862 eventNr =
event->GetEventID();