CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/CondFormats/SiStripObjects/src/SiStripNoises.cc

Go to the documentation of this file.
00001 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include <iostream>
00004 #include <algorithm>
00005 #include <math.h>
00006 #include <iomanip>
00007 #include "CondFormats/SiStripObjects/interface/SiStripDetSummary.h"
00008 
00009 SiStripNoises::SiStripNoises(const SiStripNoises& input){
00010   v_noises.clear();
00011   indexes.clear();
00012   v_noises.insert(v_noises.end(),input.v_noises.begin(),input.v_noises.end());
00013   indexes.insert(indexes.end(),input.indexes.begin(),input.indexes.end());
00014 }
00015 
00016 bool SiStripNoises::put(const uint32_t& DetId, const InputVector& input) {
00017         std::vector<unsigned char>      Vo_CHAR;
00018         encode(input, Vo_CHAR);
00019 
00020         Registry::iterator p    =       std::lower_bound(indexes.begin(),indexes.end(),DetId,SiStripNoises::StrictWeakOrdering());
00021         if (p!=indexes.end()    &&      p->detid==DetId)
00022           return false;
00023 
00024         size_t sd = Vo_CHAR.end() - Vo_CHAR.begin();
00025         DetRegistry detregistry;
00026         detregistry.detid  = DetId;
00027         detregistry.ibegin = v_noises.size();
00028         detregistry.iend   = v_noises.size()+sd;
00029         indexes.insert(p,detregistry);
00030         v_noises.insert(v_noises.end(),Vo_CHAR.begin(),Vo_CHAR.end());
00031         return true;
00032 }
00033 
00034 const SiStripNoises::Range SiStripNoises::getRange(const uint32_t& DetId) const {
00035         // get SiStripNoises Range of DetId
00036 
00037         RegistryIterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiStripNoises::StrictWeakOrdering());
00038         if (p==indexes.end()|| p->detid!=DetId) 
00039                 return SiStripNoises::Range(v_noises.end(),v_noises.end()); 
00040         else 
00041                 return SiStripNoises::Range(v_noises.begin()+p->ibegin,v_noises.begin()+p->iend);
00042 }
00043 
00044 void SiStripNoises::getDetIds(std::vector<uint32_t>& DetIds_) const {
00045         // returns vector of DetIds in map
00046         SiStripNoises::RegistryIterator begin = indexes.begin();
00047         SiStripNoises::RegistryIterator end   = indexes.end();
00048         for (SiStripNoises::RegistryIterator p=begin; p != end; ++p) {
00049                 DetIds_.push_back(p->detid);
00050         }
00051 }
00052 
00053 float SiStripNoises::getNoise(uint16_t strip, const Range& range) {
00054         if (9*strip>=(range.second-range.first)*8){
00055                 throw cms::Exception("CorruptedData")
00056                         << "[SiStripNoises::getNoise] looking for SiStripNoises for a strip out of range: strip " << strip;
00057         }
00058         return getNoiseFast(strip,range);
00059 }
00060 
00061 void SiStripNoises::setData(float noise_, InputVector& v){
00062         v.push_back((static_cast<int16_t>  (noise_*10.0 + 0.5) & 0x01FF)) ;
00063 }
00064 
00065 void SiStripNoises::encode(const InputVector& Vi, std::vector<unsigned char>& Vo){
00066   static const uint16_t  BITS_PER_STRIP  = 9;
00067   const size_t           VoSize          = (size_t)((Vi.size() *       BITS_PER_STRIP)/8+.999);
00068   Vo.resize(VoSize);
00069   for(size_t i = 0; i<VoSize; ++i)
00070     Vo[i]   &=      0x00u;
00071   
00072   for(unsigned int stripIndex =0; stripIndex<Vi.size(); ++stripIndex){
00073     unsigned char*  data    =       &Vo[VoSize-1];
00074     uint32_t lowBit         =       stripIndex * BITS_PER_STRIP;
00075     uint8_t firstByteBit    =       (lowBit & 0x7);
00076     uint8_t firstByteNBits  =       8 - firstByteBit;
00077     uint8_t firstByteMask   =       0xffu << firstByteBit;
00078     uint8_t secondByteNbits =       (BITS_PER_STRIP - firstByteNBits);
00079     uint8_t secondByteMask  =       ~(0xffu << secondByteNbits);
00080 
00081     *(data-lowBit/8)        =       (*(data-lowBit/8)   & ~(firstByteMask))         | ((Vi[stripIndex] & 0xffu) <<firstByteBit);
00082     *(data-lowBit/8-1)      =       (*(data-lowBit/8-1) & ~(secondByteMask))        | ((Vi[stripIndex] >> firstByteNBits) & secondByteMask);
00083 
00084     /*
00085     if(stripIndex   < 25 ){
00086       std::cout       << "***************ENCODE*********************"<<std::endl
00087                       << "\tdata-lowBit/8     :"<<print_as_binary((*(data-lowBit/8)   & ~(firstByteMask)))
00088                       << "-"<<print_as_binary(((Vi[stripIndex] & 0xffu) <<firstByteBit))
00089                       << "\tdata-lowBit/8-1   :"<<print_as_binary((*(data-lowBit/8-1)   & ~(secondByteMask)))
00090                       << "-"<<print_as_binary((((Vi[stripIndex]>> firstByteNBits) & secondByteMask)))
00091                       << std::endl;
00092       std::cout       << "strip "<<stripIndex<<"\tvi: " << Vi[stripIndex] <<"\t"
00093                       << print_short_as_binary(Vi[stripIndex])
00094                       << "\tvo1:"<< print_char_as_binary(*(data-lowBit/8))
00095                       << "\tvo2:"<< print_char_as_binary(*(data-lowBit/8-1))
00096                       << "\tlowBit:"<< lowBit
00097                       << "\tfirstByteMask :"<<print_as_binary(firstByteMask)
00098                       << "\tsecondByteMask:"<<print_as_binary(secondByteMask)
00099                       << "\tfirstByteBit:"<<print_as_binary(firstByteBit)
00100                       << std::endl;
00101         }
00102     */
00103   }
00104 }
00105 
00106 
00107 //============ Methods for bulk-decoding all noises for a module ================
00108 
00109 
00110 
00111 void SiStripNoises::allNoises(std::vector<float> &noises, const Range& range) const {
00112     size_t mysize  = ((range.second-range.first) << 3) / 9;
00113     size_t size = noises.size();
00114     if (mysize < size) throw cms::Exception("CorruptedData") 
00115             << "[SiStripNoises::allNoises] Requested noise for " << noises.size() << " strips, I have it only for " << mysize << " strips\n";
00116     size_t size8 = size & (~0x7), carry = size & 0x7; // we have an optimized way of unpacking 8 strips
00117     const uint8_t *ptr = (&*range.second) - 1;
00118     std::vector<float>::iterator out = noises.begin(), end8 = noises.begin() + size8;
00119     // we do it this baroque way instead of just loopin on all the strips because it's faster
00120     // as the value of 'skip' is a constant, so the compiler can compute the masks directly
00121    while (out < end8) {
00122         *out = static_cast<float> ( get9bits(ptr, 0) / 10.0f ); ++out;
00123         *out = static_cast<float> ( get9bits(ptr, 1) / 10.0f ); ++out;
00124         *out = static_cast<float> ( get9bits(ptr, 2) / 10.0f ); ++out;
00125         *out = static_cast<float> ( get9bits(ptr, 3) / 10.0f ); ++out;
00126         *out = static_cast<float> ( get9bits(ptr, 4) / 10.0f ); ++out;
00127         *out = static_cast<float> ( get9bits(ptr, 5) / 10.0f ); ++out;
00128         *out = static_cast<float> ( get9bits(ptr, 6) / 10.0f ); ++out;
00129         *out = static_cast<float> ( get9bits(ptr, 7) / 10.0f ); ++out;
00130         --ptr; // every 8 strips we have to skip one more bit
00131     } 
00132     for (size_t rem = 0; rem < carry; ++rem ) {
00133         *out = static_cast<float> ( get9bits(ptr, rem) / 10.0f ); ++out;
00134     }
00135 }
00136 
00137 
00138 /*
00139 const std::string SiStripNoises::print_as_binary(const uint8_t ch) const
00140 {
00141   std::string     str;
00142   int i = CHAR_BIT;
00143   while (i > 0)
00144     {
00145       -- i;
00146       str.push_back((ch&(1 << i) ? '1' : '0'));
00147     }
00148   return str;
00149 }
00150 
00151 std::string SiStripNoises::print_char_as_binary(const unsigned char ch) const
00152 {
00153   std::string     str;
00154   int i = CHAR_BIT;
00155   while (i > 0)
00156     {
00157       -- i;
00158       str.push_back((ch&(1 << i) ? '1' : '0'));
00159     }
00160   return str;
00161 }
00162 
00163 std::string SiStripNoises::print_short_as_binary(const short ch) const
00164 {
00165   std::string     str;
00166   int i = CHAR_BIT*2;
00167   while (i > 0)
00168     {
00169       -- i;
00170       str.push_back((ch&(1 << i) ? '1' : '0'));
00171     }
00172   return str;
00173 }
00174 */
00175 
00176 void SiStripNoises::printDebug(std::stringstream& ss) const{
00177   RegistryIterator rit=getRegistryVectorBegin(), erit=getRegistryVectorEnd();
00178   uint16_t Nstrips;
00179   std::vector<float> vstripnoise;
00180 
00181   ss << "detid" << std::setw(15) << "strip" << std::setw(10) << "noise" << std::endl;
00182 
00183   int detId = 0;
00184   int oldDetId = 0;
00185   for(;rit!=erit;++rit){
00186     Nstrips = (rit->iend-rit->ibegin)*8/9; //number of strips = number of chars * char size / strip noise size
00187     vstripnoise.resize(Nstrips);
00188     allNoises(vstripnoise,make_pair(getDataVectorBegin()+rit->ibegin,getDataVectorBegin()+rit->iend));
00189 
00190     detId = rit->detid;
00191     if( detId != oldDetId ) {
00192       oldDetId = detId;
00193       ss << detId;
00194     }
00195     else ss << "   ";
00196     for(size_t i=0;i<Nstrips;++i){
00197       if( i != 0 ) ss << "   ";
00198       ss << std::setw(15) << i << std::setw(10) << vstripnoise[i] << std::endl;
00199     }
00200   }
00201 }
00202 
00203 void SiStripNoises::printSummary(std::stringstream& ss) const{
00204 
00205   SiStripDetSummary summary;
00206 
00207   std::stringstream tempss;
00208 
00209   RegistryIterator rit=getRegistryVectorBegin(), erit=getRegistryVectorEnd();
00210   uint16_t Nstrips;
00211   std::vector<float> vstripnoise;
00212   double mean,rms,min, max;
00213   for(;rit!=erit;++rit){
00214     Nstrips = (rit->iend-rit->ibegin)*8/9; //number of strips = number of chars * char size / strip noise size
00215     vstripnoise.resize(Nstrips);
00216     allNoises(vstripnoise,make_pair(getDataVectorBegin()+rit->ibegin,getDataVectorBegin()+rit->iend));
00217     tempss << "\ndetid: " << rit->detid << " \t ";
00218     mean=0; rms=0; min=10000; max=0;  
00219 
00220     DetId detId(rit->detid);
00221 
00222     for(size_t i=0;i<Nstrips;++i){
00223       mean+=vstripnoise[i];
00224       rms+=vstripnoise[i]*vstripnoise[i];
00225       if(vstripnoise[i]<min) min=vstripnoise[i];
00226       if(vstripnoise[i]>max) max=vstripnoise[i];
00227 
00228       summary.add(detId, vstripnoise[i]);
00229     }
00230     mean/=Nstrips;
00231     rms= sqrt(rms/Nstrips-mean*mean);
00232 
00233 
00234     tempss << "Nstrips " << Nstrips << " \t; mean " << mean << " \t; rms " << rms << " \t; min " << min << " \t; max " << max << "\t " ; 
00235   }
00236   ss << std::endl << "Summary:" << std::endl;
00237   summary.print(ss);
00238   ss << std::endl;
00239   ss << tempss.str();
00240 }
00241 
00242 std::vector<SiStripNoises::ratioData> SiStripNoises::operator / ( const SiStripNoises& d) {
00243   std::vector<ratioData> result;
00244   ratioData aData;
00245 
00246   RegistryIterator iter=getRegistryVectorBegin();
00247   RegistryIterator iterE=getRegistryVectorEnd();
00248 
00249   //Divide result by d
00250   for(;iter!=iterE;++iter){
00251     float value;
00252     //get noise from d
00253     aData.detid=iter->detid;
00254     aData.values.clear();
00255     Range d_range=d.getRange(iter->detid);
00256     Range range=Range(v_noises.begin()+iter->ibegin,v_noises.begin()+iter->iend);
00257 
00258     //if denominator is missing, put the ratio value to 0xFFFF (=inf)
00259     size_t strip=0, stripE= (range.second-range.first)*8/9;
00260     for (;strip<stripE;++strip){       
00261       if(d_range.first==d_range.second){
00262         value=0xFFFF;
00263       }else{
00264         value=getNoise(strip,range)/d.getNoise(strip,d_range);
00265       }
00266       aData.values.push_back(value);
00267     }
00268     result.push_back(aData);
00269   }
00270 
00271   iter=d.getRegistryVectorBegin();
00272   iterE=d.getRegistryVectorEnd();
00273 
00274   //Divide result by d
00275   for(;iter!=iterE;++iter){
00276     float value;
00277     //get noise from d
00278     Range range=this->getRange(iter->detid);
00279     Range d_range=Range(d.v_noises.begin()+iter->ibegin,d.v_noises.begin()+iter->iend);
00280     if(range.first==range.second){
00281       aData.detid=iter->detid;
00282       aData.values.clear();
00283       size_t strip=0, stripE= (d_range.second-d_range.first)*8/9;
00284       for (;strip<stripE;++strip){       
00285         value=0.;
00286         aData.values.push_back(value);
00287       }
00288       result.push_back(aData);
00289     }
00290   }
00291   
00292   return result;
00293 }