CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/CondFormats/SiStripObjects/src/SiStripPedestals.cc

Go to the documentation of this file.
00001 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include <algorithm>
00004 
00005 bool SiStripPedestals::put(const uint32_t& DetId, InputVector& input) {
00006   // put in SiStripPedestals of DetId
00007   std::vector<unsigned char>      Vo_CHAR;
00008   encode(input, Vo_CHAR);
00009 
00010   Registry::iterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiStripPedestals::StrictWeakOrdering());
00011   if (p!=indexes.end() && p->detid==DetId)
00012     return false;
00013 
00014   //size_t sd= input.second-input.first;
00015   size_t sd= Vo_CHAR.end() - Vo_CHAR.begin();
00016   DetRegistry detregistry;
00017   detregistry.detid=DetId;
00018   detregistry.ibegin=v_pedestals.size();
00019   detregistry.iend=v_pedestals.size()+sd;
00020   indexes.insert(p,detregistry);
00021 
00022   //v_pedestals.insert(v_pedestals.end(),input.first,input.second);
00023   v_pedestals.insert(v_pedestals.end(),Vo_CHAR.begin(),Vo_CHAR.end());
00024   return true;
00025 }
00026 
00027 const SiStripPedestals::Range SiStripPedestals::getRange(const uint32_t& DetId) const {
00028   // get SiStripPedestals Range of DetId
00029 
00030   RegistryIterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiStripPedestals::StrictWeakOrdering());
00031   if (p==indexes.end()|| p->detid!=DetId) 
00032     return SiStripPedestals::Range(v_pedestals.end(),v_pedestals.end()); 
00033   else 
00034     return SiStripPedestals::Range(v_pedestals.begin()+p->ibegin,v_pedestals.begin()+p->iend);
00035 }
00036 
00037 void SiStripPedestals::getDetIds(std::vector<uint32_t>& DetIds_) const {
00038   // returns vector of DetIds in map
00039   SiStripPedestals::RegistryIterator begin = indexes.begin();
00040   SiStripPedestals::RegistryIterator end   = indexes.end();
00041   for (SiStripPedestals::RegistryIterator p=begin; p != end; ++p) {
00042     DetIds_.push_back(p->detid);
00043   }
00044 }
00045 
00046 
00047 void SiStripPedestals::setData(float ped, SiStripPedestals::InputVector& vped){
00048   vped.push_back((static_cast<uint16_t>  (ped) & 0x3FF)) ;
00049 }
00050 
00051 float SiStripPedestals::getPed(const uint16_t& strip, const Range& range) const {
00052   if (10*strip>=(range.second-range.first)*8){
00053     throw cms::Exception("CorruptedData")
00054       << "[SiStripPedestals::getPed] looking for SiStripPedestals for a strip out of range: strip " << strip;
00055   }
00056   return   static_cast<float> (decode(strip,range));
00057 }
00058 
00059 void SiStripPedestals::encode(InputVector& Vi, std::vector<unsigned char>& Vo){
00060   static const uint16_t  BITS_PER_STRIP  = 10;
00061   const size_t           VoSize          = (size_t)((Vi.size() *       BITS_PER_STRIP)/8+.999);
00062   Vo.resize(VoSize);
00063   for(size_t i = 0; i<Vo.size(); ++i)
00064     Vo[i]   &=      0x00u;
00065   
00066   for(unsigned int stripIndex =0; stripIndex<Vi.size(); ++stripIndex){
00067     unsigned char*  data    =       &Vo[Vo.size()-1];
00068     uint32_t lowBit         =       stripIndex * BITS_PER_STRIP;
00069     uint8_t firstByteBit    =       (lowBit & 0x6);
00070     uint8_t firstByteNBits  =       8 - firstByteBit;
00071     uint8_t firstByteMask   =       0xffu << firstByteBit;
00072     uint8_t secondByteNbits =       (BITS_PER_STRIP - firstByteNBits);
00073     uint8_t secondByteMask  =       ~(0xffu << secondByteNbits);
00074 
00075     *(data-lowBit/8)        =       (*(data-lowBit/8)   & ~(firstByteMask))         | ((Vi[stripIndex] & 0xffu) <<firstByteBit);
00076     *(data-lowBit/8-1)      =       (*(data-lowBit/8-1) & ~(secondByteMask))        | ((Vi[stripIndex] >> firstByteNBits) & secondByteMask);
00077 
00078     /*
00079       if(stripIndex   < 25 ){
00080       std::cout       << "***************ENCODE*********************"<<std::endl
00081       << "\tdata-lowBit/8     :"<<print_as_binary((*(data-lowBit/8)   & ~(firstByteMask)))
00082       << "-"<<print_as_binary(((Vi[stripIndex] & 0xffu) <<firstByteBit))
00083       << "\tdata-lowBit/8-1   :"<<print_as_binary((*(data-lowBit/8-1)   & ~(secondByteMask)))
00084       << "-"<<print_as_binary((((Vi[stripIndex]>> firstByteNBits) & secondByteMask)))
00085       << std::endl;
00086       std::cout       << "strip "<<stripIndex<<"\tvi: " << Vi[stripIndex] <<"\t"
00087       << print_short_as_binary(Vi[stripIndex])
00088       << "\tvo1:"<< print_char_as_binary(*(data-lowBit/8))
00089       << "\tvo2:"<< print_char_as_binary(*(data-lowBit/8-1))
00090       << "\tlowBit:"<< lowBit
00091       << "\tfirstByteMask :"<<print_as_binary(firstByteMask)
00092       << "\tsecondByteMask:"<<print_as_binary(secondByteMask)
00093       << "\tfirstByteBit:"<<print_as_binary(firstByteBit)
00094       << std::endl;
00095       }
00096     */
00097   }
00098 }
00099 
00100 uint16_t SiStripPedestals::decode (const uint16_t& strip, const Range& range) const{
00101   const char *data = &*(range.second -1);  // pointer to the last byte of data
00102   static const uint16_t BITS_PER_STRIP = 10;
00103 
00104   uint32_t lowBit        = strip * BITS_PER_STRIP;
00105   uint8_t firstByteBit   = (lowBit & 6);//module 
00106   uint8_t firstByteNBits = 8 - firstByteBit;
00107   uint8_t firstByteMask  = 0xffu << firstByteBit;
00108   uint8_t secondByteMask = ~(0xffu << (BITS_PER_STRIP - firstByteNBits));
00109   uint16_t value         =   ((uint16_t(*(data-lowBit/8  )) & firstByteMask) >> firstByteBit) | ((uint16_t(*(data-lowBit/8-1)) & secondByteMask) << firstByteNBits);
00110   
00111   /*
00112     if(strip  < 25){
00113     std::cout       << "***************DECODE*********************"<<"\n"
00114     << "strip "<<strip << " " 
00115     << value 
00116     <<"\t   :"<<print_as_binary(value) 
00117     <<"\t  :"<<print_as_binary(    ((uint16_t(*(data-lowBit/8  )) & firstByteMask) >>   firstByteBit)       )
00118     << "-"<<print_as_binary(  ((uint16_t(*(data-lowBit/8-1)) & secondByteMask) <<firstByteNBits)    )
00119     << "\t *(data-lowBit/8) " << print_as_binary(    *(data-lowBit/8 ))
00120     << "\t *(data-lowBit/8-1) " << print_as_binary(    *(data-lowBit/8 -1 ))
00121     << "\tlowBit:"<< lowBit
00122     << "\tfirstByteMask :"<<print_as_binary(firstByteMask)
00123     << "\tsecondByteMask:"<<print_as_binary(secondByteMask)
00124     << "\tfirstByteBit:"<<print_as_binary(firstByteBit)
00125     << std::endl;
00126     }
00127   */
00128   return value;
00129 }
00130 
00133 inline uint16_t SiStripPedestals::get10bits(const uint8_t * &ptr, int8_t skip) const {
00134     uint8_t maskThis = (0xFF << skip);
00135     uint8_t maskThat = ((4 << skip) - 1);
00136     uint16_t ret = ( ((*ptr) & maskThis) >> skip );
00137     --ptr;
00138     return ret | ( ((*ptr) & maskThat) << (8 - skip) );
00139 }
00140 
00141 void
00142 SiStripPedestals::allPeds  (std::vector<int>   & peds,  const Range& range) const {
00143     size_t mysize  = ((range.second-range.first) << 3) / 10;
00144     size_t size = peds.size();
00145     if (mysize < size) throw cms::Exception("CorruptedData") 
00146             << "[SiStripPedestals::allPeds] Requested pedestals for " << peds.size() << " strips, I have it only for " << mysize << " strips\n";
00147     size_t size4 = size & (~0x3), carry = size & 0x3; // we have an optimized way of unpacking 4 strips
00148     const uint8_t *ptr = reinterpret_cast<const uint8_t *>(&*range.second) - 1;
00149     std::vector<int>::iterator out = peds.begin(), end4 = peds.begin() + size4;
00150     // we do it this baroque way instead of just loopin on all the strips because it's faster
00151     // as the value of 'skip' is a constant, so the compiler can compute the masks directly
00152    while (out < end4) {
00153         *out = static_cast<int> ( get10bits(ptr, 0) ); ++out;
00154         *out = static_cast<int> ( get10bits(ptr, 2) ); ++out;
00155         *out = static_cast<int> ( get10bits(ptr, 4) ); ++out;
00156         *out = static_cast<int> ( get10bits(ptr, 6) ); ++out;
00157         --ptr; // every 4 strips we have to skip one more bit
00158     } 
00159     for (size_t rem = 0; rem < carry; ++rem ) {
00160         *out = static_cast<int> ( get10bits(ptr, 2*rem) ); ++out;
00161     }
00162 }
00163 
00164 void SiStripPedestals::printSummary(std::stringstream& ss) const
00165 {
00166   std::vector<uint32_t> detid;
00167   getDetIds(detid);
00168   SiStripDetSummary summary;
00169   for( size_t id = 0; id < detid.size(); ++id ) {
00170     SiStripPedestals::Range range = getRange(detid[id]);
00171     for( int it=0; it < (range.second-range.first)*8/10; ++it ){
00172       summary.add( detid[id], getPed(it,range) );
00173     }
00174   }
00175   ss << "Summary of pedestals:" << std::endl;
00176   summary.print(ss);
00177 }
00178 
00179 
00180 void SiStripPedestals::printDebug(std::stringstream& ss) const
00181 {
00182   std::vector<uint32_t> detid;
00183   getDetIds(detid);
00184 
00185   ss << "Number of detids = " << detid.size() << std::endl;
00186 
00187   for( size_t id = 0; id < detid.size(); ++id ) {
00188     SiStripPedestals::Range range = getRange(detid[id]);
00189 
00190     int strip = 0;
00191     ss << "detid" << std::setw(15) << "strip" << std::setw(10) << "pedestal" << std::endl;
00192     int detId = 0;
00193     int oldDetId = 0;
00194     for( int it=0; it < (range.second-range.first)*8/10; ++it ){
00195       detId = detid[id];
00196       if( detId != oldDetId ) {
00197         oldDetId = detId;
00198         ss << detid[id];
00199       }
00200       else ss << "   ";
00201       ss << std::setw(15) << strip++ << std::setw(10) << getPed(it,range) << std::endl;
00202     }
00203   }
00204 }
00205 
00206