00001 #include "CondFormats/SiPixelObjects/interface/SiPixelGainCalibrationOffline.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003
00004
00005
00006
00007 SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline() :
00008 minPed_(0.),
00009 maxPed_(255.),
00010 minGain_(0.),
00011 maxGain_(255.),
00012 numberOfRowsToAverageOver_(80),
00013 nBinsToUseForEncoding_(254),
00014 deadFlag_(255)
00015 {
00016 if (deadFlag_ > 0xFF)
00017 throw cms::Exception("GainCalibration Payload configuration error")
00018 << "[SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline] Dead flag was set to " << deadFlag_ << ", and it must be set less than or equal to 255";
00019 }
00020
00021 SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline(float minPed, float maxPed, float minGain, float maxGain) :
00022 minPed_(minPed),
00023 maxPed_(maxPed),
00024 minGain_(minGain),
00025 maxGain_(maxGain),
00026 numberOfRowsToAverageOver_(80),
00027 nBinsToUseForEncoding_(254),
00028 deadFlag_(255)
00029 {
00030 if (deadFlag_ > 0xFF)
00031 throw cms::Exception("GainCalibration Payload configuration error")
00032 << "[SiPixelGainCalibrationOffline::SiPixelGainCalibrationOffline] Dead flag was set to " << deadFlag_ << ", and it must be set less than or equal to 255";
00033 }
00034
00035 bool SiPixelGainCalibrationOffline::put(const uint32_t& DetId, Range input, const int& nCols) {
00036
00037
00038 Registry::iterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiPixelGainCalibrationOffline::StrictWeakOrdering());
00039 if (p!=indexes.end() && p->detid==DetId)
00040 return false;
00041
00042 size_t sd= input.second-input.first;
00043 DetRegistry detregistry;
00044 detregistry.detid=DetId;
00045 detregistry.ncols=nCols;
00046 detregistry.ibegin=v_pedestals.size();
00047 detregistry.iend=v_pedestals.size()+sd;
00048 indexes.insert(p,detregistry);
00049
00050 v_pedestals.insert(v_pedestals.end(),input.first,input.second);
00051 return true;
00052 }
00053
00054 const int SiPixelGainCalibrationOffline::getNCols(const uint32_t& DetId) const {
00055
00056 RegistryIterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiPixelGainCalibrationOffline::StrictWeakOrdering());
00057 if (p==indexes.end()|| p->detid!=DetId)
00058 return 0;
00059 else
00060 return p->ncols;
00061 }
00062
00063 const SiPixelGainCalibrationOffline::Range SiPixelGainCalibrationOffline::getRange(const uint32_t& DetId) const {
00064
00065
00066 RegistryIterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiPixelGainCalibrationOffline::StrictWeakOrdering());
00067 if (p==indexes.end()|| p->detid!=DetId)
00068 return SiPixelGainCalibrationOffline::Range(v_pedestals.end(),v_pedestals.end());
00069 else
00070 return SiPixelGainCalibrationOffline::Range(v_pedestals.begin()+p->ibegin,v_pedestals.begin()+p->iend);
00071 }
00072
00073 const std::pair<const SiPixelGainCalibrationOffline::Range, const int>
00074 SiPixelGainCalibrationOffline::getRangeAndNCols(const uint32_t& DetId) const {
00075 RegistryIterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiPixelGainCalibrationOffline::StrictWeakOrdering());
00076 if (p==indexes.end()|| p->detid!=DetId)
00077 return std::make_pair(SiPixelGainCalibrationOffline::Range(v_pedestals.end(),v_pedestals.end()), 0);
00078 else
00079 return std::make_pair(SiPixelGainCalibrationOffline::Range(v_pedestals.begin()+p->ibegin,v_pedestals.begin()+p->iend), p->ncols);
00080 }
00081
00082
00083 void SiPixelGainCalibrationOffline::getDetIds(std::vector<uint32_t>& DetIds_) const {
00084
00085 SiPixelGainCalibrationOffline::RegistryIterator begin = indexes.begin();
00086 SiPixelGainCalibrationOffline::RegistryIterator end = indexes.end();
00087 for (SiPixelGainCalibrationOffline::RegistryIterator p=begin; p != end; ++p) {
00088 DetIds_.push_back(p->detid);
00089 }
00090 }
00091
00092 void SiPixelGainCalibrationOffline::setDataGain(float gain, const int& nRows, std::vector<char>& vped, bool thisColumnIsDead){
00093
00094 float theEncodedGain = encodeGain(gain);
00095
00096 unsigned int gain_ = (static_cast<unsigned int>(theEncodedGain)) & 0xFF;
00097
00098
00099 if (thisColumnIsDead)
00100 gain_ = deadFlag_ & 0xFF;
00101
00102 vped.resize(vped.size()+1);
00103
00104 if (nRows != (int)numberOfRowsToAverageOver_)
00105 {
00106 throw cms::Exception("GainCalibration Payload configuration error")
00107 << "[SiPixelGainCalibrationOffline::setDataGain] You are setting a gain averaged over nRows = " << nRows << " where this payload is set ONLY to average over " << numberOfRowsToAverageOver_ << " nRows";
00108 }
00109
00110 if (vped.size() % (nRows + 1) != 0)
00111 {
00112 throw cms::Exception("FillError")
00113 << "[SiPixelGainCalibrationOffline::setDataGain] Column gain average (OR SETTING AN ENTIRE COLUMN DEAD) must be filled after the pedestal for each row has been added. An additional source of this error would be setting a pixel dead AND setting its pedestal";
00114 }
00115
00116 ::memcpy((void*)(&vped[vped.size()-1]),(void*)(&gain_),1);
00117 }
00118
00119 void SiPixelGainCalibrationOffline::setDataPedestal(float pedestal, std::vector<char>& vped, bool thisPixelIsDead){
00120
00121 float theEncodedPedestal = encodePed(pedestal);
00122
00123 unsigned int ped_ = (static_cast<unsigned int>(theEncodedPedestal)) & 0xFF;
00124
00125 if (thisPixelIsDead)
00126 ped_ = deadFlag_ & 0xFF;
00127
00128 vped.resize(vped.size()+1);
00129
00130 ::memcpy((void*)(&vped[vped.size()-1]),(void*)(&ped_),1);
00131 }
00132
00133 float SiPixelGainCalibrationOffline::getPed(const int& col, const int& row, const Range& range, const int& nCols, bool& isDead) const {
00134
00135 unsigned int lengthOfColumnData = (range.second-range.first)/nCols;
00136
00137 unsigned int lengthOfAveragedDataInEachColumn = numberOfRowsToAverageOver_ + 1;
00138 unsigned int numberOfAveragedDataBlocksToSkip = row / numberOfRowsToAverageOver_;
00139 unsigned int offSetInCorrectDataBlock = row % numberOfRowsToAverageOver_;
00140
00141 const DecodingStructure & s = (const DecodingStructure & ) *(range.first + col*(lengthOfColumnData) + (numberOfAveragedDataBlocksToSkip * lengthOfAveragedDataInEachColumn) + offSetInCorrectDataBlock);
00142
00143 int maxRow = lengthOfColumnData - (lengthOfColumnData % numberOfRowsToAverageOver_) - 1;
00144 if (col >= nCols || row > maxRow){
00145 throw cms::Exception("CorruptedData")
00146 << "[SiPixelGainCalibrationOffline::getPed] Pixel out of range: col " << col << " row " << row;
00147 }
00148
00149 if ((s.datum & 0xFF) == deadFlag_)
00150 isDead = true;
00151
00152 return decodePed(s.datum & 0xFF);
00153 }
00154
00155 float SiPixelGainCalibrationOffline::getGain(const int& col, const int& row, const Range& range, const int& nCols, bool& isDeadColumn) const {
00156
00157 unsigned int lengthOfColumnData = (range.second-range.first)/nCols;
00158
00159 unsigned int lengthOfAveragedDataInEachColumn = numberOfRowsToAverageOver_ + 1;
00160 unsigned int numberOfAveragedDataBlocksToSkip = row / numberOfRowsToAverageOver_;
00161
00162
00163 const DecodingStructure & s = (const DecodingStructure & ) *(range.first+(col)*(lengthOfColumnData) + ( (numberOfAveragedDataBlocksToSkip+1) * lengthOfAveragedDataInEachColumn) - 1);
00164
00165 if ((s.datum & 0xFF) == deadFlag_)
00166 isDeadColumn = true;
00167
00168 int maxRow = lengthOfColumnData - (lengthOfColumnData % numberOfRowsToAverageOver_) - 1;
00169 if (col >= nCols || row > maxRow){
00170 throw cms::Exception("CorruptedData")
00171 << "[SiPixelGainCalibrationOffline::getPed] Pixel out of range: col " << col;
00172 }
00173 return decodeGain(s.datum & 0xFF);
00174 }
00175
00176 float SiPixelGainCalibrationOffline::encodeGain( const float& gain ) {
00177
00178 if(gain < minGain_ || gain > maxGain_ ) {
00179 throw cms::Exception("InsertFailure")
00180 << "[SiPixelGainCalibrationOffline::encodeGain] Trying to encode gain (" << gain << ") out of range [" << minGain_ << "," << maxGain_ << "]\n";
00181 } else {
00182 double precision = (maxGain_-minGain_)/static_cast<float>(nBinsToUseForEncoding_);
00183 float encodedGain = (float)((gain-minGain_)/precision);
00184 return encodedGain;
00185 }
00186
00187 }
00188
00189 float SiPixelGainCalibrationOffline::encodePed( const float& ped ) {
00190
00191 if(ped < minPed_ || ped > maxPed_ ) {
00192 throw cms::Exception("InsertFailure")
00193 << "[SiPixelGainCalibrationOffline::encodePed] Trying to encode pedestal (" << ped << ") out of range [" << minPed_ << "," << maxPed_ << "]\n";
00194 } else {
00195 double precision = (maxPed_-minPed_)/static_cast<float>(nBinsToUseForEncoding_);
00196 float encodedPed = (float)((ped-minPed_)/precision);
00197 return encodedPed;
00198 }
00199
00200 }
00201
00202 float SiPixelGainCalibrationOffline::decodePed( unsigned int ped ) const {
00203
00204 double precision = (maxPed_-minPed_)/static_cast<float>(nBinsToUseForEncoding_);
00205 float decodedPed = (float)(ped*precision + minPed_);
00206 return decodedPed;
00207
00208 }
00209
00210 float SiPixelGainCalibrationOffline::decodeGain( unsigned int gain ) const {
00211
00212 double precision = (maxGain_-minGain_)/static_cast<float>(nBinsToUseForEncoding_);
00213 float decodedGain = (float)(gain*precision + minGain_);
00214 return decodedGain;
00215 }
00216