Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,18 @@
float timeResolution = 0.020f; ///< time resolution sigma in ns (20 ps default)
float tdcBin = 0.010f; ///< TDC time bin (10 ps default)
float efficiency = 0.98f; ///< detection efficiency

Check failure on line 33 in Detectors/Upgrades/ALICE3/IOTOF/simulation/include/IOTOFSimulation/DPLDigitizerParam.h

View workflow job for this annotation

GitHub Actions / PR formatting / whitespace

Trailing spaces

Remove the trailing spaces at the end of the line.
std::string efficiencyFilePath{}; ///< optional efficiency map file path.
///< The efficiency map is currently available at /alice/cern.ch/user/g/glucia/ALICE3/IOTOF/pixelEfficiency/PixelEfficiencyMap_TH2.root. FIXME to be removed once switch to CCDBFetcher
std::string efficiencyCcdbPath{}; ///< optional efficiency map CCDB path.
///< The efficiency map is currently available at Users/g/glucia/tmp/ALICE3/IOTOF/pixelEfficiency
std::string resolutionFilePath{}; ///< optional resolution map file path.
///< The resolution map is currently available at /alice/cern.ch/user/g/glucia/ALICE3/IOTOF/pixelEfficiency/PixelResolutionMap_TH2.root. FIXME to be removed once switch to CCDBFetcher
std::string resolutionCcdbPath{}; ///< optional resolution map CCDB path.
std::string timeOfArrivalFilePath{}; ///< optional time of arrival map file path.
///< The time of arrival map is currently available at /alice/cern.ch/user/g
std::string timeOfArrivalCcdbPath{}; ///< optional time of arrival map CCDB path.

int chargeThreshold = 100; ///< charge threshold in Nelectrons
int minChargeToAccount = 7; ///< minimum charge contribution to account
int nSimSteps = 10; ///< number of steps in response simulation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ class Digitizer : public TObject
int energyToCharge(float energyLoss) const;

/// Load the efficiency map from a file
void loadEfficiencyMap(const std::string& filePath);
void loadMap(TH2* map, const std::string& filePath, const char* mapName);
void loadMapFromCCDB(TH2* map, const std::string& ccdbPath, const char* mapName);

/// Check if the hit passes efficiency cut
/// \param x Detector local coordinate x in cm with respect to the center of the sensitive volume.
Expand All @@ -118,6 +119,8 @@ class Digitizer : public TObject

const o2::iotof::GeometryTGeo* mGeometry = nullptr; ///< IOTOF geometry
TH2D* mEfficiencyMap = nullptr; ///< Efficiency map for the detector
TH2D* mResolutionMap = nullptr; ///< Resolution map for the detector
TH2D* mTimeOfArrivalMap = nullptr; ///< Time of arrival map for the detector

std::vector<o2::iotof::Chip> mChips; //! Chips in the detector, indexed by chip ID
std::deque<std::unique_ptr<std::vector<o2::iotof::McLabelRef>>> mExtraLabelBuffer; //! buffer for multiple mc labels to the same pixel
Expand Down
79 changes: 69 additions & 10 deletions Detectors/Upgrades/ALICE3/IOTOF/simulation/src/Digitizer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "IOTOFSimulation/Digitizer.h"
#include "IOTOFSimulation/DPLDigitizerParam.h"
#include "DetectorsRaw/HBFUtils.h"
#include "CCDB/BasicCCDBManager.h"

#include <TCollection.h>
#include <TFile.h>
Expand Down Expand Up @@ -56,15 +57,42 @@
}

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();
}

Expand Down Expand Up @@ -163,6 +191,7 @@
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
Expand Down Expand Up @@ -316,12 +345,22 @@
}

//_______________________________________________________________________
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();

Check failure on line 352 in Detectors/Upgrades/ALICE3/IOTOF/simulation/src/Digitizer.cxx

View workflow job for this annotation

GitHub Actions / PR formatting / whitespace

Trailing spaces

Remove the trailing spaces at the end of the line.
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;
}
Expand All @@ -337,7 +376,8 @@
}

//_______________________________________________________________________
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());
Expand All @@ -346,7 +386,7 @@
return;
}

auto* rawMap = dynamic_cast<TH2D*>(file->Get("hEfficiencyMap"));
auto* rawMap = dynamic_cast<TH2D*>(file->Get(mapName));
if (!rawMap) {
LOG(error) << "Failed to retrieve efficiency map from file: " << filePath;
LOG(error) << "Available keys in the file:";
Expand All @@ -358,12 +398,31 @@
file->Close();
return;
}
mEfficiencyMap = dynamic_cast<TH2D*>(rawMap->Clone("mEfficiencyMap"));
mEfficiencyMap->SetDirectory(nullptr); // Detach from file to avoid deletion when file is closed
map = dynamic_cast<TH2D*>(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<TH2D>(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<TH2D*>(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
{
Expand Down
Loading