CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CondFormats/SiPixelObjects/src/SiPixelGainCalibrationOffline.cc

Go to the documentation of this file.
00001 #include "CondFormats/SiPixelObjects/interface/SiPixelGainCalibrationOffline.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include <algorithm>
00004 #include <cstring>
00005 
00006 //      
00007 // Constructors
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   // put in SiPixelGainCalibrationOffline of DetId
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   // get number of columns of DetId
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   // get SiPixelGainCalibrationOffline Range of DetId
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   // returns vector of DetIds in map
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   // if this whole column is dead, set a char based dead flag in the blob.
00111   if (thisColumnIsDead)
00112      gain_ = deadFlag_ & 0xFF;
00113   if (thisColumnIsNoisy)
00114      gain_ = noisyFlag_ & 0xFF;
00115 
00116   vped.resize(vped.size()+1);
00117   //check to make sure the column is being placed in the right place in the blob
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   // insert in vector of char
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   // insert in vector of char
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   //determine what row averaged range we are in (i.e. ROC 1 or ROC 2)
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   //determine what row averaged range we are in (i.e. ROC 1 or ROC 2)
00177   unsigned int lengthOfAveragedDataInEachColumn = numberOfRowsToAverageOver_ + 1;
00178   unsigned int numberOfAveragedDataBlocksToSkip = row / numberOfRowsToAverageOver_;
00179 
00180   // gain average is stored in the last location of current row averaged column data block
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