File indexing completed on 2024-04-06 12:02:35
0001 #include "CondFormats/SiPixelObjects/interface/SiPixelGainCalibrationOffline.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include <algorithm>
0004 #include <cstring>
0005
0006
0007
0008
0009 SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline()
0010 : minPed_(0.),
0011 maxPed_(255.),
0012 minGain_(0.),
0013 maxGain_(255.),
0014 numberOfRowsToAverageOver_(80),
0015 nBinsToUseForEncoding_(253),
0016 deadFlag_(255),
0017 noisyFlag_(254) {
0018 if (deadFlag_ > 0xFF)
0019 throw cms::Exception("GainCalibration Payload configuration error")
0020 << "[SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline] Dead flag was set to " << deadFlag_
0021 << ", and it must be set less than or equal to 255";
0022 if (noisyFlag_ > 0xFF)
0023 throw cms::Exception("GainCalibration Payload configuration error")
0024 << "[SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline] Noisy flag was set to " << noisyFlag_
0025 << ", and it must be set less than or equal to 255";
0026 }
0027
0028 SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline(float minPed, float maxPed, float minGain, float maxGain)
0029 : minPed_(minPed),
0030 maxPed_(maxPed),
0031 minGain_(minGain),
0032 maxGain_(maxGain),
0033 numberOfRowsToAverageOver_(80),
0034 nBinsToUseForEncoding_(253),
0035 deadFlag_(255),
0036 noisyFlag_(254) {
0037 if (deadFlag_ > 0xFF)
0038 throw cms::Exception("GainCalibration Payload configuration error")
0039 << "[SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline] Dead flag was set to " << deadFlag_
0040 << ", and it must be set less than or equal to 255";
0041 if (noisyFlag_ > 0xFF)
0042 throw cms::Exception("GainCalibration Payload configuration error")
0043 << "[SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline] Noisy flag was set to " << noisyFlag_
0044 << ", and it must be set less than or equal to 255";
0045 }
0046
0047 bool SiPixelGainCalibrationOffline::put(const uint32_t& DetId, Range input, const int& nCols) {
0048
0049
0050 Registry::iterator p =
0051 std::lower_bound(indexes.begin(), indexes.end(), DetId, SiPixelGainCalibrationOffline::StrictWeakOrdering());
0052 if (p != indexes.end() && p->detid == DetId)
0053 return false;
0054
0055 size_t sd = input.second - input.first;
0056 DetRegistry detregistry;
0057 detregistry.detid = DetId;
0058 detregistry.ncols = nCols;
0059 detregistry.ibegin = v_pedestals.size();
0060 detregistry.iend = v_pedestals.size() + sd;
0061 indexes.insert(p, detregistry);
0062
0063 v_pedestals.insert(v_pedestals.end(), input.first, input.second);
0064 return true;
0065 }
0066
0067 const int SiPixelGainCalibrationOffline::getNCols(const uint32_t& DetId) const {
0068
0069 RegistryIterator p =
0070 std::lower_bound(indexes.begin(), indexes.end(), DetId, SiPixelGainCalibrationOffline::StrictWeakOrdering());
0071 if (p == indexes.end() || p->detid != DetId)
0072 return 0;
0073 else
0074 return p->ncols;
0075 }
0076
0077 const SiPixelGainCalibrationOffline::Range SiPixelGainCalibrationOffline::getRange(const uint32_t& DetId) const {
0078
0079
0080 RegistryIterator p =
0081 std::lower_bound(indexes.begin(), indexes.end(), DetId, SiPixelGainCalibrationOffline::StrictWeakOrdering());
0082 if (p == indexes.end() || p->detid != DetId)
0083 return SiPixelGainCalibrationOffline::Range(v_pedestals.end(), v_pedestals.end());
0084 else
0085 return SiPixelGainCalibrationOffline::Range(v_pedestals.begin() + p->ibegin, v_pedestals.begin() + p->iend);
0086 }
0087
0088 const std::pair<const SiPixelGainCalibrationOffline::Range, const int> SiPixelGainCalibrationOffline::getRangeAndNCols(
0089 const uint32_t& DetId) const {
0090 RegistryIterator p =
0091 std::lower_bound(indexes.begin(), indexes.end(), DetId, SiPixelGainCalibrationOffline::StrictWeakOrdering());
0092 if (p == indexes.end() || p->detid != DetId)
0093 return std::make_pair(SiPixelGainCalibrationOffline::Range(v_pedestals.end(), v_pedestals.end()), 0);
0094 else
0095 return std::make_pair(
0096 SiPixelGainCalibrationOffline::Range(v_pedestals.begin() + p->ibegin, v_pedestals.begin() + p->iend), p->ncols);
0097 }
0098
0099 void SiPixelGainCalibrationOffline::getDetIds(std::vector<uint32_t>& DetIds_) const {
0100
0101 SiPixelGainCalibrationOffline::RegistryIterator begin = indexes.begin();
0102 SiPixelGainCalibrationOffline::RegistryIterator end = indexes.end();
0103 for (SiPixelGainCalibrationOffline::RegistryIterator p = begin; p != end; ++p) {
0104 DetIds_.push_back(p->detid);
0105 }
0106 }
0107
0108 void SiPixelGainCalibrationOffline::setDataGain(
0109 float gain, const int& nRows, std::vector<char>& vped, bool thisColumnIsDead, bool thisColumnIsNoisy) {
0110 float theEncodedGain = 0;
0111 if (!thisColumnIsDead && !thisColumnIsNoisy)
0112 theEncodedGain = encodeGain(gain);
0113
0114 unsigned int gain_ = (static_cast<unsigned int>(theEncodedGain)) & 0xFF;
0115
0116
0117 if (thisColumnIsDead)
0118 gain_ = deadFlag_ & 0xFF;
0119 if (thisColumnIsNoisy)
0120 gain_ = noisyFlag_ & 0xFF;
0121
0122 vped.resize(vped.size() + 1);
0123
0124 if (nRows != (int)numberOfRowsToAverageOver_) {
0125 throw cms::Exception("GainCalibration Payload configuration error")
0126 << "[SiPixelGainCalibrationOffline::setDataGain] You are setting a gain averaged over nRows = " << nRows
0127 << " where this payload is set ONLY to average over " << numberOfRowsToAverageOver_ << " nRows";
0128 }
0129
0130 if (vped.size() % (nRows + 1) != 0) {
0131 throw cms::Exception("FillError")
0132 << "[SiPixelGainCalibrationOffline::setDataGain] Column gain average (OR SETTING AN ENTIRE COLUMN DEAD/NOISY) "
0133 "must be filled after the pedestal for each row has been added. An additional source of this error would be "
0134 "setting a pixel dead/noisy AND setting its pedestal";
0135 }
0136
0137 ::memcpy((void*)(&vped[vped.size() - 1]), (void*)(&gain_), 1);
0138 }
0139
0140 void SiPixelGainCalibrationOffline::setDataPedestal(float pedestal,
0141 std::vector<char>& vped,
0142 bool thisPixelIsDead,
0143 bool thisPixelIsNoisy) {
0144 float theEncodedPedestal = encodePed(pedestal);
0145
0146 unsigned int ped_ = (static_cast<unsigned int>(theEncodedPedestal)) & 0xFF;
0147
0148 if (thisPixelIsDead)
0149 ped_ = deadFlag_ & 0xFF;
0150 if (thisPixelIsNoisy)
0151 ped_ = noisyFlag_ & 0xFF;
0152
0153 vped.resize(vped.size() + 1);
0154
0155 ::memcpy((void*)(&vped[vped.size() - 1]), (void*)(&ped_), 1);
0156 }
0157
0158 float SiPixelGainCalibrationOffline::getPed(
0159 const int& col, const int& row, const Range& range, const int& nCols, bool& isDead, bool& isNoisy) const {
0160 unsigned int lengthOfColumnData = (range.second - range.first) / nCols;
0161
0162 unsigned int lengthOfAveragedDataInEachColumn = numberOfRowsToAverageOver_ + 1;
0163 unsigned int numberOfAveragedDataBlocksToSkip = row / numberOfRowsToAverageOver_;
0164 unsigned int offSetInCorrectDataBlock = row % numberOfRowsToAverageOver_;
0165
0166 const unsigned int datum =
0167 *(range.first + col * lengthOfColumnData + numberOfAveragedDataBlocksToSkip * lengthOfAveragedDataInEachColumn +
0168 offSetInCorrectDataBlock) &
0169 0xFF;
0170
0171 int maxRow = lengthOfColumnData - (lengthOfColumnData % numberOfRowsToAverageOver_) - 1;
0172 if (col >= nCols || row > maxRow) {
0173 throw cms::Exception("CorruptedData")
0174 << "[SiPixelGainCalibrationOffline::getPed] Pixel out of range: col " << col << " row " << row;
0175 }
0176
0177 if (datum == deadFlag_)
0178 isDead = true;
0179 if (datum == noisyFlag_)
0180 isNoisy = true;
0181
0182 return decodePed(datum);
0183 }
0184
0185 float SiPixelGainCalibrationOffline::getGain(const int& col,
0186 const int& row,
0187 const Range& range,
0188 const int& nCols,
0189 bool& isDeadColumn,
0190 bool& isNoisyColumn) const {
0191 unsigned int lengthOfColumnData = (range.second - range.first) / nCols;
0192
0193 unsigned int lengthOfAveragedDataInEachColumn = numberOfRowsToAverageOver_ + 1;
0194 unsigned int numberOfAveragedDataBlocksToSkip = row / numberOfRowsToAverageOver_;
0195
0196
0197 const unsigned int datum = *(range.first + col * lengthOfColumnData +
0198 ((numberOfAveragedDataBlocksToSkip + 1) * lengthOfAveragedDataInEachColumn) - 1) &
0199 0xFF;
0200
0201 if (datum == deadFlag_)
0202 isDeadColumn = true;
0203 if (datum == noisyFlag_)
0204 isNoisyColumn = true;
0205
0206 int maxRow = lengthOfColumnData - (lengthOfColumnData % numberOfRowsToAverageOver_) - 1;
0207 if (col >= nCols || row > maxRow) {
0208 throw cms::Exception("CorruptedData")
0209 << "[SiPixelGainCalibrationOffline::getPed] Pixel out of range: col " << col << " row " << row;
0210 }
0211
0212 return decodeGain(datum);
0213 }
0214
0215 float SiPixelGainCalibrationOffline::encodeGain(const float& gain) {
0216 if (gain < minGain_ || gain > maxGain_) {
0217 throw cms::Exception("InsertFailure") << "[SiPixelGainCalibrationOffline::encodeGain] Trying to encode gain ("
0218 << gain << ") out of range [" << minGain_ << "," << maxGain_ << "]\n";
0219 } else {
0220 double precision = (maxGain_ - minGain_) / static_cast<float>(nBinsToUseForEncoding_);
0221 float encodedGain = (float)((gain - minGain_) / precision);
0222 return encodedGain;
0223 }
0224 }
0225
0226 float SiPixelGainCalibrationOffline::encodePed(const float& ped) {
0227 if (ped < minPed_ || ped > maxPed_) {
0228 throw cms::Exception("InsertFailure") << "[SiPixelGainCalibrationOffline::encodePed] Trying to encode pedestal ("
0229 << ped << ") out of range [" << minPed_ << "," << maxPed_ << "]\n";
0230 } else {
0231 double precision = (maxPed_ - minPed_) / static_cast<float>(nBinsToUseForEncoding_);
0232 float encodedPed = (float)((ped - minPed_) / precision);
0233 return encodedPed;
0234 }
0235 }
0236
0237 float SiPixelGainCalibrationOffline::decodePed(unsigned int ped) const {
0238 double precision = (maxPed_ - minPed_) / static_cast<float>(nBinsToUseForEncoding_);
0239 float decodedPed = (float)(ped * precision + minPed_);
0240 return decodedPed;
0241 }
0242
0243 float SiPixelGainCalibrationOffline::decodeGain(unsigned int gain) const {
0244 double precision = (maxGain_ - minGain_) / static_cast<float>(nBinsToUseForEncoding_);
0245 float decodedGain = (float)(gain * precision + minGain_);
0246 return decodedGain;
0247 }