Skip to content
Merged
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 @@ -95,6 +95,11 @@ class EMCALCalibExtractor
double time1 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
std::map<int, std::pair<double, double>> slices = {{0, {0.1, 0.3}}, {1, {0.3, 0.5}}, {2, {0.5, 1.0}}, {3, {1.0, 4.0}}, {4, {4.0, 39.0}}};

std::fill(std::begin(mBadCellFracSM), std::end(mBadCellFracSM), 0); // reset all fractions to 0
for (unsigned int i = 0; i < mBadCellFracFEC.size(); ++i) {
std::fill(std::begin(mBadCellFracFEC[i]), std::end(mBadCellFracFEC[i]), 0);
}

auto histScaled = hist;
if (mBCMScaleFactors) {
LOG(info) << "Rescaling BCM histo";
Expand Down Expand Up @@ -138,6 +143,8 @@ class EMCALCalibExtractor
if (calibrationInformation.energyPerHitMap[0][cellID] == 0) {
LOG(debug) << "Cell " << cellID << " is dead.";
mOutputBCM.addBadChannel(cellID, o2::emcal::BadChannelMap::MaskType_t::DEAD_CELL);
mBadCellFracSM[mGeometry->GetSuperModuleNumber(cellID)] += 1;
mBadCellFracFEC[mGeometry->GetSuperModuleNumber(cellID)][getFECNumberInSM(cellID)] += 1;
} else {
bool failed = false;
for (auto& [sliceIndex, slice] : slices) {
Expand Down Expand Up @@ -188,12 +195,25 @@ class EMCALCalibExtractor
if (failed) {
LOG(debug) << "Cell " << cellID << " is bad.";
mOutputBCM.addBadChannel(cellID, o2::emcal::BadChannelMap::MaskType_t::BAD_CELL);
mBadCellFracSM[mGeometry->GetSuperModuleNumber(cellID)] += 1;
mBadCellFracFEC[mGeometry->GetSuperModuleNumber(cellID)][getFECNumberInSM(cellID)] += 1;
} else {
LOG(debug) << "Cell " << cellID << " is good.";
mOutputBCM.addBadChannel(cellID, o2::emcal::BadChannelMap::MaskType_t::GOOD_CELL);
}
}
}

// Check if the fraction of bad+dead cells in a SM is above a certain threshold
// If yes, mask the whole SM
if (EMCALCalibParams::Instance().fracMaskSMFully_bc < 1) {
checkMaskSM(mOutputBCM);
}
// Same as above for FECs
if (EMCALCalibParams::Instance().fracMaskFECFully_bc < 1) {
checkMaskFEC(mOutputBCM);
}

double time2 = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
double diffTransfer = time2 - time1;
LOG(info) << "Total time" << diffTransfer << " ns";
Expand Down Expand Up @@ -396,12 +416,27 @@ class EMCALCalibExtractor
}

private:
EMCALChannelScaleFactors* mBCMScaleFactors = nullptr; ///< Scale factors for nentries scaling in bad channel calibration
int mSigma = 5; ///< number of sigma used in the calibration to define outliers
int mNThreads = 1; ///< number of threads used for calibration

o2::emcal::Geometry* mGeometry = nullptr;
static constexpr int mNcells = 17664;
//____________________________________________
/// \brief Check if a SM exceeds a certain fraction of dead+bad channels. If yes, mask the entire SM
/// \param bcm -- current bad channel map
void checkMaskSM(o2::emcal::BadChannelMap& bcm);

/// \brief Check if a FEC exceeds a certain fraction of dead+bad channels. If yes, mask the entire FEC
/// \param bcm -- current bad channel map
void checkMaskFEC(o2::emcal::BadChannelMap& bcm);

/// \brief Get the FEC ID in a SM (IDs are just for internal handling in this task itself)
/// \param absCellID -- cell ID
unsigned int getFECNumberInSM(int absCellID) const;

