00001 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003
00004 bool SiStripPedestals::put(const uint32_t& DetId, InputVector& input) {
00005
00006 std::vector<unsigned char> Vo_CHAR;
00007 encode(input, Vo_CHAR);
00008
00009 Registry::iterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiStripPedestals::StrictWeakOrdering());
00010 if (p!=indexes.end() && p->detid==DetId)
00011 return false;
00012
00013
00014 size_t sd= Vo_CHAR.end() - Vo_CHAR.begin();
00015 DetRegistry detregistry;
00016 detregistry.detid=DetId;
00017 detregistry.ibegin=v_pedestals.size();
00018 detregistry.iend=v_pedestals.size()+sd;
00019 indexes.insert(p,detregistry);
00020
00021
00022 v_pedestals.insert(v_pedestals.end(),Vo_CHAR.begin(),Vo_CHAR.end());
00023 return true;
00024 }
00025
00026 const SiStripPedestals::Range SiStripPedestals::getRange(const uint32_t& DetId) const {
00027
00028
00029 RegistryIterator p = std::lower_bound(indexes.begin(),indexes.end(),DetId,SiStripPedestals::StrictWeakOrdering());
00030 if (p==indexes.end()|| p->detid!=DetId)
00031 return SiStripPedestals::Range(v_pedestals.end(),v_pedestals.end());
00032 else
00033 return SiStripPedestals::Range(v_pedestals.begin()+p->ibegin,v_pedestals.begin()+p->iend);
00034 }
00035
00036 void SiStripPedestals::getDetIds(std::vector<uint32_t>& DetIds_) const {
00037
00038 SiStripPedestals::RegistryIterator begin = indexes.begin();
00039 SiStripPedestals::RegistryIterator end = indexes.end();
00040 for (SiStripPedestals::RegistryIterator p=begin; p != end; ++p) {
00041 DetIds_.push_back(p->detid);
00042 }
00043 }
00044
00045
00046 void SiStripPedestals::setData(float ped, SiStripPedestals::InputVector& vped){
00047 vped.push_back((static_cast<uint16_t> (ped) & 0x3FF)) ;
00048 }
00049
00050 float SiStripPedestals::getPed(const uint16_t& strip, const Range& range) const {
00051 if (10*strip>=(range.second-range.first)*8){
00052 throw cms::Exception("CorruptedData")
00053 << "[SiStripPedestals::getPed] looking for SiStripPedestals for a strip out of range: strip " << strip;
00054 }
00055 return static_cast<float> (decode(strip,range));
00056 }
00057
00058 void SiStripPedestals::encode(InputVector& Vi, std::vector<unsigned char>& Vo){
00059 static const uint16_t BITS_PER_STRIP = 10;
00060 const size_t VoSize = (size_t)((Vi.size() * BITS_PER_STRIP)/8+.999);
00061 Vo.resize(VoSize);
00062 for(size_t i = 0; i<Vo.size(); ++i)
00063 Vo[i] &= 0x00u;
00064
00065 for(unsigned int stripIndex =0; stripIndex<Vi.size(); ++stripIndex){
00066 unsigned char* data = &Vo[Vo.size()-1];
00067 uint32_t lowBit = stripIndex * BITS_PER_STRIP;
00068 uint8_t firstByteBit = (lowBit & 0x6);
00069 uint8_t firstByteNBits = 8 - firstByteBit;
00070 uint8_t firstByteMask = 0xffu << firstByteBit;
00071 uint8_t secondByteNbits = (BITS_PER_STRIP - firstByteNBits);
00072 uint8_t secondByteMask = ~(0xffu << secondByteNbits);
00073
00074 *(data-lowBit/8) = (*(data-lowBit/8) & ~(firstByteMask)) | ((Vi[stripIndex] & 0xffu) <<firstByteBit);
00075 *(data-lowBit/8-1) = (*(data-lowBit/8-1) & ~(secondByteMask)) | ((Vi[stripIndex] >> firstByteNBits) & secondByteMask);
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 }
00097 }
00098
00099 uint16_t SiStripPedestals::decode (const uint16_t& strip, const Range& range) const{
00100 const char *data = &*(range.second -1);
00101 static const uint16_t BITS_PER_STRIP = 10;
00102
00103 uint32_t lowBit = strip * BITS_PER_STRIP;
00104 uint8_t firstByteBit = (lowBit & 6);
00105 uint8_t firstByteNBits = 8 - firstByteBit;
00106 uint8_t firstByteMask = 0xffu << firstByteBit;
00107 uint8_t secondByteMask = ~(0xffu << (BITS_PER_STRIP - firstByteNBits));
00108 uint16_t value = ((uint16_t(*(data-lowBit/8 )) & firstByteMask) >> firstByteBit) | ((uint16_t(*(data-lowBit/8-1)) & secondByteMask) << firstByteNBits);
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 return value;
00128 }
00129
00132 inline uint16_t SiStripPedestals::get10bits(const uint8_t * &ptr, int8_t skip) const {
00133 uint8_t maskThis = (0xFF << skip);
00134 uint8_t maskThat = ((4 << skip) - 1);
00135 uint16_t ret = ( ((*ptr) & maskThis) >> skip );
00136 --ptr;
00137 return ret | ( ((*ptr) & maskThat) << (8 - skip) );
00138 }
00139
00140 void
00141 SiStripPedestals::allPeds (std::vector<int> & peds, const Range& range) const {
00142 size_t mysize = ((range.second-range.first) << 3) / 10;
00143 size_t size = peds.size();
00144 if (mysize < size) throw cms::Exception("CorruptedData")
00145 << "[SiStripPedestals::allPeds] Requested pedestals for " << peds.size() << " strips, I have it only for " << mysize << " strips\n";
00146 size_t size4 = size & (~0x3), carry = size & 0x3;
00147 const uint8_t *ptr = reinterpret_cast<const uint8_t *>(&*range.second) - 1;
00148 std::vector<int>::iterator out = peds.begin(), end4 = peds.begin() + size4;
00149
00150
00151 while (out < end4) {
00152 *out = static_cast<int> ( get10bits(ptr, 0) ); ++out;
00153 *out = static_cast<int> ( get10bits(ptr, 2) ); ++out;
00154 *out = static_cast<int> ( get10bits(ptr, 4) ); ++out;
00155 *out = static_cast<int> ( get10bits(ptr, 6) ); ++out;
00156 --ptr;
00157 }
00158 for (size_t rem = 0; rem < carry; ++rem ) {
00159 *out = static_cast<int> ( get10bits(ptr, 2*rem) ); ++out;
00160 }
00161 }
00162
00163
00164