diff --git a/Detectors/Upgrades/ALICE3/IOTOF/simulation/include/IOTOFSimulation/DPLDigitizerParam.h b/Detectors/Upgrades/ALICE3/IOTOF/simulation/include/IOTOFSimulation/DPLDigitizerParam.h index 7f96b8e509d0c..9ea9e825dd68f 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/simulation/include/IOTOFSimulation/DPLDigitizerParam.h +++ b/Detectors/Upgrades/ALICE3/IOTOF/simulation/include/IOTOFSimulation/DPLDigitizerParam.h @@ -30,8 +30,18 @@ struct DPLDigitizerParam : public o2::conf::ConfigurableParamHelper mChips; //! Chips in the detector, indexed by chip ID std::deque>> mExtraLabelBuffer; //! buffer for multiple mc labels to the same pixel diff --git a/Detectors/Upgrades/ALICE3/IOTOF/simulation/src/Digitizer.cxx b/Detectors/Upgrades/ALICE3/IOTOF/simulation/src/Digitizer.cxx index c56e97435db06..742468d1b63a9 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/simulation/src/Digitizer.cxx +++ b/Detectors/Upgrades/ALICE3/IOTOF/simulation/src/Digitizer.cxx @@ -19,6 +19,7 @@ #include "IOTOFSimulation/Digitizer.h" #include "IOTOFSimulation/DPLDigitizerParam.h" #include "DetectorsRaw/HBFUtils.h" +#include "CCDB/BasicCCDBManager.h" #include #include @@ -56,15 +57,42 @@ void Digitizer::init() } const auto& digitizerParams = o2::iotof::DPLDigitizerParam::Instance(); - if (!digitizerParams.efficiencyFilePath.empty()) { - loadEfficiencyMap(digitizerParams.efficiencyFilePath); - } LOG(info) << "Initializing IOTOF digitizer"; LOG(info) << " Time resolution: " << digitizerParams.timeResolution * 1e3 << " ps"; LOG(info) << " Charge threshold: " << digitizerParams.chargeThreshold << " electrons"; - LOG(info) << " Detection efficiency: " << digitizerParams.efficiency * 100 << " %"; LOG(info) << " Continuous mode: " << (mContinuous ? "ON" : "OFF"); + + if (!digitizerParams.efficiencyCcdbPath.empty()) { + LOG(info) << "Loading efficiency map from CCDB: " << digitizerParams.efficiencyCcdbPath; + loadMapFromCCDB(mEfficiencyMap, digitizerParams.efficiencyCcdbPath); + } else if (!digitizerParams.efficiencyFilePath.empty()) { + LOG(info) << "Loading efficiency map from file: " << digitizerParams.efficiencyFilePath; + loadMap(mEfficiencyMap, digitizerParams.efficiencyFilePath, "hEfficiencyMap"); + } else { + LOG(info) << "No efficiency map provided, using uniform efficiency: " << digitizerParams.efficiency * 100 << " %"; + } + + if (!digitizerParams.resolutionCcdbPath.empty()) { + LOG(info) << "Loading resolution map from CCDB: " << digitizerParams.resolutionCcdbPath; + loadMapFromCCDB(mResolutionMap, digitizerParams.resolutionCcdbPath); + } else if (!digitizerParams.resolutionFilePath.empty()) { + LOG(info) << "Loading resolution map from file: " << digitizerParams.resolutionFilePath; + loadMap(mResolutionMap, digitizerParams.resolutionFilePath, "hResolutionMap"); + } else { + LOG(info) << "No resolution map provided, using uniform time resolution: " << digitizerParams.timeResolution * 1e3 << " ps"; + } + + if (!digitizerParams.timeOfArrivalCcdbPath.empty()) { + LOG(info) << "Loading time of arrival map from CCDB: " << digitizerParams.timeOfArrivalCcdbPath; + loadMapFromCCDB(mTimeOfArrivalMap, digitizerParams.timeOfArrivalCcdbPath); + } else if (!digitizerParams.timeOfArrivalFilePath.empty()) { + LOG(info) << "Loading time of arrival map from file: " << digitizerParams.timeOfArrivalFilePath; + loadMap(mTimeOfArrivalMap, digitizerParams.timeOfArrivalFilePath, "hTimeOfArrivalMap"); + } else { + LOG(info) << "No time of arrival map provided"; + } + sSegmentation = o2::iotof::Segmentation::Instance(); } @@ -163,6 +191,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID) LOG(debug) << "Hit rejected by efficiency cut at pixel (row,col) = (" << rowIS << ", " << colIS << ")"; continue; } + double smearedTime = smearTime(hitTimeWrtBC, avgHitLocalX[irow][icol], avgHitLocalZ[irow][icol]); const int nElectronsSampled = gRandom->Poisson(electronsPerStep * nEleResp); // Noise can be added here if needed @@ -316,12 +345,22 @@ void Digitizer::stepping(const o2::itsmft::Hit& hit, float**& respMatrix, float* } //_______________________________________________________________________ -double Digitizer::smearTime(double time) const +double Digitizer::smearTime(double time, const float x, const float y) const { // Apply Gaussian smearing to simulate detector time resolution const auto& digitizerParams = o2::iotof::DPLDigitizerParam::Instance(); + + float resolutionScaling = 1.; + if (mResolutionMap) { + const float minimumResolution = mResolutionMap->GetMinimum(); + int bin = mResolutionMap->FindBin(x * o2::iotof::Digitizer::cm2um, y * o2::iotof::Digitizer::cm2um); + resolutionScaling = mResolutionMap->GetBinContent(bin) / minimumResolution; + LOG(debug) << "Time resolution map check: x=" << x * o2::iotof::Digitizer::cm2um << ", y=" << y * o2::iotof::Digitizer::cm2um << ", bin=" << bin << ", resolution=" << minimumResolution; + LOG(debug) << "Time resolution scaling: " << resolutionScaling; + } + if (digitizerParams.timeResolution > 0) { - return time + gRandom->Gaus(0, digitizerParams.timeResolution); + return time + gRandom->Gaus(0, digitizerParams.timeResolution * resolutionScaling); } return time; } @@ -337,7 +376,8 @@ int Digitizer::energyToCharge(float energyLoss) const } //_______________________________________________________________________ -void Digitizer::loadEfficiencyMap(const std::string& filePath) + +void Digitizer::loadMap(TH1D* map, const std::string& filePath, const char* mapName) { // Load the efficiency map from a file TFile* file = TFile::Open(filePath.c_str()); @@ -346,7 +386,7 @@ void Digitizer::loadEfficiencyMap(const std::string& filePath) return; } - auto* rawMap = dynamic_cast(file->Get("hEfficiencyMap")); + auto* rawMap = dynamic_cast(file->Get(mapName)); if (!rawMap) { LOG(error) << "Failed to retrieve efficiency map from file: " << filePath; LOG(error) << "Available keys in the file:"; @@ -358,12 +398,31 @@ void Digitizer::loadEfficiencyMap(const std::string& filePath) file->Close(); return; } - mEfficiencyMap = dynamic_cast(rawMap->Clone("mEfficiencyMap")); - mEfficiencyMap->SetDirectory(nullptr); // Detach from file to avoid deletion when file is closed + map = dynamic_cast(rawMap->Clone()); + map->SetDirectory(nullptr); // Detach from file to avoid deletion when file is closed file->Close(); } +void Digitizer::loadMapFromCCDB(TH1D* map, const std::string& ccdbPath) +{ + // Load the efficiency map from CCDB + auto rawMap = o2::ccdb::BasicCCDBManager::instance().get(ccdbPath); + + if (!rawMap) { + LOG(error) << "Failed to retrieve efficiency map from CCDB path: " << ccdbPath; + return; + } else { + LOG(info) << "Successfully retrieved efficiency map from CCDB path: " << ccdbPath; + LOG(info) << "Efficiency map dimensions: " << rawMap->GetNbinsX() << " x " << rawMap->GetNbinsY(); + } + + map = dynamic_cast(rawMap->Clone()); + map->SetDirectory(nullptr); // Detach from file to avoid deletion when file is closed + + LOG(info) << "Successfully loaded efficiency map from CCDB path: " << ccdbPath; +} + //_______________________________________________________________________ bool Digitizer::isEfficient(const float x, const float z) const {