EMCALChannelScaleFactors* mBCMScaleFactors = nullptr; ///< Scale factors for nentries scaling in bad channel calibration
int mSigma = 5; ///< number of sigma used in the calibration to define outliers
int mNThreads = 1; ///< number of threads used for calibration
std::array<float, 20> mBadCellFracSM; ///< Fraction of bad+dead channels per SM
std::array<std::array<float, 36>, 20> mBadCellFracFEC; ///< Fraction of bad+dead channels per FEC

o2::emcal::Geometry* mGeometry = nullptr; ///< pointer to the emcal geometry class
static constexpr int mNcells = 17664; ///< Number of total cells of EMCal + DCal

ClassDefNV(EMCALCalibExtractor, 1);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ struct EMCALCalibParams : public o2::conf::ConfigurableParamHelper<EMCALCalibPar
float minCellEnergy_bc = 0.1; ///< minimum cell energy considered for filling the histograms for bad channel calib. Should speedup the filling of the histogram to suppress noise
float fractionEvents_bc = 1.; ///< fraction of events used in bad channel calibration
size_t nThreads_bc = 4; ///< number of threads used for the bad channel calinration for filling the histograms
float fracMaskSMFully_bc = 0.5; ///< fraction of bad+dead channel for a SM to be fully masked
float fracMaskFECFully_bc = 0.9; ///< fraction of bad+dead channel for a FEC to be fully masked

// parameters for time calibration
unsigned int minNEvents_tc = 1e7; ///< minimum number of events to trigger the calibration
Expand All @@ -70,16 +72,16 @@ struct EMCALCalibParams : public o2::conf::ConfigurableParamHelper<EMCALCalibPar
size_t nThreads_tc = 2; ///< number of threads used for the time calinration for filling the histograms

// common parameters
std::string calibType = "time"; ///< type of calibration to run
std::string localRootFilePath = ""; ///< path to local root file in order to store the calibration histograms (off by default, only to be used for testing)
bool enableFastCalib = false; ///< switch to enable fast calibration. Instead of filling boost histograms, mean and sigma of cells is calculated on the fly
bool enableTimeProfiling = false; ///< enable to log how much time is spent in the run function in the calibrator spec. Needed for speed tests offline and at point 2
bool setSavedSlotAllowed_EMC = true; ///< if true, saving and loading of calibrations from last run and for next run is enabled
bool setSavedSlotAllowedSOR_EMC = true; ///< if true, stored calibrations from last run can be loaded in the next run (if false, storing of the calib histograms is still active in contrast to setSavedSlotAllowed_EMC)
long endTimeMargin = 2592000000; ///< set end TS to 30 days after slot ends (1000 * 60 * 60 * 24 * 30)
std::string selectedClassMasks = "C0TVX-B-NOPF-EMC"; ///< name of EMCal min. bias trigger that is used for calibration
int bcShiftCTP = 0; ///< bc shift of CTP digits to align them with EMC bc in case they are misaligned
std::string filePathSave = "./emc_calib"; ///< path where calibration histograms are stored at EOR to save them for the next run
std::string calibType = "time"; ///< type of calibration to run
std::string localRootFilePath = ""; ///< path to local root file in order to store the calibration histograms (off by default, only to be used for testing)
bool enableFastCalib = false; ///< switch to enable fast calibration. Instead of filling boost histograms, mean and sigma of cells is calculated on the fly
bool enableTimeProfiling = false; ///< enable to log how much time is spent in the run function in the calibrator spec. Needed for speed tests offline and at point 2
bool setSavedSlotAllowed_EMC = true; ///< if true, saving and loading of calibrations from last run and for next run is enabled
bool setSavedSlotAllowedSOR_EMC = true; ///< if true, stored calibrations from last run can be loaded in the next run (if false, storing of the calib histograms is still active in contrast to setSavedSlotAllowed_EMC)
long endTimeMargin = 2592000000; ///< set end TS to 30 days after slot ends (1000 * 60 * 60 * 24 * 30)
std::string selectedClassMasks = "C0TVX-B-NOPF-EMC"; ///< name of EMCal min. bias trigger that is used for calibration
int bcShiftCTP = 0; ///< bc shift of CTP digits to align them with EMC bc in case they are misaligned
std::string filePathSave = "./emc_calib"; ///< path where calibration histograms are stored at EOR to save them for the next run

