Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:11

0001 //-------------------------------------------------
0002 //
0003 //   Class: DTTM7FEDReader
0004 //
0005 //   L1 DT TwinMux Raw-to-Digi
0006 //
0007 //
0008 //
0009 //   Author :
0010 //   C. F. Bedoya  - CIEMAT
0011 //   G. Codispoti -- INFN Bologna
0012 //   J. Pazzini   -- INFN Padova
0013 //   C. Heidemann -- RWTH Aachen
0014 //
0015 //
0016 //   Changes & Notes:
0017 //   This version is able to unpack the normal and the zero suppressed data
0018 //   For storing the additional info from the ud flag in the raw data and not changing the output data format of the unpacker, it will be stored as the sign to the station number for Phi In and Out segments. ud == 0 is stored as a positive station number, while ud==1 is stored as a negative station number. Use abs(station) to obtain the real station.
0019 //   This change is transparent to old data, too.
0020 //   The switch between old and new unpacker code is done by the firmware revision. If it >= 93 the new unpacker code is used, otherwise the old and unmodified code is used.
0021 //
0022 //--------------------------------------------------
0023 
0024 #include "FWCore/Framework/interface/ConsumesCollector.h"
0025 #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambPhContainer.h"
0026 #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h"
0027 #include "DataFormats/L1DTTrackFinder/interface/L1MuDTTrackContainer.h"
0028 
0029 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0030 #include "FWCore/Framework/interface/global/EDProducer.h"
0031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0032 #include "FWCore/Utilities/interface/InputTag.h"
0033 
0034 #include "DataFormats/Common/interface/Handle.h"
0035 #include "FWCore/Framework/interface/Event.h"
0036 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0037 #include "EventFilter/Utilities/interface/DTCRC.h"
0038 
0039 #include <iostream>
0040 #include <fstream>
0041 
0042 class L1TTwinMuxRawToDigi : public edm::global::EDProducer<> {
0043 public:
0044   /// Constructor
0045   L1TTwinMuxRawToDigi(const edm::ParameterSet& pset);
0046 
0047   /// Destructor
0048   ~L1TTwinMuxRawToDigi() override;
0049 
0050   /// Produce digis out of raw data
0051   void produce(edm::StreamID, edm::Event& e, const edm::EventSetup& c) const override;
0052 
0053   /// Generate and fill FED raw data for a full event
0054   bool fillRawData(edm::Event& e,
0055                    L1MuDTChambPhContainer::Phi_Container& phi_data,
0056                    L1MuDTChambThContainer::The_Container& the_data,
0057                    L1MuDTChambPhContainer::Phi_Container& phi_out_data) const;
0058 
0059   void processFed(int twinmuxfed,
0060                   int wheel,
0061                   std::array<short, 12> const& twinMuxAmcSec,
0062                   edm::Handle<FEDRawDataCollection> data,
0063                   L1MuDTChambPhContainer::Phi_Container& phi_data,
0064                   L1MuDTChambThContainer::The_Container& the_data,
0065                   L1MuDTChambPhContainer::Phi_Container& phi_out_data) const;
0066 
0067 private:
0068   bool debug_;
0069   size_t nfeds_;
0070   edm::InputTag DTTM7InputTag_;
0071   std::vector<int> feds_;
0072   std::vector<int> wheels_;
0073   std::vector<long long int> amcsecmap_;
0074   std::vector<std::array<short, 12> > amcsec_;
0075 
0076   // utilities
0077   inline unsigned char* readline(unsigned char* lineFED, int& lines, long& dataWord) const {
0078     dataWord = *((long*)lineFED);
0079     lineFED += 8;
0080     ++lines;
0081     return lineFED;
0082   }
0083 
0084   edm::InputTag getDTTM7InputTag() const { return DTTM7InputTag_; }
0085 
0086   edm::EDGetTokenT<FEDRawDataCollection> Raw_token;
0087 
0088   int normBx(int bx_, int bxCnt_) const;
0089   int radAngConversion(int radAng_) const;
0090   int benAngConversion(int benAng_) const;
0091 };
0092 
0093 L1TTwinMuxRawToDigi::L1TTwinMuxRawToDigi(const edm::ParameterSet& pset)
0094     :
0095 
0096       debug_(pset.getUntrackedParameter<bool>("debug", false)),
0097       nfeds_(0),
0098       DTTM7InputTag_(pset.getParameter<edm::InputTag>("DTTM7_FED_Source")),
0099       feds_(pset.getUntrackedParameter<std::vector<int> >("feds", std::vector<int>())),
0100       wheels_(pset.getUntrackedParameter<std::vector<int> >("wheels", std::vector<int>())),
0101       amcsecmap_(pset.getUntrackedParameter<std::vector<long long int> >("amcsecmap", std::vector<long long int>()))
0102 
0103 {
0104   produces<L1MuDTChambPhContainer>("PhIn").setBranchAlias("PhIn");
0105   produces<L1MuDTChambThContainer>("ThIn").setBranchAlias("ThIn");
0106   produces<L1MuDTChambPhContainer>("PhOut").setBranchAlias("PhOut");
0107 
0108   Raw_token = consumes<FEDRawDataCollection>(DTTM7InputTag_);
0109 
0110   nfeds_ = feds_.size();
0111 
0112   if (nfeds_ != wheels_.size())
0113     throw cms::Exception("TwinMux_unpacker") << "Configuration file error. Size of \'wheels\' and \'feds\' differs.\n";
0114 
0115   if (amcsecmap_.size() != wheels_.size())
0116     throw cms::Exception("TwinMux_unpacker")
0117         << "Configuration file error. Size of \'wheels\' and \'amcsecmap\' differs.\n";
0118 
0119   for (size_t wh_i = 0; wh_i < amcsecmap_.size(); ++wh_i) {
0120     std::array<short, 12> whmap;
0121     for (size_t amc_i = 1; amc_i < 13; ++amc_i) {
0122       short shift = (12 - amc_i) * 4;
0123       whmap[amc_i - 1] = (amcsecmap_[wh_i] >> shift) & 0xF;
0124     }
0125     amcsec_.push_back(whmap);
0126   }
0127 }
0128 
0129 L1TTwinMuxRawToDigi::~L1TTwinMuxRawToDigi() {}
0130 
0131 void L1TTwinMuxRawToDigi::produce(edm::StreamID, edm::Event& e, const edm::EventSetup& c) const {
0132   std::unique_ptr<L1MuDTChambPhContainer> TM7phi_product(new L1MuDTChambPhContainer);
0133   std::unique_ptr<L1MuDTChambThContainer> TM7the_product(new L1MuDTChambThContainer);
0134   std::unique_ptr<L1MuDTChambPhContainer> TM7phi_out_product(new L1MuDTChambPhContainer);
0135 
0136   L1MuDTChambPhContainer::Phi_Container phi_data;
0137   L1MuDTChambThContainer::The_Container the_data;
0138   L1MuDTChambPhContainer::Phi_Container phi_out_data;
0139 
0140   if (!fillRawData(e, phi_data, the_data, phi_out_data))
0141     return;
0142 
0143   TM7phi_product->setContainer(phi_data);
0144   TM7the_product->setContainer(the_data);
0145   TM7phi_out_product->setContainer(phi_out_data);
0146 
0147   e.put(std::move(TM7phi_product), "PhIn");
0148   e.put(std::move(TM7the_product), "ThIn");
0149   e.put(std::move(TM7phi_out_product), "PhOut");
0150 }
0151 
0152 bool L1TTwinMuxRawToDigi::fillRawData(edm::Event& e,
0153                                       L1MuDTChambPhContainer::Phi_Container& phi_data,
0154                                       L1MuDTChambThContainer::The_Container& the_data,
0155                                       L1MuDTChambPhContainer::Phi_Container& phi_out_data) const {
0156   edm::Handle<FEDRawDataCollection> data;
0157   e.getByToken(Raw_token, data);
0158 
0159   for (size_t w_i = 0; w_i < nfeds_; ++w_i) {
0160     processFed(feds_[w_i], wheels_[w_i], amcsec_[w_i], data, phi_data, the_data, phi_out_data);
0161   }
0162 
0163   return true;
0164 }
0165 
0166 int L1TTwinMuxRawToDigi::normBx(int bx_, int bxCnt_) const {
0167   int bxNorm_ = bx_ - bxCnt_;
0168   if (abs(bxNorm_) < 3000)
0169     return bxNorm_;
0170 
0171   if (bxNorm_ > 0)
0172     return bxNorm_ - 3564;
0173   if (bxNorm_ < 0)
0174     return bxNorm_ + 3564;
0175 
0176   return -99;
0177 }
0178 
0179 int L1TTwinMuxRawToDigi::radAngConversion(int radAng_) const {
0180   if (radAng_ > 2047)
0181     return radAng_ - 4096;
0182 
0183   return radAng_;
0184 }
0185 
0186 int L1TTwinMuxRawToDigi::benAngConversion(int benAng_) const {
0187   if (benAng_ > 511)
0188     return benAng_ - 1024;
0189 
0190   return benAng_;
0191 }
0192 
0193 void L1TTwinMuxRawToDigi::processFed(int twinMuxFed,
0194                                      int twinMuxWheel,
0195                                      std::array<short, 12> const& twinMuxAmcSec,
0196                                      edm::Handle<FEDRawDataCollection> data,
0197                                      L1MuDTChambPhContainer::Phi_Container& phiSegments,
0198                                      L1MuDTChambThContainer::The_Container& theSegments,
0199                                      L1MuDTChambPhContainer::Phi_Container& phioutSegments) const {
0200   const unsigned int fw_rev_with_zerosupression =
0201       93;  // put the correct Firmware Revision of the first version with zerosuppression
0202   int previous_selector = -100;
0203   /// Container
0204   std::vector<long> DTTM7WordContainer;
0205 
0206   /// Debug
0207   std::ofstream logfile;
0208   if (debug_) {
0209     std::ostringstream fname;
0210     fname << "eventDump_" << twinMuxFed << ".txt";
0211     logfile.open(fname.str());
0212   }
0213 
0214   /// Header
0215   FEDRawData TM7data = data->FEDData(twinMuxFed);
0216   if (TM7data.size() == 0)
0217     return;
0218 
0219   /// Variables
0220   unsigned char* lineFED = TM7data.data();
0221   int nline = 0;  // counting already include header
0222   long dataWord = 0;
0223   int newCRC = 0xFFFF;
0224 
0225   ///--> Header - line 1 [must start with 0x5]
0226   lineFED = readline(lineFED, nline, dataWord);
0227   dt_crc::calcCRC(dataWord, newCRC);
0228 
0229   int TM7fedId = (dataWord >> 8) & 0xFFF;  // positions 8 -> 19
0230   /*** NOT UNPACKED  
0231   int bunchCnt = ( dataWord >> 20 ) & 0xFFF;  // positions 20 -> 31
0232   int eventCnt = ( dataWord >> 32 ) & 0xFFFFFF;  // positions 32 -> 55
0233   ***/
0234   int BOEevTy = (dataWord >> 60) & 0xF;  // positions 60 -> 63
0235 
0236   int linecounter = 0;
0237   if (debug_)
0238     logfile << '[' << ++linecounter << "]\t" << std::hex << dataWord << std::dec << "\t|\t"
0239             << "BOEevTy " << BOEevTy << '\t' << "TM7fedId " << TM7fedId << '\n';
0240 
0241   if ((BOEevTy != 0x5) || (TM7fedId != twinMuxFed)) {
0242     edm::LogWarning("TwinMux_unpacker") << "Not a TM7 of FED " << twinMuxFed << " header " << std::hex << dataWord;
0243     return;
0244   }
0245 
0246   ///--> Header - line 2
0247   lineFED = readline(lineFED, nline, dataWord);
0248   dt_crc::calcCRC(dataWord, newCRC);
0249 
0250   std::map<int, int> AMCsizes;
0251   /*** NOT UNPACKED  
0252   int orbit = ( dataWord >> 4 ) & 0xFFFFFFFF;  // positions 4 -> 35
0253   ***/
0254   int nAMC = (dataWord >> 52) & 0xF;  // positions 52 -> 55
0255 
0256   if (debug_)
0257     logfile << '[' << ++linecounter << "]\t" << std::hex << dataWord << std::dec << "\t|\t"
0258             << "nAMC " << nAMC << '\n';
0259 
0260   ///--> AMC - line 3 to 3+nAMC
0261   for (int j = 0; j < nAMC; ++j) {
0262     lineFED = readline(lineFED, nline, dataWord);
0263     dt_crc::calcCRC(dataWord, newCRC);
0264 
0265     int AMCno = (dataWord >> 16) & 0xF;  // positions 16 -> 19
0266     /*** NOT UNPACKED  
0267     int TM7boardID = dataWord & 0xFFFF;  // positions 0 -> 15
0268     int bulkno = (dataWord >> 20 ) & 0xFF;  // positions 20 -> 27
0269     ***/
0270     if ((AMCno < 1) || (AMCno > 12)) {
0271       edm::LogWarning("TwinMux_unpacker") << "AMCnumber " << std::dec << AMCno << " out of range (1-12)";
0272       return;
0273     }
0274 
0275     AMCsizes[AMCno] = (dataWord >> 32) & 0xFFFFFF;  // positions 32 -> 55
0276 
0277     if (debug_)
0278       logfile << '[' << ++linecounter << "]\t" << std::hex << dataWord << std::dec << "\t|\t"
0279               << "AMCsizes[" << AMCno << "] " << AMCsizes[AMCno] << std::dec << '\n';
0280   }
0281 
0282   ///--> Store payloads
0283   std::map<int, int>::iterator AMCiterator = AMCsizes.begin();
0284   std::map<int, int>::iterator AMCitend = AMCsizes.end();
0285   for (; AMCiterator != AMCitend; ++AMCiterator) {
0286     for (int k = 0; k < AMCiterator->second; ++k) {
0287       lineFED = readline(lineFED, nline, dataWord);
0288       dt_crc::calcCRC(dataWord, newCRC);
0289 
0290       DTTM7WordContainer.push_back(dataWord);
0291     }
0292   }
0293 
0294   ///--> Trailer - line 1
0295   lineFED = readline(lineFED, nline, dataWord);
0296   dt_crc::calcCRC(dataWord, newCRC);
0297 
0298   ///--> Trailer - line 2 [must start with 0xA]
0299 
0300   lineFED = readline(lineFED, nline, dataWord);
0301   dt_crc::calcCRC(dataWord & 0xFFFFFFFF0000FFFF, newCRC);
0302 
0303   ///--> AMC trailer - line 2
0304   int chkEOE = (dataWord >> 60) & 0xF;        // positions 60 -> 63
0305   int CRC = (dataWord >> 16) & 0xFFFF;        // positions 17 ->32
0306   int evtLgth = (dataWord >> 32) & 0xFFFFFF;  // positions 33 ->56
0307 
0308   if (chkEOE != 0xA) {
0309     edm::LogWarning("TwinMux_unpacker") << "AMC block closing line " << std::hex << dataWord << std::dec
0310                                         << " does not start with 0xA";
0311     return;
0312   }
0313 
0314   if (debug_)
0315     logfile << "\tevtLgth " << std::hex << evtLgth << "\tCRC " << CRC << std::dec << '\n';
0316 
0317   if (nline != evtLgth) {
0318     edm::LogWarning("TwinMux_unpacker") << "Number of words read " << std::dec << nline << " and event length "
0319                                         << std::dec << evtLgth << " differ ";
0320     return;
0321   }
0322 
0323   if (newCRC != CRC) {
0324     edm::LogWarning("TwinMux_unpacker") << "Calculated CRC " << std::hex << newCRC << " differs from CRC in trailer "
0325                                         << std::hex << CRC;
0326     return;
0327   }
0328 
0329   // --> Analyze event
0330   std::vector<long>::iterator DTTM7iterator = DTTM7WordContainer.begin();
0331   std::vector<long>::iterator DTTM7itend = DTTM7WordContainer.end();
0332 
0333   int lcounter = 0;
0334   for (; DTTM7iterator != DTTM7itend; ++DTTM7iterator) {
0335     dataWord = (*DTTM7iterator);
0336     int dataLenght = (dataWord & 0xFFFFF);     // positions 0 -> 19
0337     int bxCounter = (dataWord >> 20) & 0xFFF;  // positions 20 -> 31
0338     int event = (dataWord >> 32) & 0xFFFFFF;   // positions 32 -> 55
0339     int AMC_ID = (dataWord >> 56) & 0xF;       // positions 56 -> 59
0340     int control = (dataWord >> 60) & 0xF;      // positions 59 -> 63
0341     int wheel = twinMuxWheel;
0342 
0343     if ((AMC_ID < 1) or (AMC_ID > 12)) {
0344       edm::LogWarning("TwinMux_unpacker") << "%%%%%% AMC_ID OUT OF RANGE \n"
0345                                           << " TM7fedId " << TM7fedId << " AMC_ID " << AMC_ID;
0346       break;
0347     }
0348 
0349     int sector = twinMuxAmcSec[AMC_ID - 1];
0350 
0351     if ((sector < 1) or (sector > 12)) {
0352       if (sector != 15)
0353         edm::LogWarning("TwinMux_unpacker")
0354             << "%%%%%% VALID AMC_ID POINTS TO SECTOR OUT OF RANGE \n"
0355             << " TM7fedId " << TM7fedId << " AMC_ID " << AMC_ID << " wheel " << wheel << " sector " << sector;
0356       break;
0357     }
0358 
0359     if (debug_)
0360       logfile << '[' << ++lcounter << "]\t" << std::hex << dataWord << std::dec << "\t|\t"
0361               << "AMC_ID " << AMC_ID << '\t' << "control " << control << '\t' << "event " << event << '\t'
0362               << "bxCounter " << bxCounter << '\t' << "dataLenght " << dataLenght << '\n';
0363 
0364     ++DTTM7iterator;  // User word empty  /// ==>> increment 2
0365     if (DTTM7iterator == DTTM7itend) {
0366       LogDebug("TwinMux_unpacker") << "TRAILING WORD AS A PAYLOAD END in FED " << std::hex << TM7fedId << std::hex
0367                                    << dataWord << std::dec << " [it pos " << int(DTTM7iterator - DTTM7itend) << " ]";
0368       break;
0369     }
0370 
0371     dataWord = (*DTTM7iterator);
0372     unsigned int firmware_rev = (dataWord >> 7) & 0x1FF;
0373     int boardID = (dataWord & 0xFFFF);      // positions  0 -> 15
0374     int orbit = (dataWord >> 16) & 0xFFFF;  // positions 15 -> 32
0375 
0376     if (DTTM7iterator == DTTM7itend) {
0377       edm::LogWarning("TwinMux_unpacker")
0378           << "%%%%%% AMC_ID " << AMC_ID << " control " << control << " event " << event << " bxCounter " << bxCounter
0379           << " size " << dataLenght << " orbit " << orbit << " board " << boardID << " AMCsizes " << AMCsizes[AMC_ID]
0380           << " it pos " << int(DTTM7iterator - DTTM7itend);
0381       break;
0382     }
0383 
0384     if (debug_)
0385       logfile << '[' << ++lcounter << "]\t" << std::hex << dataWord << std::dec << "\t|\t"
0386               << " orbit " << orbit << " board " << boardID << '\n';
0387 
0388     int AMCsize = AMCsizes[AMC_ID] - 1;  /// do not consider the trailer
0389     int bxID = 99;
0390     int bc0 = -99;
0391     int bxNr = -99;
0392 
0393     /// 2 words already read, last removed because trailer with CRC
0394     for (int tm7eventsize = 2; tm7eventsize < AMCsize; ++tm7eventsize) {
0395       ++DTTM7iterator;  /// ==>> increment 3
0396       if (DTTM7iterator == DTTM7itend) {
0397         edm::LogWarning("TwinMux_unpacker") << "UNEXPECTED END OF PAYLOAD INSIDE CHAMBER DESCRIPTION"
0398                                             << " [it pos " << int(DTTM7iterator - DTTM7itend) << " ]";
0399         break;
0400       }
0401 
0402       long dataWordSub = (*DTTM7iterator);
0403       int selector = (dataWordSub >> 60) & 0xF;  // positions 60 -> 63
0404 
0405       if (firmware_rev >= fw_rev_with_zerosupression) {  // zerosuppressed data unpacking
0406         if (selector == 0xC) {                           /// BX info + theta info word
0407 
0408           bc0 = (dataWordSub >> 59) & 0x1;  // position 59
0409           /*** NOT UNPACKED  
0410             int L1A = ( dataWordSub >> 58) & 0x1;    // position 58
0411             ***/
0412           int bxOffset = (dataWordSub >> 48) & 0x3F;  // positions 48 -> 53
0413           /// Two's complement conversion
0414           /// Important: here value 0x20 has been treated as -32 when in fact it is an error code
0415           /// denoting incorrect readout window configuration, but the case should really not happen
0416           bxNr = bxOffset < 32 ? bxOffset : bxOffset - 64;
0417 
0418           //eta info
0419 
0420           int posBTI[7], qualBTI[7];
0421 
0422           int mb3_eta = (dataWordSub & 0xFF);           // positions  0 -> 7
0423           int mb3_eta_HQ = (dataWordSub >> 8) & 0xFF;   // positions  8 -> 15
0424           int mb2_eta = (dataWordSub >> 16) & 0xFF;     // positions 16 -> 23
0425           int mb2_eta_HQ = (dataWordSub >> 24) & 0xFF;  // positions 24 -> 31
0426           int mb1_eta = (dataWordSub >> 32) & 0xFF;     // positions 32 -> 39
0427           int mb1_eta_HQ = (dataWordSub >> 40) & 0xFF;  // positions 40 -> 47
0428 
0429           //MB1
0430           for (int i = 0; i <= 5; i++) {
0431             posBTI[i] = (mb1_eta >> i) & 0x01;
0432             qualBTI[i] = (mb1_eta_HQ >> i) & 0x01;
0433           }
0434           posBTI[6] = (((mb1_eta >> 6) & 0x01) || ((mb1_eta >> 7) & 0x01));
0435           qualBTI[6] = (((mb1_eta_HQ >> 6) & 0x01) || ((mb1_eta_HQ >> 7) & 0x01));
0436 
0437           theSegments.push_back(L1MuDTChambThDigi(bxNr, wheel, sector - 1, 1, posBTI, qualBTI));
0438 
0439           // posBTI and qualBTI are reused!
0440 
0441           //MB2
0442           for (int i = 0; i <= 5; i++) {
0443             posBTI[i] = (mb2_eta >> i) & 0x01;
0444             qualBTI[i] = (mb2_eta_HQ >> i) & 0x01;
0445           }
0446           posBTI[6] = ((mb2_eta >> 6) & 0x01) || ((mb2_eta >> 7) & 0x01);
0447           qualBTI[6] = ((mb2_eta_HQ >> 6) & 0x01) || ((mb2_eta_HQ >> 7) & 0x01);
0448 
0449           theSegments.push_back(L1MuDTChambThDigi(bxNr, wheel, sector - 1, 2, posBTI, qualBTI));
0450 
0451           //MB3
0452           for (int i = 0; i <= 5; i++) {
0453             posBTI[i] = (mb3_eta >> i) & 0x01;
0454             qualBTI[i] = (mb3_eta_HQ >> i) & 0x01;
0455           }
0456           posBTI[6] = ((mb3_eta >> 6) & 0x01) || ((mb3_eta >> 7) & 0x01);
0457           qualBTI[6] = ((mb3_eta_HQ >> 6) & 0x01) || ((mb3_eta_HQ >> 7) & 0x01);
0458 
0459           theSegments.push_back(L1MuDTChambThDigi(bxNr, wheel, sector - 1, 3, posBTI, qualBTI));
0460 
0461           if (debug_)
0462             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t bx info word\t"
0463                     << "bxOffset " << bxOffset << '\t' << "bc0  " << bc0 << '\t' << "mb1_eta " << mb1_eta << '\t'
0464                     << "mb2_eta " << mb2_eta << '\t' << "mb3_eta " << mb3_eta << '\t' << "mb1_eta_HQ " << mb1_eta_HQ
0465                     << '\t' << "mb2_eta_HQ " << mb2_eta_HQ << '\t' << "mb3_eta_HQ " << mb3_eta_HQ << '\n';
0466 
0467         }  /// BX info + theta info word
0468 
0469         else if (selector >= 1 && selector <= 4) {  ///Phi info word. MBx determined by selector 0x01 - 0x04
0470 
0471           int out_phi = (dataWordSub >> 0) & 0xFFF;    // positions 0 -> 11
0472           int out_phib = (dataWordSub >> 12) & 0x3FF;  // positions 12 -> 21
0473           int out_qual = (dataWordSub >> 22) & 0x7;    // positions 22 -> 24
0474           int out_q3 = (dataWordSub >> 25) & 0x1;      // positions 25
0475           int out_q4 = (dataWordSub >> 26) & 0x1;      // positions 26
0476           int out_updown = (dataWordSub >> 27) & 0x1;  // positions 27
0477           int out_ts2tag = (dataWordSub >> 28) & 0x1;  // positions 28
0478           /*** NOT UNPACKED  
0479             int out_parity = ( dataWordSub >> 29) & 0x1;    // positions 29
0480             ***/
0481           int in_phi = (dataWordSub >> 30) & 0xFFF;   // positions  30 -> 41
0482           int in_phib = (dataWordSub >> 42) & 0x3FF;  // positions 42 -> 51
0483           int in_qual = (dataWordSub >> 52) & 0x7;    // positions 52 -> 54
0484           int in_updown = (dataWordSub >> 57) & 0x1;  // positions 57
0485           int in_ts2tag = (dataWordSub >> 58) & 0x1;  // positions 58
0486           /*** NOT UNPACKED  
0487             int in_parity = ( dataWordSub >> 59) & 0x1;    // positions 59
0488             ***/
0489 
0490           int in_phi_conv = radAngConversion(in_phi);
0491           int in_phib_conv = benAngConversion(in_phib);
0492           int out_phi_conv = radAngConversion(out_phi);
0493           int out_phib_conv = benAngConversion(out_phib);
0494 
0495           if (previous_selector != selector) {  // first track
0496             if (in_qual != 7) {
0497               phiSegments.push_back(L1MuDTChambPhDigi(bxNr,
0498                                                       wheel,
0499                                                       sector - 1,
0500                                                       selector,
0501                                                       in_phi_conv,
0502                                                       in_phib_conv,
0503                                                       in_qual,
0504                                                       in_ts2tag + in_updown * 2,
0505                                                       bxCounter));
0506             }
0507             if (out_qual != 7) {
0508               phioutSegments.push_back(L1MuDTChambPhDigi(bxNr,
0509                                                          wheel,
0510                                                          sector - 1,
0511                                                          selector,
0512                                                          out_phi_conv,
0513                                                          out_phib_conv,
0514                                                          out_qual,
0515                                                          out_ts2tag + out_updown * 2,
0516                                                          bxCounter,
0517                                                          out_q3 + 2 * out_q4));
0518             }
0519           } else {  // currently no seperation between first/second in data, keep it for possible later fix
0520             // second track
0521             if (in_qual != 7) {
0522               phiSegments.push_back(L1MuDTChambPhDigi(bxNr,
0523                                                       wheel,
0524                                                       sector - 1,
0525                                                       selector,
0526                                                       in_phi_conv,
0527                                                       in_phib_conv,
0528                                                       in_qual,
0529                                                       in_ts2tag + in_updown * 2,
0530                                                       bxCounter));
0531             }
0532 
0533             if (out_qual != 7) {
0534               phioutSegments.push_back(L1MuDTChambPhDigi(bxNr,
0535                                                          wheel,
0536                                                          sector - 1,
0537                                                          selector,
0538                                                          out_phi_conv,
0539                                                          out_phib_conv,
0540                                                          out_qual,
0541                                                          out_ts2tag + out_updown * 2,
0542                                                          bxCounter,
0543                                                          out_q3 + 2 * out_q4));
0544             }
0545           }
0546           if (debug_)
0547             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t|\t"
0548                     << "in_ts2tag " << in_ts2tag << '\t' << "in_updown " << in_updown << '\t' << "in_qual " << in_qual
0549                     << '\t' << "in_phib " << in_phib_conv << '\t' << "in_phi " << in_phi_conv << '\t' << "out_ts2tag "
0550                     << out_ts2tag << '\t' << "out_updown " << out_updown << '\t' << "out_qual " << out_qual << '\t'
0551                     << "out_q3_out " << out_q3 << '\t' << "out_q4_out " << out_q4 << '\t' << "out_phib "
0552                     << out_phib_conv << '\t' << "out_phi " << out_phi_conv << '\t' << "2nd track "
0553                     << ((previous_selector == selector) ? 1 : 0) << '\n';
0554         }  ///Phi info word.
0555 
0556         else if (selector == 0x9 || selector == 0xE) {  //RPC word
0557 
0558           LogDebug("TwinMux_unpacker") << "RPC WORD [" << std::dec << tm7eventsize << "] : " << std::hex << dataWordSub
0559                                        << std::dec << " it pos " << int(DTTM7iterator - DTTM7itend);
0560 
0561           if (debug_)
0562             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t RPC WORD\n";
0563 
0564         }  //RPC word
0565 
0566         else if (selector == 0x6) {  //HO word
0567 
0568           LogDebug("TwinMux_unpacker") << "HO WORD [" << std::dec << tm7eventsize << "] : " << std::hex << dataWordSub
0569                                        << std::dec << " it pos " << int(DTTM7iterator - DTTM7itend);
0570 
0571           if (debug_)
0572             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t HO WORD\n";
0573 
0574         }  //HO word
0575 
0576         else if (selector == 0xF) {  //ERROR word
0577 
0578           LogDebug("TwinMux_unpacker") << "ERROR WORD [" << std::dec << tm7eventsize << "] : " << std::hex
0579                                        << dataWordSub << std::dec << " it pos " << int(DTTM7iterator - DTTM7itend);
0580 
0581           if (debug_)
0582             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t ERROR WORD\n";
0583         }  //ERROR word
0584 
0585         else {  //unkown word
0586 
0587           LogDebug("TwinMux_unpacker") << "UNKNOWN WORD received " << std::hex << dataWordSub << " in FED " << std::hex
0588                                        << TM7fedId;
0589 
0590           if (debug_)
0591             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t UNKNOWN WORD\n";
0592         }
0593         previous_selector = selector;  // store selector to identify 2nd track
0594       } else {
0595         // normal data unpacking below
0596         if (selector == 0x4) {  //TSC word
0597 
0598           bxID = (dataWordSub >> 48) & 0xFFF;  // positions 48 -> 60
0599           bc0 = (dataWordSub >> 22) & 0x1;     // positions 22 -> 23
0600           bxNr = normBx(bxID, bxCounter);      /// bx normalized to the bxcounter
0601 
0602           if (debug_)
0603             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t TSC WORD\t"
0604                     << "bxID " << bxID << '\t' << "bc0  " << bc0 << '\n';
0605 
0606         }  //TSC WORD
0607 
0608         else if (selector == 0x1) {  //MB1/2 word
0609 
0610           int mb2_phi = (dataWordSub & 0xFFF);         // positions  0 -> 11
0611           int mb2_phib = (dataWordSub >> 12) & 0x3FF;  // positions 12 -> 21
0612           int mb2_qual = (dataWordSub >> 22) & 0x7;    // positions 22 -> 24
0613           int mb2_ts2tag = (dataWordSub >> 28) & 0x1;  // positions 28
0614           /*** NOT UNPACKED  
0615             int mb2_parity = ( dataWordSub >> 29) & 0x1;    // positions 29
0616             ***/
0617 
0618           int mb1_phi = (dataWordSub >> 30) & 0xFFF;   // positions 30 -> 41
0619           int mb1_phib = (dataWordSub >> 42) & 0x3FF;  // positions 42 -> 51
0620           int mb1_qual = (dataWordSub >> 52) & 0x7;    // positions 52 -> 54
0621           int mb1_ts2tag = (dataWordSub >> 58) & 0x1;  // positions 58
0622           /*** NOT UNPACKED  
0623             int mb1_parity = ( dataWordSub >> 59 ) &0x1;    // positions 59
0624             ***/
0625 
0626           int mb1_phi_conv = radAngConversion(mb1_phi);
0627           int mb1_phib_conv = benAngConversion(mb1_phib);
0628 
0629           int mb2_phi_conv = radAngConversion(mb2_phi);
0630           int mb2_phib_conv = benAngConversion(mb2_phib);
0631 
0632           phiSegments.push_back(L1MuDTChambPhDigi(
0633               bxNr, wheel, sector - 1, 1, mb1_phi_conv, mb1_phib_conv, mb1_qual, mb1_ts2tag, bxCounter, -1));
0634           phiSegments.push_back(L1MuDTChambPhDigi(
0635               bxNr, wheel, sector - 1, 2, mb2_phi_conv, mb2_phib_conv, mb2_qual, mb2_ts2tag, bxCounter, -1));
0636 
0637           if (debug_)
0638             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t|\t"
0639                     << "mb1_ts2tag " << mb1_ts2tag << '\t' << "mb1_qual " << mb1_qual << '\t' << "mb1_phib "
0640                     << mb1_phib_conv << '\t' << "mb1_phi " << mb1_phi_conv << '\t' << "mb2_ts2tag " << mb2_ts2tag
0641                     << '\t' << "mb2_qual " << mb2_qual << '\t' << "mb2_phib " << mb2_phib_conv << '\t' << "mb2_phi "
0642                     << mb2_phi_conv << '\n';
0643         }  //MB1/2 word
0644 
0645         else if (selector == 0x2) {
0646           int mb4_phi = (dataWordSub & 0xFFF);         // positions  0 -> 11
0647           int mb4_phib = (dataWordSub >> 12) & 0x3FF;  // positions 12 -> 21
0648           int mb4_qual = (dataWordSub >> 22) & 0x7;    // positions 22 -> 24
0649           int mb4_ts2tag = (dataWordSub >> 28) & 0x1;  // positions 28
0650           /*** NOT UNPACKED  
0651             int mb4_parity = ( dataWordSub >> 29) & 0x1;    // positions 29
0652             ***/
0653 
0654           int mb3_phi = (dataWordSub >> 30) & 0xFFF;   // positions 30 -> 41
0655           int mb3_phib = (dataWordSub >> 42) & 0x3FF;  // positions 42 -> 51
0656           int mb3_qual = (dataWordSub >> 52) & 0x7;    // positions 52 -> 54
0657           int mb3_ts2tag = (dataWordSub >> 58) & 0x1;  // positions 58
0658           /*** NOT UNPACKED  
0659             int mb3_parity = ( dataWordSub >> 59 ) &0x1;    // positions 59
0660             ***/
0661 
0662           int mb3_phi_conv = radAngConversion(mb3_phi);
0663           int mb3_phib_conv = benAngConversion(mb3_phib);
0664 
0665           int mb4_phi_conv = radAngConversion(mb4_phi);
0666           int mb4_phib_conv = benAngConversion(mb4_phib);
0667 
0668           phiSegments.push_back(L1MuDTChambPhDigi(
0669               bxNr, wheel, sector - 1, 3, mb3_phi_conv, mb3_phib_conv, mb3_qual, mb3_ts2tag, bxCounter, -1));
0670           phiSegments.push_back(L1MuDTChambPhDigi(
0671               bxNr, wheel, sector - 1, 4, mb4_phi_conv, mb4_phib_conv, mb4_qual, mb4_ts2tag, bxCounter, -1));
0672 
0673           if (debug_)
0674             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t|\t"
0675                     << "mb3_ts2tag " << mb3_ts2tag << '\t' << "mb3_qual " << mb3_qual << '\t' << "mb3_phib "
0676                     << mb3_phib_conv << '\t' << "mb3_phi " << mb3_phi_conv << '\t' << "mb4_ts2tag " << mb4_ts2tag
0677                     << '\t' << "mb4_qual " << mb4_qual << '\t' << "mb4_phib " << mb4_phib_conv << '\t' << "mb4_phi "
0678                     << mb4_phi_conv << '\n';
0679 
0680         }  //MB3/4 word
0681 
0682         else if (selector == 0x3) {  //etha word
0683 
0684           int posBTI[7], qualBTI[7];
0685 
0686           int mb3_eta = (dataWordSub & 0xFF);        // positions  0 -> 7
0687           int mb2_eta = (dataWordSub >> 16) & 0xFF;  // positions 16 -> 23
0688           int mb1_eta = (dataWordSub >> 40) & 0xFF;  // positions 40 -> 47
0689 
0690           int mb3_eta_HQ = (dataWordSub >> 8) & 0xFF;   // positions  8 -> 15
0691           int mb2_eta_HQ = (dataWordSub >> 32) & 0xFF;  // positions 32 -> 39
0692           int mb1_eta_HQ = (dataWordSub >> 48) & 0xFF;  // positions 48 -> 55
0693 
0694           if (debug_)
0695             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t|\t"
0696                     << "mb1_eta " << mb1_eta << '\t' << "mb2_eta " << mb2_eta << '\t' << "mb3_eta " << mb3_eta << '\t'
0697                     << "mb1_eta_HQ " << mb1_eta_HQ << '\t' << "mb2_eta_HQ " << mb2_eta_HQ << '\t' << "mb3_eta_HQ "
0698                     << mb3_eta_HQ << '\n';
0699 
0700           //MB1
0701           posBTI[0] = (mb1_eta & 0x01);
0702           posBTI[1] = ((mb1_eta & 0x02) >> 1);
0703           posBTI[2] = ((mb1_eta & 0x04) >> 2);
0704           posBTI[3] = ((mb1_eta & 0x08) >> 3);
0705           posBTI[4] = ((mb1_eta & 0x10) >> 4);
0706           posBTI[5] = ((mb1_eta & 0x20) >> 5);
0707           posBTI[6] = (((mb1_eta & 0x40) >> 6) || ((mb1_eta & 0x80) >> 7));
0708 
0709           qualBTI[0] = (mb1_eta_HQ & 0x01);
0710           qualBTI[1] = ((mb1_eta_HQ & 0x02) >> 1);
0711           qualBTI[2] = ((mb1_eta_HQ & 0x04) >> 2);
0712           qualBTI[3] = ((mb1_eta_HQ & 0x08) >> 3);
0713           qualBTI[4] = ((mb1_eta_HQ & 0x10) >> 4);
0714           qualBTI[5] = ((mb1_eta_HQ & 0x20) >> 5);
0715           qualBTI[6] = (((mb1_eta_HQ & 0x40) >> 6) || ((mb1_eta_HQ & 0x80) >> 7));
0716 
0717           theSegments.push_back(L1MuDTChambThDigi(bxNr, wheel, sector - 1, 1, posBTI, qualBTI));
0718 
0719           //MB2
0720           posBTI[0] = (mb2_eta & 0x01);
0721           posBTI[1] = ((mb2_eta & 0x02) >> 1);
0722           posBTI[2] = ((mb2_eta & 0x04) >> 2);
0723           posBTI[3] = ((mb2_eta & 0x08) >> 3);
0724           posBTI[4] = ((mb2_eta & 0x10) >> 4);
0725           posBTI[5] = ((mb2_eta & 0x20) >> 5);
0726           posBTI[6] = (((mb2_eta & 0x40) >> 6) || ((mb2_eta & 0x80) >> 7));
0727 
0728           qualBTI[0] = (mb2_eta_HQ & 0x01);
0729           qualBTI[1] = ((mb2_eta_HQ & 0x02) >> 1);
0730           qualBTI[2] = ((mb2_eta_HQ & 0x04) >> 2);
0731           qualBTI[3] = ((mb2_eta_HQ & 0x08) >> 3);
0732           qualBTI[4] = ((mb2_eta_HQ & 0x10) >> 4);
0733           qualBTI[5] = ((mb2_eta_HQ & 0x20) >> 5);
0734           qualBTI[6] = (((mb2_eta_HQ & 0x40) >> 6) || ((mb2_eta_HQ & 0x80) >> 7));
0735 
0736           theSegments.push_back(L1MuDTChambThDigi(bxNr, wheel, sector - 1, 2, posBTI, qualBTI));
0737 
0738           //MB3
0739           posBTI[0] = (mb3_eta & 0x01);
0740           posBTI[1] = ((mb3_eta & 0x02) >> 1);
0741           posBTI[2] = ((mb3_eta & 0x04) >> 2);
0742           posBTI[3] = ((mb3_eta & 0x08) >> 3);
0743           posBTI[4] = ((mb3_eta & 0x10) >> 4);
0744           posBTI[5] = ((mb3_eta & 0x20) >> 5);
0745           posBTI[6] = (((mb3_eta & 0x40) >> 6) || ((mb3_eta & 0x80) >> 7));
0746 
0747           qualBTI[0] = (mb3_eta_HQ & 0x01);
0748           qualBTI[1] = ((mb3_eta_HQ & 0x02) >> 1);
0749           qualBTI[2] = ((mb3_eta_HQ & 0x04) >> 2);
0750           qualBTI[3] = ((mb3_eta_HQ & 0x08) >> 3);
0751           qualBTI[4] = ((mb3_eta_HQ & 0x10) >> 4);
0752           qualBTI[5] = ((mb3_eta_HQ & 0x20) >> 5);
0753           qualBTI[6] = (((mb3_eta_HQ & 0x40) >> 6) || ((mb3_eta_HQ & 0x80) >> 7));
0754 
0755           theSegments.push_back(L1MuDTChambThDigi(bxNr, wheel, sector - 1, 3, posBTI, qualBTI));
0756 
0757         }  //etha word
0758 
0759         else if (selector == 0xB) {  //MB1/2 output word
0760 
0761           int mb2_phi = (dataWordSub & 0xFFF);         // positions  0 -> 11
0762           int mb2_phib = (dataWordSub >> 12) & 0x3FF;  // positions 12 -> 21
0763           int mb2_qual = (dataWordSub >> 22) & 0x7;    // positions 22 -> 24
0764           int mb2_q3 = (dataWordSub >> 25) & 0x1;      // positions 25
0765           int mb2_q4 = (dataWordSub >> 26) & 0x1;      // positions 26
0766           int mb2_ts2tag = (dataWordSub >> 28) & 0x1;  // positions 28
0767           /*** NOT UNPACKED  
0768             int mb2_parity = ( dataWordSub >> 29) & 0x1;    // positions 29
0769             ***/
0770 
0771           int mb1_phi = (dataWordSub >> 30) & 0xFFF;   // positions 30 -> 41
0772           int mb1_phib = (dataWordSub >> 42) & 0x3FF;  // positions 42 -> 51
0773           int mb1_qual = (dataWordSub >> 52) & 0x7;    // positions 52 -> 54
0774           int mb1_q3 = (dataWordSub >> 55) & 0x1;      // positions 55
0775           int mb1_q4 = (dataWordSub >> 56) & 0x1;      // positions 56
0776           int mb1_ts2tag = (dataWordSub >> 58) & 0x1;  // positions 58
0777           /*** NOT UNPACKED  
0778             int mb1_parity = ( dataWordSub >> 59 ) &0x1;    // positions 59
0779             ***/
0780 
0781           int mb1_phi_conv = radAngConversion(mb1_phi);
0782           int mb1_phib_conv = benAngConversion(mb1_phib);
0783 
0784           int mb2_phi_conv = radAngConversion(mb2_phi);
0785           int mb2_phib_conv = benAngConversion(mb2_phib);
0786 
0787           phioutSegments.push_back(L1MuDTChambPhDigi(bxNr,
0788                                                      wheel,
0789                                                      sector - 1,
0790                                                      1,
0791                                                      mb1_phi_conv,
0792                                                      mb1_phib_conv,
0793                                                      mb1_qual,
0794                                                      mb1_ts2tag,
0795                                                      bxCounter,
0796                                                      mb1_q3 + 2 * mb1_q4));
0797           phioutSegments.push_back(L1MuDTChambPhDigi(bxNr,
0798                                                      wheel,
0799                                                      sector - 1,
0800                                                      2,
0801                                                      mb2_phi_conv,
0802                                                      mb2_phib_conv,
0803                                                      mb2_qual,
0804                                                      mb2_ts2tag,
0805                                                      bxCounter,
0806                                                      mb2_q3 + 2 * mb2_q4));
0807 
0808           if (debug_)
0809             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t|\t"
0810                     << "mb1_ts2tag_out " << mb1_ts2tag << '\t' << "mb1_qual_out " << mb1_qual << '\t' << "mb1_q3_out "
0811                     << mb1_q3 << '\t' << "mb1_q4_out " << mb1_q4 << '\t' << "mb1_phib_out " << mb1_phib_conv << '\t'
0812                     << "mb1_phi_out " << mb1_phi_conv << '\t' << "mb2_ts2tag_out " << mb2_ts2tag << '\t'
0813                     << "mb2_qual_out " << mb2_qual << '\t' << "mb2_q3_out " << mb2_q3 << '\t' << "mb2_q4_out " << mb2_q4
0814                     << '\t' << "mb2_phib_out " << mb2_phib_conv << '\t' << "mb2_phi_out " << mb2_phi_conv << '\n';
0815 
0816         }  //MB1/2 output word
0817 
0818         else if (selector == 0xC) {  //MB3/4 output word
0819 
0820           int mb4_phi = (dataWordSub & 0xFFF);         // positions  0 -> 11
0821           int mb4_phib = (dataWordSub >> 12) & 0x3FF;  // positions 12 -> 21
0822           int mb4_qual = (dataWordSub >> 22) & 0x7;    // positions 22 -> 24
0823           int mb4_q3 = (dataWordSub >> 25) & 0x1;      // positions 25
0824           int mb4_q4 = (dataWordSub >> 26) & 0x1;      // positions 26
0825           int mb4_ts2tag = (dataWordSub >> 28) & 0x1;  // positions 28
0826           /*** NOT UNPACKED  
0827             int mb4_parity = ( dataWordSub >> 29) & 0x1;    // positions 29
0828             ***/
0829 
0830           int mb3_phi = (dataWordSub >> 30) & 0xFFF;   // positions 30 -> 41
0831           int mb3_phib = (dataWordSub >> 42) & 0x3FF;  // positions 42 -> 51
0832           int mb3_qual = (dataWordSub >> 52) & 0x7;    // positions 52 -> 54
0833           int mb3_q3 = (dataWordSub >> 55) & 0x1;      // positions 55
0834           int mb3_q4 = (dataWordSub >> 56) & 0x1;      // positions 56
0835           int mb3_ts2tag = (dataWordSub >> 58) & 0x1;  // positions 58
0836           /*** NOT UNPACKED  
0837             int mb3_parity = ( dataWordSub >> 59 ) &0x1;    // positions 59
0838             ***/
0839 
0840           int mb3_phi_conv = radAngConversion(mb3_phi);
0841           int mb3_phib_conv = benAngConversion(mb3_phib);
0842 
0843           int mb4_phi_conv = radAngConversion(mb4_phi);
0844           int mb4_phib_conv = benAngConversion(mb4_phib);
0845 
0846           phioutSegments.push_back(L1MuDTChambPhDigi(bxNr,
0847                                                      wheel,
0848                                                      sector - 1,
0849                                                      3,
0850                                                      mb3_phi_conv,
0851                                                      mb3_phib_conv,
0852                                                      mb3_qual,
0853                                                      mb3_ts2tag,
0854                                                      bxCounter,
0855                                                      mb3_q3 + 2 * mb3_q4));
0856           phioutSegments.push_back(L1MuDTChambPhDigi(bxNr,
0857                                                      wheel,
0858                                                      sector - 1,
0859                                                      4,
0860                                                      mb4_phi_conv,
0861                                                      mb4_phib_conv,
0862                                                      mb4_qual,
0863                                                      mb4_ts2tag,
0864                                                      bxCounter,
0865                                                      mb4_q3 + 2 * mb4_q4));
0866 
0867           if (debug_)
0868             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t|\t"
0869                     << "mb3_ts2tag_out " << mb3_ts2tag << '\t' << "mb3_qual_out " << mb3_qual << '\t' << "mb3_q3_out "
0870                     << mb3_q3 << '\t' << "mb3_q4_out " << mb3_q4 << '\t' << "mb3_phib_out " << mb3_phib_conv << '\t'
0871                     << "mb3_phi_out " << mb3_phi_conv << '\t' << "mb4_ts2tag_out " << mb4_ts2tag << '\t'
0872                     << "mb4_qual_out " << mb4_qual << '\t' << "mb4_q3_out " << mb4_q3 << '\t' << "mb4_q4_out " << mb4_q4
0873                     << '\t' << "mb4_phib_out " << mb4_phib_conv << '\t' << "mb4_phi_out " << mb4_phi_conv << '\n';
0874 
0875         }  //MB3/4 output word
0876 
0877         else if (selector == 0xD) {  //etha output word
0878 
0879           if (debug_)
0880             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t ETHA OUTPUT WORD\n";
0881 
0882         }  //etha output word
0883 
0884         else if (selector == 0x9 || selector == 0xE) {  //RPC word
0885 
0886           LogDebug("TwinMux_unpacker") << "RPC WORD [" << std::dec << tm7eventsize << "] : " << std::hex << dataWordSub
0887                                        << std::dec << " it pos " << int(DTTM7iterator - DTTM7itend);
0888 
0889           if (debug_)
0890             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t RPC WORD\n";
0891 
0892         }  //RPC word
0893 
0894         else if (selector == 0x6) {  //HO word
0895 
0896           LogDebug("TwinMux_unpacker") << "HO WORD [" << std::dec << tm7eventsize << "] : " << std::hex << dataWordSub
0897                                        << std::dec << " it pos " << int(DTTM7iterator - DTTM7itend);
0898 
0899           if (debug_)
0900             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t HO WORD\n";
0901 
0902         }  //HO word
0903 
0904         else if (selector == 0xF) {  //ERROR word
0905 
0906           LogDebug("TwinMux_unpacker") << "ERROR WORD [" << std::dec << tm7eventsize << "] : " << std::hex
0907                                        << dataWordSub << std::dec << " it pos " << int(DTTM7iterator - DTTM7itend);
0908 
0909           if (debug_)
0910             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t ERROR WORD\n";
0911         }  //ERROR word
0912 
0913         else {  //unkown word
0914 
0915           LogDebug("TwinMux_unpacker") << "UNKNOWN WORD received " << std::hex << dataWordSub << " in FED " << std::hex
0916                                        << TM7fedId;
0917 
0918           if (debug_)
0919             logfile << '[' << ++lcounter << "]\t" << std::hex << dataWordSub << std::dec << "\t UNKNOWN WORD\n";
0920         }
0921 
0922         if (DTTM7iterator == DTTM7itend)
0923           break;
0924       }
0925     }  //end of loop over AMCsize
0926 
0927     /// Trailer of payload with CRC
0928     ++DTTM7iterator;
0929 
0930     if (DTTM7iterator == DTTM7itend)
0931       break;
0932 
0933   }  // end for-loop container content
0934 
0935   return;
0936 }
0937 
0938 //define this as a plug-in
0939 #include "FWCore/Framework/interface/MakerMacros.h"
0940 DEFINE_FWK_MODULE(L1TTwinMuxRawToDigi);