CbmRoot
Loading...
Searching...
No Matches
CbmMvdSensorDigitizerTask.cxx
Go to the documentation of this file.
1/* Copyright (C) 2014-2019 Institut fuer Kernphysik, Goethe-Universitaet Frankfurt, Frankfurt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Philipp Sitzmann [committer], Florian Uhlig */
4
5// -------------------------------------------------------------------------
6// ----- CbmMvdSensorDigitizerTask source file -----
7// ----- Created 02.02.2012 by M. Deveaux -----
8// -------------------------------------------------------------------------
22
23#include "CbmMatch.h" // for CbmMatch
24#include "CbmMvdDigi.h" // for CbmMvdDigi
25#include "CbmMvdPileupManager.h" // for CbmMvdPileupManager
26#include "CbmMvdPixelCharge.h" // for CbmMvdPixelCharge
27#include "CbmMvdPoint.h" // for CbmMvdPoint
28#include "CbmMvdSensor.h" // for CbmMvdSensor
29#include "CbmMvdSensorDataSheet.h" // for CbmMvdSensorDataSheet
30#include "CbmMvdSensorPlugin.h" // for CbmMvdSensorPlugin
31
32#include <FairEventHeader.h> // for FairEventHeader
33#include <FairRootManager.h> // for FairRootManager
34#include <FairRunAna.h> // for FairRunAna
35#include <FairRunSim.h> // for FairRunSim
36#include <Logger.h> // for LOG, Logger
37
38#include <TCanvas.h> // for TCanvas
39#include <TClonesArray.h> // for TClonesArray
40#include <TH1.h> // for TH1F
41#include <TH2.h> // for TH2F
42#include <TMath.h> // for Pi, ATan
43#include <TMathBase.h> // for Abs, Max
44#include <TRandom.h> // for TRandom
45#include <TRefArray.h> // for TRefArray
46#include <TVector3.h> // for TVector3, operator*, operator+
47
48#include <cmath> // for sqrt
49#include <iomanip> // for operator<<, setprecision, setw
50#include <map> // for map, operator==, __map_iterator
51#include <ostream> // for operator<<, basic_ostream, endl
52#include <vector> // for allocator, vector
53
54
55using std::endl;
56using std::ios_base;
57using std::pair;
58using std::setprecision;
59using std::setw;
60
61
62// ----- Default constructor ------------------------------------------
65 , fcurrentFrameNumber(0)
66 , fEpiTh(0.0014)
67 , fSegmentLength(0.0001)
68 , fDiffusionCoefficient(0.0055)
69 , fElectronsPerKeV(276.)
70 , fWidthOfCluster(3.5)
71 , fPixelSizeX(0.0030)
72 , fPixelSizeY(0.0030)
73 , fCutOnDeltaRays(0.00169720)
74 , fChargeThreshold(100.)
75 , fFanoSilicium(0.115)
76 , fEsum(0.)
77 , fSegmentDepth(0.)
78 , fCurrentTotalCharge(0.)
79 , fCurrentParticleMass(0.)
80 , fCurrentParticleMomentum(0.)
81 , fCurrentParticlePdg(0)
82 , fRandomGeneratorTestHisto(nullptr)
83 , fPosXY(nullptr)
84 , fpZ(nullptr)
85 , fPosXinIOut(nullptr)
86 , fAngle(nullptr)
87 , fSegResolutionHistoX(nullptr)
88 , fSegResolutionHistoY(nullptr)
89 , fSegResolutionHistoZ(nullptr)
90 , fTotalChargeHisto(nullptr)
91 , fTotalSegmentChargeHisto(nullptr)
92 , fLorentzY0(-6.1)
93 , fLorentzXc(0.)
94 , fLorentzW(1.03)
95 , fLorentzA(477.2)
96 , fLorentzNorm(1.)
97 , fLandauMPV(877.4)
98 , fLandauSigma(204.93)
99 , fLandauGain(3.3)
100 , fLandauRandom(new TRandom3())
101 , fPixelSize(0.0025)
102 , fPar0(520.)
103 , fPar1(0.34)
104 , fPar2(-1.2)
105 , fCompression(1.)
106 , fResolutionHistoX(nullptr)
107 , fResolutionHistoY(nullptr)
108 , fNumberOfSegments(0)
109 , fCurrentLayer(0)
110 , fEvent(0)
111 , fVolumeId(0)
112 , fNPixelsX(0)
113 , fNPixelsY(0)
114 , fPixelCharge(new TClonesArray("CbmMvdPixelCharge"))
115 , fDigis(nullptr)
116 , fDigiMatch(nullptr)
117 , fproduceNoise(kFALSE)
118 , fPixelChargeShort()
119 , fPixelScanAccelerator(nullptr)
120 , fChargeMap()
121 , fChargeMapIt()
122 , fSensorDataSheet(nullptr)
123 , fMode(0)
124 , fSigmaX(0.0005)
125 , fSigmaY(0.0005)
126 , fReadoutTime(0.00005)
127 , fEfficiency(-1.)
128 , fMergeDist(-1.)
129 , fFakeRate(-1.)
130 , fNPileup(0)
131 , fNDeltaElect(0)
132 , fDeltaBufferSize(0)
133 , fBgBufferSize(0)
134 , fBranchName("")
135 , fBgFileName("")
136 , fDeltaFileName("")
137 , fInputPoints(nullptr)
138 , fPoints(new TRefArray())
139 , fRandGen()
140 , fTimer()
141 , fPileupManager(nullptr)
142 , fDeltaManager(nullptr)
143 , fNEvents(0)
144 , fNPoints(0.)
145 , fNReal(0.)
146 , fNBg(0.)
147 , fNFake(0.)
148 , fNLost(0.)
149 , fNMerged(0.)
150 , fTime(0.)
151 , fSignalPoints()
152 , h_trackLength(nullptr)
153 , h_numSegments(nullptr)
154 , h_LengthVsAngle(nullptr)
155 , h_LengthVsEloss(nullptr)
156 , h_ElossVsMomIn(nullptr)
157{
158 fRandGen.SetSeed(2736);
159 fproduceNoise = kFALSE;
160 fPluginIDNumber = 100;
161}
162// -------------------------------------------------------------------------
163
164
165// ----- Standard constructor ------------------------------------------
168 , fcurrentFrameNumber(0)
169 , fEpiTh(0.0014)
170 , fSegmentLength(0.0001)
171 , fDiffusionCoefficient(0.0055)
172 , fElectronsPerKeV(276.)
173 , fWidthOfCluster(3.5)
174 , fPixelSizeX(0.0030)
175 , fPixelSizeY(0.0030)
176 , fCutOnDeltaRays(0.00169720)
177 , fChargeThreshold(100.)
178 , fFanoSilicium(0.115)
179 , fEsum(0.)
180 , fSegmentDepth(0.)
181 , fCurrentTotalCharge(0.)
182 , fCurrentParticleMass(0.)
183 , fCurrentParticleMomentum(0.)
184 , fCurrentParticlePdg(0)
185 , fRandomGeneratorTestHisto(nullptr)
186 , fPosXY(nullptr)
187 , fpZ(nullptr)
188 , fPosXinIOut(nullptr)
189 , fAngle(nullptr)
190 , fSegResolutionHistoX(nullptr)
191 , fSegResolutionHistoY(nullptr)
192 , fSegResolutionHistoZ(nullptr)
193 , fTotalChargeHisto(nullptr)
194 , fTotalSegmentChargeHisto(nullptr)
195 , fLorentzY0(-6.1)
196 , fLorentzXc(0.)
197 , fLorentzW(1.03)
198 , fLorentzA(477.2)
199 , fLorentzNorm(1.)
200 , fLandauMPV(877.4)
201 , fLandauSigma(204.93)
202 , fLandauGain(3.3)
203 , fLandauRandom(new TRandom3())
204 , fPixelSize(0.0025)
205 , fPar0(520.)
206 , fPar1(0.34)
207 , fPar2(-1.2)
208 , fCompression(1.)
209 , fResolutionHistoX(nullptr)
210 , fResolutionHistoY(nullptr)
211 , fNumberOfSegments(0)
212 , fCurrentLayer(0)
213 , fEvent(0)
214 , fVolumeId(0)
215 , fNPixelsX(0)
216 , fNPixelsY(0)
217 , fPixelCharge(new TClonesArray("CbmMvdPixelCharge", 100000))
218 , fDigis(nullptr)
219 , fDigiMatch(nullptr)
220 , fproduceNoise(kFALSE)
221 , fPixelChargeShort()
222 , fPixelScanAccelerator(nullptr)
223 , fChargeMap()
224 , fChargeMapIt()
225 , fSensorDataSheet(nullptr)
226 , fMode(iMode)
227 , fSigmaX(0.0005)
228 , fSigmaY(0.0005)
229 , fReadoutTime(0.00005)
230 , fEfficiency(-1.)
231 , fMergeDist(-1.)
232 , fFakeRate(-1.)
233 , fNPileup(0)
234 , fNDeltaElect(0)
235 , fDeltaBufferSize(0)
236 , fBgBufferSize(0)
237 , fBranchName("MvdPoint")
238 , fBgFileName("")
239 , fDeltaFileName("")
240 , fInputPoints(nullptr)
241 , fPoints(new TRefArray())
242 , fRandGen()
243 , fTimer()
244 , fPileupManager(nullptr)
245 , fDeltaManager(nullptr)
246 , fNEvents(0)
247 , fNPoints(0.)
248 , fNReal(0.)
249 , fNBg(0.)
250 , fNFake(0.)
251 , fNLost(0.)
252 , fNMerged(0.)
253 , fTime(0.)
254 , fSignalPoints()
255 , h_trackLength(nullptr)
256 , h_numSegments(nullptr)
257 , h_LengthVsAngle(nullptr)
258 , h_LengthVsEloss(nullptr)
259 , h_ElossVsMomIn(nullptr)
260
261{
262 fPluginIDNumber = 100;
263 LOG(debug) << "Starting CbmMvdSensorDigitizerTask::CbmMvdSensorDigitizerTask() ";
264
265 fRandGen.SetSeed(2736);
266 fEvent = 0;
267 fTime = 0.;
268 fSigmaX = 0.0005;
269 fSigmaY = 0.0005;
270 fReadoutTime = 0.00005;
271
272
273 fEpiTh = 0.0014;
274 fSegmentLength = 0.0001;
275 fDiffusionCoefficient = 0.0055; // correspondes to the sigma of the gauss with the max drift length
276 fElectronsPerKeV = 276; //3.62 eV for e-h creation
277 fWidthOfCluster = 3.5; // in sigmas
278 fPixelSizeX = 0.0025; // in cm
279 fPixelSizeY = 0.0025;
280 fCutOnDeltaRays = 0.00169720; //MeV
281 fChargeThreshold = 100.; //electrons change 1 to 10
282 fFanoSilicium = 0.115;
283 fEsum = 0;
284 fSegmentDepth = 0;
289
290
291 fPixelSize = 0.0025;
292 fPar0 = 520.;
293 fPar1 = 0.34;
294 fPar2 = -1.2;
295 fLandauMPV = 877.4;
296 fLandauSigma = 204.93;
297 fLandauGain = 3.3;
298
299 fLorentzY0 = -6.1;
300 fLorentzXc = 0.;
301 fLorentzW = 1.03;
302 fLorentzA = 477.2;
303
304
305 fCompression = 1.;
306
307
308 //fLorentzNorm=0.00013010281679422413;
309 fLorentzNorm = 1;
310
311
313
314 fproduceNoise = kFALSE;
315}
316
317
318// -------------------------------------------------------------------------
319
320
321// ----- Destructor ----------------------------------------------------
323{
324
325 if (fPileupManager) delete fPileupManager;
326 if (fDeltaManager) delete fDeltaManager;
327 if (fInputPoints) {
328 fInputPoints->Delete();
329 delete fInputPoints;
330 }
331
332
333 if (fOutputBuffer) {
334 fOutputBuffer->Delete();
335 delete fOutputBuffer;
336 }
337}
338// ------------------------------------------------------------------------
339
340
341// ----- Virtual private method ReadSensorInformation ----------------
343{
344
345 CbmMvdSensorDataSheet* sensorData;
346 sensorData = fSensor->GetDataSheet();
347 if (!sensorData) {
348 return kERROR;
349 }
350 fSensorDataSheet = sensorData;
351
352 fPixelSizeX = sensorData->GetPixelPitchX();
353 fPixelSizeY = sensorData->GetPixelPitchY();
354 fNPixelsX = sensorData->GetNPixelsX();
355 fNPixelsY = sensorData->GetNPixelsY();
356
357 fChargeThreshold = sensorData->GetChargeThreshold();
358
359 fPar0 = sensorData->GetLorentzPar0();
360 fPar1 = sensorData->GetLorentzPar1();
361 fPar2 = sensorData->GetLorentzPar2(); //LOG(debug) << " LorentzPar2 is now set to " << fPar2;
362
363 fLandauMPV = sensorData->GetLandauMPV(); //LOG(debug)<< " Landau MPV is now set to " << fLandauMPV;
364 fLandauSigma = sensorData->GetLandauSigma(); //LOG(debug) << " Landau Sigma is now set to " << fLandauSigma;
365 fLandauGain = sensorData->GetLandauGain(); //LOG(debug) << " Landau Gain is now set to " << fLandauGain;
366 fEpiTh = sensorData->GetEpiThickness(); //LOG(debug) << " Epitaxial thickness is now set to " << fEpiTh;
368
369 if (fCompression != 1)
370 //LOG(debug) << "working with non uniform pixels";
371 if (fCompression <= 0) fCompression = 1;
372 return kSUCCESS;
373}
374
375//
376// -----------------------------------------------------------------------------
377
378void CbmMvdSensorDigitizerTask::SetInputArray(TClonesArray* inputStream)
379{
380
381 Int_t i = 0;
382 Int_t nInputs = inputStream->GetEntriesFast();
383 while (nInputs > i) {
384 new ((*fInputPoints)[fInputPoints->GetEntriesFast()]) CbmMvdPoint(*((CbmMvdPoint*) inputStream->At(i)));
385
386 //LOG(debug) << "New Input registered";
387 i++;
388 }
389}
390//-----------------------------------------------------------------------------
391
393{
394
395 new ((*fInputPoints)[fInputPoints->GetEntriesFast()]) CbmMvdPoint(*((CbmMvdPoint*) point));
396}
397
398
399// -------------- public method ExecChain ------------------------------------
401{
402
403 // LOG(debug) << "start Digitizer on sensor " << fSensor->GetName();
404
405
406 Exec();
407}
408
409// ----- Virtual public method Exec ------------------------------------
411{
412
413 if (fPreviousPlugin) {
414 fInputPoints->Delete();
416 }
417 fOutputBuffer->Clear("C");
418 fDigis->Clear("C");
419 fDigiMatch->Clear("C");
420
421
422 //Int_t nDigis = 0;
424
425 if (fInputPoints->GetEntriesFast() > 0) {
426
427 for (Int_t iPoint = 0; iPoint < fInputPoints->GetEntriesFast(); iPoint++) {
428
429 CbmMvdPoint* point = (CbmMvdPoint*) fInputPoints->At(iPoint);
430
431 if (!point) {
432 LOG(warning) << " -received bad MC-Point. Ignored.";
433 continue;
434 }
435 if (point->GetStationNr() != fSensor->GetSensorNr()) {
436 LOG(warning) << " -received bad MC-Point which doesn't belong here. Ignored.";
437 continue;
438 }
439 fcurrentFrameNumber = point->GetFrame();
440 //The digitizer acts only on particles, which crossed the station.
441 //Particles generated in the sensor or being absorbed in this sensor are ignored
442 if (TMath::Abs(point->GetZOut() - point->GetZ()) < 0.9 * fEpiTh) {
443 LOG(debug) << "hit not on chip with thickness " << fEpiTh * 10000 << "µm";
444 LOG(debug) << "hit not on chip with length " << TMath::Abs(point->GetZOut() - point->GetZ()) * 10000 << "µm";
445 continue;
446 }
447 // Reject for the time being light nuclei (no digitization modell yet)
448 if (point->GetPdgCode() > 100000) {
449 continue;
450 }
451 // Digitize the point
452 //LOG(debug) << " found point make digi";
454 ProducePixelCharge(point);
455 } //loop on MCpoints
456
457
458 ProduceDigis();
460
461 /* Clean pixel charges, which do not reach threshold.
462 * This avoids that the first entries in the pixelCharge objects contain information about hits, which are insufficient
463 * for creating a hit. Having first entries below threshold complicates defining the hit time.
464 * Draw back: The charge of tracks from different events does not add.
465 */
466
467
469 }
470
471 else {
472 //LOG(debug)<< "No input found on Sensor " << fSensor->GetSensorNr() << " from " << fInputPoints->GetEntriesFast()<< " McPoints";
473 }
474
475
476 // fixme - This seems too much deleting
477 // fPixelCharge->Delete();
478 //fChargeMap.clear();
479 fInputPoints->Clear();
480 fSignalPoints.clear();
481
482} // end of exec
483
484// -------------------------------------------------------------------------
486{
487 CbmMvdPixelCharge* pixel;
488
490 LOG(debug) << "CbmMvdSensorDigitizerTask::ProduceDigis() - NumberOfPixelCharge = " << fPixelCharge->GetEntriesFast();
491
492
493 for (Int_t i = 0; i < fPixelCharge->GetEntriesFast(); i++) {
494 pixel = (CbmMvdPixelCharge*) fPixelCharge->At(i);
495 // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Length of array : " << fPixelCharge->GetEntriesFast();
496 // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Working on PixelCharge " << i << " Address = " << pixel;
497 // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelChargeTime = " << pixel->GetEndOfBusyTime();
498 // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - EventTime = " << fEventTime;
499
500 // When in event based mode create the digi even if busy time isn't
501 // reached
502 if (!fEventMode) {
503 if (pixel->GetEndOfBusyTime() > fEventTime) {
504 //LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - will care for this later";
505 continue;
506 }
507 }
508
509 FlushBuffer(pixel, i);
510 }
511 // LOG(debug)<< "CbmMvdSensorDigitizerTask::ProduceDigis() - NumberOfPixelCharge before compress = " << fPixelCharge->GetEntriesFast();
512
513 fPixelCharge->Compress();
514
515 // LOG(debug)<< "CbmMvdSensorDigitizerTask::ProduceDigis() - NumberOfPixelCharge after compress = " << fPixelCharge->GetEntriesFast();
516}
517
519{
520
521 pair<Int_t, Int_t> thispoint;
522 Int_t nDigis = 0;
523 /* The digi is only generated once the busy-time has passed. This is an easy way to avoid double counting of hits.
524 * If no digi is formed, the initial hit information remains stored in the CbmMvdPixelCharge
525 */
526 // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Working on PixelCharge " << i << " Address = " << pixel;
527 Int_t numberOfContributorCausingHit = CheckForHit(pixel);
528
529 LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge >" << pixel->GetEarliestHitCharge();
530
531 if (numberOfContributorCausingHit == -1) { // pixel did not fire and busy time has expired. Forget about it.
532 thispoint = std::make_pair(pixel->GetX(), pixel->GetY());
533 fChargeMap.erase(thispoint); // Delete entry in the fChargeMap (points from coordinate to the pixel
534 fPixelCharge->RemoveAt(i); // Delete the pixelCharge object
535 LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge " << i << " deleted (to few charge).";
536
537
538 return;
539 }
540
541 // LOG(debug)<< " CbmMvdSensorDigitizerTask::ProduceDigis() - Starting to create Digi from PixelCharge " << i;
542
543 Int_t diodeCharge = pixel->GetCharge()[numberOfContributorCausingHit]
544 + GetPixelCharge(pixel, pixel->GetTime()[numberOfContributorCausingHit]);
545 // Compute charge causing the hit. Note: GetPixelCharge does not account for the charge caused by the last hit if handed over the time of the last hit as the
546 // signal in the shaper did not yet build up. Therefore, this charge is added explicitely.
547
548 LOG(debug) << " --- CbmMvdSensorDigitizerTask::ProduceDigis() - DiodeCharge0 = " << pixel->GetCharge()[0];
549 LOG(debug) << " --- CbmMvdSensorDigitizerTask::ProduceDigis() - Full diode charge = " << diodeCharge;
550
551 Double_t analogHitTime =
552 fSensor->ComputeIndecatedAnalogTime(pixel->GetTime()[numberOfContributorCausingHit], diodeCharge);
553
554 // Write Digis
555
556 nDigis = fDigis->GetEntriesFast();
557
558 new ((*fDigis)[nDigis]) CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, fPixelSizeX,
559 fPixelSizeY, analogHitTime, fSensor->GetFrameNumber(analogHitTime, pixel->GetY()));
560
561
562 new ((*fOutputBuffer)[nDigis])
563 CbmMvdDigi(fSensor->GetSensorNr(), pixel->GetX(), pixel->GetY(), diodeCharge, fPixelSizeX, fPixelSizeY,
564 analogHitTime, fSensor->GetFrameNumber(analogHitTime, pixel->GetY()));
565
566 // To Do: Time and pixel charge are now in an array. Write function testing if the pixel is busy at a given time.
567 // Write function which computes the status of the pixel at the time of readout and which cell one has to readout.
568
569 new ((*fDigiMatch)[nDigis]) CbmMatch();
570 CbmMatch* match = (CbmMatch*) fDigiMatch->At(nDigis);
571 for (Int_t iLink = 0; iLink < pixel->GetNContributors(); iLink++) {
572
573 if (pixel->GetTrackID()[iLink] > -2) {
574 match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink], pixel->GetEventNr()[iLink],
575 pixel->GetInputNr()[iLink]);
576 // std::cout << "CbmMvdSensorDigitizerTask::ProduceDigis() : PointID= " << pixel->GetPointID()[iLink] << std::endl;
577 }
578
579 else
580 match->AddLink((Double_t) pixel->GetPointWeight()[iLink], pixel->GetPointID()[iLink]);
581 }
582
583 thispoint = std::make_pair(pixel->GetX(), pixel->GetY());
584 fChargeMap.erase(thispoint); // Delete entry in the fChargeMap (points from coordinate to the pixel
585 fPixelCharge->RemoveAt(i); // Delete the pixelCharge object
586 LOG(debug) << " CbmMvdSensorDigitizerTask::ProduceDigis() - PixelCharge " << i << " deleted (digi produced).";
587}
588
589
590// -------------------------------------------------------------------------
592{
593
594 // So far a code fragment
595
596 /*
597 Float_t sensorAnalogThreshold=fSensorDataSheet->GetAnalogThreshold ();
598
599 for (Int_t i=0; i<fPixelCharge->GetEntriesFast();i++){
600 CbmMvdPixelCharge* pixel= (CbmMvdPixelCharge*) fPixelCharge->At(i);
601
602 if(pixel->GetEarliestHitCharge()> sensorAnalogThreshold) {continue;} //pixel has fired, nothing to be done
603
604 else if (pixel->GetNContributors()>1) {// pixel was hit multiple times within the event, check if charge sums up within an event.
605 Float_t summedCharge=0.;
606
607 for(Int_t iContributor; iContributor<pixel->GetNContributors(); iContributor++){
608
609 if(pixel->GetTime[iContributor] < (pixel->GetEarliestHitTime() + fSensorDataSheet->GetSignalRiseTime ()) {summedCharge = summedCharge + pixel->fCharge[iContributor]}
610 else{break;} //Sum up charges impinging within the integration time. If going beyond the integration time, skip.
611 }
612
613 if (summedCharge<sensorAnalogThreshold) {continue;} //pixel fired due to combined charge of hits. Nothing to be done.
614 // to be done -> Think about events and signal rise time.
615
616 if (pixel->GetNContributors()==1 && pixel->GetEarliestHitCharge()<sensorAnalogThreshold) { //pixel was hit by one particle and did not fire.
617 fPixelCharge->RemoveAt(i); // pixel is considered as cleared after the event
618 }
619
620 */
621}
622
623// -------------------------------------------------------------------------
624
626{
627
628 /* Intended to spot the number of contributors to the pixel charge, which fired the pixel.
629 * The number of the contributor is returned
630 */
631 if (!fSensorDataSheet) {
632 std::cout << " - E - CbmMvdSensorDigitizerTask::CheckForHit : Missing Datasheet." << std::endl;
633 }
634
635 // std::vector<Float_t>& chargeArray=pixel->GetCharge();
636 // if(chargeArray.size() != pixel->GetNContributors()) {Fatal("ContributorCrash","ContributorCrash");}
637 //
638 // for(Int_t i=0; i<pixel->GetNContributors(); i++){ std::cout << " " << chargeArray[i];}
639 // std::cout << std::endl;
640
642 return 0;
643 }
644 /* The pixel fired immedeately, easiest case.else ...
645 * Else: Check if a later impact fired the pixel
646 */
647
648 Int_t nContributors = pixel->GetNContributors();
649 Int_t charge = 0;
650
651 // Get charge and time arrays from pixel (both stl::vector)
652
653 for (Int_t i = 1; i < nContributors; i++) {
654
655 // compute charge at the time of the impinging of particle i accounting for pixel history.
656 // pixel->GetCharge[i] stands for the charge of the particle under study, GetPixelCharge wraps up the history.
657
658 charge = pixel->GetCharge()[i] + GetPixelCharge(pixel, pixel->GetTime()[i]);
659 if (charge > fSensorDataSheet->GetAnalogThreshold()) {
660 return i;
661 }
662 }
663
664 return -1;
665};
666
667// -------------------------------------------------------------------------
668
670{
671 /* Adds the accumulated charge of the pixel until readout time.
672 * Accounts for a signal rise and signal fall time (clearance) of the analog amplifier.
673 */
674
675 Int_t pixelCharge = 0;
676 Double_t pixelSignalRiseTime = fSensorDataSheet->GetSignalRiseTime();
677 Double_t pixelSignalFallTime = fSensorDataSheet->GetSignalFallTime();
678 Int_t nHits = myPixel->GetNContributors();
679
680 for (Int_t hitNr = 0; hitNr < nHits; hitNr++) {
681 Int_t hitTime = myPixel->GetTime()[hitNr];
682 if (hitTime > readoutTime) {
683 break;
684 }
685 Int_t hitCharge = myPixel->GetCharge()[hitNr];
686
687 //pixelCharge=pixelCharge+hitCharge;
688
689 //Use ideal charge accumulation in the pixel at this time
690 pixelCharge = pixelCharge
691 + hitCharge
692 * (1
693 - TMath::Exp(-(readoutTime - hitTime)
694 / pixelSignalRiseTime)); //exponential signal rise of the analog charge
695 pixelCharge = pixelCharge
696 - hitCharge
697 * (1
698 - TMath::Exp(-(readoutTime - hitTime)
699 / pixelSignalFallTime)); //exponential signal fall of the analog charge
700 pixelCharge = pixelCharge * fSensorDataSheet->GetShaperNormalisationFactor();
701 }
702
703 return pixelCharge;
704}
705
706// ------------------------------------------------------------------------------
707
708
710{
715 // CbmMvdSensor* mySensor; // not used FU 12.05.23
716
717
718 return (GetPixelCharge(myPixel, readoutTime) > fSensorDataSheet->GetAnalogThreshold());
719}
720/*
721Bool_t CbmMvdSensorDigitizerTask::GetPixelIsBusy(CbmMvdPixelCharge* myPixel, Double_t readoutTime) {}
722*/
723
724
725// ------------------------------------------------------------------------------
726
727
728// -------------------------------------------------------------------------
729void CbmMvdSensorDigitizerTask::GetEventInfo(Int_t& inputNr, Int_t& eventNr, Double_t& eventTime)
730{
731
732 // --- The event number is taken from the FairRootManager
733 eventNr = FairRootManager::Instance()->GetEntryNr(); // global MC event number (over all input files)
734
735 // --- In a FairRunAna, take the information from FairEventHeader
736 if (FairRunAna::Instance()) {
737 FairEventHeader* event = FairRunAna::Instance()->GetEventHeader();
738 inputNr = event->GetInputFileId();
739 eventNr = event->GetMCEntryNumber(); // local MC event number (for a given file ID)
740 eventTime = event->GetEventTime();
741 }
742
743 // --- In a FairRunSim, the input number and event time are always zero.
744 else {
745 if (!FairRunSim::Instance()) LOG(fatal) << GetName() << ": neither SIM nor ANA run.";
746 inputNr = 0;
747 eventTime = 0.;
748 }
749}
750// -------------------------------------------------------------------------
751
752// -------------------------------------------------------------------------
754{
759 //Option_t* opt1;
760 //LOG(debug) << "Computing Point ";
761 //point->Print(opt1);
762
763 // Int_t pdgCode = point->GetPdgCode();
764
765 //Transform coordinates of the point into sensor frame
766
767 Double_t globalPositionIn[3] = {point->GetX(), point->GetY(), point->GetZ()};
768 Double_t globalPositionOut[3] = {point->GetXOut(), point->GetYOut(), point->GetZOut()};
769
770 Double_t localPositionIn[3] = {0, 0, 0};
771
772 Double_t localPositionOut[3] = {0, 0, 0};
773
774 fSensor->TopToLocal(globalPositionIn, localPositionIn);
775 fSensor->TopToLocal(globalPositionOut, localPositionOut);
776
777 Int_t pixelX, pixelY;
778 fSensor->LocalToPixel(&localPositionIn[0], pixelX, pixelY);
779
780 // Copy results into variables used by earlier versions
781
782 Double_t entryX = localPositionIn[0];
783 Double_t exitX = localPositionOut[0];
784 Double_t entryY = localPositionIn[1];
785 Double_t exitY = localPositionOut[1];
786 Double_t entryZ = localPositionIn[2];
787 Double_t exitZ = localPositionOut[2];
788
807 // entry and exit from the epi layer ( det ref frame ) :
808 Double_t entryZepi = -fEpiTh / 2;
809 Double_t exitZepi = fEpiTh / 2;
810
811
812 TVector3 a(entryX, entryY, entryZ); // entry in the detector
813 TVector3 b(exitX, exitY, exitZ); // exit from the detector
814 TVector3 c;
815
816 c = b - a; // AB in schema
817
818 TVector3 d;
819 TVector3 e;
820
821 Double_t scale1 = (entryZepi - entryZ) / (exitZ - entryZ);
822 Double_t scale2 = (exitZepi - entryZ) / (exitZ - entryZ);
823
824
825 d = c * scale1;
826 e = c * scale2;
827
828 TVector3 entryEpiCoord;
829 TVector3 exitEpiCoord;
830
831 entryEpiCoord = d + a;
832 exitEpiCoord = e + a;
833
834
835 //Get x and y coordinates at the ENTRY of the epi layer
836 Double_t entryXepi = entryEpiCoord.X();
837 Double_t entryYepi = entryEpiCoord.Y();
838 entryZepi = entryEpiCoord.Z();
839
840 //Get x and y coordinates at the EXIT of the epi layer
841 Double_t exitXepi = exitEpiCoord.X();
842 Double_t exitYepi = exitEpiCoord.Y();
843 exitZepi = exitEpiCoord.Z();
844
845
846 Double_t lx = -(entryXepi - exitXepi); //length of segment x-direction
847 Double_t ly = -(entryYepi - exitYepi);
848 Double_t lz = -(entryZepi - exitZepi);
849
850
851 //-----------------------------------------------------------
852
853
854 Double_t rawLength = sqrt(lx * lx + ly * ly + lz * lz); //length of the track inside the epi-layer, in cm
855 Double_t trackLength = 0;
856
857 if (rawLength < 1.0e+3) {
858 trackLength = rawLength;
859 }
860
861 else {
862 LOG(warning) << GetName() << " : rawlength > 1.0e+3 : " << rawLength;
863 trackLength = 1.0e+3;
864 }
865
866 //Smear the energy on each track segment
867 Double_t charge = fLandauRandom->Landau(fLandauGain, fLandauSigma / fLandauMPV);
868
869 LOG(debug) << "CbmMvdSensorTask:: ProduceIonisationPoints() : LandauCharge = " << charge << endl;
870
871 if (charge > (12000 / fLandauMPV)) {
872 charge = 12000 / fLandauMPV;
873 } //limit Random generator behaviour
874
875 if (fShowDebugHistos) {
877 }
878 //Translate the charge to normalized energy
879
880 // LOG(debug) << "charge after random generator " << charge;
881 Double_t dEmean = charge / (fElectronsPerKeV * 1e6);
882 // LOG(debug) << "dEmean " << dEmean;
883 fNumberOfSegments = int(trackLength / fSegmentLength) + 1;
884
885 dEmean = dEmean * ((Double_t) trackLength / fEpiTh); //scale the energy to the track length
886
887 dEmean = dEmean / ((Double_t) fNumberOfSegments); // From this point dEmean corresponds to the E lost per segment.
888
889
891
892 fEsum = 0.0;
893
894 //Double_t segmentLength_update = trackLength/((Double_t)fNumberOfSegments);
895
896 if (lz != 0) {
901 fSegmentDepth = fEpiTh / ((Double_t) fNumberOfSegments);
902 }
903 else { //condition added 05/08/08
904 fSegmentDepth = 0;
905 LOG(warning) << GetName() << " Length of track in detector (z-direction) is 0!!!";
906 }
907
908
909 Double_t x = 0, y = 0, z = 0;
910
911 Double_t xDebug = 0, yDebug = 0, zDebug = 0;
912 Float_t totalSegmentCharge = 0;
913
914 for (int i = 0; i < fNumberOfSegments; ++i) {
915
916 z = -fEpiTh / 2 + ((double) (i) + 0.5) * fSegmentDepth; //middle position of the segment; zdirection
917 x = entryXepi
918 + ((double) (i) + 0.5) * (lx / ((Double_t) fNumberOfSegments)); //middle position of the segment; xdirection
919 y = entryYepi
920 + ((double) (i) + 0.5) * (ly / ((Double_t) fNumberOfSegments)); //middle position of the segment; ydirection
921
922 if (fShowDebugHistos) {
923 xDebug = xDebug + x;
924 yDebug = yDebug + y;
925 zDebug = zDebug + z;
926 };
927
928 SignalPoint* sPoint = &fSignalPoints[i];
929
930 fEsum = fEsum + dEmean;
931 sPoint->eloss = dEmean;
932 sPoint->x = x; //here the coordinates x,y,z are given in the sensor reference frame.
933 sPoint->y = y;
934 sPoint->z = z;
935 charge = 1.0e+6 * dEmean * fElectronsPerKeV;
936 //LOG(debug) << "charge " << charge;
937 sPoint->sigmaX = fPixelSize;
938 sPoint->sigmaY = fPixelSize;
939 sPoint->charge = charge;
940 totalSegmentCharge = totalSegmentCharge + charge;
941 }
942 //if (fShowDebugHistos ) LOG(debug) << "totalSegmentCharge " << totalSegmentCharge << endl;
943 if (fShowDebugHistos) {
944 fTotalSegmentChargeHisto->Fill(totalSegmentCharge * fLandauMPV);
945 fSegResolutionHistoX->Fill(xDebug / fNumberOfSegments - (point->GetX() + point->GetXOut()) / 2 - fSensor->GetX());
946 fSegResolutionHistoY->Fill(yDebug / fNumberOfSegments - (point->GetY() + point->GetYOut()) / 2 - fSensor->GetY());
947 fSegResolutionHistoZ->Fill(zDebug / fNumberOfSegments - (point->GetZ() + point->GetZOut()) / 2 - fSensor->GetZ());
948 }
949}
950
951
952// -------------------------------------------------------------------------
953
955{
961
962
963 // MDx - Variables needed in order to compute a "Monte Carlo Center of Gravity" of the cluster
964
965 Float_t xCharge = 0., yCharge = 0., totClusterCharge = 0.;
966 CbmMvdPixelCharge* pixel;
967
968 pair<Int_t, Int_t> thispoint;
969
970 Double_t xCentre, yCentre, sigmaX, sigmaY, xLo, xUp, yLo, yUp;
971
972 SignalPoint* sPoint;
973 sPoint = &fSignalPoints[0];
974
975 xCentre = sPoint->x; //of segment
976 yCentre = sPoint->y;
977 sigmaX = sPoint->sigmaX;
978 sigmaY = sPoint->sigmaY;
979
980 xLo = sPoint->x - fWidthOfCluster * sigmaX;
981 xUp = sPoint->x + fWidthOfCluster * sigmaX;
982 yLo = sPoint->y - fWidthOfCluster * sigmaY;
983 yUp = sPoint->y + fWidthOfCluster * sigmaY;
984
985 if (fNumberOfSegments < 2) {
986 LOG(fatal) << "fNumberOfSegments < 2, this makes no sense, check parameters.";
987 }
988
989 Int_t* lowerXArray = new Int_t[fNumberOfSegments];
990 Int_t* upperXArray = new Int_t[fNumberOfSegments];
991 Int_t* lowerYArray = new Int_t[fNumberOfSegments];
992 Int_t* upperYArray = new Int_t[fNumberOfSegments];
993
994 Int_t ixLo, ixUp, iyLo, iyUp;
995
996
997 Double_t minCoord[] = {xLo, yLo};
998 Double_t maxCoord[] = {xUp, yUp};
999
1000
1001 fSensor->LocalToPixel(minCoord, lowerXArray[0], lowerYArray[0]);
1002 fSensor->LocalToPixel(maxCoord, upperXArray[0], upperYArray[0]);
1003
1004
1005 if (lowerXArray[0] < 0) lowerXArray[0] = 0;
1006 if (lowerYArray[0] < 0) lowerYArray[0] = 0;
1007 if (upperXArray[0] > fNPixelsX) upperXArray[0] = fNPixelsX;
1008 if (upperYArray[0] > fNPixelsY) upperYArray[0] = fNPixelsY;
1009
1010 ixLo = lowerXArray[0];
1011 iyLo = lowerYArray[0];
1012 ixUp = upperXArray[0];
1013 iyUp = upperYArray[0];
1014
1015
1016 for (Int_t i = 1; i < fNumberOfSegments; i++) {
1017
1018 sPoint = &fSignalPoints[i];
1019 sigmaX = sPoint->sigmaX;
1020 sigmaY = sPoint->sigmaY;
1021
1022 minCoord[0] = sPoint->x - fWidthOfCluster * sigmaX;
1023 minCoord[1] = sPoint->y - fWidthOfCluster * sigmaY;
1024 maxCoord[0] = sPoint->x + fWidthOfCluster * sigmaX;
1025 maxCoord[1] = sPoint->y + fWidthOfCluster * sigmaY;
1026
1027
1028 fSensor->LocalToPixel(minCoord, lowerXArray[i], lowerYArray[i]);
1029 fSensor->LocalToPixel(maxCoord, upperXArray[i], upperYArray[i]);
1030
1031 if (lowerXArray[i] < 0) lowerXArray[i] = 0;
1032 if (lowerYArray[i] < 0) lowerYArray[i] = 0;
1033
1034 if (upperXArray[i] > fNPixelsX) upperXArray[i] = fNPixelsX;
1035 if (upperYArray[i] > fNPixelsY) upperYArray[i] = fNPixelsY;
1036
1037 if (ixLo > lowerXArray[i]) {
1038 ixLo = lowerXArray[i];
1039 }
1040 if (ixUp < upperXArray[i]) {
1041 ixUp = upperXArray[i];
1042 }
1043 if (iyLo > lowerYArray[i]) {
1044 iyLo = lowerYArray[i];
1045 }
1046 if (iyUp < upperYArray[i]) {
1047 iyUp = upperYArray[i];
1048 }
1049 }
1050
1051
1052 //LOG(debug) << "Scanning from x= " << ixLo << " to " <<ixUp <<" and y= "<<iyLo<< " to " << iyUp;
1053
1054 // loop over all pads of interest.
1055 fPixelChargeShort.clear();
1056 Int_t ix, iy;
1057
1058
1059 for (ix = ixLo; ix < ixUp + 1; ix++) {
1060
1061 for (iy = iyLo; iy < iyUp + 1; iy++) {
1062
1063 //calculate the position of the current pixel in the lab-system
1064
1065 Double_t Current[3];
1066 fSensor->PixelToLocal(ix, iy, Current);
1067 pixel = nullptr; //decouple pixel-pointer from previous pixel
1068
1069 //loop over segments, check if the pad received some charge
1070 for (Int_t i = 0; i < fNumberOfSegments; ++i) {
1071 // LOG(debug) << "check segment nr. " << i << " from " << fNumberOfSegments;
1072 // ignore pads, which are out of reach for this segments
1073 if (ix < lowerXArray[i]) {
1074 continue;
1075 }
1076 if (iy < lowerYArray[i]) {
1077 continue;
1078 }
1079 if (ix > upperXArray[i]) {
1080 continue;
1081 }
1082 if (iy > upperYArray[i]) {
1083 continue;
1084 }
1085
1086 // LOG(debug) << "found vallied pad " << i;
1087 sPoint = &fSignalPoints[i];
1088
1089 xCentre = sPoint->x; //of segment
1090 yCentre = sPoint->y; // idem
1091 sigmaX = sPoint->sigmaX;
1092 sigmaY = sPoint->sigmaY;
1093
1094 fCurrentTotalCharge += sPoint->charge;
1095
1096 //compute the charge distributed to this pixel by this segment
1097 // Float_t totCharge = (sPoint->charge * fLorentzNorm * (0.5 * fPar0 * fPar1 / TMath::Pi())
1098 // / TMath::Max(1.e-10, (((Current[0] - xCentre) * (Current[0] - xCentre))
1099 // + ((Current[1] - yCentre) * (Current[1] - yCentre)))
1100 // / fPixelSize / fPixelSize
1101 // + 0.25 * fPar1 * fPar1)
1102 // + fPar2);
1103
1104 Float_t totCharge =
1105 sPoint->charge * fLorentzNorm * fSensorDataSheet->ComputeCCE(xCentre, yCentre, 0, Current[0], Current[1], 0);
1106
1107 if (totCharge < 1) {
1108
1109 // LOG(debug) << "charge is " << totCharge << " < 1 electron thus charge is negligible";
1110 continue;
1111 } //ignore negligible charge (< 1 electron)
1112 if (!pixel) {
1113 // LOG(debug) << "charge is " << totCharge << " > 1 electron thus pixel is firred at "<< ix << " " << iy;
1114 // Look for pixel in charge map if not yet linked.
1115 thispoint = std::make_pair(ix, iy);
1116 // LOG(debug) << "creat pair at "<< ix << " " << iy;
1117 fChargeMapIt = fChargeMap.find(thispoint);
1118 // LOG(debug) << "found pair at "<< ix << " " << iy;
1119 // LOG(debug) << "Map size is now " << fChargeMap.size();
1120 // Pixel not yet in map -> Add new pixel
1121 if (fChargeMapIt == fChargeMap.end()) {
1122 pixel = new ((*fPixelCharge)[fPixelCharge->GetEntriesFast()]) CbmMvdPixelCharge(totCharge, ix, iy);
1123 //LOG(debug) << "new charched pixel with charge " << totCharge << " at " << ix << " " << iy;
1124 // fPixelChargeShort.push_back(pixel);
1125 // LOG(debug) << "added pixel to ChargeShort vector ";
1126
1127 fChargeMap[thispoint] = pixel;
1128 }
1129
1130 // Pixel already in map -> Add charge
1131 else {
1132 pixel = fChargeMapIt->second;
1133 //if ( ! pixel ) Fatal("AddChargeToPixel", "Zero pointer in charge map!");
1134 pixel->AddCharge(totCharge);
1135 // if(pixel->GetCharge()>150)
1136 // {LOG(debug) << "added charge to pixel summing up to "<< pixel->GetCharge();}
1137 }
1138 fPixelChargeShort.push_back(pixel);
1139 }
1140 else { //pixel already linked => add charge only
1141 pixel->AddCharge(totCharge);
1142 // LOG(debug) <<"put charge";
1143 }
1144
1145 totClusterCharge = totClusterCharge + totCharge;
1146 if (fShowDebugHistos) {
1147 xCharge = xCharge + Current[0] * totCharge;
1148 yCharge = yCharge + Current[1] * totCharge;
1149 totClusterCharge = totClusterCharge + totCharge;
1150 } // end if
1151 } // end for (track segments)
1152
1153
1154 } //for y
1155 } // for x
1156 // LOG(debug) << "End of loops ";
1157 std::vector<CbmMvdPixelCharge*>::size_type vectorSize = fPixelChargeShort.size();
1158
1159 for (ULong64_t f = 0; f < vectorSize; f++) {
1160 CbmMvdPixelCharge* pixelCharge = fPixelChargeShort.at(f);
1161 if (pixelCharge) {
1162 pixelCharge->DigestCharge(((float) (point->GetX() + point->GetXOut()) / 2),
1163 ((float) (point->GetY() + point->GetYOut()) / 2), fEventTime + point->GetTime(),
1164 point->GetPointId(), point->GetTrackID(), fInputNr, fEventNr);
1165
1166
1167 // So far, the charge created by this MC-hit in a given pixel was added up in the Pixel charge objects.
1168 // Digest charge closes the summing and adds the MC information related to the hit. The MC information will be forwarded to the digi links later.
1169 // Digest charge also stores the history of the pixel to process possible dead times of the sensor.
1170
1171 Float_t latestHitCharge = pixelCharge->GetLatestHitCharge();
1172 Double_t endOfBusyTime =
1173 fSensor->ComputeEndOfBusyTime(fEventTime + point->GetTime(), latestHitCharge, pixelCharge->GetY());
1174 /* LOG(debug) << "CbmMvdSensorDigitizerTask::ProducePixelCharge() - latestHitCharge = "<< latestHitCharge;
1175 LOG(debug) << "CbmMvdSensorDigitizerTask::ProducePixelCharge() - MCTime = "<< fEventTime + point->GetTime();
1176 LOG(debug) << "CbmMvdSensorDigitizerTask::ProducePixelCharge() - EndOfBusyTime = "<< endOfBusyTime;
1177 */
1178
1179 if (endOfBusyTime > pixelCharge->GetEndOfBusyTime()) {
1180 pixelCharge->SetEndOfBusyTime(endOfBusyTime);
1181 }
1182
1183 /* Next, the pixelChargeObject is combined with a time information on the endOfBusyTime of the pixelChargeObject.
1184 * This end of busy is reached once the related channel is ready for receiving new hit information.
1185 * In case a hit arrives until then, the information is recorded and the end-of-busy is postponed in accordance with the new hit.
1186 * Note: This endOfBusyTime is not equal to the analog dead time of the channel but accounts also for the frame readout.
1187 */
1188
1189 LOG(debug) << "CbmMvdSensorDigitizerTask: Produced pixelCharge with charge " << latestHitCharge;
1190 }
1191 else {
1192 LOG(warning) << "Warning working on broken pixel ";
1193 }
1194 }
1195 LOG(debug) << "CbmMvdSensorDigitizerTask: Produced cluster with " << fPixelChargeShort.size()
1196 << " active pixels and with total charge of " << totClusterCharge;
1197 if (fShowDebugHistos) {
1198 //LOG(debug) << "produced " << fPixelChargeShort.size() << " Digis with total charge of " << totClusterCharge;
1199 TVector3 momentum, position;
1200 if (totClusterCharge > 0) fTotalChargeHisto->Fill(totClusterCharge);
1201 point->Position(position);
1202 point->Momentum(momentum);
1203 fPosXY->Fill(position.X(), position.Y());
1204 fpZ->Fill(momentum.Z());
1205 fPosXinIOut->Fill(point->GetZ() - point->GetZOut());
1206 fAngle->Fill(TMath::ATan(momentum.Pt() / momentum.Pz()) * 180 / TMath::Pi());
1207 }
1208
1209 delete[] lowerXArray;
1210 delete[] upperXArray;
1211 delete[] lowerYArray;
1212 delete[] upperYArray;
1213
1214
1215} //end of function
1216
1217
1218// -------------------------------------------------------------------------
1219
1221{
1222 Int_t fmaxNoise = 100;
1223 Int_t noiseHits = (Int_t)(gRandom->Rndm(fmaxNoise) * fmaxNoise);
1224 Int_t xPix, yPix;
1225 CbmMvdPixelCharge* pixel;
1226 pair<Int_t, Int_t> thispoint;
1227
1228 for (Int_t i = 0; i <= noiseHits; i++) {
1229 xPix = gRandom->Integer(fNPixelsX);
1230 yPix = gRandom->Integer(fNPixelsY);
1231
1232 Double_t Current[3];
1233 fSensor->PixelToLocal(xPix, yPix, Current);
1234
1235 thispoint = std::make_pair(xPix, yPix);
1236
1237 fChargeMapIt = fChargeMap.find(thispoint);
1238
1239 if (fChargeMapIt == fChargeMap.end()) {
1240 pixel =
1241 new ((*fPixelCharge)[fPixelCharge->GetEntriesFast()]) CbmMvdPixelCharge(1000, xPix, yPix); // TODO: Add time
1242 pixel->DigestCharge(Current[0], Current[1], fEventTime, 0, -4, -1, -1);
1243 fChargeMap[thispoint] = pixel;
1244 }
1245 else {
1246 pixel = fChargeMapIt->second;
1247 pixel->AddCharge(1000); // TODO: Add time
1248 pixel->DigestCharge(Current[0], Current[1], fEventTime, 0, -4, -1, -1);
1249 }
1250 }
1251}
1252// -------------------------------------------------------------------------
1253
1254// -------------------------------------------------------------------------
1255
1256
1257// ----- Virtual private method SetParContainers -----------------------
1259{
1260 // FairRunAna* ana = FairRunAna::Instance();
1261 // FairRuntimeDb* rtdb = ana->GetRuntimeDb();
1262}
1263// -------------------------------------------------------------------------
1264
1265
1266// ----- Virtual private method Init ----------------------------------
1268{
1269
1270 //Read information on the sensor von data base
1271 fSensor = mySensor;
1272
1273 // LOG(info) << GetName() << ": Initialisation of sensor " << fSensor->GetName();
1274
1275 fDigis = new TClonesArray("CbmMvdDigi", 100);
1276 fDigiMatch = new TClonesArray("CbmMatch", 100);
1277
1278 fOutputBuffer = new TClonesArray("CbmMvdDigi", 100);
1279 fInputPoints = new TClonesArray("CbmMvdPoint", 100);
1280
1281 if (!fSensor) {
1282 LOG(fatal) << "Init(CbmMvdSensor*) called without valid pointer, don't know how to proceed.";
1283 };
1284
1286
1287 // Initialize histogramms used for debugging
1288
1289 if (fShowDebugHistos) {
1290 fHistoArray = new TObjArray();
1291 LOG(info) << "Show debug histos in this Plugin";
1292 fRandomGeneratorTestHisto = new TH1F("TestHisto", "TestHisto", 1000, 0, 12000);
1293 fResolutionHistoX = new TH1F("DigiResolutionX", "DigiResolutionX", 1000, -.005, .005);
1294 fResolutionHistoY = new TH1F("DigiResolutionY", "DigiResolutionY", 1000, -.005, .005);
1295 fPosXY = new TH2F("DigiPointXY", "DigiPointXY", 100, -6, 6, 100, -6, 6);
1296 fpZ = new TH1F("DigiPointPZ", "DigiPointPZ", 1000, -0.5, 0.5);
1297 fPosXinIOut = new TH1F("DigiZInOut", "Digi Z InOut", 1000, -0.04, 0.04);
1298 fAngle = new TH1F("DigiAngle", "DigiAngle", 1000, 0, 90);
1299 fSegResolutionHistoX = new TH1F("SegmentResolutionX", "SegmentResolutionX", 1000, -.005, .005);
1300 fSegResolutionHistoY = new TH1F("SegmentResolutionY", "SegmentResolutionY", 1000, -.005, .005);
1301 fSegResolutionHistoZ = new TH1F("SegmentResolutionZ", "SegmentResolutionZ", 1000, -.005, .005);
1302 fTotalChargeHisto = new TH1F("TotalChargeHisto", "TotalChargeHisto", 1000, 0, 12000);
1303 fTotalSegmentChargeHisto = new TH1F("TotalSegmentChargeHisto", "TotalSegmentChargeHisto", 1000, 0, 12000);
1304
1305 // Push histograms into the related array as required for communicating them to the steering classes (CbmMvdDetector, FairTask)
1309 fHistoArray->AddLast(fPosXY);
1310 fHistoArray->AddLast(fpZ);
1311 fHistoArray->AddLast(fPosXinIOut);
1312 fHistoArray->AddLast(fAngle);
1318 }
1319
1321 LOG(info) << GetName() << " initialised with parameters: ";
1323
1324 fPreviousPlugin = nullptr;
1325 initialized = kTRUE;
1326}
1327// -------------------------------------------------------------------------
1328
1329
1330// ----- Virtual public method Reinit ----------------------------------
1332{
1333
1334 delete fOutputBuffer;
1335
1336 InitTask(sensor);
1337}
1338// -------------------------------------------------------------------------
1339
1340
1341// ----- Virtual method Finish -----------------------------------------
1343{
1344
1345 // Convert the CbmMvdPixelCharge still in the buffer to CbmMvdDigis
1346 fOutputBuffer->Clear("C");
1347 fDigis->Clear("C");
1348 fDigiMatch->Clear("C");
1349
1351 LOG(debug) << "CbmMvdSensorDigitizerTask::Finish() - NumberOfPixelCharge = " << fPixelCharge->GetEntriesFast();
1352
1353 for (Int_t i = 0; i < fPixelCharge->GetEntriesFast(); i++) {
1355
1356 FlushBuffer(pixel, i);
1357 }
1358
1359 // PrintParameters();
1360
1361
1362 if (kFALSE && fShowDebugHistos) { // Finish code of initial FairTask. Switched off right now.
1363 TCanvas* c = new TCanvas("DigiCanvas", "DigiCanvas", 150, 10, 800, 600);
1364 c->Divide(3, 3);
1365 c->cd(1);
1366 fResolutionHistoX->Draw();
1367 fResolutionHistoX->Write();
1368 c->cd(2);
1369 fResolutionHistoY->Draw();
1370 fResolutionHistoY->Write();
1371 c->cd(3);
1372 fPosXY->Draw();
1373 fPosXY->Write();
1374 c->cd(4);
1375 fpZ->Draw();
1376 fpZ->Write();
1377 c->cd(5);
1378 fPosXinIOut->Draw();
1379 fPosXinIOut->Write();
1380 c->cd(6);
1381 fAngle->Draw();
1382 fAngle->Write();
1383 c->cd(7);
1384 //fSegResolutionHistoX->Draw();
1385 fSegResolutionHistoX->Write();
1387 fTotalSegmentChargeHisto->Write();
1388 c->cd(8);
1391
1392 fSegResolutionHistoY->Write();
1393 c->cd(9);
1394 fTotalChargeHisto->Draw();
1395 fTotalChargeHisto->Write();
1396 LOG(info) << "CbmMvdDigitizerL::Finish - Fit of the total cluster charge";
1397 fTotalChargeHisto->Fit("landau");
1398 // new TCanvas();
1399 //fTotalChargeHisto->Draw();
1400 };
1401}
1402// -------------------------------------------------------------------------
1403
1404
1405// ----- Private method Reset ------------------------------------------
1407// -------------------------------------------------------------------------
1408
1410
1411// ----- Private method PrintParameters --------------------------------
1413{
1414
1415 std::stringstream ss;
1416 ss.setf(ios_base::fixed, ios_base::floatfield);
1417 ss << "============================================================" << endl;
1418 ss << "============== Parameters of the Lorentz - Digitizer =======" << endl;
1419 ss << "============================================================" << endl;
1420
1421
1422 ss << "Pixel Size X : " << setw(8) << setprecision(2) << fPixelSizeX * 10000. << " mum" << endl;
1423 ss << "Pixel Size Y : " << setw(8) << setprecision(2) << fPixelSizeY * 10000. << " mum" << endl;
1424 ss << "Epitaxial layer thickness : " << setw(8) << setprecision(2) << fEpiTh * 10000. << " mum" << endl;
1425 ss << "Segment Length : " << setw(8) << setprecision(2) << fSegmentLength * 10000. << " mum" << endl;
1426 ss << "Diffusion Coefficient : " << setw(8) << setprecision(2) << fDiffusionCoefficient * 10000. << " mum"
1427 << endl;
1428 ss << "Width of Cluster : " << setw(8) << setprecision(2) << fWidthOfCluster << " * sigma " << endl;
1429 ss << "ElectronsPerKeV 3.62 eV/eh : " << setw(8) << setprecision(2) << fElectronsPerKeV << endl;
1430 ss << "CutOnDeltaRays : " << setw(8) << setprecision(8) << fCutOnDeltaRays << " MeV " << endl;
1431 ss << "ChargeThreshold : " << setw(8) << setprecision(2) << fChargeThreshold << endl;
1432 ss << "Pileup: " << fNPileup << endl;
1433 ss << "Delta - Pileup: " << fNDeltaElect << endl;
1434 ss << "=============== End Parameters Digitizer ===================" << endl;
1435 return ss.str();
1436}
1437// -------------------------------------------------------------------------
1438
1439
ClassImp(CbmMvdSensorDigitizerTask)
friend fvec sqrt(const fvec &a)
void AddLink(const CbmLink &newLink)
Definition CbmMatch.cxx:47
std::vector< Int_t > & GetEventNr()
Float_t GetEarliestHitCharge()
void SetEndOfBusyTime(Double_t endOfBusyTime)
std::vector< Int_t > & GetInputNr()
std::vector< Double_t > & GetTime()
void DigestCharge(Float_t pointX, Float_t pointY, Double_t time, Int_t PointId, Int_t trackId, Int_t inputNr, Int_t eventNr)
void AddCharge(Float_t charge)
std::vector< Int_t > & GetPointID()
std::vector< Int_t > & GetTrackID()
std::vector< Float_t > & GetPointWeight()
std::vector< Float_t > & GetCharge()
int32_t GetFrame() const
Definition CbmMvdPoint.h:83
double GetXOut() const
Definition CbmMvdPoint.h:67
int32_t GetPointId() const
Definition CbmMvdPoint.h:76
int32_t GetStationNr() const
Definition CbmMvdPoint.h:75
double GetZOut() const
Definition CbmMvdPoint.h:69
double GetYOut() const
Definition CbmMvdPoint.h:68
int32_t GetPdgCode() const
Definition CbmMvdPoint.h:73
virtual Double_t GetSignalRiseTime()
virtual Double_t GetEpiThickness()
virtual Float_t GetShaperNormalisationFactor()
virtual Double_t GetLorentzPar1()
virtual Double_t GetPixelPitchX()
virtual Double_t ComputeCCE(Float_t chargePointX, Float_t chargePointY, Float_t chargePointZ, Float_t diodeX, Float_t diodeY, Float_t diodeZ)
virtual Double_t GetLandauMPV()
virtual Double_t GetPixelPitchY()
virtual Double_t GetLandauSigma()
virtual Double_t GetChargeThreshold()
virtual Double_t GetLandauGain()
virtual Double_t GetSignalFallTime()
virtual Double_t GetLorentzPar0()
virtual Double_t GetLorentzPar2()
CbmMvdSensorDataSheet * fSensorDataSheet
std::map< std::pair< Int_t, Int_t >, CbmMvdPixelCharge * >::iterator fChargeMapIt
Int_t CheckForHit(CbmMvdPixelCharge *pixel)
void ProduceIonisationPoints(CbmMvdPoint *point)
virtual void InitTask(CbmMvdSensor *mySensor)
virtual void ReInit(CbmMvdSensor *mySensor)
Int_t GetPixelCharge(CbmMvdPixelCharge *myPixel, Double_t readoutTime)
std::vector< CbmMvdPixelCharge * > fPixelChargeShort
void GetEventInfo(Int_t &inputNr, Int_t &eventNr, Double_t &eventTime)
void FlushBuffer(CbmMvdPixelCharge *pixel, Int_t i)
std::map< std::pair< Int_t, Int_t >, CbmMvdPixelCharge * > fChargeMap
Bool_t GetSignalAboveThreshold(CbmMvdPixelCharge *myPixel, Double_t readoutTime)
void SetInputArray(TClonesArray *inputStream)
void ProducePixelCharge(CbmMvdPoint *point)
virtual TClonesArray * GetOutputArray()
CbmMvdSensorPlugin * fPreviousPlugin
virtual const char * GetName() const
CbmMvdSensor * fSensor
TClonesArray * fOutputBuffer
Int_t GetFrameNumber(Double_t absoluteTime, Int_t pixelNumberY=0) const
void TopToLocal(Double_t *lab, Double_t *local)
Double_t GetY() const
Int_t GetSensorNr() const
void PixelToLocal(Int_t pixelNumberX, Int_t pixelNumberY, Double_t *local)
Double_t GetX() const
void LocalToPixel(Double_t *local, Int_t &pixelNumberX, Int_t &pixelNumberY)
Double_t GetZ() const
Double_t ComputeEndOfBusyTime(Double_t hitMCTime, Float_t diodeCharge, Int_t pixelNumberY)
Double_t ComputeIndecatedAnalogTime(Double_t hitMCTime, Float_t diodeCharge)
CbmMvdSensorDataSheet * GetDataSheet()