Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:03

0001 #include <iomanip>
0002 #include <ostream>
0003 #include <sstream>
0004 #include <cstring>
0005 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
0006 #include "FWCore/Utilities/interface/CRC16.h"
0007 
0008 namespace sistrip {
0009 
0010   void printHexValue(const uint8_t value, std::ostream& os) {
0011     const std::ios_base::fmtflags originalFormatFlags = os.flags();
0012     os << std::hex << std::setfill('0') << std::setw(2);
0013     os << uint16_t(value);
0014     os.flags(originalFormatFlags);
0015   }
0016 
0017   void printHexWord(const uint8_t* pointer, const size_t lengthInBytes, std::ostream& os) {
0018     size_t i = lengthInBytes - 1;
0019     do {
0020       printHexValue(pointer[i], os);
0021       if (i != 0)
0022         os << " ";
0023     } while (i-- != 0);
0024   }
0025 
0026   void printHex(const void* pointer, const size_t lengthInBytes, std::ostream& os) {
0027     const uint8_t* bytePointer = reinterpret_cast<const uint8_t*>(pointer);
0028     //if there is one 64 bit word or less, print it out
0029     if (lengthInBytes <= 8) {
0030       printHexWord(bytePointer, lengthInBytes, os);
0031     }
0032     //otherwise, print word numbers etc
0033     else {
0034       //header
0035       os << "word\tbyte\t                       \t\tbyte" << std::endl;
0036       ;
0037       const size_t words = lengthInBytes / 8;
0038       const size_t extraBytes = lengthInBytes - 8 * words;
0039       //print full words
0040       for (size_t w = 0; w < words; w++) {
0041         const size_t startByte = w * 8;
0042         os << w << '\t' << startByte + 8 << '\t';
0043         printHexWord(bytePointer + startByte, 8, os);
0044         os << "\t\t" << startByte << std::endl;
0045       }
0046       //print part word, if any
0047       if (extraBytes) {
0048         const size_t startByte = words * 8;
0049         os << words << '\t' << startByte + 8 << '\t';
0050         //padding
0051         size_t p = 8;
0052         while (p-- > extraBytes) {
0053           os << "00 ";
0054         }
0055         printHexWord(bytePointer + startByte, extraBytes, os);
0056         os << "\t\t" << startByte << std::endl;
0057       }
0058       os << std::endl;
0059     }
0060   }
0061 
0062   uint16_t calculateFEDBufferCRC(const uint8_t* buffer, const size_t lengthInBytes) {
0063     uint16_t crc = 0xFFFF;
0064     for (size_t i = 0; i < lengthInBytes - 8; i++) {
0065       crc = evf::compute_crc_8bit(crc, buffer[i ^ 7]);
0066     }
0067     for (size_t i = lengthInBytes - 8; i < lengthInBytes; i++) {
0068       uint8_t byte;
0069       //set CRC bytes to zero since these were not set when CRC was calculated
0070       if (i == lengthInBytes - 4 || i == lengthInBytes - 3)
0071         byte = 0x00;
0072       else
0073         byte = buffer[i ^ 7];
0074       crc = evf::compute_crc_8bit(crc, byte);
0075     }
0076     return crc;
0077   }
0078 
0079   std::ostream& operator<<(std::ostream& os, const FEDBufferFormat& value) {
0080     switch (value) {
0081       case BUFFER_FORMAT_OLD_VME:
0082         os << "Old VME";
0083         break;
0084       case BUFFER_FORMAT_OLD_SLINK:
0085         os << "Old S-Link";
0086         break;
0087       case BUFFER_FORMAT_NEW:
0088         os << "New";
0089         break;
0090       case BUFFER_FORMAT_INVALID:
0091         os << "Invalid";
0092         break;
0093       default:
0094         os << "Unrecognized";
0095         os << " (";
0096         printHexValue(value, os);
0097         os << ")";
0098         break;
0099     }
0100     return os;
0101   }
0102 
0103   std::ostream& operator<<(std::ostream& os, const FEDHeaderType& value) {
0104     switch (value) {
0105       case HEADER_TYPE_FULL_DEBUG:
0106         os << "Full debug";
0107         break;
0108       case HEADER_TYPE_APV_ERROR:
0109         os << "APV error";
0110         break;
0111       case HEADER_TYPE_NONE:
0112         os << "None";
0113         break;
0114       case HEADER_TYPE_INVALID:
0115         os << "Invalid";
0116         break;
0117       default:
0118         os << "Unrecognized";
0119         os << " (";
0120         printHexValue(value, os);
0121         os << ")";
0122         break;
0123     }
0124     return os;
0125   }
0126 
0127   std::ostream& operator<<(std::ostream& os, const FEDLegacyReadoutMode& value) {
0128     switch (value) {
0129       case READOUT_MODE_LEGACY_SCOPE:
0130         os << "(L) Scope mode";
0131         break;
0132       case READOUT_MODE_LEGACY_VIRGIN_RAW_REAL:
0133         os << "(L) Virgin raw (real)";
0134         break;
0135       case READOUT_MODE_LEGACY_VIRGIN_RAW_FAKE:
0136         os << "(L) Virgin raw (fake)";
0137         break;
0138       case READOUT_MODE_LEGACY_PROC_RAW_REAL:
0139         os << "(L) Processed raw (real)";
0140         break;
0141       case READOUT_MODE_LEGACY_PROC_RAW_FAKE:
0142         os << "(L) Processed raw (fake)";
0143         break;
0144       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_REAL:
0145         os << "(L) Zero suppressed (real)";
0146         break;
0147       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_FAKE:
0148         os << "(L) Zero suppressed (fake)";
0149         break;
0150       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_LITE_REAL:
0151         os << "(L) Zero suppressed lite (real)";
0152         break;
0153       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_LITE_FAKE:
0154         os << "(L) Zero suppressed lite (fake)";
0155         break;
0156       case READOUT_MODE_LEGACY_SPY:
0157         os << "(L) Spy channel";
0158         break;
0159       case READOUT_MODE_LEGACY_PREMIX_RAW:
0160         os << "(L) PreMix raw";
0161         break;
0162       case READOUT_MODE_LEGACY_INVALID:
0163         os << "(L) Invalid";
0164         break;
0165       default:
0166         os << "(L) Unrecognized";
0167         os << " (";
0168         printHexValue(value, os);
0169         os << ")";
0170         break;
0171     }
0172     return os;
0173   }
0174 
0175   std::ostream& operator<<(std::ostream& os, const FEDReadoutMode& value) {
0176     switch (value) {
0177       case READOUT_MODE_SCOPE:
0178         os << "Scope mode";
0179         break;
0180       case READOUT_MODE_VIRGIN_RAW:
0181         os << "Virgin raw";
0182         break;
0183       case READOUT_MODE_PROC_RAW:
0184         os << "Processed raw";
0185         break;
0186       case READOUT_MODE_ZERO_SUPPRESSED:
0187         os << "Zero suppressed";
0188         break;
0189       case READOUT_MODE_ZERO_SUPPRESSED_FAKE:
0190         os << "Zero suppressed (fake)";
0191         break;
0192       case READOUT_MODE_ZERO_SUPPRESSED_LITE10:
0193         os << "Zero suppressed lite";
0194         break;
0195       case READOUT_MODE_SPY:
0196         os << "Spy channel";
0197         break;
0198       /*case READOUT_MODE_ZERO_SUPPRESSED_CMOVERRIDE:
0199       os << "Zero suppressed CM Override";
0200       break;*/
0201       case READOUT_MODE_ZERO_SUPPRESSED_LITE10_CMOVERRIDE:
0202         os << "Zero suppressed lite CM Override";
0203         break;
0204       case READOUT_MODE_ZERO_SUPPRESSED_LITE8:
0205         os << "Zero suppressed lite (8 bit, top-stripped)";
0206         break;
0207       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_CMOVERRIDE:
0208         os << "Zero suppressed lite CM Override (8 bit, top-stripped)";
0209         break;
0210       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT:
0211         os << "Zero suppressed lite (8 bit, bottom-stripped)";
0212         break;
0213       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT_CMOVERRIDE:
0214         os << "Zero suppressed lite CM Override (8 bit, bottom-stripped)";
0215         break;
0216       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT:
0217         os << "Zero suppressed lite (8 bit, top/bottom-stripped)";
0218         break;
0219       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT_CMOVERRIDE:
0220         os << "Zero suppressed lite CM Override (8 bit, top/bottom-stripped)";
0221         break;
0222       case READOUT_MODE_PREMIX_RAW:
0223         os << "PreMix raw";
0224         break;
0225       case READOUT_MODE_INVALID:
0226         os << "Invalid";
0227         break;
0228       default:
0229         os << "Unrecognized";
0230         os << " (";
0231         printHexValue(value, os);
0232         os << ")";
0233         break;
0234     }
0235     return os;
0236   }
0237 
0238   std::ostream& operator<<(std::ostream& os, const FEDDAQEventType& value) {
0239     switch (value) {
0240       case DAQ_EVENT_TYPE_PHYSICS:
0241         os << "Physics trigger";
0242         break;
0243       case DAQ_EVENT_TYPE_CALIBRATION:
0244         os << "Calibration trigger";
0245         break;
0246       case DAQ_EVENT_TYPE_TEST:
0247         os << "Test trigger";
0248         break;
0249       case DAQ_EVENT_TYPE_TECHNICAL:
0250         os << "Technical trigger";
0251         break;
0252       case DAQ_EVENT_TYPE_SIMULATED:
0253         os << "Simulated event";
0254         break;
0255       case DAQ_EVENT_TYPE_TRACED:
0256         os << "Traced event";
0257         break;
0258       case DAQ_EVENT_TYPE_ERROR:
0259         os << "Error";
0260         break;
0261       case DAQ_EVENT_TYPE_INVALID:
0262         os << "Unknown";
0263         break;
0264       default:
0265         os << "Unrecognized";
0266         os << " (";
0267         printHexValue(value, os);
0268         os << ")";
0269         break;
0270     }
0271     return os;
0272   }
0273 
0274   std::ostream& operator<<(std::ostream& os, const FEDTTSBits& value) {
0275     switch (value) {
0276       case TTS_DISCONNECTED0:
0277         os << "Disconected 0";
0278         break;
0279       case TTS_WARN_OVERFLOW:
0280         os << "Warning overflow";
0281         break;
0282       case TTS_OUT_OF_SYNC:
0283         os << "Out of sync";
0284         break;
0285       case TTS_BUSY:
0286         os << "Busy";
0287         break;
0288       case TTS_READY:
0289         os << "Ready";
0290         break;
0291       case TTS_ERROR:
0292         os << "Error";
0293         break;
0294       case TTS_INVALID:
0295         os << "Invalid";
0296         break;
0297       case TTS_DISCONNECTED1:
0298         os << "Disconected 1";
0299         break;
0300       default:
0301         os << "Unrecognized";
0302         os << " (";
0303         printHexValue(value, os);
0304         os << ")";
0305         break;
0306     }
0307     return os;
0308   }
0309 
0310   std::ostream& operator<<(std::ostream& os, const FEDBufferState& value) {
0311     switch (value) {
0312       case BUFFER_STATE_UNSET:
0313         os << "Unset";
0314         break;
0315       case BUFFER_STATE_EMPTY:
0316         os << "Empty";
0317         break;
0318       case BUFFER_STATE_PARTIAL_FULL:
0319         os << "Partial Full";
0320         break;
0321       case BUFFER_STATE_FULL:
0322         os << "Full";
0323         break;
0324       default:
0325         os << "Unrecognized";
0326         os << " (";
0327         printHexValue(value, os);
0328         os << ")";
0329         break;
0330     }
0331     return os;
0332   }
0333 
0334   std::ostream& operator<<(std::ostream& os, const FEDChannelStatus& value) {
0335     if (!(value & CHANNEL_STATUS_LOCKED))
0336       os << "Unlocked ";
0337     if (!(value & CHANNEL_STATUS_IN_SYNC))
0338       os << "Out-of-sync ";
0339     if (!(value & CHANNEL_STATUS_APV1_ADDRESS_GOOD))
0340       os << "APV 1 bad address ";
0341     if (!(value & CHANNEL_STATUS_APV1_NO_ERROR_BIT))
0342       os << "APV 1 error ";
0343     if (!(value & CHANNEL_STATUS_APV0_ADDRESS_GOOD))
0344       os << "APV 0 bad address ";
0345     if (!(value & CHANNEL_STATUS_APV0_NO_ERROR_BIT))
0346       os << "APV 0 error ";
0347     if (value == CHANNEL_STATUS_NO_PROBLEMS)
0348       os << "No errors";
0349     return os;
0350   }
0351 
0352   std::ostream& operator<<(std::ostream& os, const FEDBufferStatusCode& value) {
0353     switch (value) {
0354       case FEDBufferStatusCode::SUCCESS:
0355         os << "SUCCESS";
0356         break;
0357       case FEDBufferStatusCode::BUFFER_NULL:
0358         os << "Buffer pointer is NULL.";
0359         break;
0360       case FEDBufferStatusCode::BUFFER_TOO_SHORT:
0361         os << "Buffer is too small. Min size is 24.";
0362         break;
0363       case FEDBufferStatusCode::UNRECOGNIZED_FORMAT:
0364         os << "Buffer format not recognized. ";
0365         break;
0366       case FEDBufferStatusCode::EXPECT_NOT_SPY:
0367         os << "Unpacking of spy channel data with FEDBuffer is not supported";
0368         break;
0369       case FEDBufferStatusCode::EXPECT_SPY:
0370         os << "Buffer is not from spy channel";
0371         break;
0372       case FEDBufferStatusCode::WRONG_HEADERTYPE:
0373         os << "No or invalid header type";
0374         break;
0375       case FEDBufferStatusCode::CHANNEL_BEGIN_BEYOND_PAYLOAD:
0376       case FEDBufferStatusCode::CHANNEL_END_BEYOND_PAYLOAD:
0377         os << "Channel does not fit into buffer";
0378         break;
0379       case FEDBufferStatusCode::CHANNEL_TOO_SHORT:
0380         os << "Channel is too short";
0381         break;
0382     }
0383     return os;
0384   }
0385 
0386   FEDBufferFormat fedBufferFormatFromString(const std::string& bufferFormatString) {
0387     if ((bufferFormatString == "OLD_VME") || (bufferFormatString == "BUFFER_FORMAT_OLD_VME") ||
0388         (bufferFormatString == "Old VME")) {
0389       return BUFFER_FORMAT_OLD_VME;
0390     }
0391     if ((bufferFormatString == "OLD_SLINK") || (bufferFormatString == "BUFFER_FORMAT_OLD_SLINK") ||
0392         (bufferFormatString == "Old S-Link")) {
0393       return BUFFER_FORMAT_OLD_SLINK;
0394     }
0395     if ((bufferFormatString == "NEW") || (bufferFormatString == "BUFFER_FORMAT_NEW") || (bufferFormatString == "New")) {
0396       return BUFFER_FORMAT_NEW;
0397     }
0398     //if it was none of the above then return invalid
0399     return BUFFER_FORMAT_INVALID;
0400   }
0401 
0402   FEDHeaderType fedHeaderTypeFromString(const std::string& headerTypeString) {
0403     if ((headerTypeString == "FULL_DEBUG") || (headerTypeString == "HEADER_TYPE_FULL_DEBUG") ||
0404         (headerTypeString == "Full debug")) {
0405       return HEADER_TYPE_FULL_DEBUG;
0406     }
0407     if ((headerTypeString == "APV_ERROR") || (headerTypeString == "HEADER_TYPE_APV_ERROR") ||
0408         (headerTypeString == "APV error")) {
0409       return HEADER_TYPE_APV_ERROR;
0410     }
0411     if ((headerTypeString == "None") || (headerTypeString == "none")) {
0412       return HEADER_TYPE_NONE;
0413     }
0414     //if it was none of the above then return invalid
0415     return HEADER_TYPE_INVALID;
0416   }
0417 
0418   FEDReadoutMode fedReadoutModeFromString(const std::string& readoutModeString) {
0419     if ((readoutModeString == "READOUT_MODE_SCOPE") || (readoutModeString == "SCOPE") ||
0420         (readoutModeString == "SCOPE_MODE") || (readoutModeString == "Scope mode")) {
0421       return READOUT_MODE_SCOPE;
0422     }
0423     if ((readoutModeString == "READOUT_MODE_VIRGIN_RAW") || (readoutModeString == "VIRGIN_RAW") ||
0424         (readoutModeString == "Virgin raw")) {
0425       return READOUT_MODE_VIRGIN_RAW;
0426     }
0427     if ((readoutModeString == "READOUT_MODE_PROC_RAW") || (readoutModeString == "PROC_RAW") ||
0428         (readoutModeString == "PROCESSED_RAW") || (readoutModeString == "Processed raw")) {
0429       return READOUT_MODE_PROC_RAW;
0430     }
0431     if ((readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED") || (readoutModeString == "ZERO_SUPPRESSED") ||
0432         (readoutModeString == "Zero suppressed")) {
0433       return READOUT_MODE_ZERO_SUPPRESSED;
0434     }
0435     if ((readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE8") || (readoutModeString == "ZERO_SUPPRESSED_LITE8") ||
0436         (readoutModeString == "Zero suppressed lite8")) {
0437       return READOUT_MODE_ZERO_SUPPRESSED_LITE8;
0438     }
0439     if ((readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT") ||
0440         (readoutModeString == "ZERO_SUPPRESSED_LITE8_TOPBOT") ||
0441         (readoutModeString == "Zero suppressed lite8 TopBot")) {
0442       return READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT;
0443     }
0444     if ((readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT") ||
0445         (readoutModeString == "ZERO_SUPPRESSED_LITE8_BOTBOT") ||
0446         (readoutModeString == "Zero suppressed lite8 BotBot")) {
0447       return READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT;
0448     }
0449     if ((readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE10") ||
0450         (readoutModeString == "ZERO_SUPPRESSED_LITE10") || (readoutModeString == "Zero suppressed lite10")) {
0451       return READOUT_MODE_ZERO_SUPPRESSED_LITE10;
0452     }
0453     if ((readoutModeString == "READOUT_MODE_PREMIX_RAW") || (readoutModeString == "PREMIX_RAW") ||
0454         (readoutModeString == "PreMix Raw")) {
0455       return READOUT_MODE_PREMIX_RAW;
0456     }
0457     if ((readoutModeString == "READOUT_MODE_SPY") || (readoutModeString == "SPY") ||
0458         (readoutModeString == "Spy channel")) {
0459       return READOUT_MODE_SPY;
0460     }
0461     //if it was none of the above then return invalid
0462     return READOUT_MODE_INVALID;
0463   }
0464   uint8_t packetCodeFromString(const std::string& packetCode, FEDReadoutMode mode) {
0465     if (mode == READOUT_MODE_ZERO_SUPPRESSED) {
0466       if (packetCode == "ZERO_SUPPRESSED" || packetCode == "Zero suppressed") {
0467         return PACKET_CODE_ZERO_SUPPRESSED;
0468       } else if (packetCode == "ZERO_SUPPRESSED10" || packetCode == "Zero suppressed 10") {
0469         return PACKET_CODE_ZERO_SUPPRESSED10;
0470       } else if (packetCode == "ZERO_SUPPRESSED8_BOTBOT" || packetCode == "Zero suppressed 8 BOTBOT") {
0471         return PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT;
0472       } else if (packetCode == "ZERO_SUPPRESSED8_TOPBOT" || packetCode == "Zero suppressed 8 TOPBOT") {
0473         return PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT;
0474       } else {
0475         throw cms::Exception("FEDBuffer")
0476             << "'" << packetCode << "' cannot be converted into a valid packet code for FEDReadoutMode ZERO_SUPPRESSED";
0477       }
0478     } else if (mode == READOUT_MODE_VIRGIN_RAW) {
0479       if (packetCode == "VIRGIN_RAW" || packetCode == "Virgin raw") {
0480         return PACKET_CODE_VIRGIN_RAW;
0481       } else if (packetCode == "VIRGIN_RAW10" || packetCode == "Virgin raw 10") {
0482         return PACKET_CODE_VIRGIN_RAW10;
0483       } else if (packetCode == "VIRGIN_RAW8_BOTBOT" || packetCode == "Virgin raw 8 BOTBOT") {
0484         return PACKET_CODE_VIRGIN_RAW8_BOTBOT;
0485       } else if (packetCode == "VIRGIN_RAW8_TOPBOT" || packetCode == "Virgin raw 8 TOPBOT") {
0486         return PACKET_CODE_VIRGIN_RAW8_TOPBOT;
0487       } else {
0488         throw cms::Exception("FEDBuffer")
0489             << "'" << packetCode << "' cannot be converted into a valid packet code for FEDReadoutMode VIRGIN_RAW";
0490       }
0491     } else if (mode == READOUT_MODE_PROC_RAW) {
0492       if (packetCode == "PROC_RAW" || packetCode == "Processed raw") {
0493         return PACKET_CODE_PROC_RAW;
0494       } else if (packetCode == "PROC_RAW10" || packetCode == "Processed raw 10") {
0495         return PACKET_CODE_PROC_RAW10;
0496       } else if (packetCode == "PROC_RAW8_BOTBOT" || packetCode == "Processed raw 8 BOTBOT") {
0497         return PACKET_CODE_PROC_RAW8_BOTBOT;
0498       } else if (packetCode == "PROC_RAW8_TOPBOT" || packetCode == "Processed raw 8 TOPBOT") {
0499         return PACKET_CODE_PROC_RAW8_TOPBOT;
0500       } else {
0501         throw cms::Exception("FEDBuffer")
0502             << "'" << packetCode << "' cannot be converted into a valid packet code for FEDReadoutMode PROC_RAW";
0503       }
0504     } else if (mode == READOUT_MODE_SCOPE) {
0505       if (packetCode == "SCOPE" || packetCode == "Scope" || packetCode.empty()) {  // default
0506         return PACKET_CODE_SCOPE;
0507       } else {
0508         throw cms::Exception("FEDBuffer")
0509             << "'" << packetCode << "' cannot be converted into a valid packet code for FEDReadoutMode SCOPE";
0510       }
0511     } else {
0512       if (!packetCode.empty()) {
0513         throw cms::Exception("FEDBuffer") << "Packet codes are only needed for zero-suppressed (non-lite), virgin raw, "
0514                                              "processed raw and spy data. FEDReadoutMode="
0515                                           << mode << " and packetCode='" << packetCode << "'";
0516       }
0517       return 0;
0518     }
0519   }
0520 
0521   FEDDAQEventType fedDAQEventTypeFromString(const std::string& daqEventTypeString) {
0522     if ((daqEventTypeString == "PHYSICS") || (daqEventTypeString == "DAQ_EVENT_TYPE_PHYSICS") ||
0523         (daqEventTypeString == "Physics trigger")) {
0524       return DAQ_EVENT_TYPE_PHYSICS;
0525     }
0526     if ((daqEventTypeString == "CALIBRATION") || (daqEventTypeString == "DAQ_EVENT_TYPE_CALIBRATION") ||
0527         (daqEventTypeString == "Calibration trigger")) {
0528       return DAQ_EVENT_TYPE_CALIBRATION;
0529     }
0530     if ((daqEventTypeString == "TEST") || (daqEventTypeString == "DAQ_EVENT_TYPE_TEST") ||
0531         (daqEventTypeString == "Test trigger")) {
0532       return DAQ_EVENT_TYPE_TEST;
0533     }
0534     if ((daqEventTypeString == "TECHNICAL") || (daqEventTypeString == "DAQ_EVENT_TYPE_TECHNICAL") ||
0535         (daqEventTypeString == "Technical trigger")) {
0536       return DAQ_EVENT_TYPE_TECHNICAL;
0537     }
0538     if ((daqEventTypeString == "SIMULATED") || (daqEventTypeString == "DAQ_EVENT_TYPE_SIMULATED") ||
0539         (daqEventTypeString == "Simulated trigger")) {
0540       return DAQ_EVENT_TYPE_SIMULATED;
0541     }
0542     if ((daqEventTypeString == "TRACED") || (daqEventTypeString == "DAQ_EVENT_TYPE_TRACED") ||
0543         (daqEventTypeString == "Traced event")) {
0544       return DAQ_EVENT_TYPE_TRACED;
0545     }
0546     if ((daqEventTypeString == "ERROR") || (daqEventTypeString == "DAQ_EVENT_TYPE_ERROR") ||
0547         (daqEventTypeString == "Error")) {
0548       return DAQ_EVENT_TYPE_ERROR;
0549     }
0550     //if it was none of the above then return invalid
0551     return DAQ_EVENT_TYPE_INVALID;
0552   }
0553 
0554   void FEDStatusRegister::printFlags(std::ostream& os) const {
0555     if (slinkFullFlag())
0556       os << "SLINK_FULL ";
0557     if (trackerHeaderMonitorDataReadyFlag())
0558       os << "HEADER_MONITOR_READY ";
0559     if (qdrMemoryFullFlag())
0560       os << "QDR_FULL ";
0561     if (qdrMemoryPartialFullFlag())
0562       os << "QDR_PARTIAL_FULL ";
0563     if (qdrMemoryEmptyFlag())
0564       os << "QDR_EMPTY ";
0565     if (l1aBxFIFOFullFlag())
0566       os << "L1A_FULL ";
0567     if (l1aBxFIFOPartialFullFlag())
0568       os << "L1A_PARTIAL_FULL ";
0569     if (l1aBxFIFOEmptyFlag())
0570       os << "L1A_EMPTY ";
0571     for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
0572       if (feDataMissingFlag(iFE))
0573         os << "FEUNIT" << uint16_t(iFE) << "MISSING ";
0574     }
0575   }
0576 
0577   FEDBufferState FEDStatusRegister::qdrMemoryState() const {
0578     uint8_t result(0x00);
0579     if (qdrMemoryFullFlag())
0580       result |= BUFFER_STATE_FULL;
0581     if (qdrMemoryPartialFullFlag())
0582       result |= BUFFER_STATE_PARTIAL_FULL;
0583     if (qdrMemoryEmptyFlag())
0584       result |= BUFFER_STATE_EMPTY;
0585     return FEDBufferState(result);
0586   }
0587 
0588   FEDBufferState FEDStatusRegister::l1aBxFIFOState() const {
0589     uint8_t result(0x00);
0590     if (l1aBxFIFOFullFlag())
0591       result |= BUFFER_STATE_FULL;
0592     if (l1aBxFIFOPartialFullFlag())
0593       result |= BUFFER_STATE_PARTIAL_FULL;
0594     if (l1aBxFIFOEmptyFlag())
0595       result |= BUFFER_STATE_EMPTY;
0596     return FEDBufferState(result);
0597   }
0598 
0599   void FEDStatusRegister::setBit(const uint8_t num, const bool bitSet) {
0600     const uint16_t mask = (0x0001 << num);
0601     if (bitSet)
0602       data_ |= mask;
0603     else
0604       data_ &= (~mask);
0605   }
0606 
0607   FEDStatusRegister& FEDStatusRegister::setQDRMemoryBufferState(const FEDBufferState state) {
0608     switch (state) {
0609       case BUFFER_STATE_FULL:
0610       case BUFFER_STATE_PARTIAL_FULL:
0611       case BUFFER_STATE_EMPTY:
0612       case BUFFER_STATE_UNSET:
0613         break;
0614       default:
0615         std::ostringstream ss;
0616         ss << "Invalid buffer state: ";
0617         printHex(&state, 1, ss);
0618         throw cms::Exception("FEDBuffer") << ss.str();
0619     }
0620     setQDRMemoryFullFlag(state & BUFFER_STATE_FULL);
0621     setQDRMemoryPartialFullFlag(state & BUFFER_STATE_PARTIAL_FULL);
0622     setQDRMemoryEmptyFlag(state & BUFFER_STATE_EMPTY);
0623     return *this;
0624   }
0625 
0626   FEDStatusRegister& FEDStatusRegister::setL1ABXFIFOBufferState(const FEDBufferState state) {
0627     switch (state) {
0628       case BUFFER_STATE_FULL:
0629       case BUFFER_STATE_PARTIAL_FULL:
0630       case BUFFER_STATE_EMPTY:
0631       case BUFFER_STATE_UNSET:
0632         break;
0633       default:
0634         std::ostringstream ss;
0635         ss << "Invalid buffer state: ";
0636         printHex(&state, 1, ss);
0637         throw cms::Exception("FEDBuffer") << ss.str();
0638     }
0639     setL1ABXFIFOFullFlag(state & BUFFER_STATE_FULL);
0640     setL1ABXFIFOPartialFullFlag(state & BUFFER_STATE_PARTIAL_FULL);
0641     setL1ABXFIFOEmptyFlag(state & BUFFER_STATE_EMPTY);
0642     return *this;
0643   }
0644 
0645   void FEDBackendStatusRegister::printFlags(std::ostream& os) const {
0646     if (internalFreezeFlag())
0647       os << "INTERNAL_FREEZE ";
0648     if (slinkDownFlag())
0649       os << "SLINK_DOWN ";
0650     if (slinkFullFlag())
0651       os << "SLINK_FULL ";
0652     if (backpressureFlag())
0653       os << "BACKPRESSURE ";
0654     if (ttcReadyFlag())
0655       os << "TTC_READY ";
0656     if (trackerHeaderMonitorDataReadyFlag())
0657       os << "HEADER_MONITOR_READY ";
0658     printFlagsForBuffer(qdrMemoryState(), "QDR", os);
0659     printFlagsForBuffer(frameAddressFIFOState(), "FRAME_ADDRESS", os);
0660     printFlagsForBuffer(totalLengthFIFOState(), "TOTAL_LENGTH", os);
0661     printFlagsForBuffer(trackerHeaderFIFOState(), "TRACKER_HEADER", os);
0662     printFlagsForBuffer(l1aBxFIFOState(), "L1ABX", os);
0663     printFlagsForBuffer(feEventLengthFIFOState(), "FE_LENGTH", os);
0664     printFlagsForBuffer(feFPGABufferState(), "FE", os);
0665   }
0666 
0667   void FEDBackendStatusRegister::printFlagsForBuffer(const FEDBufferState bufferState,
0668                                                      const std::string name,
0669                                                      std::ostream& os) const {
0670     if (bufferState & BUFFER_STATE_EMPTY)
0671       os << name << "_EMPTY ";
0672     if (bufferState & BUFFER_STATE_PARTIAL_FULL)
0673       os << name << "_PARTIAL_FULL ";
0674     if (bufferState & BUFFER_STATE_FULL)
0675       os << name << "_FULL ";
0676     if (bufferState == BUFFER_STATE_UNSET)
0677       os << name << "_UNSET ";
0678   }
0679 
0680   FEDBufferState FEDBackendStatusRegister::getBufferState(const uint8_t bufferPosition) const {
0681     uint8_t result = 0x00;
0682     if (getBit(bufferPosition + STATE_OFFSET_EMPTY))
0683       result |= BUFFER_STATE_EMPTY;
0684     if (getBit(bufferPosition + STATE_OFFSET_PARTIAL_FULL))
0685       result |= BUFFER_STATE_PARTIAL_FULL;
0686     if (getBit(bufferPosition + STATE_OFFSET_FULL))
0687       result |= BUFFER_STATE_FULL;
0688     return FEDBufferState(result);
0689   }
0690 
0691   void FEDBackendStatusRegister::setBufferSate(const uint8_t bufferPosition, const FEDBufferState state) {
0692     switch (state) {
0693       case BUFFER_STATE_FULL:
0694       case BUFFER_STATE_PARTIAL_FULL:
0695       case BUFFER_STATE_EMPTY:
0696       case BUFFER_STATE_UNSET:
0697         break;
0698       default:
0699         std::ostringstream ss;
0700         ss << "Invalid buffer state: ";
0701         printHex(&state, 1, ss);
0702         throw cms::Exception("FEDBuffer") << ss.str();
0703     }
0704     setBit(bufferPosition + STATE_OFFSET_EMPTY, state & BUFFER_STATE_EMPTY);
0705     setBit(bufferPosition + STATE_OFFSET_PARTIAL_FULL, state & BUFFER_STATE_PARTIAL_FULL);
0706     setBit(bufferPosition + STATE_OFFSET_FULL, state & BUFFER_STATE_FULL);
0707   }
0708 
0709   void FEDBackendStatusRegister::setBit(const uint8_t num, const bool bitSet) {
0710     const uint32_t mask = (0x00000001 << num);
0711     if (bitSet)
0712       data_ |= mask;
0713     else
0714       data_ &= (~mask);
0715   }
0716 
0717   FEDBackendStatusRegister::FEDBackendStatusRegister(const FEDBufferState qdrMemoryBufferState,
0718                                                      const FEDBufferState frameAddressFIFOBufferState,
0719                                                      const FEDBufferState totalLengthFIFOBufferState,
0720                                                      const FEDBufferState trackerHeaderFIFOBufferState,
0721                                                      const FEDBufferState l1aBxFIFOBufferState,
0722                                                      const FEDBufferState feEventLengthFIFOBufferState,
0723                                                      const FEDBufferState feFPGABufferState,
0724                                                      const bool backpressure,
0725                                                      const bool slinkFull,
0726                                                      const bool slinkDown,
0727                                                      const bool internalFreeze,
0728                                                      const bool trackerHeaderMonitorDataReady,
0729                                                      const bool ttcReady)
0730       : data_(0) {
0731     setInternalFreezeFlag(internalFreeze);
0732     setSLinkDownFlag(slinkDown);
0733     setSLinkFullFlag(slinkFull);
0734     setBackpressureFlag(backpressure);
0735     setTTCReadyFlag(ttcReady);
0736     setTrackerHeaderMonitorDataReadyFlag(trackerHeaderMonitorDataReady);
0737     setQDRMemoryState(qdrMemoryBufferState);
0738     setFrameAddressFIFOState(frameAddressFIFOBufferState);
0739     setTotalLengthFIFOState(totalLengthFIFOBufferState);
0740     setTrackerHeaderFIFOState(trackerHeaderFIFOBufferState);
0741     setL1ABXFIFOState(l1aBxFIFOBufferState);
0742     setFEEventLengthFIFOState(feEventLengthFIFOBufferState);
0743     setFEFPGABufferState(feFPGABufferState);
0744   }
0745 
0746   TrackerSpecialHeader::TrackerSpecialHeader(const uint8_t* headerPointer) {
0747     //the buffer format byte is one of the valid values if we assume the buffer is not swapped
0748     const bool validFormatByteWhenNotWordSwapped = ((headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_NEW) ||
0749                                                     (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_OLD));
0750     //the buffer format byte is the old value if we assume the buffer is swapped
0751     const bool validFormatByteWhenWordSwapped = (headerPointer[BUFFERFORMAT ^ 4] == BUFFER_FORMAT_CODE_OLD);
0752     //if the buffer format byte is valid if the buffer is not swapped or it is never valid
0753     if (validFormatByteWhenNotWordSwapped || (!validFormatByteWhenNotWordSwapped && !validFormatByteWhenWordSwapped)) {
0754       memcpy(specialHeader_, headerPointer, 8);
0755       wordSwapped_ = false;
0756     } else {
0757       memcpy(specialHeader_, headerPointer + 4, 4);
0758       memcpy(specialHeader_ + 4, headerPointer, 4);
0759       wordSwapped_ = true;
0760     }
0761   }
0762 
0763   FEDBufferFormat TrackerSpecialHeader::bufferFormat() const {
0764     if (bufferFormatByte() == BUFFER_FORMAT_CODE_NEW)
0765       return BUFFER_FORMAT_NEW;
0766     else if (bufferFormatByte() == BUFFER_FORMAT_CODE_OLD) {
0767       if (wordSwapped_)
0768         return BUFFER_FORMAT_OLD_VME;
0769       else
0770         return BUFFER_FORMAT_OLD_SLINK;
0771     } else
0772       return BUFFER_FORMAT_INVALID;
0773   }
0774 
0775   FEDLegacyReadoutMode TrackerSpecialHeader::legacyReadoutMode() const {
0776     const uint8_t eventTypeNibble = trackerEventTypeNibble();
0777     const uint8_t mode = (eventTypeNibble & 0xF);
0778     switch (mode) {
0779       case READOUT_MODE_LEGACY_VIRGIN_RAW_REAL:
0780       case READOUT_MODE_LEGACY_VIRGIN_RAW_FAKE:
0781       case READOUT_MODE_LEGACY_PROC_RAW_REAL:
0782       case READOUT_MODE_LEGACY_PROC_RAW_FAKE:
0783       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_REAL:
0784       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_FAKE:
0785       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_LITE_REAL:
0786       case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_LITE_FAKE:
0787         return FEDLegacyReadoutMode(mode);
0788       default:
0789         return READOUT_MODE_LEGACY_INVALID;
0790     }
0791   }
0792 
0793   TrackerSpecialHeader& TrackerSpecialHeader::setBufferFormat(const FEDBufferFormat newBufferFormat) {
0794     //check if order in buffer is different
0795     if (((bufferFormat() == BUFFER_FORMAT_OLD_VME) && (newBufferFormat != BUFFER_FORMAT_OLD_VME)) ||
0796         ((bufferFormat() != BUFFER_FORMAT_OLD_VME) && (newBufferFormat == BUFFER_FORMAT_OLD_VME))) {
0797       wordSwapped_ = !wordSwapped_;
0798     }
0799     //set appropriate code
0800     setBufferFormatByte(newBufferFormat);
0801     return *this;
0802   }
0803 
0804   void TrackerSpecialHeader::setBufferFormatByte(const FEDBufferFormat newBufferFormat) {
0805     switch (newBufferFormat) {
0806       case BUFFER_FORMAT_OLD_VME:
0807       case BUFFER_FORMAT_OLD_SLINK:
0808         specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_OLD;
0809         break;
0810       case BUFFER_FORMAT_NEW:
0811         specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_NEW;
0812         break;
0813       default:
0814         std::ostringstream ss;
0815         ss << "Invalid buffer format: ";
0816         printHex(&newBufferFormat, 1, ss);
0817         throw cms::Exception("FEDBuffer") << ss.str();
0818     }
0819   }
0820 
0821   TrackerSpecialHeader& TrackerSpecialHeader::setHeaderType(const FEDHeaderType headerType) {
0822     switch (headerType) {
0823       case HEADER_TYPE_FULL_DEBUG:
0824       case HEADER_TYPE_APV_ERROR:
0825       case HEADER_TYPE_NONE:
0826         setHeaderTypeNibble(headerType);
0827         return *this;
0828       default:
0829         std::ostringstream ss;
0830         ss << "Invalid header type: ";
0831         printHex(&headerType, 1, ss);
0832         throw cms::Exception("FEDBuffer") << ss.str();
0833     }
0834   }
0835 
0836   TrackerSpecialHeader& TrackerSpecialHeader::setReadoutMode(const FEDReadoutMode readoutMode) {
0837     switch (readoutMode) {
0838       case READOUT_MODE_SCOPE:
0839       case READOUT_MODE_VIRGIN_RAW:
0840       case READOUT_MODE_PROC_RAW:
0841       case READOUT_MODE_SPY:
0842       case READOUT_MODE_ZERO_SUPPRESSED:
0843       case READOUT_MODE_ZERO_SUPPRESSED_FAKE:
0844       case READOUT_MODE_ZERO_SUPPRESSED_LITE10:
0845       case READOUT_MODE_ZERO_SUPPRESSED_LITE10_CMOVERRIDE:
0846       case READOUT_MODE_ZERO_SUPPRESSED_LITE8:
0847       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_CMOVERRIDE:
0848       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT:
0849       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT_CMOVERRIDE:
0850       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT:
0851       case READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT_CMOVERRIDE:
0852       case READOUT_MODE_PREMIX_RAW:
0853         setReadoutModeBits(readoutMode);
0854         break;
0855       default:
0856         std::ostringstream ss;
0857         ss << "Invalid readout mode: ";
0858         printHex(&readoutMode, 1, ss);
0859         throw cms::Exception("FEDBuffer") << ss.str();
0860     }
0861     return *this;
0862   }
0863 
0864   TrackerSpecialHeader& TrackerSpecialHeader::setAPVAddressErrorForFEUnit(const uint8_t internalFEUnitNum,
0865                                                                           const bool error) {
0866     const uint8_t mask = 0x1 << internalFEUnitNum;
0867     const uint8_t result = ((apvAddressErrorRegister() & (~mask)) | (error ? mask : 0x00));
0868     setAPVEAddressErrorRegister(result);
0869     return *this;
0870   }
0871 
0872   TrackerSpecialHeader& TrackerSpecialHeader::setFEEnableForFEUnit(const uint8_t internalFEUnitNum,
0873                                                                    const bool enabled) {
0874     const uint8_t mask = 0x1 << internalFEUnitNum;
0875     const uint8_t result = ((feEnableRegister() & (~mask)) | (enabled ? mask : 0x00));
0876     setFEEnableRegister(result);
0877     return *this;
0878   }
0879 
0880   TrackerSpecialHeader& TrackerSpecialHeader::setFEOverflowForFEUnit(const uint8_t internalFEUnitNum,
0881                                                                      const bool overflow) {
0882     const uint8_t mask = 0x1 << internalFEUnitNum;
0883     const uint8_t result = ((feOverflowRegister() & (~mask)) | (overflow ? mask : 0x00));
0884     setFEEnableRegister(result);
0885     return *this;
0886   }
0887 
0888   TrackerSpecialHeader::TrackerSpecialHeader(const FEDBufferFormat bufferFormat,
0889                                              const FEDReadoutMode readoutMode,
0890                                              const FEDHeaderType headerType,
0891                                              const uint8_t address,
0892                                              const uint8_t addressErrorRegister,
0893                                              const uint8_t feEnableRegister,
0894                                              const uint8_t feOverflowRegister,
0895                                              const FEDStatusRegister fedStatusRegister) {
0896     memset(specialHeader_, 0x00, 8);
0897     //determine if order is swapped in real buffer
0898     wordSwapped_ = (bufferFormat == BUFFER_FORMAT_OLD_VME);
0899     //set fields
0900     setBufferFormatByte(bufferFormat);
0901     setReadoutMode(readoutMode);
0902     setHeaderType(headerType);
0903     setAPVEAddress(address);
0904     setAPVEAddressErrorRegister(addressErrorRegister);
0905     setFEEnableRegister(feEnableRegister);
0906     setFEOverflowRegister(feOverflowRegister);
0907     setFEDStatusRegister(fedStatusRegister);
0908   }
0909 
0910   FEDDAQEventType FEDDAQHeader::eventType() const {
0911     switch (eventTypeNibble()) {
0912       case DAQ_EVENT_TYPE_PHYSICS:
0913       case DAQ_EVENT_TYPE_CALIBRATION:
0914       case DAQ_EVENT_TYPE_TEST:
0915       case DAQ_EVENT_TYPE_TECHNICAL:
0916       case DAQ_EVENT_TYPE_SIMULATED:
0917       case DAQ_EVENT_TYPE_TRACED:
0918       case DAQ_EVENT_TYPE_ERROR:
0919         return FEDDAQEventType(eventTypeNibble());
0920       default:
0921         return DAQ_EVENT_TYPE_INVALID;
0922     }
0923   }
0924 
0925   FEDDAQHeader& FEDDAQHeader::setEventType(const FEDDAQEventType evtType) {
0926     header_[7] = ((header_[7] & 0xF0) | evtType);
0927     return *this;
0928   }
0929 
0930   FEDDAQHeader& FEDDAQHeader::setL1ID(const uint32_t l1ID) {
0931     header_[4] = (l1ID & 0x000000FF);
0932     header_[5] = ((l1ID & 0x0000FF00) >> 8);
0933     header_[6] = ((l1ID & 0x00FF0000) >> 16);
0934     return *this;
0935   }
0936 
0937   FEDDAQHeader& FEDDAQHeader::setBXID(const uint16_t bxID) {
0938     header_[3] = ((bxID & 0x0FF0) >> 4);
0939     header_[2] = ((header_[2] & 0x0F) | ((bxID & 0x000F) << 4));
0940     return *this;
0941   }
0942 
0943   FEDDAQHeader& FEDDAQHeader::setSourceID(const uint16_t sourceID) {
0944     header_[2] = ((header_[2] & 0xF0) | ((sourceID & 0x0F00) >> 8));
0945     header_[1] = (sourceID & 0x00FF);
0946     return *this;
0947   }
0948 
0949   FEDDAQHeader::FEDDAQHeader(const uint32_t l1ID,
0950                              const uint16_t bxID,
0951                              const uint16_t sourceID,
0952                              const FEDDAQEventType evtType) {
0953     //clear everything (FOV,H,x,$ all set to 0)
0954     memset(header_, 0x0, 8);
0955     //set the BoE nibble to indicate this is the last fragment
0956     header_[7] = 0x50;
0957     //set variable fields vith values supplied
0958     setEventType(evtType);
0959     setL1ID(l1ID);
0960     setBXID(bxID);
0961     setSourceID(sourceID);
0962   }
0963 
0964   FEDTTSBits FEDDAQTrailer::ttsBits() const {
0965     switch (ttsNibble()) {
0966       case TTS_DISCONNECTED0:
0967       case TTS_WARN_OVERFLOW:
0968       case TTS_OUT_OF_SYNC:
0969       case TTS_BUSY:
0970       case TTS_READY:
0971       case TTS_ERROR:
0972       case TTS_DISCONNECTED1:
0973         return FEDTTSBits(ttsNibble());
0974       default:
0975         return TTS_INVALID;
0976     }
0977   }
0978 
0979   FEDDAQTrailer::FEDDAQTrailer(const uint32_t eventLengthIn64BitWords,
0980                                const uint16_t crc,
0981                                const FEDTTSBits ttsBits,
0982                                const bool slinkTransmissionError,
0983                                const bool badFEDID,
0984                                const bool slinkCRCError,
0985                                const uint8_t eventStatusNibble) {
0986     //clear everything (T,x,$ all set to 0)
0987     memset(trailer_, 0x0, 8);
0988     //set the EoE nibble to indicate this is the last fragment
0989     trailer_[7] = 0xA0;
0990     //set variable fields vith values supplied
0991     setEventLengthIn64BitWords(eventLengthIn64BitWords);
0992     setEventStatusNibble(eventStatusNibble);
0993     setTTSBits(ttsBits);
0994     setCRC(crc);
0995     setSLinkTransmissionErrorBit(slinkTransmissionError);
0996     setBadSourceIDBit(badFEDID);
0997     setSLinkCRCErrorBit(slinkCRCError);
0998   }
0999 
1000   FEDDAQTrailer& FEDDAQTrailer::setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords) {
1001     trailer_[4] = (eventLengthIn64BitWords & 0x000000FF);
1002     trailer_[5] = ((eventLengthIn64BitWords & 0x0000FF00) >> 8);
1003     trailer_[6] = ((eventLengthIn64BitWords & 0x00FF0000) >> 16);
1004     return *this;
1005   }
1006 
1007   FEDDAQTrailer& FEDDAQTrailer::setCRC(const uint16_t crc) {
1008     trailer_[2] = (crc & 0x00FF);
1009     trailer_[3] = ((crc >> 8) & 0x00FF);
1010     return *this;
1011   }
1012 
1013   FEDDAQTrailer& FEDDAQTrailer::setSLinkTransmissionErrorBit(const bool bitSet) {
1014     if (bitSet)
1015       trailer_[1] |= 0x80;
1016     else
1017       trailer_[1] &= (~0x80);
1018     return *this;
1019   }
1020 
1021   FEDDAQTrailer& FEDDAQTrailer::setBadSourceIDBit(const bool bitSet) {
1022     if (bitSet)
1023       trailer_[1] |= 0x40;
1024     else
1025       trailer_[1] &= (~0x40);
1026     return *this;
1027   }
1028 
1029   FEDDAQTrailer& FEDDAQTrailer::setSLinkCRCErrorBit(const bool bitSet) {
1030     if (bitSet)
1031       trailer_[0] |= 0x04;
1032     else
1033       trailer_[0] &= (~0x40);
1034     return *this;
1035   }
1036 
1037   FEDDAQTrailer& FEDDAQTrailer::setEventStatusNibble(const uint8_t eventStatusNibble) {
1038     trailer_[1] = ((trailer_[1] & 0xF0) | (eventStatusNibble & 0x0F));
1039     return *this;
1040   }
1041 
1042   FEDDAQTrailer& FEDDAQTrailer::setTTSBits(const FEDTTSBits ttsBits) {
1043     trailer_[0] = ((trailer_[0] & 0x0F) | (ttsBits & 0xF0));
1044     return *this;
1045   }
1046 
1047   FEDAPVErrorHeader::~FEDAPVErrorHeader() {}
1048 
1049   size_t FEDAPVErrorHeader::lengthInBytes() const { return APV_ERROR_HEADER_SIZE_IN_BYTES; }
1050 
1051   void FEDAPVErrorHeader::print(std::ostream& os) const { printHex(header_, APV_ERROR_HEADER_SIZE_IN_BYTES, os); }
1052 
1053   FEDAPVErrorHeader* FEDAPVErrorHeader::clone() const { return new FEDAPVErrorHeader(*this); }
1054 
1055   bool FEDAPVErrorHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const {
1056     //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
1057     const uint16_t bitNumber = (internalFEDChannelNum / FEDCH_PER_FEUNIT) * 24 +
1058                                (FEDCH_PER_FEUNIT - 1 - (internalFEDChannelNum % FEDCH_PER_FEUNIT)) * 2 + apvNum;
1059     //bit high means no error
1060     return (header_[bitNumber / 8] & (0x01 << (bitNumber % 8)));
1061   }
1062 
1063   bool FEDAPVErrorHeader::checkChannelStatusBits(const uint8_t internalFEDChannelNum) const {
1064     return (checkStatusBits(internalFEDChannelNum, 0) && checkStatusBits(internalFEDChannelNum, 1));
1065   }
1066 
1067   const uint8_t* FEDAPVErrorHeader::data() const { return header_; }
1068 
1069   FEDAPVErrorHeader::FEDAPVErrorHeader(const std::vector<bool>& apvsGood) {
1070     memset(header_, 0x00, APV_ERROR_HEADER_SIZE_IN_BYTES);
1071     for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
1072       setAPVStatusBit(iCh, 0, apvsGood[iCh * 2]);
1073       setAPVStatusBit(iCh, 1, apvsGood[iCh * 2 + 1]);
1074     }
1075   }
1076 
1077   FEDAPVErrorHeader& FEDAPVErrorHeader::setAPVStatusBit(const uint8_t internalFEDChannelNum,
1078                                                         const uint8_t apvNum,
1079                                                         const bool apvGood) {
1080     //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
1081     const uint16_t bitNumber = (internalFEDChannelNum / FEDCH_PER_FED) * 24 +
1082                                (FEDCH_PER_FED - 1 - (internalFEDChannelNum % FEDCH_PER_FED)) * 2 + apvNum;
1083     const uint8_t byteNumber = bitNumber / 8;
1084     const uint8_t bitInByte = bitNumber % 8;
1085     const uint8_t mask = (0x01 << bitInByte);
1086     header_[byteNumber] = ((header_[byteNumber] & (~mask)) | (apvGood ? mask : 0x00));
1087     return *this;
1088   }
1089 
1090   void FEDAPVErrorHeader::setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status) {
1091     //if channel is unlocked then set both APV bits bad
1092     if ((!(status & CHANNEL_STATUS_LOCKED)) || (!(status & CHANNEL_STATUS_IN_SYNC))) {
1093       setAPVStatusBit(internalFEDChannelNum, 0, false);
1094       setAPVStatusBit(internalFEDChannelNum, 1, false);
1095       return;
1096     } else {
1097       if ((status & CHANNEL_STATUS_APV0_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV0_NO_ERROR_BIT)) {
1098         setAPVStatusBit(internalFEDChannelNum, 0, true);
1099       } else {
1100         setAPVStatusBit(internalFEDChannelNum, 0, false);
1101       }
1102       if ((status & CHANNEL_STATUS_APV1_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV1_NO_ERROR_BIT)) {
1103         setAPVStatusBit(internalFEDChannelNum, 1, true);
1104       } else {
1105         setAPVStatusBit(internalFEDChannelNum, 1, false);
1106       }
1107     }
1108   }
1109 
1110   //These methods do nothing as the values in question are in present in the APV Error header.
1111   //The methods exist so that users of the base class can set the values without caring which type of header they have and so if they are needed.
1112   void FEDAPVErrorHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address) { return; }
1113   void FEDAPVErrorHeader::setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister) { return; }
1114   void FEDAPVErrorHeader::setDAQRegister(const uint32_t daqRegister) { return; }
1115   void FEDAPVErrorHeader::setDAQRegister2(const uint32_t daqRegister2) { return; }
1116   void FEDAPVErrorHeader::set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister) {
1117     return;
1118   }
1119   void FEDAPVErrorHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length) { return; }
1120 
1121   FEDFullDebugHeader::~FEDFullDebugHeader() {}
1122 
1123   size_t FEDFullDebugHeader::lengthInBytes() const { return FULL_DEBUG_HEADER_SIZE_IN_BYTES; }
1124 
1125   void FEDFullDebugHeader::print(std::ostream& os) const { printHex(header_, FULL_DEBUG_HEADER_SIZE_IN_BYTES, os); }
1126 
1127   FEDFullDebugHeader* FEDFullDebugHeader::clone() const { return new FEDFullDebugHeader(*this); }
1128 
1129   bool FEDFullDebugHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const {
1130     return (!unlockedFromBit(internalFEDChannelNum) && !outOfSyncFromBit(internalFEDChannelNum) &&
1131             !apvError(internalFEDChannelNum, apvNum) && !apvAddressError(internalFEDChannelNum, apvNum));
1132   }
1133 
1134   bool FEDFullDebugHeader::checkChannelStatusBits(const uint8_t internalFEDChannelNum) const {
1135     //return ( !unlockedFromBit(internalFEDChannelNum) &&
1136     //         !outOfSyncFromBit(internalFEDChannelNum) &&
1137     //         !apvErrorFromBit(internalFEDChannelNum,0) &&
1138     //         !apvAddressErrorFromBit(internalFEDChannelNum,0) &&
1139     //         !apvErrorFromBit(internalFEDChannelNum,1) &&
1140     //         !apvAddressErrorFromBit(internalFEDChannelNum,1) );
1141     return (getChannelStatus(internalFEDChannelNum) == CHANNEL_STATUS_NO_PROBLEMS);
1142   }
1143 
1144   FEDChannelStatus FEDFullDebugHeader::getChannelStatus(const uint8_t internalFEDChannelNum) const {
1145     const uint8_t* pFEWord = feWord(internalFEDChannelNum / FEDCH_PER_FEUNIT);
1146     const uint8_t feUnitChanNum = internalFEDChannelNum % FEDCH_PER_FEUNIT;
1147     const uint8_t startByteInFEWord = (FEDCH_PER_FEUNIT - 1 - feUnitChanNum) * 6 / 8;
1148     switch ((FEDCH_PER_FEUNIT - 1 - feUnitChanNum) % 4) {
1149       case 0:
1150         return FEDChannelStatus(pFEWord[startByteInFEWord] & 0x3F);
1151       case 1:
1152         return FEDChannelStatus(((pFEWord[startByteInFEWord] & 0xC0) >> 6) |
1153                                 ((pFEWord[startByteInFEWord + 1] & 0x0F) << 2));
1154       case 2:
1155         return FEDChannelStatus(((pFEWord[startByteInFEWord] & 0xF0) >> 4) |
1156                                 ((pFEWord[startByteInFEWord + 1] & 0x03) << 4));
1157       case 3:
1158         return FEDChannelStatus((pFEWord[startByteInFEWord] & 0xFC) >> 2);
1159       //stop compiler warning
1160       default:
1161         return FEDChannelStatus(0);
1162     }
1163     /*const uint8_t feUnitChanNum = internalFEDChannelNum / FEDCH_PER_FEUNIT;
1164     const uint8_t* pFEWord = feWord(feUnitChanNum);
1165     const uint8_t startByteInFEWord = feUnitChanNum * 3 / 4;
1166     //const uint8_t shift = ( 6 - ((feUnitChanNum-1)%4) );
1167     //const uint16_t mask = ( 0x003F << shift );
1168     //uint8_t result = ( (pFEWord[startByteInFEWord] & (mask&0x00FF)) >> shift );
1169     //result |= ( (pFEWord[startByteInFEWord+1] & (mask>>8)) << (8-shift) );
1170     switch (feUnitChanNum % 4) {
1171     case 0:
1172       return FEDChannelStatus( pFEWord[startByteInFEWord] & 0x3F );
1173     case 1:
1174       return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xC0) >> 6) | ((pFEWord[startByteInFEWord+1] & 0x0F) << 2) );
1175     case 2:
1176       return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xF0) >> 4) | ((pFEWord[startByteInFEWord+1] & 0x03) << 4) );
1177     case 3:
1178       return FEDChannelStatus( (pFEWord[startByteInFEWord] & 0xFC) >> 2 );
1179     //stop compiler warning
1180     default:
1181       return FEDChannelStatus(0);
1182     }*/
1183   }
1184 
1185   const uint8_t* FEDFullDebugHeader::data() const { return header_; }
1186 
1187   FEDFullDebugHeader::FEDFullDebugHeader(const std::vector<uint16_t>& feUnitLengths,
1188                                          const std::vector<uint8_t>& feMajorityAddresses,
1189                                          const std::vector<FEDChannelStatus>& channelStatus,
1190                                          const FEDBackendStatusRegister beStatusRegister,
1191                                          const uint32_t daqRegister,
1192                                          const uint32_t daqRegister2) {
1193     memset(header_, 0x00, FULL_DEBUG_HEADER_SIZE_IN_BYTES);
1194     setBEStatusRegister(beStatusRegister);
1195     setDAQRegister(daqRegister);
1196     setDAQRegister2(daqRegister2);
1197     for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1198       setFEUnitLength(iFE, feUnitLengths[iFE]);
1199       setFEUnitMajorityAddress(iFE, feMajorityAddresses[iFE]);
1200     }
1201     for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
1202       setChannelStatus(iCh, channelStatus[iCh]);
1203     }
1204   }
1205 
1206   void FEDFullDebugHeader::setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status) {
1207     setUnlocked(internalFEDChannelNum, !(status & CHANNEL_STATUS_LOCKED));
1208     setOutOfSync(internalFEDChannelNum, !(status & CHANNEL_STATUS_IN_SYNC));
1209     setAPVAddressError(internalFEDChannelNum, 1, !(status & CHANNEL_STATUS_APV1_ADDRESS_GOOD));
1210     setAPVAddressError(internalFEDChannelNum, 0, !(status & CHANNEL_STATUS_APV0_ADDRESS_GOOD));
1211     setAPVError(internalFEDChannelNum, 1, !(status & CHANNEL_STATUS_APV1_NO_ERROR_BIT));
1212     setAPVError(internalFEDChannelNum, 0, !(status & CHANNEL_STATUS_APV0_NO_ERROR_BIT));
1213   }
1214 
1215   void FEDFullDebugHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address) {
1216     feWord(internalFEUnitNum)[9] = address;
1217   }
1218 
1219   void FEDFullDebugHeader::setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister) {
1220     set32BitWordAt(feWord(0) + 10, beStatusRegister);
1221   }
1222 
1223   void FEDFullDebugHeader::setDAQRegister(const uint32_t daqRegister) { set32BitWordAt(feWord(7) + 10, daqRegister); }
1224 
1225   void FEDFullDebugHeader::setDAQRegister2(const uint32_t daqRegister2) {
1226     set32BitWordAt(feWord(6) + 10, daqRegister2);
1227   }
1228 
1229   //used by DigiToRaw to copy reserved registers in internalFEUnit buffers 1 through 5
1230   void FEDFullDebugHeader::set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister) {
1231     set32BitWordAt(feWord(internalFEUnitNum) + 10, reservedRegister);
1232   }
1233 
1234   void FEDFullDebugHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length) {
1235     feWord(internalFEUnitNum)[15] = ((length & 0xFF00) >> 8);
1236     feWord(internalFEUnitNum)[14] = (length & 0x00FF);
1237   }
1238 
1239   void FEDFullDebugHeader::setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value) {
1240     const uint8_t bitInFeWord = (FEDCH_PER_FEUNIT - 1 - (internalFEDChannelNum % FEDCH_PER_FEUNIT)) * 6 + bit;
1241     uint8_t& byte = *(feWord(internalFEDChannelNum / FEDCH_PER_FEUNIT) + (bitInFeWord / 8));
1242     const uint8_t mask = (0x1 << bitInFeWord % 8);
1243     byte = ((byte & (~mask)) | (value ? mask : 0x0));
1244   }
1245 
1246   FEDFEHeader::~FEDFEHeader() {}
1247 
1248   FEDBufferBase::FEDBufferBase(const FEDRawData& fedBuffer)
1249       : channels_(FEDCH_PER_FED, FEDChannel(nullptr, 0, 0)),
1250         originalBuffer_(fedBuffer.data()),
1251         bufferSize_(fedBuffer.size()) {
1252     init();
1253   }
1254 
1255   FEDBufferBase::FEDBufferBase(const FEDRawData& fedBuffer, const bool fillChannelVector)
1256       : originalBuffer_(fedBuffer.data()), bufferSize_(fedBuffer.size()) {
1257     init();
1258     if (fillChannelVector)
1259       channels_.assign(FEDCH_PER_FED, FEDChannel(nullptr, 0, 0));
1260   }
1261 
1262   void FEDBufferBase::init() {
1263     //construct tracker special header using second 64 bit word
1264     specialHeader_ = TrackerSpecialHeader(originalBuffer_ + 8);
1265 
1266     //check the buffer format
1267     const FEDBufferFormat bufferFormat = specialHeader_.bufferFormat();
1268     //swap the buffer words so that the whole buffer is in slink ordering
1269     if ((bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW)) {
1270       uint8_t* newBuffer = new uint8_t[bufferSize_];
1271       const uint32_t* originalU32 = reinterpret_cast<const uint32_t*>(originalBuffer_);
1272       const size_t sizeU32 = bufferSize_ / 4;
1273       uint32_t* newU32 = reinterpret_cast<uint32_t*>(newBuffer);
1274       if (bufferFormat == BUFFER_FORMAT_OLD_VME) {
1275         //swap whole buffer
1276         for (size_t i = 0; i < sizeU32; i += 2) {
1277           newU32[i] = originalU32[i + 1];
1278           newU32[i + 1] = originalU32[i];
1279         }
1280       }
1281       if (bufferFormat == BUFFER_FORMAT_NEW) {
1282         //copy DAQ header
1283         memcpy(newU32, originalU32, 8);
1284         //copy DAQ trailer
1285         memcpy(newU32 + sizeU32 - 2, originalU32 + sizeU32 - 2, 8);
1286         //swap the payload
1287         for (size_t i = 2; i < sizeU32 - 2; i += 2) {
1288           newU32[i] = originalU32[i + 1];
1289           newU32[i + 1] = originalU32[i];
1290         }
1291       }
1292       orderedBuffer_ = newBuffer;
1293     }  //if ( (bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW) )
1294     else {
1295       orderedBuffer_ = originalBuffer_;
1296     }
1297 
1298     //construct header object at begining of buffer
1299     daqHeader_ = FEDDAQHeader(orderedBuffer_);
1300     //construct trailer object using last 64 bit word of buffer
1301     daqTrailer_ = FEDDAQTrailer(orderedBuffer_ + bufferSize_ - 8);
1302   }
1303 
1304   FEDBufferBase::~FEDBufferBase() {
1305     //if the buffer was coppied and swapped then delete the copy
1306     if (orderedBuffer_ != originalBuffer_)
1307       delete[] orderedBuffer_;
1308   }
1309 
1310   void FEDBufferBase::print(std::ostream& os) const {
1311     os << "buffer format: " << bufferFormat() << std::endl;
1312     os << "Buffer size: " << bufferSize() << " bytes" << std::endl;
1313     os << "Event length from DAQ trailer: " << daqEventLengthInBytes() << " bytes" << std::endl;
1314     os << "Source ID: " << daqSourceID() << std::endl;
1315     os << "Header type: " << headerType() << std::endl;
1316     os << "Readout mode: " << readoutMode() << std::endl;
1317     os << "DAQ event type: " << daqEventType() << std::endl;
1318     os << "TTS state: " << daqTTSState() << std::endl;
1319     os << "L1 ID: " << daqLvl1ID() << std::endl;
1320     os << "BX ID: " << daqBXID() << std::endl;
1321     os << "FED status register flags: ";
1322     fedStatusRegister().printFlags(os);
1323     os << std::endl;
1324     os << "APVe Address: " << uint16_t(apveAddress()) << std::endl;
1325     os << "Enabled FE units: " << uint16_t(nFEUnitsEnabled()) << std::endl;
1326   }
1327 
1328   uint8_t FEDBufferBase::nFEUnitsEnabled() const {
1329     uint8_t result = 0;
1330     for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1331       if (feEnabled(iFE))
1332         result++;
1333     }
1334     return result;
1335   }
1336 
1337   bool FEDBufferBase::checkSourceIDs() const {
1338     return ((daqSourceID() >= FED_ID_MIN) && (daqSourceID() <= FED_ID_MAX));
1339   }
1340 
1341   bool FEDBufferBase::checkMajorityAddresses() const {
1342     for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1343       if (!feEnabled(iFE))
1344         continue;
1345       if (majorityAddressErrorForFEUnit(iFE))
1346         return false;
1347     }
1348     return true;
1349   }
1350 
1351   bool FEDBufferBase::channelGood(const uint8_t internalFEDChannelNum) const {
1352     const uint8_t feUnit = internalFEDChannelNum / FEDCH_PER_FEUNIT;
1353     return (!majorityAddressErrorForFEUnit(feUnit) && feEnabled(feUnit) && !feOverflow(feUnit));
1354   }
1355 
1356   std::string FEDBufferBase::checkSummary() const {
1357     std::ostringstream summary;
1358     summary << "Check buffer type valid: " << (checkBufferFormat() ? "passed" : "FAILED") << std::endl;
1359     summary << "Check header format valid: " << (checkHeaderType() ? "passed" : "FAILED") << std::endl;
1360     summary << "Check readout mode valid: " << (checkReadoutMode() ? "passed" : "FAILED") << std::endl;
1361     //summary << "Check APVe address valid: " << ( checkAPVEAddressValid() ? "passed" : "FAILED" ) << std::endl;
1362     summary << "Check FE unit majority addresses: " << (checkMajorityAddresses() ? "passed" : "FAILED") << std::endl;
1363     if (!checkMajorityAddresses()) {
1364       summary << "FEs with majority address error: ";
1365       unsigned int badFEs = 0;
1366       for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1367         if (!feEnabled(iFE))
1368           continue;
1369         if (majorityAddressErrorForFEUnit(iFE)) {
1370           summary << uint16_t(iFE) << " ";
1371           badFEs++;
1372         }
1373       }
1374       summary << std::endl;
1375       summary << "Number of FE Units with bad addresses: " << badFEs << std::endl;
1376     }
1377     summary << "Check for FE unit buffer overflows: " << (checkNoFEOverflows() ? "passed" : "FAILED") << std::endl;
1378     if (!checkNoFEOverflows()) {
1379       summary << "FEs which overflowed: ";
1380       unsigned int badFEs = 0;
1381       for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1382         if (feOverflow(iFE)) {
1383           summary << uint16_t(iFE) << " ";
1384           badFEs++;
1385         }
1386       }
1387       summary << std::endl;
1388       summary << "Number of FE Units which overflowed: " << badFEs << std::endl;
1389     }
1390     summary << "Check for S-Link CRC errors: " << (checkNoSlinkCRCError() ? "passed" : "FAILED") << std::endl;
1391     summary << "Check for S-Link transmission error: " << (checkNoSLinkTransmissionError() ? "passed" : "FAILED")
1392             << std::endl;
1393     summary << "Check CRC: " << (checkCRC() ? "passed" : "FAILED") << std::endl;
1394     summary << "Check source ID is FED ID: " << (checkSourceIDs() ? "passed" : "FAILED") << std::endl;
1395     summary << "Check for unexpected source ID at FRL: " << (checkNoUnexpectedSourceID() ? "passed" : "FAILED")
1396             << std::endl;
1397     summary << "Check there are no extra headers or trailers: "
1398             << (checkNoExtraHeadersOrTrailers() ? "passed" : "FAILED") << std::endl;
1399     summary << "Check length from trailer: " << (checkLengthFromTrailer() ? "passed" : "FAILED") << std::endl;
1400     return summary.str();
1401   }
1402 }  // namespace sistrip