Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:30

0001 /****************************************************************************
0002 *
0003 * This is a part of the TOTEM offline software.
0004 * Authors:
0005 *   Nicola Minafra
0006 *
0007 ****************************************************************************/
0008 
0009 #ifndef EventFilter_CTPPSRawToDigi_TotemSampicFrame
0010 #define EventFilter_CTPPSRawToDigi_TotemSampicFrame
0011 
0012 #include <vector>
0013 #include <cstddef>
0014 #include <cstdint>
0015 #include <iomanip>
0016 #include <bitset>
0017 #include <iostream>
0018 
0019 #include "EventFilter/CTPPSRawToDigi/interface/VFATFrame.h"
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 
0022 enum TotemSampicConstant {
0023   hwId_Position = 0,  // hwId_Size = 1,
0024   controlBits0_Position = 1,
0025   controlBits1_Position = 2,
0026   controlBits2_Position = 3,
0027   controlBits3_Position = 4,
0028   controlBits4_Position = 5,
0029   controlBits5_Position = 6,
0030   fpgaTime_Position = 7,     // fpgaTime_Size = 5,
0031   timestampA_Position = 12,  // timestampA_Size = 2,
0032   fpgaTime_Size = timestampA_Position - fpgaTime_Position,
0033   timestampB_Position = 14,  // timestampB_Size = 2,
0034   timestampA_Size = timestampB_Position - timestampA_Position,
0035   cellInfo_Position = 16,  // cellInfo_Size = 2,
0036   timestampB_Size = cellInfo_Position - timestampB_Position,
0037   planeChannelId_Position = 18,  // planeChannelId_Size = 1,
0038   cellInfo_Size = planeChannelId_Position - cellInfo_Position,
0039   reserved_Position = 19,  // reserved_Size = 5,
0040 
0041   boardId_Position = 0,       // boardId_Size = 1,
0042   l1ATimestamp_Position = 1,  // l1ATimestamp_Size = 5,
0043   bunchNumber_Position = 6,   // bunchNumber_Size = 2,
0044   l1ATimestamp_Size = bunchNumber_Position - l1ATimestamp_Position,
0045   orbitNumber_Position = 8,  // orbitNumber_Size = 4,
0046   bunchNumber_Size = orbitNumber_Position - bunchNumber_Position,
0047   eventNumber_Position = 12,  // eventNumber_Size = 4,
0048   orbitNumber_Size = eventNumber_Position - orbitNumber_Position,
0049   channelMap_Position = 16,  // channelMap_Size = 2,
0050   eventNumber_Size = channelMap_Position - eventNumber_Position,
0051   l1ALatency_Position = 18,  // l1ALatency_Size = 2,
0052   channelMap_Size = l1ALatency_Position - channelMap_Position,
0053   numberOfSamples_Position = 20,  // numberOfSamples_Size = 1,
0054   l1ALatency_Size = numberOfSamples_Position - l1ALatency_Position,
0055   offsetOfSamples_Position = 21,  // offsetOfSamples_Size = 1,
0056   fwVersion_Position = 22,        // fwVersion_Size = 1,
0057   pllInfo_Position = 23,          // pllInfo_Size = 1,
0058 
0059   numberOfSamples = 24,
0060   controlBits3 = 0x69,
0061   cellInfo_Mask = 0x3F,
0062 
0063 };
0064 
0065 template <typename T>
0066 T grayToBinary(const T& gcode_data) {
0067   // assign b[0] = g[0]
0068   T binary = gcode_data & (0x0001 << (8 * sizeof(T) - 1));  // MSB is the same
0069 
0070   // assign b[i] = g[i] xor b[i-1]
0071   for (unsigned short int i = 1; i < 8 * sizeof(T); ++i)
0072     binary |= (gcode_data ^ (binary >> 1)) & (0x0001 << (8 * sizeof(T) - i - 1));
0073 
0074   return binary;
0075 }
0076 
0077 /**
0078  * This class is intended to handle the timing infromation of SAMPIC in the TOTEM implementation
0079 **/
0080 class TotemSampicFrame {
0081 public:
0082   TotemSampicFrame(const uint8_t* chInfoPtr, const uint8_t* chDataPtr, const uint8_t* eventInfoPtr)
0083       : totemSampicInfoPtr_(chInfoPtr),
0084         totemSampicDataPtr_(chDataPtr),
0085         totemSampicEventInfoPtr_(eventInfoPtr),
0086         status_(0) {
0087     if (chInfoPtr != nullptr && chDataPtr != nullptr && eventInfoPtr != nullptr &&
0088         totemSampicInfoPtr_[TotemSampicConstant::controlBits3_Position] == TotemSampicConstant::controlBits3)
0089       status_ = 1;
0090   }
0091   ~TotemSampicFrame() {}
0092 
0093   /// Prints the frame.
0094   /// If binary is true, binary format is used.
0095   void printRaw(bool binary = false) const {
0096     edm::LogInfo("TotemSampicFrame") << "Event Info: \n";
0097     printRawBuffer((uint16_t*)totemSampicEventInfoPtr_);
0098 
0099     edm::LogInfo("TotemSampicFrame") << "Channel Info: \n";
0100     printRawBuffer((uint16_t*)totemSampicInfoPtr_);
0101 
0102     edm::LogInfo("TotemSampicFrame") << "Channel Data: \n";
0103     printRawBuffer((uint16_t*)totemSampicDataPtr_);
0104   }
0105 
0106   void print() const {
0107     std::bitset<16> bitsChannelMap(getChannelMap());
0108     std::bitset<16> bitsPLLInfo(getPLLInfo());
0109     edm::LogInfo("TotemSampicFrame") << "\nEvent:"
0110                                      << "\nHardwareId (Event):\t" << std::hex << (unsigned int)getEventHardwareId()
0111                                      << "\nL1A Timestamp:\t" << std::dec << getL1ATimestamp() << "\nL1A Latency:\t"
0112                                      << std::dec << getL1ALatency() << "\nBunch Number:\t" << std::dec
0113                                      << getBunchNumber() << "\nOrbit Number:\t" << std::dec << getOrbitNumber()
0114                                      << "\nEvent Number:\t" << std::dec << getEventNumber() << "\nChannels fired:\t"
0115                                      << std::hex << bitsChannelMap.to_string() << "\nNumber of Samples:\t" << std::dec
0116                                      << getNumberOfSentSamples() << "\nOffset of Samples:\t" << std::dec
0117                                      << (int)getOffsetOfSamples() << "\nFW Version:\t" << std::hex
0118                                      << (int)getFWVersion() << "\nChannel:\nHardwareId:\t" << std::hex
0119                                      << (unsigned int)getHardwareId() << "\nFPGATimestamp:\t" << std::dec
0120                                      << getFPGATimestamp() << "\nTimestampA:\t" << std::dec << getTimestampA()
0121                                      << "\nTimestampB:\t" << std::dec << getTimestampB() << "\nCellInfo:\t" << std::dec
0122                                      << getCellInfo() << "\nPlane:\t" << std::dec << getDetPlane() << "\nChannel:\t"
0123                                      << std::dec << getDetChannel() << "\nPLL Info:\t" << bitsPLLInfo.to_string()
0124                                      << "\n\n";
0125   }
0126 
0127   // All getters
0128   inline uint8_t getHardwareId() const {
0129     uint8_t tmp = 0;
0130     if (status_)
0131       tmp = totemSampicInfoPtr_[TotemSampicConstant::hwId_Position];
0132     return tmp;
0133   }
0134 
0135   template <class T>
0136   T extractDataFromBytesLSB(const uint8_t* array, int start, int size) const {
0137     T result = 0;
0138     for (int i = start + size - 1; i >= start; i--)
0139       result = (result << 8) | array[i];
0140     return result;
0141   }
0142 
0143   inline uint64_t getFPGATimestamp() const {
0144     uint64_t tmp = 0;
0145     if (status_)
0146       tmp =
0147           extractDataFromBytesLSB<uint64_t>(totemSampicInfoPtr_, TotemSampicConstant::fpgaTime_Position, fpgaTime_Size);
0148     return tmp;
0149   }
0150 
0151   inline uint16_t getTimestampA() const {
0152     uint16_t tmp = 0;
0153     if (status_)
0154       tmp = extractDataFromBytesLSB<uint16_t>(
0155           totemSampicInfoPtr_, TotemSampicConstant::timestampA_Position, timestampA_Size);
0156     tmp = 0xFFF - tmp;
0157     return grayToBinary<uint16_t>(tmp);
0158   }
0159 
0160   inline uint16_t getTimestampB() const {
0161     uint16_t tmp = 0;
0162     if (status_)
0163       tmp = extractDataFromBytesLSB<uint16_t>(
0164           totemSampicInfoPtr_, TotemSampicConstant::timestampB_Position, timestampB_Size);
0165     return grayToBinary<uint16_t>(tmp);
0166   }
0167 
0168   inline uint16_t getCellInfo() const {
0169     uint16_t tmp = 0;
0170     if (status_)
0171       tmp =
0172           extractDataFromBytesLSB<uint16_t>(totemSampicInfoPtr_, TotemSampicConstant::cellInfo_Position, cellInfo_Size);
0173     return tmp & TotemSampicConstant::cellInfo_Mask;
0174   }
0175 
0176   inline int getDetPlane() const {
0177     int tmp = 0;
0178     if (status_)
0179       tmp = (totemSampicInfoPtr_[planeChannelId_Position] & 0xF0) >> 4;
0180     return tmp;
0181   }
0182 
0183   inline int getDetChannel() const {
0184     int tmp = 0;
0185     if (status_)
0186       tmp = totemSampicInfoPtr_[planeChannelId_Position] & 0x0F;
0187     return tmp;
0188   }
0189 
0190   const std::vector<uint8_t> getSamples() const {
0191     std::vector<uint8_t> samples;
0192     if (status_) {
0193       samples.assign(totemSampicDataPtr_, totemSampicDataPtr_ + TotemSampicConstant::numberOfSamples);
0194       for (auto it = samples.begin(); it != samples.end(); ++it)
0195         *it = grayToBinary<uint8_t>(*it);
0196     }
0197     return samples;
0198   }
0199 
0200   inline unsigned int getNumberOfSamples() const { return status_ * TotemSampicConstant::numberOfSamples; }
0201 
0202   // Event Info
0203   inline uint8_t getEventHardwareId() const {
0204     uint8_t tmp = 0;
0205     if (status_)
0206       tmp = totemSampicEventInfoPtr_[TotemSampicConstant::boardId_Position];
0207     return tmp;
0208   }
0209 
0210   inline uint64_t getL1ATimestamp() const {
0211     uint64_t tmp = 0;
0212     if (status_)
0213       tmp = extractDataFromBytesLSB<uint64_t>(
0214           totemSampicEventInfoPtr_, TotemSampicConstant::l1ATimestamp_Position, l1ATimestamp_Size);
0215     return tmp;
0216   }
0217 
0218   inline uint16_t getBunchNumber() const {
0219     uint16_t tmp = 0;
0220     if (status_)
0221       tmp = extractDataFromBytesLSB<uint16_t>(
0222           totemSampicEventInfoPtr_, TotemSampicConstant::bunchNumber_Position, bunchNumber_Size);
0223     return tmp;
0224   }
0225 
0226   inline uint32_t getOrbitNumber() const {
0227     uint32_t tmp = 0;
0228     if (status_)
0229       tmp = extractDataFromBytesLSB<uint32_t>(
0230           totemSampicEventInfoPtr_, TotemSampicConstant::orbitNumber_Position, orbitNumber_Size);
0231     return tmp;
0232   }
0233 
0234   inline uint32_t getEventNumber() const {
0235     uint32_t tmp = 0;
0236     if (status_)
0237       tmp = extractDataFromBytesLSB<uint32_t>(
0238           totemSampicEventInfoPtr_, TotemSampicConstant::eventNumber_Position, eventNumber_Size);
0239     return tmp;
0240   }
0241 
0242   inline uint16_t getChannelMap() const {
0243     uint16_t tmp = 0;
0244     if (status_)
0245       tmp = extractDataFromBytesLSB<uint16_t>(
0246           totemSampicEventInfoPtr_, TotemSampicConstant::channelMap_Position, channelMap_Size);
0247     return tmp;
0248   }
0249 
0250   inline uint16_t getL1ALatency() const {
0251     uint16_t tmp = 0;
0252     if (status_)
0253       tmp = extractDataFromBytesLSB<uint16_t>(
0254           totemSampicEventInfoPtr_, TotemSampicConstant::l1ALatency_Position, l1ALatency_Size);
0255     return tmp;
0256   }
0257 
0258   inline uint8_t getNumberOfSentSamples() const {
0259     uint8_t tmp = 0;
0260     if (status_)
0261       tmp = totemSampicEventInfoPtr_[TotemSampicConstant::numberOfSamples_Position];
0262     return tmp;
0263   }
0264 
0265   inline uint8_t getOffsetOfSamples() const {
0266     uint8_t tmp = 0;
0267     if (status_)
0268       tmp = totemSampicEventInfoPtr_[TotemSampicConstant::offsetOfSamples_Position];
0269     return tmp;
0270   }
0271 
0272   inline uint8_t getPLLInfo() const {
0273     uint8_t tmp = 0;
0274     if (status_)
0275       tmp = totemSampicEventInfoPtr_[pllInfo_Position];
0276     return tmp;
0277   }
0278 
0279   inline uint8_t getFWVersion() const {
0280     uint8_t tmp = 0;
0281     if (status_)
0282       tmp = totemSampicEventInfoPtr_[fwVersion_Position];
0283     return tmp;
0284   }
0285 
0286   inline bool valid() const { return status_ != 0; }
0287 
0288 protected:
0289   const uint8_t* totemSampicInfoPtr_;
0290   const uint8_t* totemSampicDataPtr_;
0291   const uint8_t* totemSampicEventInfoPtr_;
0292 
0293   int status_;
0294 
0295   inline void printRawBuffer(const uint16_t* buffer, const bool binary = false, const unsigned int size = 12) const {
0296     for (unsigned int i = 0; i < size; i++) {
0297       if (binary) {
0298         std::bitset<16> bits(*(buffer++));
0299         edm::LogInfo("TotemSampicFrame") << bits.to_string() << "\n";
0300       } else
0301         edm::LogInfo("TotemSampicFrame") << std::setfill('0') << std::setw(4) << std::hex << *(buffer++) << "\n";
0302     }
0303   }
0304 };
0305 
0306 #endif