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