// old parameters. Keep them for a bit (can be deleted after september 5th) as otherwise ccdb and o2 version might not be in synch
unsigned int minNEvents = 1e7; ///< minimum number of events to trigger the calibration
Expand Down
52 changes: 52 additions & 0 deletions Detectors/EMCAL/calibration/src/EMCALCalibExtractor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,59 @@ boostHisto EMCALCalibExtractor::buildHitAndEnergyMeanScaled(double emin, double

return eSumHistoScaled;
}

//____________________________________________
void EMCALCalibExtractor::checkMaskSM(o2::emcal::BadChannelMap& bcm)
{

for (unsigned int i = 0; i < mBadCellFracSM.size(); ++i) {
if (mGeometry->GetSMType(i) == o2::emcal::EMCALSMType::EMCAL_STANDARD) {
mBadCellFracSM[i] /= 1152.;
} else if (mGeometry->GetSMType(i) == o2::emcal::EMCALSMType::EMCAL_THIRD || mGeometry->GetSMType(i) == o2::emcal::EMCALSMType::DCAL_EXT) {
mBadCellFracSM[i] /= 384.;
} else if (mGeometry->GetSMType(i) == o2::emcal::EMCALSMType::DCAL_STANDARD) {
mBadCellFracSM[i] /= 768.;
}
}
for (unsigned int i = 0; i < mNcells; ++i) {
if (mBadCellFracSM[mGeometry->GetSuperModuleNumber(i)] > EMCALCalibParams::Instance().fracMaskSMFully_bc) {
if (bcm.getChannelStatus(i) == o2::emcal::BadChannelMap::MaskType_t::GOOD_CELL) { // only mask good cells, to keep information about dead channels
bcm.addBadChannel(i, o2::emcal::BadChannelMap::MaskType_t::BAD_CELL);
}
}
}
}

//____________________________________________
void EMCALCalibExtractor::checkMaskFEC(o2::emcal::BadChannelMap& bcm)
{
for (unsigned int iSM = 0; iSM < mBadCellFracFEC.size(); ++iSM) {
for (unsigned int iFEC = 0; iFEC < mBadCellFracFEC[iSM].size(); ++iFEC) {
mBadCellFracFEC[iSM][iFEC] /= 32.; // 32 channels per FEC
}
}

for (unsigned int i = 0; i < mNcells; ++i) {
if (mBadCellFracFEC[mGeometry->GetSuperModuleNumber(i)][getFECNumberInSM(i)] > EMCALCalibParams::Instance().fracMaskFECFully_bc) {
if (bcm.getChannelStatus(i) == o2::emcal::BadChannelMap::MaskType_t::GOOD_CELL) { // only mask good cells, to keep information about dead channels
bcm.addBadChannel(i, o2::emcal::BadChannelMap::MaskType_t::BAD_CELL);
}
}
}
}

//____________________________________________
unsigned int EMCALCalibExtractor::getFECNumberInSM(int absCellID) const
{
std::tuple<int, int> RowCol = mGeometry->GlobalRowColFromIndex(absCellID);
std::tuple<int, int, int> PosInSM = mGeometry->GetPositionInSupermoduleFromGlobalRowCol(std::get<0>(RowCol), std::get<1>(RowCol));
int iSM = std::get<0>(PosInSM);
int col = std::get<1>(PosInSM);
int row = std::get<2>(PosInSM);
int FECid = static_cast<int>(row / 4.) + 12 * static_cast<int>(col / 8.);
LOG(debug) << "FECid " << FECid << " iSM " << iSM << " row " << row << " col " << col;
return FECid;
}

} // end namespace emcal
} // end namespace o2