2020#include " IOTOFSimulation/DPLDigitizerParam.h"
2121#include " DetectorsRaw/HBFUtils.h"
2222
23+ #include < TCollection.h>
24+ #include < TFile.h>
25+ #include < TKey.h>
2326#include < TRandom.h>
27+
2428#include < vector>
2529#include < iostream>
2630#include < numeric>
@@ -51,6 +55,9 @@ void Digitizer::init()
5155 }
5256
5357 const auto & digitizerParams = o2::iotof::DPLDigitizerParam::Instance ();
58+ if (!digitizerParams.efficiencyFilePath .empty ()) {
59+ loadEfficiencyMap (digitizerParams.efficiencyFilePath );
60+ }
5461
5562 LOG (info) << " Initializing IOTOF digitizer" ;
5663 LOG (info) << " Time resolution: " << digitizerParams.timeResolution * 1e3 << " ps" ;
@@ -95,12 +102,6 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
95102{
96103 // Process a single hit and create a digit if it passes all cuts
97104
98- // Apply efficiency cut
99- if (!isEfficient ()) {
100- LOG (debug) << " Hit rejected by efficiency cut" ;
101- return ;
102- }
103-
104105 // Get detector element ID
105106 const int chipID = hit.GetDetectorID ();
106107 auto & chip = mChips [chipID];
@@ -109,6 +110,26 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
109110 return ;
110111 }
111112
113+ // middle position of the hit in the sensor frame
114+ const auto & matrix = mGeometry ->getMatrixL2G (chipID);
115+ auto xyzPositionStart = matrix ^ hit.GetPosStart ();
116+ auto xyzPositionEnd = matrix ^ hit.GetPos ();
117+ const auto xMid = 0 .5f * (xyzPositionStart.X () + xyzPositionEnd.X ());
118+ const auto zMid = 0 .5f * (xyzPositionStart.Z () + xyzPositionEnd.Z ());
119+ // move this to the local pixel coordinates for the efficiency map
120+ int row, col;
121+ float xPixelCenter, zPixelCenter;
122+ if (!sSegmentation ->localToDetector (xMid, zMid, row, col, mGeometry ->getIOTOFLayer (chipID))) {
123+ LOG (debug) << " Hit rejected because position (" << xMid << " , " << zMid << " ) is outside the active area of chip " << chipID;
124+ return ; // hit is outside the active area
125+ }
126+ sSegmentation ->detectorToLocalUnchecked (row, col, xPixelCenter, zPixelCenter, mGeometry ->getIOTOFLayer (chipID));
127+
128+ if (!isEfficient (xMid - xPixelCenter, zMid - zPixelCenter)) {
129+ LOG (debug) << " Hit rejected by efficiency cut" ;
130+ return ;
131+ }
132+
112133 // Convert energy loss to charge (number of electrons)
113134 float energyLoss = hit.GetEnergyLoss (); // in GeV
114135 int charge = energyToCharge (energyLoss);
@@ -126,7 +147,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
126147 double hitTime = hit.GetTime () * sec2ns; // convert to ns
127148 double eventTimeInBC = mEventTime .getTimeOffsetWrtBC (); // event time wrt bc
128149 double hitTimeWrtBC = hitTime + eventTimeInBC; // hit time wrt bc
129- double smearedTime = smearTime (hitTimeWrtBC); // apply detector resolution
150+ double smearedTime = smearTime (hitTimeWrtBC);
130151
131152 if (chipID < 0 || chipID >= mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
132153 LOG (debug) << " Invalid detector ID: " << chipID << " , geometry size: " << mGeometry ->getSize ();
@@ -166,8 +187,8 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
166187
167188void Digitizer::stepping (const o2::itsmft::Hit& hit, float **& respMatrix, int & rowStart, int & colStart, int & rowSpan, int & colSpan)
168189{
169- const auto & matrix = mGeometry ->getMatrixL2G (hit.GetDetectorID ());
170190 const int chipID = hit.GetDetectorID ();
191+ const auto & matrix = mGeometry ->getMatrixL2G (chipID);
171192 const int subdetectorID = mGeometry ->getIOTOFLayer (chipID);
172193
173194 auto xyzPositionStart (matrix ^ (hit.GetPosStart ())); // start position in sensor frame
@@ -277,10 +298,45 @@ int Digitizer::energyToCharge(float energyLoss) const
277298}
278299
279300// _______________________________________________________________________
280- bool Digitizer::isEfficient () const
301+ void Digitizer::loadEfficiencyMap (const std::string& filePath)
302+ {
303+ // Load the efficiency map from a file
304+ TFile* file = TFile::Open (filePath.c_str ());
305+ if (!file || !file->IsOpen ()) {
306+ LOG (error) << " Failed to open efficiency map file: " << filePath;
307+ return ;
308+ }
309+
310+ auto * rawMap = dynamic_cast <TH2D *>(file->Get (" hEfficiencyMap" ));
311+ if (!rawMap) {
312+ LOG (error) << " Failed to retrieve efficiency map from file: " << filePath;
313+ LOG (error) << " Available keys in the file:" ;
314+ TIter next (file->GetListOfKeys ());
315+ TKey* key;
316+ while ((key = dynamic_cast <TKey*>(next ()))) {
317+ LOG (error) << " " << key->GetName () << " (" << key->GetClassName () << " )" ;
318+ }
319+ file->Close ();
320+ return ;
321+ }
322+ mEfficiencyMap = dynamic_cast <TH2D *>(rawMap->Clone (" mEfficiencyMap" ));
323+ mEfficiencyMap ->SetDirectory (nullptr ); // Detach from file to avoid deletion when file is closed
324+
325+ file->Close ();
326+ }
327+
328+ // _______________________________________________________________________
329+ bool Digitizer::isEfficient (const float x, const float z) const
281330{
282331 // Apply efficiency cut using random number
283332 const auto & digitizerParams = o2::iotof::DPLDigitizerParam::Instance ();
333+ if (mEfficiencyMap ) {
334+ // int bin = mEfficiencyMap->FindBin(x * o2::iotof::Digitizer::cm2um, z * o2::iotof::Digitizer::cm2um);
335+ int bin = mEfficiencyMap ->FindBin (x * o2::iotof::Digitizer::cm2um, z * o2::iotof::Digitizer::cm2um);
336+ float efficiency = mEfficiencyMap ->GetBinContent (bin);
337+ LOG (debug) << " Efficiency map check: x=" << x * o2::iotof::Digitizer::cm2um << " , z=" << z * o2::iotof::Digitizer::cm2um << " , bin=" << bin << " , efficiency=" << efficiency;
338+ return gRandom ->Uniform () < efficiency;
339+ }
284340 return gRandom ->Uniform () < digitizerParams.efficiency ;
285341}
286342
0 commit comments