Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:51:33

0001 #include "CondFormats/SiPixelObjects/interface/SiPixelGainCalibrationOffline.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include <algorithm>
0004 #include <cstring>
0005 
0006 //
0007 // Constructors
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   // put in SiPixelGainCalibrationOffline of DetId
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   // get number of columns of DetId
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   // get SiPixelGainCalibrationOffline Range of DetId
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   // returns vector of DetIds in map
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   // if this whole column is dead, set a char based dead flag in the blob.
0117   if (thisColumnIsDead)
0118     gain_ = deadFlag_ & 0xFF;
0119   if (thisColumnIsNoisy)
0120     gain_ = noisyFlag_ & 0xFF;
0121 
0122   vped.resize(vped.size() + 1);
0123   //check to make sure the column is being placed in the right place in the blob
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   // insert in vector of char
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   // insert in vector of char
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   // determine what row averaged range we are in (i.e. ROC 1 or ROC 2)
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   // determine what row averaged range we are in (i.e. ROC 1 or ROC 2)
0193   unsigned int lengthOfAveragedDataInEachColumn = numberOfRowsToAverageOver_ + 1;
0194   unsigned int numberOfAveragedDataBlocksToSkip = row / numberOfRowsToAverageOver_;
0195 
0196   // gain average is stored in the last location of current row averaged column data block
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 }