Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "EventFilter/CSCRawToDigi/interface/CSCTMBHeader2020_TMB.h"
0002 #include "EventFilter/CSCRawToDigi/interface/CSCDMBHeader.h"
0003 #include "FWCore/Utilities/interface/Exception.h"
0004 
0005 /* /// commented to prevent compilation warning 
0006    /// use it when copper TMB fw would implement CCLUT features
0007  
0008 const std::vector<std::pair<unsigned, unsigned> >
0009     run3_pattern_lookup_tbl = {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4},  /// Valid LCT0, invalid LCT1 combination. Check LCT1 vpf
0010                                {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {1, 0}, {1, 1}, {1, 2}, {1, 3},
0011                                {1, 4}, {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 0}, {3, 1}, {3, 2},
0012                                {3, 3}, {3, 4}, {4, 0}, {4, 1}, {4, 2}, {4, 3}, {4, 4}};  /// pattern IDs 30,31 are reserved
0013 
0014 const unsigned run2_pattern_lookup_tbl[2][16] = {{10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 2},
0015                                                  {10, 10, 10, 9, 9, 9, 7, 7, 7, 5, 5, 5, 3, 3, 3, 3}};
0016 */
0017 
0018 CSCTMBHeader2020_TMB::CSCTMBHeader2020_TMB() {
0019   bzero(data(), sizeInWords() * 2);
0020   bits.nHeaderFrames = 42;
0021   bits.e0bline = 0x6E0B;
0022   bits.b0cline = 0xDB0C;
0023   bits.firmRevCode = 0x801;  /// copper TMB hybrid fw Run2 CLCT + Run3 MPC/LCT data format + anode-only HMT (March 2022)
0024   bits.nTBins = 12;
0025   bits.nCFEBs = 5;
0026 }
0027 
0028 CSCTMBHeader2020_TMB::CSCTMBHeader2020_TMB(const unsigned short* buf) { memcpy(data(), buf, sizeInWords() * 2); }
0029 
0030 void CSCTMBHeader2020_TMB::setEventInformation(const CSCDMBHeader& dmbHeader) {
0031   bits.cscID = dmbHeader.dmbID();
0032   bits.l1aNumber = dmbHeader.l1a();
0033   bits.bxnCount = dmbHeader.bxn();
0034 }
0035 
0036 ///returns CLCT digis
0037 std::vector<CSCCLCTDigi> CSCTMBHeader2020_TMB::CLCTDigis(uint32_t idlayer) {
0038   std::vector<CSCCLCTDigi> result;
0039   unsigned halfstrip = bits.clct0_key_low + (bits.clct0_key_high << 7);
0040   unsigned strip = halfstrip % 32;
0041   unsigned cfeb = halfstrip / 32;
0042   unsigned pattern = bits.clct0_shape;
0043   unsigned bend = pattern & 0x1;
0044 
0045   CSCCLCTDigi digi0(
0046       bits.clct0_valid, bits.clct0_quality, pattern, 1, bend, strip, cfeb, bits.clct_bxn, 1, bits.bxnPreTrigger);
0047 
0048   halfstrip = bits.clct1_key_low + (bits.clct1_key_high << 7);
0049   strip = halfstrip % 32;
0050   cfeb = halfstrip / 32;
0051   pattern = bits.clct1_shape;
0052   bend = pattern & 0x1;
0053 
0054   CSCCLCTDigi digi1(
0055       bits.clct1_valid, bits.clct1_quality, pattern, 1, bend, strip, cfeb, bits.clct_bxn, 2, bits.bxnPreTrigger);
0056   result.push_back(digi0);
0057   result.push_back(digi1);
0058   return result;
0059 }
0060 
0061 ///returns CorrelatedLCT digis
0062 std::vector<CSCCorrelatedLCTDigi> CSCTMBHeader2020_TMB::CorrelatedLCTDigis(uint32_t idlayer) const {
0063   std::vector<CSCCorrelatedLCTDigi> result;
0064   unsigned strip = bits.MPC_Muon0_clct_key_halfstrip;  //this goes from 0-223
0065 
0066   /// For TMB Hybrid fw slope is 0 instead of Run3 (bits.MPC_Muon0_clct_bend_low & 0x7) | (bits.MPC_Muon0_clct_bend_bit4 << 3);
0067   /// 1/4 and 1/8 strips flags are 0
0068   unsigned slope = 0;
0069   unsigned hmt = bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1);  // HighMultiplicityTrigger
0070   /* /// Run3 format, when full-featured  Run3 copper TMB firmware will be available
0071   unsigned clct_pattern_id = bits.MPC_Muon_clct_pattern_low | (bits.MPC_Muon_clct_pattern_bit5 << 4);
0072   std::pair<unsigned, unsigned> run3_pattern_pair = run3_pattern_lookup_tbl[clct_pattern_id % 30];
0073   unsigned run2_pattern = run2_pattern_lookup_tbl[bits.MPC_Muon0_clct_LR][slope];
0074   unsigned run3_pattern = run3_pattern_pair.second & 0x7;
0075   */
0076   /// For TMB Hybrid fw run3 pattern is set to 0
0077   unsigned run3_pattern = 0;
0078   /// For TMB Hybrid fw run2_pattern is directly set in Run3 4-bits bend/slope
0079   unsigned run2_pattern = (bits.MPC_Muon0_clct_bend_low & 0x7) | (bits.MPC_Muon0_clct_bend_bit4 << 3);
0080 
0081   CSCCorrelatedLCTDigi digi(1,
0082                             bits.MPC_Muon0_lct_vpf,
0083                             bits.MPC_Muon0_lct_quality,
0084                             bits.MPC_Muon0_alct_key_wire,
0085                             strip,
0086                             run2_pattern,
0087                             bits.MPC_Muon0_clct_LR,
0088                             bits.MPC_Muon_alct_bxn,
0089                             0,
0090                             bits.MPC_Muon0_clct_bx0,
0091                             0,
0092                             0,
0093                             CSCCorrelatedLCTDigi::Version::Run3,
0094                             false,  /// 1/4 strip flag
0095                             false,  /// 1/8 strip flag
0096                             run3_pattern,
0097                             slope);
0098   digi.setHMT(hmt);
0099   result.push_back(digi);
0100   /// for the first MPC word:
0101   strip = bits.MPC_Muon1_clct_key_halfstrip;  //this goes from 0-223
0102   /* /// Run3 format, when full-featured  Run3 copper TMB firmware will be available
0103   slope = (bits.MPC_Muon1_clct_bend_low & 0x7) | (bits.MPC_Muon1_clct_bend_bit4 << 3);
0104   run2_pattern = run2_pattern_lookup_tbl[bits.MPC_Muon1_clct_LR][slope];
0105   run3_pattern = run3_pattern_pair.first & 0x7;
0106   run2_pattern = (bits.MPC_Muon1_clct_bend_low & 0x7) | (bits.MPC_Muon1_clct_bend_bit4 << 3);
0107   */
0108   /// For TMB Hybrid fw run2_pattern is directly set in Run3 4-bits bend/slope
0109   run2_pattern = (bits.MPC_Muon1_clct_bend_low & 0x7) | (bits.MPC_Muon1_clct_bend_bit4 << 3);
0110   digi = CSCCorrelatedLCTDigi(2,
0111                               bits.MPC_Muon1_lct_vpf,
0112                               bits.MPC_Muon1_lct_quality,
0113                               bits.MPC_Muon1_alct_key_wire,
0114                               strip,
0115                               run2_pattern,
0116                               bits.MPC_Muon1_clct_LR,
0117                               bits.MPC_Muon_alct_bxn,
0118                               0,
0119                               bits.MPC_Muon1_clct_bx0,
0120                               0,
0121                               0,
0122                               CSCCorrelatedLCTDigi::Version::Run3,
0123                               false,  /// 1/4 strip flag
0124                               false,  /// 1/8 strip flag
0125                               run3_pattern,
0126                               slope);
0127   digi.setHMT(hmt);
0128   result.push_back(digi);
0129   return result;
0130 }
0131 
0132 CSCShowerDigi CSCTMBHeader2020_TMB::showerDigi(uint32_t idlayer) const {
0133   unsigned hmt_bits = bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1);  // HighMultiplicityTrigger bits
0134   uint16_t cscid = bits.cscID;  // ??? What is 4-bits CSC Id in CSshowerDigi
0135   //L1A_TMB_WINDOW is not included in below formula
0136   //correct version:  CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win + L1A_TMB_WINDOW/2;
0137   // same for anode HMT and cathode HMT
0138   uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win;
0139   //LCTshower with showerType = 3. wireNHits is not avaiable
0140   //TMB LCT shower is copied from ALCT shower
0141   CSCShowerDigi result(hmt_bits & 0x3,
0142                        (hmt_bits >> 2) & 0x3,
0143                        cscid,
0144                        bx,
0145                        CSCShowerDigi::ShowerType::kLCTShower,
0146                        0,
0147                        0);  // 2-bits intime, 2-bits out of time
0148   return result;
0149 }
0150 
0151 CSCShowerDigi CSCTMBHeader2020_TMB::anodeShowerDigi(uint32_t idlayer) const {
0152   uint16_t cscid = bits.cscID;
0153   uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win;
0154   //ALCTshower with showerType = 1. wireNHits is not avaiable
0155   CSCShowerDigi result(
0156       bits.anode_hmt & 0x3, 0, cscid, bx, CSCShowerDigi::ShowerType::kALCTShower, 0, 0);  // 2-bits intime, no out of time
0157   return result;
0158 }
0159 
0160 CSCShowerDigi CSCTMBHeader2020_TMB::cathodeShowerDigi(uint32_t idlayer) const {
0161   uint16_t cscid = bits.cscID;
0162   uint16_t bx = CSCConstants::LCT_CENTRAL_BX - bits.pop_l1a_match_win;
0163   //CLCTshower with showerType = 2. comparatorNhits is not avaiable for TMB yet
0164   CSCShowerDigi result(bits.cathode_hmt & 0x3,
0165                        0,
0166                        cscid,
0167                        bx,
0168                        CSCShowerDigi::ShowerType::kCLCTShower,
0169                        0,
0170                        0);  // 2-bits intime, no out of time
0171   return result;
0172 }
0173 
0174 void CSCTMBHeader2020_TMB::addALCT0(const CSCALCTDigi& digi) {
0175   throw cms::Exception("In CSC TMBHeaderFormat 2007, ALCTs belong in  ALCT header");
0176 }
0177 
0178 void CSCTMBHeader2020_TMB::addALCT1(const CSCALCTDigi& digi) {
0179   throw cms::Exception("In CSC TMBHeaderFormat 2007, ALCTs belong in  ALCT header");
0180 }
0181 
0182 void CSCTMBHeader2020_TMB::addCLCT0(const CSCCLCTDigi& digi) {
0183   unsigned halfStrip = digi.getKeyStrip();
0184   unsigned pattern = digi.getPattern();
0185   bits.clct0_valid = digi.isValid();
0186   bits.clct0_quality = digi.getQuality();
0187   bits.clct0_shape = pattern;
0188   // first 7 bits of halfstrip
0189   bits.clct0_key_low = halfStrip & (0x7F);
0190   // most-significant (8th) bit
0191   bits.clct0_key_high = (halfStrip >> 7) & (0x1);
0192   bits.clct_bxn = digi.getBX();
0193   bits.bxnPreTrigger = digi.getFullBX();
0194 }
0195 
0196 void CSCTMBHeader2020_TMB::addCLCT1(const CSCCLCTDigi& digi) {
0197   unsigned halfStrip = digi.getKeyStrip();
0198   unsigned pattern = digi.getPattern();
0199   bits.clct1_valid = digi.isValid();
0200   bits.clct1_quality = digi.getQuality();
0201   bits.clct1_shape = pattern;
0202   // first 7 bits of halfstrip
0203   bits.clct1_key_low = halfStrip & (0x7F);
0204   // most-significant (8th) bit
0205   bits.clct1_key_high = (halfStrip >> 7) & (0x1);
0206   // There is just one BX field common for CLCT0 and CLCT1 (since both
0207   // are latched at the same BX); set it in addCLCT0().
0208   bits.bxnPreTrigger = digi.getFullBX();
0209 }
0210 
0211 void CSCTMBHeader2020_TMB::addCorrelatedLCT0(const CSCCorrelatedLCTDigi& digi) {
0212   bits.MPC_Muon0_lct_vpf = digi.isValid();
0213   bits.MPC_Muon0_alct_key_wire = digi.getKeyWG();
0214   bits.MPC_Muon0_clct_key_halfstrip = digi.getStrip(2) & 0xFF;
0215   /// For TMB hybrid fw 1/4 and 1/8 strip flags are 0
0216   /*
0217   bits.MPC_Muon0_clct_QuarterStrip = digi.getQuartStripBit() & 0x1;
0218   bits.MPC_Muon0_clct_EighthStrip = digi.getEighthStripBit() & 0x1;
0219   */
0220   bits.MPC_Muon0_clct_QuarterStrip = 0;
0221   bits.MPC_Muon0_clct_EighthStrip = 0;
0222   bits.MPC_Muon0_lct_quality = digi.getQuality() & 0x7;
0223 
0224   /// For TMB hybrid fw 5-bits clct_pattern and run3_pattern are 0
0225   /*
0226   // To restore 5-bits Run3 CLCT Pattern ID first assume and set pattern ID = LCT0 Run3 pattern
0227   uint16_t run3_pattern = digi.getRun3Pattern();
0228   bits.MPC_Muon_clct_pattern_low = run3_pattern & 0xF;
0229   bits.MPC_Muon_clct_pattern_bit5 = (run3_pattern >> 4) & 0x1;
0230   */
0231   bits.MPC_Muon_clct_pattern_low = 0;
0232   bits.MPC_Muon_clct_pattern_bit5 = 0;
0233   /// For TMB hybrid fw use run2 pattern ID to fill run3 4-bits bend/slope field
0234   bits.MPC_Muon0_clct_bend_low = digi.getPattern() & 0x7;
0235   bits.MPC_Muon0_clct_bend_bit4 = (digi.getPattern() >> 3) & 0x1;
0236   bits.MPC_Muon0_clct_LR = digi.getBend() & 0x1;
0237   bits.MPC_Muon_HMT_bit0 = digi.getHMT() & 0x1;
0238   bits.MPC_Muon_HMT_high = (digi.getHMT() >> 1) & 0x7;
0239   bits.MPC_Muon_alct_bxn = digi.getBX();
0240   bits.MPC_Muon0_clct_bx0 = digi.getBX0();
0241 }
0242 
0243 void CSCTMBHeader2020_TMB::addCorrelatedLCT1(const CSCCorrelatedLCTDigi& digi) {
0244   bits.MPC_Muon1_lct_vpf = digi.isValid();
0245   bits.MPC_Muon1_alct_key_wire = digi.getKeyWG();
0246   bits.MPC_Muon1_clct_key_halfstrip = digi.getStrip(2) & 0xFF;
0247   /// For TMB hybrid fw 1/4 and 1/8 strip flags are 0
0248   /*
0249   bits.MPC_Muon1_clct_QuarterStrip = digi.getQuartStripBit() & 0x1;
0250   bits.MPC_Muon1_clct_EighthStrip = digi.getEighthStripBit() & 0x1;
0251   */
0252   bits.MPC_Muon1_clct_QuarterStrip = 0;
0253   bits.MPC_Muon1_clct_EighthStrip = 0;
0254   bits.MPC_Muon1_lct_quality = digi.getQuality() & 0x7;
0255 
0256   /// For TMB hybrid fw 5-bits clct_pattern and run3_pattern are 0
0257   /*
0258   // To restore 5-bits Run3 CLCT Pattern ID assume that LCT0 pattern ID is already processed
0259   // and combine LCT1 Run3 pattern to set final 5-bit pattern ID
0260   if (digi.isValid()) {
0261     uint16_t clct_pattern_id = bits.MPC_Muon_clct_pattern_low | (bits.MPC_Muon_clct_pattern_bit5 << 4);
0262     uint16_t run3_pattern = digi.getRun3Pattern();
0263     clct_pattern_id = (clct_pattern_id + (run3_pattern + 1) * 5) % 30;
0264     bits.MPC_Muon_clct_pattern_low = clct_pattern_id & 0xF;
0265     bits.MPC_Muon_clct_pattern_bit5 = (clct_pattern_id >> 4) & 0x1;
0266   }
0267   */
0268   bits.MPC_Muon_clct_pattern_low = 0;
0269   bits.MPC_Muon_clct_pattern_bit5 = 0;
0270   /// For TMB hybrid fw use run2 pattern ID to fill run3 4-bits bend/slope field
0271   bits.MPC_Muon1_clct_bend_low = digi.getPattern() & 0x7;
0272   bits.MPC_Muon1_clct_bend_bit4 = (digi.getPattern() >> 3) & 0x1;
0273   bits.MPC_Muon1_clct_LR = digi.getBend() & 0x1;
0274   bits.MPC_Muon_HMT_bit0 = digi.getHMT() & 0x1;
0275   bits.MPC_Muon_HMT_high = (digi.getHMT() >> 1) & 0x7;
0276   bits.MPC_Muon_alct_bxn = digi.getBX();
0277   bits.MPC_Muon1_clct_bx0 = digi.getBX0();
0278 }
0279 
0280 void CSCTMBHeader2020_TMB::addShower(const CSCShowerDigi& digi) {
0281   uint16_t hmt_bits = (digi.bitsInTime() & 0x3) + ((digi.bitsOutOfTime() & 0x3) << 2);
0282   //not valid LCT shower, then in-time bits must be 0
0283   if (not digi.isValid())
0284     hmt_bits = ((digi.bitsOutOfTime() & 0x3) << 2);
0285   bits.MPC_Muon_HMT_bit0 = hmt_bits & 0x1;
0286   bits.MPC_Muon_HMT_high = (hmt_bits >> 1) & 0x7;
0287   if (digi.isValid())
0288     bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX();
0289   else
0290     bits.pop_l1a_match_win = 3;  //default value
0291 }
0292 
0293 void CSCTMBHeader2020_TMB::addAnodeShower(const CSCShowerDigi& digi) {
0294   uint16_t hmt_bits = digi.bitsInTime() & 0x3;
0295   if (not digi.isValid())
0296     hmt_bits = 0;
0297   bits.anode_hmt = hmt_bits;
0298   if (digi.isValid())
0299     bits.pop_l1a_match_win = CSCConstants::LCT_CENTRAL_BX - digi.getBX();
0300   else
0301     bits.pop_l1a_match_win = 3;  //default value
0302 }
0303 
0304 void CSCTMBHeader2020_TMB::addCathodeShower(const CSCShowerDigi& digi) {
0305   /// For TMB hybrid fw cathode HMT bits are 0
0306   /* uint16_t hmt_bits = digi.bitsInTime() & 0x3;
0307   bits.cathode_hmt = hmt_bits;
0308   */
0309   bits.cathode_hmt = 0;
0310 }
0311 
0312 void CSCTMBHeader2020_TMB::print(std::ostream& os) const {
0313   os << "...............(O)TMB2020 TMB Run3 Header.................."
0314      << "\n";
0315   os << std::hex << "BOC LINE " << bits.b0cline << " EOB " << bits.e0bline << "\n";
0316   os << std::hex << "FW revision: 0x" << bits.firmRevCode << "\n";
0317   os << std::dec << "fifoMode = " << bits.fifoMode << ", nTBins = " << bits.nTBins << "\n";
0318   os << "boardID = " << bits.boardID << ", cscID = " << bits.cscID << "\n";
0319   os << "l1aNumber = " << bits.l1aNumber << ", bxnCount = " << bits.bxnCount << "\n";
0320   os << "trigSourceVect = " << bits.trigSourceVect << ", activeCFEBs = 0x" << std::hex
0321      << (bits.activeCFEBs | (bits.activeCFEBs_2 << 5)) << ", readCFEBs = 0x" << std::hex
0322      << (bits.readCFEBs | (bits.readCFEBs_2 << 5)) << std::dec << "\n";
0323   os << "bxnPreTrigger = " << bits.bxnPreTrigger << "\n";
0324   os << "ALCT location in CLCT window " << bits.matchWin << " L1A location in TMB window " << bits.pop_l1a_match_win
0325      << "\n";
0326   os << "tmbMatch = " << bits.tmbMatch << " alctOnly = " << bits.alctOnly << " clctOnly = " << bits.clctOnly << "\n";
0327 
0328   os << "CLCT Words:\n"
0329      << " bits.clct0_valid = " << bits.clct0_valid << " bits.clct0_shape = " << bits.clct0_shape
0330      << " bits.clct0_quality = " << bits.clct0_quality
0331      << " halfstrip = " << (bits.clct0_key_low + (bits.clct0_key_high << 7)) << "\n";
0332 
0333   os << " bits.clct1_valid = " << bits.clct1_valid << " bits.clct1_shape = " << bits.clct1_shape
0334      << " bits.clct1_quality = " << bits.clct1_quality
0335      << " halfstrip = " << (bits.clct1_key_low + (bits.clct1_key_high << 7)) << "\n";
0336 
0337   os << "MPC Words:\n"
0338      << " LCT0 valid = " << bits.MPC_Muon0_lct_vpf << " key WG = " << bits.MPC_Muon0_alct_key_wire
0339      << " key halfstrip = " << bits.MPC_Muon0_clct_key_halfstrip
0340      << " 1/4strip flag = " << bits.MPC_Muon0_clct_QuarterStrip
0341      << " 1/8strip flag = " << bits.MPC_Muon0_clct_EighthStrip << "\n"
0342      << " quality = " << bits.MPC_Muon0_lct_quality
0343      << " slope/bend = " << ((bits.MPC_Muon0_clct_bend_low & 0x7) | (bits.MPC_Muon0_clct_bend_bit4 << 3))
0344      << " L/R bend = " << bits.MPC_Muon0_clct_LR << "\n";
0345 
0346   os << " LCT1 valid = " << bits.MPC_Muon1_lct_vpf << " key WG = " << bits.MPC_Muon1_alct_key_wire
0347      << " key halfstrip = " << bits.MPC_Muon1_clct_key_halfstrip
0348      << " 1/4strip flag = " << bits.MPC_Muon1_clct_QuarterStrip
0349      << " 1/8strip flag = " << bits.MPC_Muon1_clct_EighthStrip << "\n"
0350      << " quality = " << bits.MPC_Muon1_lct_quality
0351      << " slope/bend = " << ((bits.MPC_Muon1_clct_bend_low & 0x7) | (bits.MPC_Muon1_clct_bend_bit4 << 3))
0352      << " L/R bend = " << bits.MPC_Muon1_clct_LR << "\n";
0353 
0354   os << " clct_5bit_pattern_id = " << (bits.MPC_Muon_clct_pattern_low | (bits.MPC_Muon_clct_pattern_bit5 << 4))
0355      << " HMT = " << (bits.MPC_Muon_HMT_bit0 | (bits.MPC_Muon_HMT_high << 1)) << ", alctHMT = " << bits.anode_hmt
0356      << ", clctHMT = " << bits.cathode_hmt << "\n";
0357 }