CbmRoot
Loading...
Searching...
No Matches
CbmMvdSensorHitfinderTask.cxx
Go to the documentation of this file.
1/* Copyright (C) 2013-2020 Institut fuer Kernphysik, Goethe-Universitaet Frankfurt, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Philipp Sitzmann [committer], Samir Amar-Youcef, Florian Uhlig */
4
5// ---------------------------------------------------------------------------------------------
6// ----- CbmMvdSensorHitfinderTask source file -----
7// ----- Created 11/09/13 by P.Sitzmann -----
8// ----- -----
9// ---------------------------------------------------------------------------------------------
11
12#include "CbmMvdCluster.h" // for CbmMvdCluster
13#include "CbmMvdDigi.h" // for CbmMvdDigi
14#include "CbmMvdHit.h" // for CbmMvdHit
15#include "CbmMvdSensor.h" // for CbmMvdSensor
16
17#include <TClonesArray.h> // for TClonesArray
18#include <TGeoMatrix.h> // for TGeoHMatrix
19#include <TMath.h> // for Power
20#include <TMathBase.h> // for Abs
21#include <TObjArray.h> // for TObjArray
22#include <TRandom.h> // for TRandom
23#include <TRandom3.h> // for gRandom
24#include <TVector3.h> // for TVector3
25
26#include <iomanip> // for setprecision, setw
27#include <iostream> // for operator<<, basic_ostream, char_traits, endl
28#include <map> // for map, __map_iterator, operator!=, operator==
29#include <vector> // for vector
30
31using std::endl;
32using std::fixed;
33using std::ios_base;
34using std::left;
35using std::map;
36using std::pair;
37using std::right;
38using std::setprecision;
39using std::setw;
40using std::vector;
41
42
43// ----- Default constructor ------------------------------------------
46 , fAdcDynamic(200)
47 , fAdcOffset(0)
48 , fAdcBits(1)
49 , fAdcSteps(-1)
50 , fAdcStepSize(-1.)
51 , fClusters(new TClonesArray("CbmMvdCluster", 10000))
52 , fPixelChargeHistos(nullptr)
53 , fTotalChargeInNpixelsArray(nullptr)
54 , fResolutionHistoX(nullptr)
55 , fResolutionHistoY(nullptr)
56 , fResolutionHistoCleanX(nullptr)
57 , fResolutionHistoCleanY(nullptr)
58 , fResolutionHistoMergedX(nullptr)
59 , fResolutionHistoMergedY(nullptr)
60 , fBadHitHisto(nullptr)
61 , fGausArray(nullptr)
62 , fGausArrayIt(-1)
63 , fGausArrayLimit(5000)
64 , fDigiMap()
65 , fDigiMapIt()
66 , h(nullptr)
67 , h3(nullptr)
68 , h1(nullptr)
69 , h2(nullptr)
70 , Qseed(nullptr)
71 , fFullClusterHisto(nullptr)
72 , c1(nullptr)
73 , fNEvent(0)
74 , fMode(0)
75 , fCounter(0)
76 , fSigmaNoise(15.)
77 , fSeedThreshold(1.)
78 , fNeighThreshold(1.)
79 , fShowDebugHistos(kFALSE)
80 , fUseMCInfo(kFALSE)
81 , inputSet(kFALSE)
82 , fLayerRadius(0.)
83 , fLayerRadiusInner(0.)
84 , fLayerPosZ(0.)
85 , fHitPosX(0.)
86 , fHitPosY(0.)
87 , fHitPosZ(0.)
88 , fHitPosErrX(0.0005)
89 , fHitPosErrY(0.0005)
90 , fHitPosErrZ(0.0)
91 , fBranchName("MvdHit")
92 , fDigisInCluster(0)
93 , fAddNoise(kFALSE)
94{
95 fPluginIDNumber = 300;
96}
97// -------------------------------------------------------------------------
98
99
100// ----- Standard constructor ------------------------------------------
103 , fAdcDynamic(200)
104 , fAdcOffset(0)
105 , fAdcBits(1)
106 , fAdcSteps(-1)
107 , fAdcStepSize(-1.)
108 , fClusters(new TClonesArray("CbmMvdCluster", 10000))
109 , fPixelChargeHistos(nullptr)
110 , fTotalChargeInNpixelsArray(nullptr)
111 , fResolutionHistoX(nullptr)
112 , fResolutionHistoY(nullptr)
113 , fResolutionHistoCleanX(nullptr)
114 , fResolutionHistoCleanY(nullptr)
115 , fResolutionHistoMergedX(nullptr)
116 , fResolutionHistoMergedY(nullptr)
117 , fBadHitHisto(nullptr)
118 , fGausArray(nullptr)
119 , fGausArrayIt(-1)
120 , fGausArrayLimit(5000)
121 , fDigiMap()
122 , fDigiMapIt()
123 , h(nullptr)
124 , h3(nullptr)
125 , h1(nullptr)
126 , h2(nullptr)
127 , Qseed(nullptr)
128 , fFullClusterHisto(nullptr)
129 , c1(nullptr)
130 , fNEvent(0)
131 , fMode(iMode)
132 , fCounter(0)
133 , fSigmaNoise(15.)
134 , fSeedThreshold(1.)
135 , fNeighThreshold(1.)
136 , fShowDebugHistos(kFALSE)
137 , fUseMCInfo(kFALSE)
138 , inputSet(kFALSE)
139 , fLayerRadius(0.)
140 , fLayerRadiusInner(0.)
141 , fLayerPosZ(0.)
142 , fHitPosX(0.)
143 , fHitPosY(0.)
144 , fHitPosZ(0.)
145 , fHitPosErrX(0.0005)
146 , fHitPosErrY(0.0005)
147 , fHitPosErrZ(0.0)
148 , fBranchName("MvdHit")
149 , fDigisInCluster(0)
150 , fAddNoise(kFALSE)
151{
152 fPluginIDNumber = 300;
153}
154// -------------------------------------------------------------------------
155
156// ----- Destructor ----------------------------------------------------
158{
159
160 if (fOutputBuffer) {
161 fOutputBuffer->Delete();
162 delete fOutputBuffer;
163 }
164
165 if (fClusters) {
166 fClusters->Delete();
167 delete fClusters;
168 }
169
170 if (fInputBuffer) {
171 fInputBuffer->Delete();
172 delete fInputBuffer;
173 }
174}
175// -------------------------------------------------------------------------
176
177// ----- Virtual private method Init ----------------------------------
179{
180
181
182 fSensor = mysensor;
183 LOG(debug) << "CbmMvdSensorHitfinderTask: Initialisation of sensor " << fSensor->GetName();
184
185 fInputBuffer = new TClonesArray("CbmMvdCluster", 100);
186 fOutputBuffer = new TClonesArray("CbmMvdHit", 100);
187
188
189 //Add charge collection histograms
190 fPixelChargeHistos = new TObjArray();
191
192 fTotalChargeInNpixelsArray = new TObjArray();
193
194 fAdcSteps = (Int_t) TMath::Power(2, fAdcBits);
196
197 fGausArray = new Float_t[fGausArrayLimit];
198 for (Int_t i = 0; i < fGausArrayLimit; i++) {
199 fGausArray[i] = gRandom->Gaus(0, fSigmaNoise);
200 };
201 fGausArrayIt = 0;
202
203
204 initialized = kTRUE;
205
206 //LOG(debug) << "-Finished- " << GetName() << ": Initialisation of sensor " << fSensor->GetName();
207}
208// -------------------------------------------------------------------------
209
210// ----- Virtual public method Reinit ----------------------------------
212{
213 LOG(info) << "CbmMvdSensorHitfinderTask::ReInt---------------";
214 return kSUCCESS;
215}
216// -------------------------------------------------------------------------
217
218// ----- Virtual public method ExecChain --------------
220// -------------------------------------------------------------------------
221
222// ----- Virtual public method Exec --------------
224{
225
226 // if(!inputSet)
227 // {
228 // fInputBuffer->Clear();
229 // fInputBuffer->AbsorbObjects(fPreviousPlugin->GetOutputArray());
230 // LOG(debug) << "absorbt object from previous plugin at " << fSensor->GetName() << " got " << fInputBuffer->GetEntriesFast() << " entrys";
231 // }
232 if (fInputBuffer->GetEntriesFast() > 0) {
233
234 fOutputBuffer->Clear();
235 inputSet = kFALSE;
236 for (Int_t i = 0; i < fInputBuffer->GetEntriesFast(); i++) {
237 CbmMvdCluster* cluster = (CbmMvdCluster*) fInputBuffer->At(i);
238 TVector3 pos(0, 0, 0);
239 TVector3 dpos(0, 0, 0);
240 CreateHit(cluster, pos, dpos);
241 }
242 }
243 fInputBuffer->Delete();
244}
245//--------------------------------------------------------------------------
246
247
248//--------------------------------------------------------------------------
249void CbmMvdSensorHitfinderTask::CreateHit(CbmMvdCluster* cluster, TVector3& pos, TVector3& dpos)
250{
251 // Calculate the center of gravity of the charge of a cluster
252 double startTime = 0;
253 double endTime = 0;
254 double indicatedTime = 0;
255
256 ComputeCenterOfGravity(cluster, pos, dpos, indicatedTime, startTime, endTime);
257
258
259 Int_t indexX, indexY;
260 Double_t local[3] = {pos.X(), pos.Y(), pos.Z()};
261
262 //LOG(debug)<< "found center of gravity at: " << local[0] << " , " << local[1];
263
264 fSensor->TopToPixel(local, indexX, indexY);
265
266 //LOG(debug) << "Center is on pixel: " << indexX << " , " << indexY;
267
268
269 // Save hit into array
270
271 //LOG(debug) << "adding new hit to fHits at X: " << pos.X() << " , Y: "<< pos.Y() << " , Z: " << pos.Z() << " , from cluster nr " << cluster->GetRefId();
272 Int_t nHits = fOutputBuffer->GetEntriesFast();
273 new ((*fOutputBuffer)[nHits]) CbmMvdHit(fSensor->GetStationNr(), pos, dpos, indexX, indexY, cluster->GetRefId(),
274 0); // Bug - Should be the sensor ID
275 CbmMvdHit* currentHit = (CbmMvdHit*) fOutputBuffer->At(nHits);
276
277 currentHit->SetTime(indicatedTime);
278 currentHit->SetTimeError((endTime - startTime) / 3.64); //Assume Sqrt(12) - Error
279 currentHit->SetValidityStartTime(startTime);
280 currentHit->SetValidityEndTime(endTime);
281 currentHit->SetRefId(cluster->GetRefId());
282}
283
284//--------------------------------------------------------------------------
285
286/*void CbmMvdSensorHitfinderTask::UpdateDebugHistos(vector<Int_t>* clusterArray, Int_t seedIndexX, Int_t seedIndexY)
287{
288;
289} */
290
291
292//--------------------------------------------------------------------------
293
295 double& indicatedTime, double& startTime, double& endTime)
296{
297
298 Double_t numeratorX = 0;
299 Double_t numeratorY = 0;
300 Double_t denominator = 0;
301 Int_t charge;
302 Int_t xIndex;
303 Int_t yIndex;
304 Double_t x, y;
305 Double_t layerPosZ = fSensor->GetZ();
306 Double_t lab[3] = {0, 0, 0};
307 std::map<pair<Int_t, Int_t>, Int_t> PixelMap = cluster->GetPixelMap();
308 Int_t clusterSize = cluster->GetNofDigis();
309
310 // UInt_t shape = 0;
311 // Int_t xIndex0 = 0;
312 // Int_t yIndex0 = 0;
313
314 Double_t sigmaIn[3] = {0., 0., 0.}, sigmaOut[3] = {0., 0., 0.}, shiftIn[3] = {0., 0., 0.}, shiftOut[3] = {0., 0., 0.};
315
316 //Double_t GetFrameStartTime(Int_t frameNumber);
317 //Double_t GetFrameEndTime(Int_t frameNumber) {return GetFrameStartTime (frameNumber+1);}
318
319
320 //Scan digis for the digi with minimal frame number.
321 //For the time being, it is anticipated that this digi provides the best time estimate as it has lowest signal delay
322
323 // CbmMvdDigi* myDigi=(CbmMvdDigi*)cluster->GetDigi(0);
324 // int32_t minFrameNumber=myDigi->GetFrameNumber();
325 //
326 // for(Int_t i=0;i<clusterSize; i++){
327 // myDigi=(CbmMvdDigi*)cluster->GetDigi(i);
328 // int32_t frame=myDigi->GetFrameNumber();
329 // if(frame<minFrameNumber){minFrameNumber=frame;}
330 // }
331
332 //Estimate the highest possible delay and jitter of the analog amplifier chain from the sensor data sheet.
333
334 CbmMvdSensorDataSheet* sensorDataSheet = fSensor->GetDataSheet();
335 int32_t minFrameNumber = cluster->GetEarliestFrameNumber();
336
337
338 //Compute time walk and jitter assuming that the maximum possible signal is reasonably well represented with 10k signal electrons
339 Double_t timeWalk =
340 sensorDataSheet->GetDelay(sensorDataSheet->GetAnalogThreshold()) - sensorDataSheet->GetDelay(10000);
341 timeWalk =
342 timeWalk
343 + 2 * sensorDataSheet->GetDelaySigma(sensorDataSheet->GetAnalogThreshold()); //include pixel-to-pixel spread.
344 Double_t jitter = sensorDataSheet->GetJitter(sensorDataSheet->GetAnalogThreshold()); //include jitter.
345
346 // fixme: pixel-to-pixel spread not accounted for
347
348 startTime = fSensor->GetFrameStartTime(minFrameNumber) - timeWalk - 2 * jitter;
349 endTime = fSensor->GetFrameEndTime(minFrameNumber) + 2 * jitter;
350
351 indicatedTime = startTime + (endTime - startTime) / 2;
352
353
354 for (map<pair<Int_t, Int_t>, Int_t>::iterator it = PixelMap.begin(); it != PixelMap.end(); ++it) {
355 pair<Int_t, Int_t> pixel = it->first;
356
357 charge = GetAdcCharge(it->second);
358 xIndex = pixel.first;
359 yIndex = pixel.second;
360
361 // Determine Cluster Shape
362 //if (PixelMap.size() <= 4) {
363 // if (it == PixelMap.begin()) {
364 // xIndex0 = xIndex;
365 // yIndex0 = yIndex;
366 // }
367 // shape += TMath::Power(2, (4 * (yIndex - yIndex0 + 3)) + (xIndex - xIndex0));
368 //}
369
370 LOG(debug) << "CbmMvdSensorHitfinderTask:: iCluster= " << cluster->GetRefId() << " , clusterSize= " << clusterSize;
371 LOG(debug) << "CbmMvdSensorHitfinderTask::xIndex " << xIndex << " , yIndex " << yIndex << " , charge = " << charge;
372
374
375 x = lab[0];
376 y = lab[1];
377
378 Double_t xc = x * charge;
379 Double_t yc = y * charge;
380
381 numeratorX += xc;
382 numeratorY += yc;
383 denominator += charge;
384 }
385
386 LOG(debug) << "CbmMvdSensorHitfinderTask::=========================";
387 LOG(debug) << "CbmMvdSensorHitfinderTask::numeratorX: " << numeratorX << " , numeratorY: " << numeratorY
388 << ", denominator: " << denominator << ", indicated time: " << indicatedTime;
389
390 //Calculate x,y coordinates of the pixel in the laboratory ref frame
391 if (denominator != 0) {
394 fHitPosZ = layerPosZ;
395 }
396 else {
397 fHitPosX = 0;
398 fHitPosY = 0;
399 fHitPosZ = 0;
400 }
401
402 LOG(debug) << "CbmMvdSensorHitfinderTask::-----------------------------------";
403 LOG(debug) << "CbmMvdSensorHitfinderTask::X hit= " << fHitPosX << " Y hit= " << fHitPosY << " Z hit= " << fHitPosZ;
404 LOG(debug) << "CbmMvdSensorHitfinderTask::-----------------------------------";
405
406 // Quick fix to get some errors for the MvdHits.
407 // Proposed value 8mum
408 // See Redmine issue 3066
409 // See plots with residuals from GitLab MR 1504
410 sigmaIn[0] = 0.0008;
411 sigmaIn[1] = 0.0008;
412 sigmaIn[2] = 0.;
413
414 // // Treat Sigma/Shift of the Cluster according to the Shape
415 // // This goes back to some results of a specific MIMOSA-26 beam time. Switch off for the time being.
416 //
417 // if (shape == 12288) {
418 // sigmaIn[0] = 0.00053;
419 // sigmaIn[1] = 0.00063;
420 // sigmaIn[2] = 0.;
421 // shiftIn[0] = -0.00000;
422 // shiftIn[1] = -0.00001;
423 // shiftIn[2] = 0.;
424 // }
425 // else if (shape == 208896) {
426 // sigmaIn[0] = 0.00035;
427 // sigmaIn[1] = 0.00036;
428 // sigmaIn[2] = 0.;
429 // shiftIn[0] = -0.00000;
430 // shiftIn[1] = -0.00002;
431 // shiftIn[2] = 0.;
432 // }
433 // else if (shape == 69632) {
434 // sigmaIn[0] = 0.00028;
435 // sigmaIn[1] = 0.00028;
436 // sigmaIn[2] = 0.;
437 // shiftIn[0] = -0.00000;
438 // shiftIn[1] = -0.00002;
439 // shiftIn[2] = 0.;
440 // }
441 // else if (shape == 28672) {
442 // sigmaIn[0] = 0.00028;
443 // sigmaIn[1] = 0.00039;
444 // sigmaIn[2] = 0.;
445 // shiftIn[0] = -0.00000;
446 // shiftIn[1] = -0.00001;
447 // shiftIn[2] = 0.;
448 // }
449 // else if (shape == 143360) {
450 // sigmaIn[0] = 0.00024;
451 // sigmaIn[1] = 0.00022;
452 // sigmaIn[2] = 0.;
453 // shiftIn[0] = +0.00020;
454 // shiftIn[1] = +0.00008;
455 // shiftIn[2] = 0.;
456 // }
457 // else if (shape == 200704) {
458 // sigmaIn[0] = 0.00024;
459 // sigmaIn[1] = 0.00022;
460 // sigmaIn[2] = 0.;
461 // shiftIn[0] = -0.00020;
462 // shiftIn[1] = -0.00011;
463 // shiftIn[2] = 0.;
464 // }
465 // else if (shape == 77824) {
466 // sigmaIn[0] = 0.00024;
467 // sigmaIn[1] = 0.00022;
468 // sigmaIn[2] = 0.;
469 // shiftIn[0] = -0.00020;
470 // shiftIn[1] = +0.00008;
471 // shiftIn[2] = 0.;
472 // }
473 // else if (shape == 12800) {
474 // sigmaIn[0] = 0.00024;
475 // sigmaIn[1] = 0.00022;
476 // sigmaIn[2] = 0.;
477 // shiftIn[0] = +0.00020;
478 // shiftIn[1] = -0.00011;
479 // shiftIn[2] = 0.;
480 // }
481 // else if (shape == 4096) {
482 // sigmaIn[0] = 0.00027;
483 // sigmaIn[1] = 0.00092;
484 // sigmaIn[2] = 0.;
485 // shiftIn[0] = +0.00002;
486 // shiftIn[1] = +0.00004;
487 // shiftIn[2] = 0.;
488 // }
489 // else {
490 // sigmaIn[0] = 0.00036;
491 // sigmaIn[1] = 0.00044;
492 // sigmaIn[2] = 0.;
493 // shiftIn[0] = -0.00000;
494 // shiftIn[1] = -0.00002;
495 // shiftIn[2] = 0.;
496 // }
497 // Consider Sensor Orientation
498 TGeoHMatrix* RecoMatrix = fSensor->GetRecoMatrix();
499 TGeoHMatrix RotMatrix;
500 RotMatrix.SetRotation(RecoMatrix->GetRotationMatrix());
501
502 RotMatrix.LocalToMaster(sigmaIn, sigmaOut);
503 RotMatrix.LocalToMaster(shiftIn, shiftOut);
504
505 fHitPosErrX = TMath::Abs(sigmaOut[0]);
506 fHitPosErrY = TMath::Abs(sigmaOut[1]);
507 fHitPosErrZ = TMath::Abs(sigmaOut[2]);
508
509 fHitPosX += shiftOut[0];
510 fHitPosY += shiftOut[1];
511 fHitPosZ += shiftOut[2];
512
513 // pos = center of gravity (labframe), dpos uncertainty LOG(info)<<setw(10)<<setprecision(2)<< VolumeShape->GetDX();
514 pos.SetXYZ(fHitPosX, fHitPosY, fHitPosZ);
516}
517
518//--------------------------------------------------------------------------
519
520
521//--------------------------------------------------------------------------
523//--------------------------------------------------------------------------
524
526{
527
528 Int_t adcCharge;
529
530 if (charge < fAdcOffset) {
531 return 0;
532 };
533
534 adcCharge = int((charge - fAdcOffset) / fAdcStepSize);
535 if (adcCharge > fAdcSteps - 1) {
536 adcCharge = fAdcSteps - 1;
537 }
538
539 return adcCharge;
540}
541
542
543// ----- Private method Reset ------------------------------------------
545
546// -------------------------------------------------------------------------
547
548
Double_t denominator
TVector3 dpos
Double_t numeratorY
Double_t lab[3]
Double_t numeratorX
const constexpr Int_t fCounter(0)
ClassImp(CbmMvdSensorHitfinderTask)
int32_t GetNofDigis() const
Number of digis in cluster.
Definition CbmCluster.h:69
void SetTimeError(double error)
Definition CbmHit.h:91
void SetRefId(int32_t refId)
Definition CbmHit.h:82
void SetTime(double time)
Definition CbmHit.h:85
int32_t GetRefId()
int32_t GetEarliestFrameNumber()
std::map< std::pair< int32_t, int32_t >, int32_t > GetPixelMap()
void SetValidityStartTime(double time)
Definition CbmMvdHit.h:72
void SetValidityEndTime(double time)
Definition CbmMvdHit.h:73
virtual Double_t GetDelaySigma(Float_t charge)
virtual Double_t GetJitter(Float_t charge)
virtual Double_t GetDelay(Float_t charge)
void InitTask(CbmMvdSensor *mySensor)
void ComputeCenterOfGravity(CbmMvdCluster *clusterArray, TVector3 &pos, TVector3 &dpos, double &indicatedTime, double &startTime, double &endTime)
void CreateHit(CbmMvdCluster *clusterArray, TVector3 &pos, TVector3 &dpos)
CbmMvdSensor * fSensor
TClonesArray * fOutputBuffer
TClonesArray * fInputBuffer
void PixelToTop(Int_t pixelNumberX, Int_t pixelNumberY, Double_t *lab)
Double_t GetFrameStartTime(Int_t frameNumber)
TGeoHMatrix * GetRecoMatrix()
Double_t GetZ() const
Double_t GetFrameEndTime(Int_t frameNumber)
Int_t GetStationNr() const
void TopToPixel(Double_t *lab, Int_t &pixelNumberX, Int_t &pixelNumberY)
CbmMvdSensorDataSheet * GetDataSheet()
Data class with information on a STS local track.