CbmRoot
Loading...
Searching...
No Matches
CbmTofTBClusterizer.cxx
Go to the documentation of this file.
1/* Copyright (C) 2017-2021 Facility for Antiproton and Ion Research in Europe, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Pierre-Alain Loizeau [committer] */
4
5/*
6 * To change this license header, choose License Headers in Project Properties.
7 * To change this template file, choose Tools | Templates
8 * and open the template in the editor.
9 */
10
11#include "CbmTofTBClusterizer.h"
12
13#include "CbmDefs.h"
14#include "CbmMatch.h"
15#include "CbmTofGeoHandler.h"
16#include "CbmTofHit.h"
17#include "CbmTofPoint.h"
18#include "FairEventHeader.h"
19#include "FairMCEventHeader.h"
20#include "FairRunAna.h"
21#include "FairRunSim.h"
22#include "FairRuntimeDb.h"
23#include "TClonesArray.h"
24#include "TGeoManager.h"
25#include "TH1.h"
26
27#include <Logger.h>
28
29#ifdef __MACH__
30#include <mach/mach_time.h>
31#include <sys/time.h>
32#ifndef CLOCK_REALTIME
33#define CLOCK_REALTIME 0
34#endif
35#ifndef CLOCK_MONOTONIC
36#define CLOCK_MONOTONIC 0
37#endif
38inline int clock_gettime(int clk_id, struct timespec* t)
39{
40 mach_timebase_info_data_t timebase;
41 mach_timebase_info(&timebase);
42 uint64_t time;
43 time = mach_absolute_time();
44 double nseconds = ((double) time * (double) timebase.numer) / ((double) timebase.denom);
45 double seconds = ((double) time * (double) timebase.numer) / ((double) timebase.denom * 1e9);
46 t->tv_sec = seconds;
47 t->tv_nsec = nseconds;
48 return 0;
49}
50#else
51#include <time.h>
52#endif
53
55
56 const Int_t nbClWalkBinX = 20;
57const Int_t nbClDelTofBinX = 50;
58const Int_t iNTrg = 1;
59extern Double_t TOTMax;
60extern Double_t TOTMin;
61
62using std::cout;
63using std::endl;
64using std::list;
65using std::map;
66using std::pair;
67using std::set;
68using std::vector;
69
71 : fGeoHandler(0)
72 , fTofId(0)
73 , fDigiPar(0)
74 , fChannelInfo(0)
75 , fDigiBdfPar(0)
76 , fvCPSigPropSpeed()
77 , fvCPDelTof()
78 , fvCPTOff()
79 , fvCPTotGain()
80 , fvCPWalk()
81 , fTofDigis(0)
82 , fTofPoints(0)
83 , fTofHits(0)
84 , fTofDigiMatchs(0)
85 , fStorDigiExp()
86 , fStorDigiExpOld()
87 , fOutTimeFactor(1)
88{
89}
90
92{
93 // dimension and initialize calib parameter
94 //
95 Int_t iNbSmTypes = fDigiBdfPar->GetNbSmTypes();
96
97 fvCPSigPropSpeed.resize(iNbSmTypes);
98 for (Int_t iT = 0; iT < iNbSmTypes; iT++) {
99 Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iT);
100 fvCPSigPropSpeed[iT].resize(iNbRpc);
101 for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++)
102 if (0.0 < fDigiBdfPar->GetSigVel(iT, 0, iRpc))
103 fvCPSigPropSpeed[iT][iRpc] = /*1000.0 * */ fDigiBdfPar->GetSigVel(iT, 0, iRpc); // convert in cm/ns
104 else
106 } // for (Int_t iT=0; iT<iNbSmTypes; iT++)
107
108 fvCPTOff.resize(iNbSmTypes);
109 fvCPTotGain.resize(iNbSmTypes);
110 fvCPWalk.resize(iNbSmTypes);
111 fvCPDelTof.resize(iNbSmTypes);
112 for (Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++) {
113 Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
114 Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
115 fvCPTOff[iSmType].resize(iNbSm * iNbRpc);
116 fvCPTotGain[iSmType].resize(iNbSm * iNbRpc);
117 fvCPWalk[iSmType].resize(iNbSm * iNbRpc);
118 fvCPDelTof[iSmType].resize(iNbSm * iNbRpc);
119 for (Int_t iSm = 0; iSm < iNbSm; iSm++) {
120 for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++) {
121 // LOG(info)<<Form(" fvCPDelTof resize for SmT %d, R %d, B %d ",iSmType,iNbSm*iNbRpc,nbClDelTofBinX)
122 // ;
123 fvCPDelTof[iSmType][iSm * iNbRpc + iRpc].resize(nbClDelTofBinX);
124 for (Int_t iBx = 0; iBx < nbClDelTofBinX; iBx++) {
125 // LOG(info)<<Form(" fvCPDelTof for SmT %d, R %d, B %d",iSmType,iSm*iNbRpc+iRpc,iBx);
126 fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx].resize(iNTrg);
127 for (Int_t iTrg = 0; iTrg < iNTrg; iTrg++)
128 fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx][iTrg] = 0.; // initialize
129 }
130
131 Int_t iNbChan = fDigiBdfPar->GetNbChan(iSmType, iRpc);
132 fvCPTOff[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
133 fvCPTotGain[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
134 fvCPWalk[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
135 Int_t nbSide = 2 - fDigiBdfPar->GetChanType(iSmType, iRpc);
136 for (Int_t iCh = 0; iCh < iNbChan; iCh++) {
137 fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
138 fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
139 fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
140 for (Int_t iSide = 0; iSide < nbSide; iSide++) {
141 fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] = 0.; //initialize
142 fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] = 1.; //initialize
143 fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][iSide].resize(nbClWalkBinX);
144 for (Int_t iWx = 0; iWx < nbClWalkBinX; iWx++) {
145 fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][iSide][iWx] = 0.;
146 }
147 }
148 }
149 }
150 }
151 }
152
153 LOG(info) << "CbmTofSimpClusterizer::InitCalibParameter: defaults set";
154
156 // <= To prevent histos from being sucked in by the param file of the TRootManager!
157 TFile* oldFile = gFile;
158 TDirectory* oldDir = gDirectory;
159
160#if 0
161 if(0<fCalMode){
162 LOG(info) << "CbmTofSimpClusterizer::InitCalibParameter: read histos from "
163 << "file " << fCalParFileName ;
164
165 // read parameter from histos
166 if(fCalParFileName.IsNull()) return kTRUE;
167
168 fCalParFile = new TFile(fCalParFileName,"");
169 if(NULL == fCalParFile) {
170 LOG(error) << "CbmTofSimpClusterizer::InitCalibParameter: "
171 << "file " << fCalParFileName << " does not exist!" ;
172 return kTRUE;
173 }
174 /*
175 gDirectory->Print();
176 fCalParFile->cd();
177 fCalParFile->ls();
178 */
179
180 for( Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++ )
181 {
182 Int_t iNbSm = fDigiBdfPar->GetNbSm( iSmType );
183 Int_t iNbRpc = fDigiBdfPar->GetNbRpc( iSmType );
184 for( Int_t iSm = 0; iSm < iNbSm; iSm++ )
185 for( Int_t iRpc = 0; iRpc < iNbRpc; iRpc++ )
186 {
187 TH2F *htempPos_pfx =(TH2F*) gDirectory->FindObjectAny( Form("cl_CorSmT%01d_sm%03d_rpc%03d_Pos_pfx",iSmType,iSm,iRpc));
188 TH2F *htempTOff_pfx=(TH2F*) gDirectory->FindObjectAny( Form("cl_CorSmT%01d_sm%03d_rpc%03d_TOff_pfx",iSmType,iSm,iRpc));
189 TH2F *htempTot_pfx =(TH2F*) gDirectory->FindObjectAny( Form("cl_CorSmT%01d_sm%03d_rpc%03d_Tot_pfx",iSmType,iSm,iRpc));
190 if(NULL != htempPos_pfx && NULL != htempTOff_pfx && NULL != htempTot_pfx)
191 {
192 Int_t iNbCh = fDigiBdfPar->GetNbChan( iSmType, iRpc );
193 Int_t iNbinTot = htempTot_pfx->GetNbinsX();
194 for( Int_t iCh = 0; iCh < iNbCh; iCh++ )
195 {
196 Double_t YMean=((TProfile *)htempPos_pfx)->GetBinContent(iCh+1); //nh +1 empirical(?)
197 Double_t TMean=((TProfile *)htempTOff_pfx)->GetBinContent(iCh+1);
198 Double_t dTYOff=YMean/fvCPSigPropSpeed[iSmType][iRpc] ;
199 fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][0] += -dTYOff + TMean ;
200 fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][1] += +dTYOff + TMean ;
201
202 Double_t TotMean=((TProfile *)htempTot_pfx)->GetBinContent(iCh+1); //nh +1 empirical(?)
203 if(1<TotMean){
204 fvCPTotGain[iSmType][iSm*iNbRpc+iRpc][iCh][0] *= TTotMean / TotMean;
205 fvCPTotGain[iSmType][iSm*iNbRpc+iRpc][iCh][1] *= TTotMean / TotMean;
206 }
207 LOG(debug1)<<"CbmTofSimpClusterizer::InitCalibParameter:"
208 <<" SmT "<< iSmType<<" Sm "<<iSm<<" Rpc "<<iRpc<<" Ch "<<iCh
209 <<": YMean "<<YMean<<", TMean "<< TMean
210 <<" -> " << fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][0]
211 <<", " << fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][1]
212 <<", " << fvCPTotGain[iSmType][iSm*iNbRpc+iRpc][iCh][0]
213 <<", NbinTot "<< iNbinTot
214 ;
215
216 TH1D *htempWalk0=(TH1D*)gDirectory->FindObjectAny(
217 Form("Cor_SmT%01d_sm%03d_rpc%03d_Ch%03d_S0_Walk_px", iSmType, iSm, iRpc, iCh ));
218 TH1D *htempWalk1=(TH1D*)gDirectory->FindObjectAny(
219 Form("Cor_SmT%01d_sm%03d_rpc%03d_Ch%03d_S1_Walk_px", iSmType, iSm, iRpc, iCh ));
220 if(NULL != htempWalk0 && NULL != htempWalk1 ) { // reinitialize Walk array
221 LOG(info)<<"Initialize Walk correction for "
222 <<Form(" SmT%01d_sm%03d_rpc%03d_Ch%03d",iSmType, iSm, iRpc, iCh)
223 ;
224 if(htempWalk0->GetNbinsX() != nbClWalkBinX)
225 LOG(error)<<"CbmTofSimpClusterizer::InitCalibParameter: Inconsistent Walk histograms"
226 ;
227 for( Int_t iBin = 0; iBin < nbClWalkBinX; iBin++ )
228 {
229 fvCPWalk[iSmType][iSm*iNbRpc+iRpc][iCh][0][iBin]=htempWalk0->GetBinContent(iBin+1);
230 fvCPWalk[iSmType][iSm*iNbRpc+iRpc][iCh][1][iBin]=htempWalk1->GetBinContent(iBin+1);
231 LOG(debug1)<<Form(" SmT%01d_sm%03d_rpc%03d_Ch%03d bin %d walk %f ",iSmType, iSm, iRpc, iCh, iBin,
232 fvCPWalk[iSmType][iSm*iNbRpc+iRpc][iCh][0][iBin])
233 ;
234
235 }
236 }
237 }
238 }
239 else {
240 LOG(error)<<" Histos " << Form("cl_SmT%01d_sm%03d_rpc%03d_XXX", iSmType, iSm, iRpc) << " not found. "
241 ;
242 }
243 for(Int_t iTrg=0; iTrg<iNTrg; iTrg++){
244 TH1D *htmpDelTof =(TH1D*) gDirectory->FindObjectAny( Form("cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof",iSmType,iSm,iRpc,iTrg));
245 if (NULL==htmpDelTof) {
246 LOG(info)<<" Histos " << Form("cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof", iSmType, iSm, iRpc, iTrg) << " not found. "
247 ;
248 continue;
249 }
250 LOG(info)<<" Load DelTof from histos "<< Form("cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof",iSmType,iSm,iRpc,iTrg)<<"."
251 ;
252 for(Int_t iBx=0; iBx<nbClDelTofBinX; iBx++){
253 fvCPDelTof[iSmType][iSm*iNbRpc+iRpc][iBx][iTrg] += htmpDelTof->GetBinContent(iBx+1);
254 }
255
256 // copy Histo to memory
257 TDirectory * curdir = gDirectory;
258 gDirectory->cd( oldDir->GetPath() );
259 TH1D *h1DelTof=(TH1D *)htmpDelTof->Clone(Form("cl_CorSmT%01d_sm%03d_rpc%03d_Trg%02d_DelTof",iSmType,iSm,iRpc,iTrg));
260
261 LOG(info)<<" copy histo "
262 <<h1DelTof->GetName()
263 <<" to directory "
264 <<oldDir->GetName()
265 ;
266
267 gDirectory->cd( curdir->GetPath() );
268 }
269 }
270 }
271 }
272#endif //0
273 // fCalParFile->Delete();
275 // <= To prevent histos from being sucked in by the param file of the TRootManager!
276 gFile = oldFile;
277 gDirectory = oldDir;
278 LOG(info) << "CbmTofSimpClusterizer::InitCalibParameter: initialization done";
279 return kTRUE;
280}
281
282static TH1F* deltaChannelTHisto = 0;
283static TH1F* deltaPointTHisto = 0;
284static TH1F* nofChannelsTHisto = 0;
285static TH1F* digiTimeHisto = 0;
286
288{
289 if (0 == fDigiBdfPar) LOG(fatal) << "No CbmTofDigiBdfPar found";
290
291 FairRootManager* ioman = FairRootManager::Instance();
292
293 if (0 == ioman) LOG(fatal) << "No FairRootManager";
294
295 fTofDigis = static_cast<TClonesArray*>(ioman->GetObject("TofDigiExp"));
296
297 if (0 == fTofDigis) LOG(fatal) << "No TofDigi array found";
298
300 Bool_t isSimulation = kFALSE;
301 Int_t iGeoVersion = fGeoHandler->Init(isSimulation);
302
303 switch (iGeoVersion) {
304 case k12b: fTofId = new CbmTofDetectorId_v12b(); break;
305
306 case k14a: fTofId = new CbmTofDetectorId_v14a(); break;
307
308 default: LOG(fatal) << "Invalid geometry!!";
309 }
310
311 Int_t iNrOfCells = fDigiPar->GetNrOfModules();
313
314 for (Int_t icell = 0; icell < iNrOfCells; ++icell) {
315 Int_t cellId = fDigiPar->GetCellId(icell); // cellId is assigned in CbmTofCreateDigiPar
316 fChannelInfo = fDigiPar->GetCell(cellId);
317
318 Int_t smtype = fGeoHandler->GetSMType(cellId);
319 Int_t smodule = fGeoHandler->GetSModule(cellId);
320 Int_t module = fGeoHandler->GetCounter(cellId);
321 Int_t cell = fGeoHandler->GetCell(cellId);
322
323 Double_t x = fChannelInfo->GetX();
324 Double_t y = fChannelInfo->GetY();
325 Double_t z = fChannelInfo->GetZ();
326 Double_t dx = fChannelInfo->GetSizex();
327 Double_t dy = fChannelInfo->GetSizey();
328 }
329
330 if (!InitCalibParameter()) LOG(fatal) << "Failed to read calib parameters";
331
332 Int_t iNbSmTypes = fDigiBdfPar->GetNbSmTypes();
333 fStorDigiExp.resize(iNbSmTypes);
334 LOG(info) << "Number of supermodule types is " << iNbSmTypes;
335
336 for (Int_t iSmType = 0; iSmType < iNbSmTypes; ++iSmType) {
337 Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
338 Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
339 fStorDigiExp[iSmType].resize(iNbSm * iNbRpc);
340 LOG(info) << "For the supermodule with the type: " << iSmType << ", the number of such supermodules is: " << iNbSm
341 << ", and the number of Rpc is: " << iNbRpc;
342
343 for (Int_t iSm = 0; iSm < iNbSm; ++iSm) {
344 for (Int_t iRpc = 0; iRpc < iNbRpc; ++iRpc) {
345 Int_t iNbChan = fDigiBdfPar->GetNbChan(iSmType, iRpc);
346 fStorDigiExp[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
347 }
348 }
349 }
350
351 deltaChannelTHisto = new TH1F("deltaChannelTHisto", "deltaChannelTHisto", 100, 0., 10.);
352 deltaPointTHisto = new TH1F("deltaPointTHisto", "deltaPointTHisto", 100, 0., 1.);
353 nofChannelsTHisto = new TH1F("nofChannelsTHisto", "nofChannelsTHisto", 20, 0., 20.);
354 digiTimeHisto = new TH1F("digiTimeHisto", "digiTimeHisto", 10100, -100., 10000.);
355
356 fTofHits = new TClonesArray("CbmTofHit");
357 ioman->Register("TofHit", "Tof", fTofHits, IsOutputBranchPersistent("TofHit"));
358 fTofDigiMatchs = new TClonesArray("CbmMatch", 100);
359 ioman->Register("TofDigiMatch", "Tof", fTofDigiMatchs, IsOutputBranchPersistent("TofDigiMatch"));
360
361 return kSUCCESS;
362}
363
365{
366 FairRunAna* ana = FairRunAna::Instance();
367 FairRuntimeDb* rtdb = ana->GetRuntimeDb();
368
369 fDigiPar = static_cast<CbmTofDigiPar*>(rtdb->getContainer("CbmTofDigiPar"));
370 fDigiBdfPar = static_cast<CbmTofDigiBdfPar*>(rtdb->getContainer("CbmTofDigiBdfPar"));
371}
372
373static void AddPts(set<pair<Int_t, Int_t>>& sPtsRef, const CbmTofDigiExp* digi)
374{
375 CbmMatch* match = digi->GetMatch();
376 assert(match);
377 Int_t nofLinks = match->GetNofLinks();
378
379 for (int i = 0; i < nofLinks; ++i) {
380 const CbmLink& link = match->GetLink(i);
381 sPtsRef.insert(pair<Int_t, Int_t>(link.GetEntry(), link.GetIndex()));
382 }
383}
384
385static Int_t currentEvN = 0;
386static long fullDuration = 0;
387
388void CbmTofTBClusterizer::Exec(Option_t* option)
389{
390 timespec ts;
391 clock_gettime(CLOCK_REALTIME, &ts);
392 long beginTime = ts.tv_sec * 1000000000 + ts.tv_nsec;
393 // --- MC Event info (input file, entry number, start time)
394 Int_t iInputNr = 0;
395 Int_t iEventNr = 0;
396 Double_t dEventTime = 0.;
397 GetEventInfo(iInputNr, iEventNr, dEventTime);
398 LOG(debug) << GetName() << ": Input " << iInputNr << ", event " << iEventNr << ", event time " << dEventTime << " ns";
399
400 fTofHits->Clear("C");
401 //fTofHits->Delete();
402 fTofDigiMatchs->Delete();
403 //fTofDigiMatchs->Clear("C");
404 //Double_t dMaxTimeDist = fDigiBdfPar->GetMaxTimeDist();
405 Double_t dMaxPairTimeDist = 3.2;
406 Double_t dMaxClustTimeDist = 0.2;
407 Double_t dMaxSpaceDist = fDigiBdfPar->GetMaxDistAlongCh();
408 Int_t iNbTofDigi = fTofDigis->GetEntriesFast();
409
410 LOG(debug) << GetName() << ": Input " << iInputNr << ", event " << iEventNr << ", event time " << dEventTime << " ns"
411 << ", TOF digis: " << iNbTofDigi;
412 /*map<pair<Int_t, Int_t>, list<Int_t> > tofPointDigiInds;
413
414 Int_t nofTofPoints = fTofPoints->GetEntriesFast();
415
416 for(Int_t iDigInd = 0; iDigInd < iNbTofDigi; ++iDigInd)
417 {
418 CbmTofDigiExp* pDigi = static_cast<CbmTofDigiExp*> (fTofDigis->At(iDigInd));
419 const CbmMatch* pMatch = pDigi->GetMatch();
420 Int_t nofLinks = pMatch->GetNofLinks();
421
422 for (Int_t iLink = 0; iLink < nofLinks; ++iLink)
423 {
424 const CbmLink& link = pMatch->GetLink(iLink);
425 Int_t tpi = link.GetIndex();
426 Int_t tpe = link.GetEntry();
427
428 //if (tpi < nofTofPoints)
429 tofPointDigiInds[pair<Int_t, Int_t> (tpe, tpi)].push_back(iDigInd);
430 }
431 }
432
433 for (map<pair<Int_t, Int_t>, list<Int_t> >::const_iterator i = tofPointDigiInds.begin(); i != tofPointDigiInds.end(); ++i)
434 {
435 //const CbmTofPoint* pTofPoint = static_cast<const CbmTofPoint*> (fTofPoints->At(i->first));
436 const list<Int_t>& pointDigis = i->second;
437 set<Int_t> firedChannels;
438 map<Int_t, pair<Double_t, Double_t> > channelDigis;
439
440 for (list<Int_t>::const_iterator j = i->second.begin(); j != i->second.end(); ++j)
441 {
442 const CbmTofDigiExp* pTofDigi = static_cast<const CbmTofDigiExp*> (fTofDigis->At(*j));
443 firedChannels.insert(pTofDigi->GetChannel());
444
445 if (0 == pTofDigi->GetSide())
446 channelDigis[pTofDigi->GetChannel()].first = pTofDigi->GetTime();
447 else
448 channelDigis[pTofDigi->GetChannel()].second = pTofDigi->GetTime();
449
450 //Double_t deltaT = pTofDigi->GetTime() - pTofPoint->GetTime();
451 //deltaTHisto->Fill(deltaT);
452 }
453
454 Double_t minDigiTime = std::numeric_limits<Double_t>::max();
455 Double_t maxDigiTime = std::numeric_limits<Double_t>::min();
456
457 for (map<Int_t, pair<Double_t, Double_t> >::iterator j = channelDigis.begin(); j != channelDigis.end(); ++j)
458 {
459 if (0 == j->second.first || 0 == j->second.second)
460 continue;
461
462 Double_t channelDelta = TMath::Abs(j->second.first - j->second.second);
463 deltaChannelTHisto->Fill(channelDelta);
464 Double_t channelTime = (j->second.first + j->second.second) / 2;
465
466 if (channelTime < minDigiTime)
467 minDigiTime = channelTime;
468
469 if (channelTime > maxDigiTime)
470 maxDigiTime = channelTime;
471 }
472
473 if (maxDigiTime > minDigiTime)
474 deltaPointTHisto->Fill(maxDigiTime - minDigiTime);
475
476 nofChannelsTHisto->Fill(firedChannels.size());
477 }
478
479 return;*/
480
481 for (Int_t iDigInd = 0; iDigInd < iNbTofDigi; ++iDigInd) {
482 CbmTofDigiExp* pDigi = static_cast<CbmTofDigiExp*>(fTofDigis->At(iDigInd));
483 LOG(debug) << GetName() << ": digi " << iDigInd << " pointer " << pDigi;
484 digiTimeHisto->Fill(pDigi->GetTime());
485
486 if (0 == pDigi->GetSide()) { // 0 - top side
487 LOG(debug) << "top side";
488 LOG(debug) << "Type" << pDigi->GetType();
489 LOG(debug) << "RPC" << pDigi->GetRpc();
490 LOG(debug) << "Channel" << pDigi->GetChannel();
491 LOG(debug) << "Time" << pDigi->GetTime();
492 LOG(debug) << "SM " << pDigi->GetSm();
493 LOG(debug) << "NbRpc " << fDigiBdfPar->GetNbRpc(pDigi->GetType());
494 Int_t type = pDigi->GetType();
495 Int_t superModule = pDigi->GetSm();
496 Int_t rpc = pDigi->GetRpc();
497 Int_t nofRpc = fDigiBdfPar->GetNbRpc(type + rpc);
498 Int_t channel = pDigi->GetChannel();
499 Double_t time = pDigi->GetTime();
500 Int_t index1 = type;
501 Int_t index2 = superModule * nofRpc;
502 Int_t index3 = channel;
503 LOG(debug) << "Index 1 " << index1;
504 LOG(debug) << "Index 2 " << index2;
505 LOG(debug) << "Index 2 " << index3;
506
507 LOG(debug) << "Size 1 " << fStorDigiExp.size();
508 LOG(debug) << "Size 2 " << fStorDigiExp[index1].size();
509 LOG(debug) << "Size 3 " << fStorDigiExp[index1][index2].size();
510
511
512 fStorDigiExp[pDigi->GetType()][pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
513 [pDigi->GetChannel()]
514 .topDigis[pDigi->GetTime()] = {pDigi, iDigInd};
515 LOG(debug) << "done";
516 }
517 else {
518 LOG(debug) << "bottom side";
519 fStorDigiExp[pDigi->GetType()][pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
520 [pDigi->GetChannel()]
521 .bottomDigis[pDigi->GetTime()] = {pDigi, iDigInd};
522 }
523
524 // apply calibration vectors
525 /*pDigi->SetTime(pDigi->GetTime() - // calibrate Digi Time
526 fvCPTOff[pDigi->GetType()]
527 [pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
528 [pDigi->GetChannel()]
529 [pDigi->GetSide()]);
530
531 pDigi->SetTot(pDigi->GetTot() * // calibrate Digi ToT
532 fvCPTotGain[pDigi->GetType()]
533 [pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
534 [pDigi->GetChannel()]
535 [pDigi->GetSide()]);
536
537 // walk correction
538 Double_t dTotBinSize = (TOTMax - TOTMin) / 2. / nbClWalkBinX;
539 Int_t iWx = (Int_t) ((pDigi->GetTot() - TOTMin / 2.) / dTotBinSize);
540
541 if (0 > iWx)
542 iWx = 0;
543
544 if (iWx > nbClWalkBinX)
545 iWx = nbClWalkBinX - 1;
546
547 Double_t dDTot = (pDigi->GetTot() - TOTMin / 2.) / dTotBinSize - (Double_t) iWx - 0.5;
548 Double_t dWT = fvCPWalk[pDigi->GetType()]
549 [pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
550 [pDigi->GetChannel()]
551 [pDigi->GetSide()]
552 [iWx];
553
554 if (dDTot > 0)
555 { // linear interpolation to next bin
556 dWT += dDTot * (fvCPWalk[pDigi->GetType()]
557 [pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
558 [pDigi->GetChannel()]
559 [pDigi->GetSide()]
560 [iWx + 1]
561 - fvCPWalk[pDigi->GetType()]
562 [pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
563 [pDigi->GetChannel()]
564 [pDigi->GetSide()]
565 [iWx]);
566 }
567 else // dDTot < 0, linear interpolation to next bin
568 {
569 dWT -= dDTot * (fvCPWalk[pDigi->GetType()]
570 [pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
571 [pDigi->GetChannel()]
572 [pDigi->GetSide()]
573 [iWx - 1]
574 - fvCPWalk[pDigi->GetType()]
575 [pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
576 [pDigi->GetChannel()]
577 [pDigi->GetSide()]
578 [iWx]);
579 }
580
581 pDigi->SetTime(pDigi->GetTime() - dWT); // calibrate Digi Time*/
582 } // iDigiInd
583
584 LOG(debug) << GetName() << ": TOF digis sorted";
585
586 Double_t hitpos_local[3];
587 Double_t hitpos[3];
588 Int_t fiNbHits = 0;
589 Int_t iNbSmTypes = fDigiBdfPar->GetNbSmTypes();
590
591 for (Int_t iSmType = 0; iSmType < iNbSmTypes; ++iSmType) {
592 vector<vector<ChannelDigis>>& digisOfType = fStorDigiExp[iSmType];
593 Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
594 Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
595
596 for (Int_t iSm = 0; iSm < iNbSm; ++iSm) {
597 for (Int_t iRpc = 0; iRpc < iNbRpc; ++iRpc) {
598 vector<ChannelDigis>& digisOfRpc = digisOfType[iSm * fDigiBdfPar->GetNbRpc(iSmType) + iRpc];
599 Int_t iNbCh = fDigiBdfPar->GetNbChan(iSmType, iRpc);
600
601 // Vertical strips => Y comes from bottom top time difference
602 for (Int_t iCh = 0; iCh < iNbCh; ++iCh) {
603 ChannelDigis& digisOfChannel = digisOfRpc[iCh];
604 map<Double_t, ChannelDigis::DigiDesc>& topDigis = digisOfChannel.topDigis;
605 map<Double_t, ChannelDigis::DigiDesc>& bottomDigis = digisOfChannel.bottomDigis;
606
607 if (bottomDigis.empty()) {
608 topDigis.clear();
609 continue;
610 }
611
612 map<Double_t, ChannelDigis::DigiPair>& digiPairs = digisOfChannel.digiPairs;
613
614 for (map<Double_t, ChannelDigis::DigiDesc>::iterator topDigiIter = topDigis.begin();
615 topDigiIter != topDigis.end(); ++topDigiIter) {
616 Double_t topTime = topDigiIter->first;
617 map<Double_t, ChannelDigis::DigiDesc>::iterator bottomDigiIter = bottomDigis.lower_bound(topTime);
618
619 if (bottomDigiIter == bottomDigis.end())
620 --bottomDigiIter;
621 else if (bottomDigiIter->first > topTime) {
622 Double_t deltaT = bottomDigiIter->first - topTime;
623
624 if (deltaT > dMaxPairTimeDist && bottomDigiIter != bottomDigis.begin())
625 --bottomDigiIter;
626 else {
627 map<Double_t, ChannelDigis::DigiDesc>::iterator bottomDigiIter2 = bottomDigiIter;
628 --bottomDigiIter2;
629
630 Double_t deltaT2 = topTime - bottomDigiIter2->first;
631
632 if (deltaT2 < deltaT) bottomDigiIter = bottomDigiIter2;
633 }
634 }
635
636 if (TMath::Abs(bottomDigiIter->first - topTime) > dMaxPairTimeDist) continue;
637
638 Double_t y = fvCPSigPropSpeed[iSmType][iRpc] * (bottomDigiIter->first - topTime) / 2;
639
640 CbmTofDetectorInfo xDetInfo(kTof, iSmType, iSm, iRpc, 0, iCh);
641 Int_t iChId = fTofId->SetDetectorInfo(xDetInfo);
642 fChannelInfo = fDigiPar->GetCell(iChId);
643
644 if (0 == fChannelInfo) continue;
645
646 if (TMath::Abs(y) > fChannelInfo->GetSizey() / 2) continue;
647
648 Double_t digiPairTime = (topTime + bottomDigiIter->first) / 2;
649 digiPairs[digiPairTime] = {y, topDigiIter->second, bottomDigiIter->second};
650 } // for (map<Double_t, CbmTofDigiExp*>::iterator topDigiIter = topDigis.begin(); topDigiIter != topDigis.end(); ++topDigiIter)
651
652 topDigis.clear();
653 bottomDigis.clear();
654 } // for (Int_t iCh = 0; iCh < iNbCh; ++iCh)
655
656 gGeoManager->FindNode(fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
657 gGeoManager->GetCurrentMatrix();
658 gGeoManager->CdUp();
659 gGeoManager->GetCurrentMatrix();
660
661 for (Int_t iCh = 0; iCh < iNbCh; ++iCh) // 2
662 {
663 map<Double_t, ChannelDigis::DigiPair>& digiPairs = digisOfRpc[iCh].digiPairs;
664
665 for (map<Double_t, ChannelDigis::DigiPair>::iterator chIter = digiPairs.begin(); chIter != digiPairs.end();
666 ++chIter) {
667 Double_t chTime = chIter->first;
668 Double_t chY = chIter->second.y;
669 Double_t dTotS = chIter->second.topDigi.pDigi->GetTot() + chIter->second.bottomDigi.pDigi->GetTot();
670 Double_t dWeightedTime = chTime * dTotS;
671 Double_t dWeightedPosY = chY * dTotS;
672 Double_t dWeightedPosX = (iCh - Double_t(iNbCh) / 2) * fChannelInfo->GetSizex() * dTotS;
673 Double_t dWeightedTimeErrorS =
674 chIter->second.topDigi.pDigi->GetTot() * chIter->second.topDigi.pDigi->GetTot()
675 + chIter->second.bottomDigi.pDigi->GetTot() * chIter->second.bottomDigi.pDigi->GetTot();
676 Double_t dWeightsSum = dTotS;
677 CbmMatch* digiMatch = new CbmMatch;
678 digiMatch->AddLink(CbmLink(0., chIter->second.topDigi.digiInd, iEventNr, iInputNr));
679 digiMatch->AddLink(CbmLink(0., chIter->second.bottomDigi.digiInd, iEventNr, iInputNr));
680 set<pair<Int_t, Int_t>> sPtsRef;
681 AddPts(sPtsRef, chIter->second.topDigi.pDigi);
682 AddPts(sPtsRef, chIter->second.bottomDigi.pDigi);
683
684 for (Int_t iNeighCh = iCh + 1; iNeighCh < iNbCh /* && iNeighCh - iCh < 4*/; ++iNeighCh) {
685 map<Double_t, ChannelDigis::DigiPair>& neighDigiPairs = digisOfRpc[iNeighCh].digiPairs;
686
687 if (neighDigiPairs.empty()) break;
688
689 map<Double_t, ChannelDigis::DigiPair>::iterator neighIter = neighDigiPairs.lower_bound(chTime);
690
691 if (neighIter == neighDigiPairs.end())
692 --neighIter;
693 else if (neighIter->first > chTime && neighIter != neighDigiPairs.begin()) {
694 Double_t deltaTHigh = neighIter->first - chTime;
695 map<Double_t, ChannelDigis::DigiPair>::iterator neighIter_1 = neighIter;
696 --neighIter_1;
697 Double_t deltaTLow = chTime - neighIter_1->first;
698
699 if (deltaTLow < deltaTHigh) neighIter = neighIter_1;
700 }
701
702 if (TMath::Abs(neighIter->first - chTime) > dMaxClustTimeDist
703 || TMath::Abs(neighIter->second.y - chY) > dMaxSpaceDist)
704 break;
705
706 Double_t dTotNeighS =
707 neighIter->second.topDigi.pDigi->GetTot() + neighIter->second.bottomDigi.pDigi->GetTot();
708 dWeightedTimeErrorS +=
709 neighIter->second.topDigi.pDigi->GetTot() * neighIter->second.topDigi.pDigi->GetTot()
710 + neighIter->second.bottomDigi.pDigi->GetTot() * neighIter->second.bottomDigi.pDigi->GetTot();
711 dWeightedTime += neighIter->first * dTotNeighS;
712 dWeightedPosY += neighIter->second.y * dTotNeighS;
713 dWeightedPosX += (iNeighCh - Double_t(iNbCh) / 2) * fChannelInfo->GetSizex() * dTotNeighS;
714 dWeightsSum += dTotNeighS;
715
716 digiMatch->AddLink(CbmLink(0., neighIter->second.topDigi.digiInd, iEventNr, iInputNr));
717 digiMatch->AddLink(CbmLink(0., neighIter->second.bottomDigi.digiInd, iEventNr, iInputNr));
718 AddPts(sPtsRef, neighIter->second.topDigi.pDigi);
719 AddPts(sPtsRef, neighIter->second.bottomDigi.pDigi);
720 neighDigiPairs.erase(neighIter);
721 } // for (Int_t iNeighCh = iCh + 1; iNeighCh < iNbCh; ++iNeighCh)
722
723 Double_t clusterTime = dWeightedTime / dWeightsSum;
724 Double_t timeRes = fDigiBdfPar->GetFeeTimeRes();
725 Double_t clusterTimeError = TMath::Sqrt(dWeightedTimeErrorS) * timeRes / dWeightsSum;
726 Double_t clusterY = dWeightedPosY / dWeightsSum;
727 Double_t clusterX = dWeightedPosX / dWeightsSum;
728 hitpos_local[0] = clusterX;
729 hitpos_local[1] = clusterY;
730 hitpos_local[2] = 0;
731 hitpos[0] = 0;
732 hitpos[1] = 0;
733 hitpos[2] = 0;
734 gGeoManager->LocalToMaster(hitpos_local, hitpos);
735 TVector3 hitPos(hitpos[0], hitpos[1], hitpos[2]);
736 // Simple errors, not properly done at all for now
737 // Right way of doing it should take into account the weight distribution
738 // and real system time resolution
739 TVector3 hitPosErr(fChannelInfo->GetSizex() / sqrt(12.0), // Single strips approximation
741 * fvCPSigPropSpeed[iSmType][iRpc], // Use the electronics resolution
742 fDigiBdfPar->GetNbGaps(iSmType, iRpc) * fDigiBdfPar->GetGapSize(iSmType, iRpc) / 10.0
743 / // Change gap size in cm
744 sqrt(12.0)); // Use full RPC thickness as "Channel" Z size
745 Int_t iChm = floor((clusterX + Double_t(iNbCh) / 2) / fChannelInfo->GetSizex());
746 Int_t iDetId = CbmTofAddress::GetUniqueAddress(iSm, iRpc, iChm, 0, iSmType);
747 new ((*fTofHits)[fiNbHits]) CbmTofHit(iDetId, hitPos,
748 hitPosErr, //local detector coordinates
749 fiNbHits, clusterTime * fOutTimeFactor,
750 sPtsRef.size(), // flag = number of TofPoints generating the cluster
751 0);
752 static_cast<CbmTofHit*>(fTofHits->At(fiNbHits))->SetTimeError(clusterTimeError);
753 new ((*fTofDigiMatchs)[fiNbHits]) CbmMatch(*digiMatch);
754 delete digiMatch;
755 ++fiNbHits;
756 } // for (map<Double_t, pair<CbmTofDigiExp*, CbmTofDigiExp*> >::iterator chIter = digiPairs.begin(); chIter != digiPairs.end(); ++chIter)
757
758 digiPairs.clear();
759 } // for (Int_t iCh = 0; iCh < iNbCh; ++iCh) 2
760 } // for (Int_t iRpc = 0; iRpc < iNbRpc; ++iRpc)
761 } // for (Int_t iSm = 0; iSm < iNbSm; ++iSm)
762 } // for (Int_t iSmType = 0; iSmType < iNbSmTypes; ++iSmType)
763
764 ++currentEvN;
765 clock_gettime(CLOCK_REALTIME, &ts);
766 long endTime = ts.tv_sec * 1000000000 + ts.tv_nsec;
767 fullDuration += endTime - beginTime;
768}
769
770static void SaveHisto(TH1* histo)
771{
772 TFile* curFile = TFile::CurrentFile();
773 TString histoName = histo->GetName();
774 histoName += ".root";
775 TFile fh(histoName.Data(), "RECREATE");
776 histo->Write();
777 fh.Close();
778 delete histo;
779 TFile::CurrentFile() = curFile;
780}
781
783{
788 cout << "ToF Time Based clustering runtime: " << fullDuration << endl;
789}
790
791void CbmTofTBClusterizer::GetEventInfo(Int_t& inputNr, Int_t& eventNr, Double_t& eventTime)
792{
793
794 // --- In a FairRunAna, take the information from FairEventHeader
795 if (FairRunAna::Instance()) {
796 FairEventHeader* event = FairRunAna::Instance()->GetEventHeader();
797 inputNr = event->GetInputFileId();
798 eventNr = event->GetMCEntryNumber();
799 eventTime = event->GetEventTime();
800 }
801
802 // --- In a FairRunSim, the input number and event time are always zero;
803 // --- only the event number is retrieved.
804 else {
805 if (!FairRunSim::Instance()) LOG(fatal) << GetName() << ": neither SIM nor ANA run.";
806 FairMCEventHeader* event = FairRunSim::Instance()->GetMCEventHeader();
807 inputNr = 0;
808 eventNr = event->GetEventID();
809 eventTime = 0.;
810 }
811}
@ kTof
Time-of-flight Detector.
const Int_t iNTrg
const Int_t nbClWalkBinX
const Int_t nbClDelTofBinX
@ k12b
@ k14a
static Int_t currentEvN
static void SaveHisto(TH1 *histo)
const Double_t TTotMean
static Int_t currentEvN
static TH1F * deltaPointTHisto
ClassImp(CbmTofTBClusterizer) const Int_t nbClWalkBinX
static TH1F * deltaChannelTHisto
const Int_t iNTrg
static void AddPts(set< pair< Int_t, Int_t > > &sPtsRef, const CbmTofDigiExp *digi)
Double_t TOTMax
const Int_t nbClDelTofBinX
static long fullDuration
static TH1F * digiTimeHisto
static void SaveHisto(TH1 *histo)
Double_t TOTMin
static TH1F * nofChannelsTHisto
void SetTimeError(double error)
Definition CbmHit.h:91
const CbmLink & GetLink(int32_t i) const
Definition CbmMatch.h:39
int32_t GetNofLinks() const
Definition CbmMatch.h:42
void AddLink(const CbmLink &newLink)
Definition CbmMatch.cxx:47
static uint32_t GetUniqueAddress(uint32_t Sm, uint32_t Rpc, uint32_t Channel, uint32_t Side=0, uint32_t SmType=0, uint32_t RpcType=0)
Double_t GetSizey() const
Definition CbmTofCell.h:40
Double_t GetY() const
Definition CbmTofCell.h:36
Double_t GetSizex() const
Definition CbmTofCell.h:39
Double_t GetX() const
Definition CbmTofCell.h:35
Double_t GetZ() const
Definition CbmTofCell.h:37
virtual int32_t SetDetectorInfo(const CbmTofDetectorInfo detectorInfo)=0
Parameters class for the CBM ToF digitizer using beam data distributions.
Double_t GetFeeTimeRes() const
Int_t GetNbSmTypes() const
Double_t GetGapSize(Int_t iSmType, Int_t iRpc) const
Int_t GetNbSm(Int_t iSmType) const
Double_t GetMaxDistAlongCh() const
Int_t GetNbChan(Int_t iSmType, Int_t iRpc) const
Int_t GetNbGaps(Int_t iSmType, Int_t iRpc) const
Int_t GetChanType(Int_t iSmType, Int_t iRpc) const
Int_t GetNbRpc(Int_t iSmType) const
Double_t GetSignalSpeed() const
Double_t GetSigVel(Int_t iSmType, Int_t iSm, Int_t iRpc) const
CbmTofCell * GetCell(Int_t i)
Int_t GetNrOfModules()
Int_t GetCellId(Int_t i)
Int_t GetCell(Int_t uniqueId)
Int_t Init(Bool_t isSimulation=kFALSE)
Int_t GetSModule(Int_t uniqueId)
Int_t GetCounter(Int_t uniqueId)
Int_t GetSMType(Int_t uniqueId)
CbmTofGeoHandler * fGeoHandler
std::vector< std::vector< std::vector< ChannelDigis > > > fStorDigiExp
CbmTofDetectorId * fTofId
TClonesArray * fTofDigiMatchs
void Exec(Option_t *option)
std::vector< std::vector< std::vector< std::vector< Double_t > > > > fvCPTotGain
std::vector< std::vector< std::vector< std::vector< std::vector< Double_t > > > > > fvCPWalk
std::vector< std::vector< std::vector< std::vector< Double_t > > > > fvCPDelTof
CbmTofDigiBdfPar * fDigiBdfPar
void GetEventInfo(Int_t &inputNr, Int_t &eventNr, Double_t &eventTime)
std::vector< std::vector< Double_t > > fvCPSigPropSpeed
std::vector< std::vector< std::vector< std::vector< Double_t > > > > fvCPTOff
std::map< Double_t, DigiDesc > topDigis
std::map< Double_t, DigiDesc > bottomDigis
std::map< Double_t, DigiPair > digiPairs