CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DQM/SiStripMonitorHardware/src/SiStripFEDSpyBuffer.cc

Go to the documentation of this file.
00001 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 
00004 namespace sistrip {
00005   
00006   const uint8_t FEDSpyBuffer::channelPositionsInData_[FEDCH_PER_DELAY_CHIP] = { 0, 3, 2, 1 };
00007   
00008   FEDSpyBuffer::FEDSpyBuffer(const uint8_t* fedBuffer, const size_t fedBufferSize)
00009     : FEDBufferBase(fedBuffer,fedBufferSize,false),
00010       payloadPointer_(getPointerToDataAfterTrackerSpecialHeader()+16),
00011       payloadLength_(getPointerToByteAfterEndOfPayload()-payloadPointer_),
00012       versionId_(*(getPointerToDataAfterTrackerSpecialHeader()+3))
00013   {
00014     //Check it is spy data
00015     if (!(readoutMode() == READOUT_MODE_SPY))
00016       throw cms::Exception("FEDSpyBuffer") << "Buffer is not from spy channel";
00017     //Check the buffer format version ID and take action for any exceptions
00018     if (versionId_ == 0x00) {
00019       payloadPointer_ = payloadPointer_-8;
00020     }
00021     //find the channel start positions
00022     findChannels();
00023   }
00024 
00025   FEDSpyBuffer::~FEDSpyBuffer()
00026   {
00027   }
00028 
00029   void FEDSpyBuffer::findChannels()
00030   {
00031     size_t delayChipStartByteIndex = 0;
00032     //Loop over delay chips checking their data fits into buffer and setting up channel objects with correct offset
00033     for (uint8_t iDelayChip = 0; iDelayChip < DELAY_CHIPS_PER_FED; ++iDelayChip) {
00034       if (delayChipStartByteIndex+SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES > payloadLength_) {
00035         throw cms::Exception("FEDSpyBuffer") << "Delay chip " << uint16_t(iDelayChip) << " does not fit into buffer. "
00036                                              << "Buffer size is " << bufferSize() << " delay chip data starts at " << delayChipStartByteIndex+8+8+8+8 << ". ";
00037       }
00038       for (uint8_t i = 0; i < FEDCH_PER_DELAY_CHIP; i++) {
00039         const uint8_t chanelIndexInDataOrder = channelPositionsInData_[i];
00040         const uint8_t fedCh = iDelayChip*FEDCH_PER_DELAY_CHIP + i;
00041         const size_t channelOffsetInBits = SPY_DELAYCHIP_DATA_OFFSET_IN_BITS + 10*chanelIndexInDataOrder;
00042         channels_[fedCh] = FEDChannel(payloadPointer_+delayChipStartByteIndex,channelOffsetInBits,SPY_SAMPLES_PER_CHANNEL);
00043       }
00044       delayChipStartByteIndex += SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES;
00045     }
00046   }
00047 
00048   uint32_t FEDSpyBuffer::globalRunNumber() const
00049   {
00050     if (versionId_ < 0x02) {
00051       return 0;
00052     }
00053     const uint8_t * runNumberPointer = getPointerToDataAfterTrackerSpecialHeader()+4;
00054     uint32_t result = 0;
00055     result |= runNumberPointer[0];
00056     result |= (uint32_t(runNumberPointer[1]) << 8);
00057     result |= (uint32_t(runNumberPointer[2]) << 16);
00058     result |= (uint32_t(runNumberPointer[3]) << 24);
00059     return result;
00060   }
00061 
00062   uint32_t FEDSpyBuffer::spyHeaderL1ID() const
00063   {
00064     if (versionId_ == 0x00) {
00065       return delayChipL1ID(0);
00066     }
00067     uint32_t result = 0;
00068     const uint8_t* spyCounters = payloadPointer_-8;
00069     result |= spyCounters[4];
00070     result |= (uint32_t(spyCounters[5]) << 8);
00071     result |= (uint32_t(spyCounters[6]) << 16);
00072     result |= (uint32_t(spyCounters[7]) << 24);
00073     return result;
00074   }
00075 
00076   uint32_t FEDSpyBuffer::spyHeaderTotalEventCount() const
00077   {
00078     if (versionId_ == 0x00) {
00079       return delayChipTotalEventCount(0);
00080     }
00081     uint32_t result = 0;
00082     const uint8_t* spyCounters = payloadPointer_-8;
00083     result |= spyCounters[0];
00084     result |= (uint32_t(spyCounters[1]) << 8);
00085     result |= (uint32_t(spyCounters[2]) << 16);
00086     result |= (uint32_t(spyCounters[3]) << 24);
00087     return result;
00088   }
00089 
00090   uint32_t FEDSpyBuffer::delayChipL1ID(const uint8_t delayChip) const
00091   {
00092     const uint8_t* delayChipCounters = payloadPointer_ + ( (SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES) * (delayChip+1) - 8);
00093     uint32_t result = 0;
00094     result |= delayChipCounters[4];
00095     result |= (uint32_t(delayChipCounters[5]) << 8);
00096     result |= (uint32_t(delayChipCounters[6]) << 16);
00097     result |= (uint32_t(delayChipCounters[7]) << 24);
00098     return result;
00099   }
00100 
00101   uint32_t FEDSpyBuffer::delayChipTotalEventCount(const uint8_t delayChip) const
00102   {
00103     const uint8_t* delayChipCounters = payloadPointer_ + ( (SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES) * (delayChip+1) - 8);
00104     uint32_t result = 0;
00105     result |= delayChipCounters[0];
00106     result |= (uint32_t(delayChipCounters[1]) << 8);
00107     result |= (uint32_t(delayChipCounters[2]) << 16);
00108     result |= (uint32_t(delayChipCounters[3]) << 24);
00109     return result;
00110   }
00111 
00112   void FEDSpyBuffer::print(std::ostream& os) const
00113   {
00114     FEDBufferBase::print(os);
00115     //TODO
00116   }
00117 
00118   bool FEDSpyBuffer::delayChipGood(const uint8_t delayChip) const
00119   {
00120     if (versionId_ == 0x00) {
00121       if (delayChip == 0) return true;
00122     }
00123     uint32_t l1CountBefore = 0;
00124     uint32_t totalEventCountBefore = 0;
00125     if (delayChip == 0) {
00126       l1CountBefore = spyHeaderL1ID();
00127       totalEventCountBefore = spyHeaderTotalEventCount();
00128     } else {
00129       l1CountBefore = delayChipL1ID(delayChip-1);
00130       totalEventCountBefore = delayChipTotalEventCount(delayChip-1);
00131     }
00132     const uint32_t l1CountAfter = delayChipL1ID(delayChip);
00133     const uint32_t totalEventCountAfter = delayChipTotalEventCount(delayChip);
00134     const bool eventMatches = ( (l1CountBefore == l1CountAfter) && (totalEventCountBefore == totalEventCountAfter) );
00135     if (!eventMatches) {
00136       std::ostringstream ss;
00137       ss << "Delay chip data was overwritten on chip " << uint16_t(delayChip)
00138          << " L1A before: " << l1CountBefore << " after: " << l1CountAfter
00139          << " Total event count before: " << totalEventCountBefore << " after: " << totalEventCountAfter << std::endl;
00140       dump(ss);
00141       edm::LogInfo("FEDSpyBuffer") << ss.str();
00142     }
00143     return eventMatches;
00144   }
00145 
00146   bool FEDSpyBuffer::channelGood(const uint8_t internalFEDChannelNum) const
00147   {
00148     return delayChipGood(internalFEDChannelNum/FEDCH_PER_DELAY_CHIP);
00149   }
00150 
00151 
00152 
00153 
00154   uint16_t FEDSpyChannelUnpacker::adc() const
00155   {
00156     const size_t offsetWords = currentOffset_/32;
00157     const uint8_t offsetBits = currentOffset_%32;
00158     if (offsetBits < 23) {
00159       return ( (data_[offsetWords]>>(32-10-offsetBits)) & 0x3FF );
00160     } else {
00161       return ( ((data_[offsetWords]<<(10-32+offsetBits))&0x3FF) | ((data_[offsetWords+1]&(0xFFC00000<<(32-offsetBits)))>>(64-10-offsetBits)) );
00162     }
00163   }
00164 
00165 }