23#include "TProfile2D.h"
84 mMCTruthContainerNext[
j] = &(mMCTruthContainer[
j + 1]);
107 if (readoutwindow < mReadoutWindowCurrent && mReadoutWindowCurrent - readoutwindow > max_readout_diff) {
116 checkIfReuseFutureDigits();
120 for (
auto& hit : *hits) {
123 if (hit.GetTime() > max_hit_time) {
148Int_t Digitizer::processHit(
const HitType& hit, Double_t event_time)
155 Int_t detIndOtherPad[5];
159 detIndOtherPad[0] = detInd[0], detIndOtherPad[1] = detInd[1],
160 detIndOtherPad[2] = detInd[2];
163 if (detInd[3] == 0) {
167 Int_t iZshift = otherraw ? 1 : -1;
193 mXLastShift[mNLastHit] = 0;
194 mZLastShift[mNLastHit] = 0;
195 addDigit(channel, istrip,
time, xLocal, zLocal,
charge, 0, 0, detInd[3], trackID, hit.
GetTime(), event_time * 1E3);
199 detIndOtherPad[3] = otherraw;
200 detIndOtherPad[4] = detInd[4];
202 xLocal = deltapos[0];
210 mXLastShift[mNLastHit] = 0;
211 mZLastShift[mNLastHit] = iZshift;
212 addDigit(channel, istrip,
time, xLocal, zLocal,
charge, 0, iZshift, detInd[3], trackID, hit.
GetTime(), event_time * 1E3);
216 detIndOtherPad[3] = detInd[3];
217 detIndOtherPad[4] = detInd[4] - 1;
218 if (detIndOtherPad[4] >= 0) {
221 zLocal = deltapos[2];
224 mXLastShift[mNLastHit] = -1;
225 mZLastShift[mNLastHit] = 0;
226 addDigit(channel, istrip,
time, xLocal, zLocal,
charge, -1, 0, detInd[3], trackID, hit.
GetTime(), event_time * 1E3);
231 detIndOtherPad[3] = detInd[3];
232 detIndOtherPad[4] = detInd[4] + 1;
236 zLocal = deltapos[2];
239 mXLastShift[mNLastHit] = 1;
240 mZLastShift[mNLastHit] = 0;
241 addDigit(channel, istrip,
time, xLocal, zLocal,
charge, 1, 0, detInd[3], trackID, hit.
GetTime(), event_time * 1E3);
246 detIndOtherPad[3] = otherraw;
247 detIndOtherPad[4] = detInd[4] - 1;
248 if (detIndOtherPad[4] >= 0) {
258 mXLastShift[mNLastHit] = -1;
259 mZLastShift[mNLastHit] = iZshift;
260 addDigit(channel, istrip,
time, xLocal, zLocal,
charge, -1, iZshift, detInd[3], trackID, hit.
GetTime(), event_time * 1E3);
265 detIndOtherPad[3] = otherraw;
266 detIndOtherPad[4] = detInd[4] + 1;
277 mXLastShift[mNLastHit] = 1;
278 mZLastShift[mNLastHit] = iZshift;
279 addDigit(channel, istrip,
time, xLocal, zLocal,
charge, 1, iZshift, detInd[3], trackID, hit.
GetTime(), event_time * 1E3);
287 Int_t padZfired, Int_t trackID,
float geanttime,
double t0)
291 if (mCalibApi->
isOff(channel)) {
310 Float_t timewalkX =
x * mTimeWalkeSlope;
316 time += gRandom->Gaus(mTimeDelay, extraTimeSmear);
326 time += TMath::Sqrt(timewalkX * timewalkX + timewalkZ * timewalkZ) - mTimeDelayCorr - mTimeWalkeSlope * 2;
330 if (std::abs(tsCorr) > 200E3) {
331 LOG(error) <<
"Wrong de-calibration correction for ch = " << channel <<
", tot = " << tot <<
" (Skip it)";
335 mTimeLastHit[mNLastHit] =
time;
336 mTotLastHit[mNLastHit] = tot;
359 bool iscurrent =
true;
361 Int_t isIfOverlap = -1;
367 if (isnext == isIfOverlap) {
369 }
else if (isnext < 0 && isIfOverlap >= 0) {
370 isnext = isIfOverlap;
373 isnext = isIfOverlap;
386 lblCurrent = mFutureIevent.size();
387 mFutureIevent.push_back(mEventID);
388 mFutureIsource.push_back(mSrcID);
389 mFutureItrackID.push_back(trackID);
395 lblCurrent = mFutureIevent.size();
396 mFutureIevent.push_back(mEventID);
397 mFutureIsource.push_back(mSrcID);
398 mFutureItrackID.push_back(trackID);
411 std::vector<Strip>* strips;
416 mcTruthContainer = mMCTruthContainerCurrent;
419 mcTruthContainer = mMCTruthContainerNext[isnext - 1];
422 fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID, geanttime,
t0);
424 if (isIfOverlap > -1 && isIfOverlap <
MAXWINDOWS) {
427 mcTruthContainer = mMCTruthContainerCurrent;
430 mcTruthContainer = mMCTruthContainerNext[isIfOverlap - 1];
433 fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID, geanttime,
t0);
437void Digitizer::fillDigitsInStrip(std::vector<Strip>* strips,
o2::dataformats::MCTruthContainer<o2::tof::MCLabel>* mcTruthContainer,
int channel,
int tdc,
int tot, uint64_t nbc, UInt_t istrip, Int_t trackID, Int_t eventID, Int_t sourceID,
float geanttime,
double t0)
440 if (mcTruthContainer) {
444 Int_t lbl = (*strips)[istrip].addDigit(channel, tdc, tot, nbc, lblCurrent, 0, 0, geanttime,
t0);
446 if (mcTruthContainer) {
447 if (lbl == lblCurrent) {
465 return time + gRandom->Gaus(0, mShowerResolution);
473 return time + gRandom->Gaus(0, mDigitResolution);
483 return gRandom->Landau(adcMean, adcRms);
499 Float_t efficiency = TMath::Min(effX, effZ);
501 if (gRandom->Rndm() > efficiency) {
514 if (xborder > mBound1) {
516 }
else if (xborder > mBound2) {
517 return mEffBoundary1 + (mEffCenter - mEffBoundary1) * (xborder - mBound2) / (mBound1 - mBound2);
519 return mEffBoundary2 + (mEffBoundary1 - mEffBoundary2) * xborder / mBound2;
523 if (xborder > mBound4) {
525 }
else if (xborder > mBound3) {
526 return mEffBoundary3 - mEffBoundary3 * (xborder - mBound3) / (mBound4 - mBound3);
528 return mEffBoundary2 + (mEffBoundary3 - mEffBoundary2) * xborder / mBound3;
541 if (zborder > mBound1) {
543 }
else if (zborder > mBound2) {
544 return mEffBoundary1 + (mEffCenter - mEffBoundary1) * (zborder - mBound2) / (mBound1 - mBound2);
546 return mEffBoundary2 + (mEffBoundary1 - mEffBoundary2) * zborder / mBound2;
550 if (zborder > mBound4) {
552 }
else if (zborder > mBound3) {
553 return mEffBoundary3 - mEffBoundary3 * (zborder - mBound3) / (mBound4 - mBound3);
555 return mEffBoundary2 + (mEffBoundary3 - mEffBoundary2) * zborder / mBound3;
567 mShowerResolution = 50;
568 if (mTOFresolution > mShowerResolution) {
569 mDigitResolution = TMath::Sqrt(mTOFresolution * mTOFresolution - mShowerResolution * mShowerResolution);
571 mShowerResolution = mTOFresolution;
572 mDigitResolution = 0;
590 mTimeWalkeSlope = 40;
598 mTimeDelayCorr = mTimeDelay / 3.5;
599 if (mShowerResolution > mTimeDelayCorr) {
600 mShowerResolution = TMath::Sqrt(mShowerResolution * mShowerResolution - mTimeDelayCorr * mTimeDelayCorr);
602 mShowerResolution = 0;
605 if (mShowerResolution > mTimeWalkeSlope * 0.8) {
606 mShowerResolution = TMath::Sqrt(mShowerResolution * mShowerResolution - mTimeWalkeSlope * mTimeWalkeSlope * 0.64);
608 mShowerResolution = 0;
621 printf(
"Efficiency in the pad center = %f\n", mEffCenter);
622 printf(
"Efficiency in the pad border = %f\n", mEffBoundary2);
623 printf(
"Time resolution = %f ps (shower=%f, digit=%f)\n", mTOFresolution, mShowerResolution, mDigitResolution);
624 if (mTimeSlope > 0) {
625 printf(
"Degration resolution for pad with signal induced = %f ps/cm x border distance\n", mTimeSlope);
627 if (mTimeDelay > 0) {
628 printf(
"Time delay for pad with signal induced = %f ps\n", mTimeDelay);
630 if (mTimeWalkeSlope > 0) {
631 printf(
"Time walk ON = %f ps/cm\n", mTimeWalkeSlope);
648 Int_t nhit = 1000000;
656 TH1F*
h =
new TH1F(
"hTime",
"Time as from digitizer;time (ps);N", 100, -500, 500);
657 TH1F* h2 =
new TH1F(
"hTot",
"Tot as from digitizer;time (ns);N", 100, 0, 30);
658 TH1F* h3 =
new TH1F(
"hNdig",
"N_{digitis} distribution from one hit;N_{digits};N", 7, -0.5, 6.5);
659 TH1F* h4 =
new TH1F(
"hTimeCorr",
"Time correlation for double digits;#Deltat (ps)", 200, -1000, 1000);
660 TH1F* h5 =
new TH1F(
"hTimeAv",
"Time average for double digits;#Deltat (ps)", 200, -1000, 1000);
663 for (Int_t
i = 0;
i < 3;
i++) {
664 for (Int_t
j = 0;
j < 3;
j++) {
666 new TH1F(Form(
"hpad%i_%i",
i,
j), Form(
"Time as from digitizer, pad(%i,%i);time (ps);N",
i,
j), 100, -500, 500);
670 TProfile2D* hTimeWalk =
new TProfile2D(
"hTimeWalk",
"Time Walk;x (cm);z (cm)", 40, -1.25, 1.25, 40, -1.75, 1.75);
673 hpadAll =
new TH2F(
"hpadAll",
"all hits;x (cm);z (cm)", 40, -1.25, 1.25, 40, -1.75, 1.75);
676 for (Int_t
i = 0;
i < 3;
i++) {
677 for (Int_t
j = 0;
j < 3;
j++) {
678 hpadHit[
i][
j] =
new TH2F(Form(
"hpadHit%i_%i",
i,
j), Form(
"pad(%i,%i) hits;x (cm);z (cm)",
i - 1, 1 -
j), 40,
679 -1.25, 1.25, 40, -1.75, 1.75);
680 hpadEff[
i][
j] =
new TH2F(Form(
"hpadEff%i_%i",
i,
j), Form(
"pad(%i,%i) hits;x (cm);z (cm)",
i - 1, 1 -
j), 40,
681 -1.25, 1.25, 40, -1.75, 1.75);
685 Int_t det1[5] = {0, 0, 0, 1, 23};
686 Int_t det2[5] = {0, 0, 0, 0, 24};
687 Int_t det3[5] = {0, 0, 0, 1, 24};
688 Int_t det4[5] = {0, 0, 0, 0, 47};
712 mod = TMath::Sqrt(pos3[0] * pos3[0] + pos3[1] * pos3[1] + pos3[2] * pos3[2]);
713 vz[0] = pos3[0] / mod;
714 vz[1] = pos3[1] / mod;
715 vz[2] = pos3[2] / mod;
721 mod = TMath::Sqrt(pos4[0] * pos4[0] + pos4[1] * pos4[1] + pos4[2] * pos4[2]);
722 vx[0] = pos4[0] / mod;
723 vx[1] = pos4[1] / mod;
724 vx[2] = pos4[2] / mod;
726 Float_t x[3], dx, dz, xlocal, zlocal;
728 for (Int_t
i = 0;
i < nhit;
i++) {
729 dx = gRandom->Rndm() * 2.5 * 48;
730 dz = gRandom->Rndm() * 3.5 * 2;
732 xlocal = dx - Int_t(dx / 2.5) * 2.5 - 1.25;
733 zlocal = dz - Int_t(dz / 3.5) * 3.5 - 1.75;
738 x[0] =
pos[0] + vx[0] * dx + vz[0] * dz;
739 x[1] =
pos[1] + vx[1] * dx + vz[1] * dz;
740 x[2] =
pos[2] + vx[2] * dx + vz[2] * dz;
751 Int_t ndigits = mNLastHit;
754 hpadAll->Fill(xlocal, zlocal);
755 for (Int_t k = 0; k < ndigits; k++) {
763 hTimeWalk->Fill(xlocal, zlocal * (0.5 - detCur[3]) * 2,
getTimeLastHit(k));
787 hTimeWalk->Draw(
"SURF");
789 TCanvas* cpad =
new TCanvas();
791 for (Int_t
i = 0;
i < 3;
i++) {
792 for (Int_t
j = 0;
j < 3;
j++) {
793 cpad->cd(
j * 3 +
i + 1);
797 TCanvas* cpadH =
new TCanvas();
799 for (Int_t
i = 0;
i < 3;
i++) {
800 for (Int_t
j = 0;
j < 3;
j++) {
801 cpadH->cd(
j * 3 +
i + 1);
802 hpadHit[
i][
j]->Draw(
"colz");
804 hpadHit[
i][
j]->Scale(2);
806 hpadEff[
i][
j]->Divide(hpadHit[
i][
j], hpadAll, 1, 1,
"B");
807 hpadEff[
i][
j]->Draw(
"surf");
808 hpadEff[
i][
j]->SetMaximum(1);
809 hpadEff[
i][
j]->SetMinimum(0);
810 hpadEff[
i][
j]->SetStats(0);
814 printf(
"\nEfficiency = %f\n", (h3->GetEntries() - h3->GetBinContent(1)) / h3->GetEntries());
815 printf(
"Multiple digits fraction = %f\n\n",
816 (h3->GetEntries() - h3->GetBinContent(1) - h3->GetBinContent(2)) / (h3->GetEntries() - h3->GetBinContent(1)));
824 TFile* fHit =
new TFile(hits);
827 TTree* t = (TTree*)fHit->Get(
"o2sim");
828 Int_t nev = t->GetEntriesFast();
834 TH1F*
h =
new TH1F(
"hTime",
"Time as from digitizer;time (ps);N", 100, -500, 500);
835 TH1F* h2 =
new TH1F(
"hTot",
"Tot as from digitizer;time (ns);N", 100, 0, 30);
836 TH1F* h3 =
new TH1F(
"hNdig",
"N_{digitis} distribution from one hit;N_{digits};N", 7, -0.5, 6.5);
838 for (Int_t
i = 0;
i < nev;
i++) {
840 Int_t nhit = t->GetLeaf(
"o2root.TOF.TOFHit_")->GetLen();
842 for (Int_t
j = 0;
j < nhit;
j++) {
844 hit->
SetXYZ(t->GetLeaf(
"o2root.TOF.TOFHit.mPos.fCoordinates.fX")->GetValue(
j),
845 t->GetLeaf(
"o2root.TOF.TOFHit.mPos.fCoordinates.fY")->GetValue(
j),
846 t->GetLeaf(
"o2root.TOF.TOFHit.mPos.fCoordinates.fZ")->GetValue(
j));
848 hit->
SetEnergyLoss(t->GetLeaf(
"o2root.TOF.TOFHit.mELoss")->GetValue(
j));
853 for (Int_t k = 0; k < ndigits; k++) {
871 mMCTruthOutputContainer->
clear();
876 strip.fillOutputContainer(
digits);
877 if (strip.getNumberOfDigits()) {
878 LOG(
debug) <<
"strip size = " << strip.getNumberOfDigits() <<
" - digit size = " <<
digits.size() <<
"\n";
895 float p = gRandom->Rndm();
901 int itrmreached = -1;
906 if (crateProb[
i] > p) {
908 isEmptyCrate[
i] =
true;
918 isEmptyCrate[
i] =
false;
919 int slotreached = -1;
920 const std::vector<std::pair<int, float>>& trmProg = mCalibApi->
getTRMerrorProb();
921 const std::vector<int>& trmErr = mCalibApi->
getTRMmask();
922 for (
int itrm = itrmreached + 1; itrm < trmProg.size(); itrm++) {
923 int crate = trmProg[itrm].first / 100;
925 int slot = trmProg[itrm].first % 100;
926 if (slot != slotreached) {
931 if (trmProg[itrm].second > p) {
937 for (
int ibit = 0; ibit < 28; ibit++) {
938 if (trmErr[itrm] & cbit) {
947 p -= trmProg[itrm].second;
960 std::map<ULong64_t, o2::tof::Digit>& dmap = strip.getDigitMap();
962 std::vector<ULong64_t> keyToBeRemoved;
964 for (
auto [
key, dig] : dmap) {
969 keyToBeRemoved.push_back(
key);
972 for (
auto&
key : keyToBeRemoved) {
976 strip.fillOutputContainer(
digits);
991 if (mMCTruthOutputContainer) {
1000 mMCTruthOutputContainerPerTimeFrame.push_back(*mMCTruthOutputContainer);
1002 mMCTruthContainerCurrent->
clear();
1016 mMCTruthContainerNext[
i] = &(mMCTruthContainer[k]);
1031 checkIfReuseFutureDigits();
1036 checkIfReuseFutureDigits();
1045 mFutureItrackID.clear();
1046 mFutureIsource.clear();
1047 mFutureIevent.clear();
1050void Digitizer::checkIfReuseFutureDigits()
1052 uint64_t bclimit = 999999999999999999;
1058 if (digit->getBC() > bclimit) {
1066 if (isnext == isIfOverlap) {
1068 }
else if (isnext < 0 && isIfOverlap >= 0) {
1069 isnext = isIfOverlap;
1072 isnext = isIfOverlap;
1077 LOG(info) <<
"Digit lost because we jump too ahead in future. Current RO window=" << isnext <<
"\n";
1080 int labelremoved = digit->getLabel();
1108 mcTruthContainer = mMCTruthContainerNext[isnext - 1];
1111 int trackID = mFutureItrackID[digit->getLabel()];
1112 int sourceID = mFutureIsource[digit->getLabel()];
1113 int eventID = mFutureIevent[digit->getLabel()];
1114 fillDigitsInStrip(strips, mcTruthContainer, digit->getChannel(), digit->getTDC(), digit->getTOT(), digit->getBC(), digit->getChannel() /
Geo::NPADS, trackID, eventID, sourceID, digit->getTgeant());
1116 if (isIfOverlap < 0) {
1118 int labelremoved = digit->getLabel();
1136 bclimit = digit->getBC();
std::vector< std::string > labels
Definition of the GeometryManager class.
Class for time synchronization of RawReader instances.
void SetEnergyLoss(V val)
void SetXYZ(T x, T y, T z)
static void loadGeometry(std::string_view geomFilePath="", bool applyMisalignment=false, bool preferAlignedFile=true)
static const HBFUtils & Instance()
bool isChannelError(int channel) const
const float * getEmptyCratesProb() const
const std::vector< std::pair< int, float > > & getTRMerrorProb() const
void readTimeSlewingParam()
void setTimeStamp(long t)
float getDRMprobError(int crate, int type) const
float getEmptyTOFProb() const
void processError(int crate, int trm, int mask)
bool isChannelDRMError(int channel) const
float getTimeDecalibration(int ich, float tot) const
const std::vector< int > & getTRMmask() const
void processErrorDRM(int crate, int codeErr)
int process(const std::vector< HitType > *hits, std::vector< Digit > *digits)
Float_t getEffX(Float_t x)
void flushOutputContainer(std::vector< Digit > &digits)
Double_t getShowerTimeSmeared(Double_t time, Float_t charge)
void test(const char *geo="")
Int_t getXshift(Int_t idigit) const
void fillOutputContainer(std::vector< Digit > &digits)
Float_t getEffZ(Float_t z)
void runFullTestExample(const char *geo="")
void testFromHits(const char *geo="", const char *hits="AliceO2_TGeant3.tof.mc_10_event.root")
Bool_t isFired(Float_t x, Float_t z, Float_t charge)
Double_t getDigitTimeSmeared(Double_t time, Float_t x, Float_t z, Float_t charge)
uint64_t getReadoutWindow(double timeNS) const
Float_t getTotLastHit(Int_t idigit) const
Float_t getCharge(Float_t eDep)
Float_t getTimeLastHit(Int_t idigit) const
Int_t getZshift(Int_t idigit) const
void setCalibApi(CalibApi *calibApi)
Float_t getFractionOfCharge(Float_t x, Float_t z)
static constexpr Float_t ZPAD
static constexpr Float_t XPAD
static constexpr Double_t BC_TIME_INPS
static constexpr Double_t BC_TIME_INPS_INV
static constexpr Float_t NTOTBIN_PER_NS
static constexpr Int_t NPADS
static constexpr Float_t NTDCBIN_PER_PS
number of TDC bins in 1 ns
static constexpr Double_t READOUTWINDOW_INV
static Int_t getCrateFromECH(int ech)
static void getPos(Int_t *det, Float_t *pos)
static constexpr Int_t LATENCYWINDOW_IN_BC
static constexpr Double_t BC_TIME
static constexpr Float_t TOTBIN_NS
static Int_t getIndex(const Int_t *detId)
static constexpr Float_t TDCBIN
TDC bin width [ps].
static void getDetID(Float_t *pos, Int_t *det)
static constexpr int BC_IN_WINDOW
static void getPadDxDyDz(const Float_t *pos, Int_t *det, Float_t *DeltaPos, int sector=-1)
static constexpr Int_t OVERLAP_IN_BC
static constexpr Int_t NPADX
static Int_t getECHFromCH(int chan)
static constexpr int NWINDOW_IN_ORBIT
static constexpr Double_t LATENCYWINDOW
static constexpr Int_t NSTRIPS
int mIcurrentReadoutWindow
uint64_t mReadoutWindowCurrent
std::vector< Strip > mStrips[MAXWINDOWS]
static const int MAXWINDOWS
InteractionTimeRecord mEventTime
std::vector< Strip > * mStripsCurrent
std::vector< Strip > * mStripsNext[MAXWINDOWS - 1]
std::vector< uint8_t > mPatterns
std::vector< Digit > mDigitsPerTimeFrame
void insertDigitInFuture(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t label=0, uint32_t triggerorbit=0, uint16_t triggerbunch=0)
std::vector< Digit > mFutureDigits
std::vector< ReadoutWindowData > mReadoutWindowData
InteractionRecord mFirstIR
GLint GLint GLsizei GLint border
GLboolean GLboolean GLboolean b
GLuint GLsizei const GLchar * label
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
GLboolean GLboolean GLboolean GLboolean a
GLdouble GLdouble GLdouble z
constexpr int LHCMaxBunches
FIXME: do not use data model tables.
uint16_t bc
bunch crossing ID of interaction
double getTimeOffsetWrtBC() const
double getTimeNS() const
get time in ns from orbit=0/bc=0
void setEmptyCrate(int crate)
void setBCData(int orbit, int bc)
void addedDiagnostic(int crate)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits