Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:02:41

0001 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include <algorithm>
0004 
0005 bool SiStripPedestals::put(const uint32_t& DetId, InputVector& input) {
0006   // put in SiStripPedestals of DetId
0007   std::vector<unsigned char> Vo_CHAR;
0008   encode(input, Vo_CHAR);
0009 
0010   Registry::iterator p =
0011       std::lower_bound(indexes.begin(), indexes.end(), DetId, SiStripPedestals::StrictWeakOrdering());
0012   if (p != indexes.end() && p->detid == DetId)
0013     return false;
0014 
0015   //size_t sd= input.second-input.first;
0016   size_t sd = Vo_CHAR.end() - Vo_CHAR.begin();
0017   DetRegistry detregistry;
0018   detregistry.detid = DetId;
0019   detregistry.ibegin = v_pedestals.size();
0020   detregistry.iend = v_pedestals.size() + sd;
0021   indexes.insert(p, detregistry);
0022 
0023   //v_pedestals.insert(v_pedestals.end(),input.first,input.second);
0024   v_pedestals.insert(v_pedestals.end(), Vo_CHAR.begin(), Vo_CHAR.end());
0025   return true;
0026 }
0027 
0028 const SiStripPedestals::Range SiStripPedestals::getRange(const uint32_t& DetId) const {
0029   // get SiStripPedestals Range of DetId
0030 
0031   RegistryIterator p = std::lower_bound(indexes.begin(), indexes.end(), DetId, SiStripPedestals::StrictWeakOrdering());
0032   if (p == indexes.end() || p->detid != DetId)
0033     return SiStripPedestals::Range(v_pedestals.end(), v_pedestals.end());
0034   else
0035     return SiStripPedestals::Range(v_pedestals.begin() + p->ibegin, v_pedestals.begin() + p->iend);
0036 }
0037 
0038 void SiStripPedestals::getDetIds(std::vector<uint32_t>& DetIds_) const {
0039   // returns vector of DetIds in map
0040   SiStripPedestals::RegistryIterator begin = indexes.begin();
0041   SiStripPedestals::RegistryIterator end = indexes.end();
0042   for (SiStripPedestals::RegistryIterator p = begin; p != end; ++p) {
0043     DetIds_.push_back(p->detid);
0044   }
0045 }
0046 
0047 void SiStripPedestals::setData(float ped, SiStripPedestals::InputVector& vped) {
0048   vped.push_back((static_cast<uint16_t>(ped) & 0x3FF));
0049 }
0050 
0051 float SiStripPedestals::getPed(const uint16_t& strip, const Range& range) const {
0052   if (10 * strip >= (range.second - range.first) * 8) {
0053     throw cms::Exception("CorruptedData")
0054         << "[SiStripPedestals::getPed] looking for SiStripPedestals for a strip out of range: strip " << strip;
0055   }
0056   return static_cast<float>(decode(strip, range));
0057 }
0058 
0059 void SiStripPedestals::encode(InputVector& Vi, std::vector<unsigned char>& Vo) {
0060   static const uint16_t BITS_PER_STRIP = 10;
0061   const size_t VoSize = (size_t)((Vi.size() * BITS_PER_STRIP) / 8 + .999);
0062   Vo.resize(VoSize);
0063   for (size_t i = 0; i < Vo.size(); ++i)
0064     Vo[i] &= 0x00u;
0065 
0066   for (unsigned int stripIndex = 0; stripIndex < Vi.size(); ++stripIndex) {
0067     unsigned char* data = &Vo[Vo.size() - 1];
0068     uint32_t lowBit = stripIndex * BITS_PER_STRIP;
0069     uint8_t firstByteBit = (lowBit & 0x6);
0070     uint8_t firstByteNBits = 8 - firstByteBit;
0071     uint8_t firstByteMask = 0xffu << firstByteBit;
0072     uint8_t secondByteNbits = (BITS_PER_STRIP - firstByteNBits);
0073     uint8_t secondByteMask = ~(0xffu << secondByteNbits);
0074 
0075     *(data - lowBit / 8) = (*(data - lowBit / 8) & ~(firstByteMask)) | ((Vi[stripIndex] & 0xffu) << firstByteBit);
0076     *(data - lowBit / 8 - 1) =
0077         (*(data - lowBit / 8 - 1) & ~(secondByteMask)) | ((Vi[stripIndex] >> firstByteNBits) & secondByteMask);
0078 
0079     /*
0080       if(stripIndex   < 25 ){
0081       std::cout       << "***************ENCODE*********************"<<std::endl
0082       << "\tdata-lowBit/8     :"<<print_as_binary((*(data-lowBit/8)   & ~(firstByteMask)))
0083       << "-"<<print_as_binary(((Vi[stripIndex] & 0xffu) <<firstByteBit))
0084       << "\tdata-lowBit/8-1   :"<<print_as_binary((*(data-lowBit/8-1)   & ~(secondByteMask)))
0085       << "-"<<print_as_binary((((Vi[stripIndex]>> firstByteNBits) & secondByteMask)))
0086       << std::endl;
0087       std::cout       << "strip "<<stripIndex<<"\tvi: " << Vi[stripIndex] <<"\t"
0088       << print_short_as_binary(Vi[stripIndex])
0089       << "\tvo1:"<< print_char_as_binary(*(data-lowBit/8))
0090       << "\tvo2:"<< print_char_as_binary(*(data-lowBit/8-1))
0091       << "\tlowBit:"<< lowBit
0092       << "\tfirstByteMask :"<<print_as_binary(firstByteMask)
0093       << "\tsecondByteMask:"<<print_as_binary(secondByteMask)
0094       << "\tfirstByteBit:"<<print_as_binary(firstByteBit)
0095       << std::endl;
0096       }
0097     */
0098   }
0099 }
0100 
0101 uint16_t SiStripPedestals::decode(const uint16_t& strip, const Range& range) const {
0102   const char* data = &*(range.second - 1);  // pointer to the last byte of data
0103   static const uint16_t BITS_PER_STRIP = 10;
0104 
0105   uint32_t lowBit = strip * BITS_PER_STRIP;
0106   uint8_t firstByteBit = (lowBit & 6);  //module
0107   uint8_t firstByteNBits = 8 - firstByteBit;
0108   uint8_t firstByteMask = 0xffu << firstByteBit;
0109   uint8_t secondByteMask = ~(0xffu << (BITS_PER_STRIP - firstByteNBits));
0110   uint16_t value = ((uint16_t(*(data - lowBit / 8)) & firstByteMask) >> firstByteBit) |
0111                    ((uint16_t(*(data - lowBit / 8 - 1)) & secondByteMask) << firstByteNBits);
0112 
0113   /*
0114     if(strip  < 25){
0115     std::cout       << "***************DECODE*********************"<<"\n"
0116     << "strip "<<strip << " " 
0117     << value 
0118     <<"\t   :"<<print_as_binary(value) 
0119     <<"\t  :"<<print_as_binary(    ((uint16_t(*(data-lowBit/8  )) & firstByteMask) >>   firstByteBit)       )
0120     << "-"<<print_as_binary(  ((uint16_t(*(data-lowBit/8-1)) & secondByteMask) <<firstByteNBits)    )
0121     << "\t *(data-lowBit/8) " << print_as_binary(    *(data-lowBit/8 ))
0122     << "\t *(data-lowBit/8-1) " << print_as_binary(    *(data-lowBit/8 -1 ))
0123     << "\tlowBit:"<< lowBit
0124     << "\tfirstByteMask :"<<print_as_binary(firstByteMask)
0125     << "\tsecondByteMask:"<<print_as_binary(secondByteMask)
0126     << "\tfirstByteBit:"<<print_as_binary(firstByteBit)
0127     << std::endl;
0128     }
0129   */
0130   return value;
0131 }
0132 
0133 /// Get 9 bit words from a bit stream, starting from the right, skipping the first 'skip' bits (0 < skip < 7).
0134 /// Ptr must point to the rightmost byte that has some bits of this word, and is updated by this function
0135 inline uint16_t SiStripPedestals::get10bits(const uint8_t*& ptr, int8_t skip) const {
0136   uint8_t maskThis = (0xFF << skip);
0137   uint8_t maskThat = ((4 << skip) - 1);
0138   uint16_t ret = (((*ptr) & maskThis) >> skip);
0139   --ptr;
0140   return ret | (((*ptr) & maskThat) << (8 - skip));
0141 }
0142 
0143 void SiStripPedestals::allPeds(std::vector<int>& peds, const Range& range) const {
0144   size_t mysize = ((range.second - range.first) << 3) / 10;
0145   size_t size = peds.size();
0146   if (mysize < size)
0147     throw cms::Exception("CorruptedData") << "[SiStripPedestals::allPeds] Requested pedestals for " << peds.size()
0148                                           << " strips, I have it only for " << mysize << " strips\n";
0149   size_t size4 = size & (~0x3), carry = size & 0x3;  // we have an optimized way of unpacking 4 strips
0150   const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&*range.second) - 1;
0151   std::vector<int>::iterator out = peds.begin(), end4 = peds.begin() + size4;
0152   // we do it this baroque way instead of just loopin on all the strips because it's faster
0153   // as the value of 'skip' is a constant, so the compiler can compute the masks directly
0154   while (out < end4) {
0155     *out = static_cast<int>(get10bits(ptr, 0));
0156     ++out;
0157     *out = static_cast<int>(get10bits(ptr, 2));
0158     ++out;
0159     *out = static_cast<int>(get10bits(ptr, 4));
0160     ++out;
0161     *out = static_cast<int>(get10bits(ptr, 6));
0162     ++out;
0163     --ptr;  // every 4 strips we have to skip one more bit
0164   }
0165   for (size_t rem = 0; rem < carry; ++rem) {
0166     *out = static_cast<int>(get10bits(ptr, 2 * rem));
0167     ++out;
0168   }
0169 }
0170 
0171 void SiStripPedestals::printSummary(std::stringstream& ss, const TrackerTopology* trackerTopo) const {
0172   std::vector<uint32_t> detid;
0173   getDetIds(detid);
0174   SiStripDetSummary summary{trackerTopo};
0175   for (size_t id = 0; id < detid.size(); ++id) {
0176     SiStripPedestals::Range range = getRange(detid[id]);
0177     for (int it = 0; it < (range.second - range.first) * 8 / 10; ++it) {
0178       summary.add(detid[id], getPed(it, range));
0179     }
0180   }
0181   ss << "Summary of pedestals:" << std::endl;
0182   summary.print(ss);
0183 }
0184 
0185 void SiStripPedestals::printDebug(std::stringstream& ss, const TrackerTopology* /*trackerTopo*/) const {
0186   std::vector<uint32_t> detid;
0187   getDetIds(detid);
0188 
0189   ss << "Number of detids = " << detid.size() << std::endl;
0190 
0191   for (size_t id = 0; id < detid.size(); ++id) {
0192     SiStripPedestals::Range range = getRange(detid[id]);
0193 
0194     int strip = 0;
0195     ss << "detid" << std::setw(15) << "strip" << std::setw(10) << "pedestal" << std::endl;
0196     int detId = 0;
0197     int oldDetId = 0;
0198     for (int it = 0; it < (range.second - range.first) * 8 / 10; ++it) {
0199       detId = detid[id];
0200       if (detId != oldDetId) {
0201         oldDetId = detId;
0202         ss << detid[id];
0203       } else
0204         ss << "   ";
0205       ss << std::setw(15) << strip++ << std::setw(10) << getPed(it, range) << std::endl;
0206     }
0207   }
0208 }
0209 
0210 /**
0211   const std::string SiStripNoises::print_as_binary(const uint8_t ch) const
0212   {
0213   std::string     str;
0214   int i = CHAR_BIT;
0215   while (i > 0)
0216   {
0217   -- i;
0218   str.push_back((ch&(1 << i) ? '1' : '0'));
0219   }
0220   return str;
0221   }
0222 
0223   std::string SiStripNoises::print_char_as_binary(const unsigned char ch) const
0224   {
0225   std::string     str;
0226   int i = CHAR_BIT;
0227   while (i > 0)
0228   {
0229   -- i;
0230   str.push_back((ch&(1 << i) ? '1' : '0'));
0231   }
0232   return str;
0233   }
0234 
0235   std::string SiStripNoises::print_short_as_binary(const short ch) const
0236   {
0237   std::string     str;
0238   int i = CHAR_BIT*2;
0239   while (i > 0)
0240   {
0241   -- i;
0242   str.push_back((ch&(1 << i) ? '1' : '0'));
0243   }
0244   return str;
0245   }
0246 **/