Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "EventFilter/CSCRawToDigi/interface/CSCComparatorData.h"
0002 #include "EventFilter/CSCRawToDigi/interface/CSCTMBHeader.h"
0003 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0004 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 #include <iostream>
0007 #include <cstdio>
0008 #include <cstring>
0009 
0010 #ifdef LOCAL_UNPACK
0011 bool CSCComparatorData::debug = false;
0012 #else
0013 #include <atomic>
0014 std::atomic<bool> CSCComparatorData::debug{false};
0015 #endif
0016 
0017 CSCComparatorData::CSCComparatorData(const CSCTMBHeader* tmbHeader)
0018     : ncfebs_(tmbHeader->NCFEBs()), ntbins_(tmbHeader->NTBins()) {
0019   if (tmbHeader != nullptr)
0020     theFirmwareVersion = tmbHeader->FirmwareVersion();
0021   else
0022     theFirmwareVersion = 2007;
0023   size_ = nlines();
0024   zero();
0025 }
0026 
0027 CSCComparatorData::CSCComparatorData(int ncfebs, int ntbins, int firmware_version)
0028     : ncfebs_(ncfebs), ntbins_(ntbins), theFirmwareVersion(firmware_version) {
0029   size_ = nlines();
0030   zero();
0031 }
0032 
0033 CSCComparatorData::CSCComparatorData(int ncfebs, int ntbins, const unsigned short* buf, int firmware_version)
0034     : ncfebs_(ncfebs), ntbins_(ntbins), theFirmwareVersion(firmware_version) {
0035   // add two more for odd ntbins, plus one for the e0c
0036   // Oct 2004 Rick: e0c line belongs to CSCTMBTrailer
0037   size_ = (nlines() % 2 == 1) ? nlines() + 2 : nlines();
0038 
0039   memcpy(theData, buf, size_ * 2);
0040 }
0041 
0042 void CSCComparatorData::zero() {
0043   for (int ifeb = 0; ifeb < ncfebs_; ++ifeb) {
0044     for (int tbin = 0; tbin < ntbins_; ++tbin) {
0045       for (int layer = CSCDetId::minLayerId(); layer <= CSCDetId::maxLayerId(); ++layer) {
0046         dataWord(ifeb, tbin, layer) = CSCComparatorDataWord(ifeb, tbin, 0);
0047       }
0048     }
0049   }
0050 }
0051 
0052 std::vector<CSCComparatorDigi> CSCComparatorData::comparatorDigis(uint32_t idlayer, unsigned cfeb) {
0053   static const bool doStripSwapping = true;
0054   bool me1a = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 4);
0055   bool zplus = (CSCDetId::endcap(idlayer) == 1);
0056   bool me1b = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 1);
0057   int layer = CSCDetId::layer(idlayer);
0058 
0059   assert(layer >= CSCDetId::minLayerId());
0060   assert(layer <= CSCDetId::maxLayerId());
0061 
0062   //looking for comp output on layer
0063   std::vector<CSCComparatorDigi> result;
0064 
0065   // this is pretty sparse data, so I wish we could check the
0066   // data word by word, not bit by bit, but I don't see how to
0067   // do the time sequencing that way.
0068   for (int distrip = 0; distrip < CSCConstants::NUM_DISTRIPS_PER_CFEB; ++distrip) {
0069     uint16_t tbinbitsS0HS0 = 0;
0070     uint16_t tbinbitsS0HS1 = 0;
0071     uint16_t tbinbitsS1HS0 = 0;
0072     uint16_t tbinbitsS1HS1 = 0;
0073     for (int tbin = 0; tbin < ntbins_ - 2; ++tbin) {
0074       if (bitValue(cfeb, tbin, layer, distrip)) {
0075         /// first do some checks
0076         CSCComparatorDataWord word = dataWord(cfeb, tbin, layer);
0077         assert(word.tbin_ == tbin);
0078         assert(word.cfeb_ == cfeb);
0079         // we have a hit.  The next two time samples
0080         // are the other two bits in the triad
0081         int bit2 = bitValue(cfeb, tbin + 1, layer, distrip);
0082         int bit3 = bitValue(cfeb, tbin + 2, layer, distrip);
0083         // should count from zero
0084         int chamberDistrip = distrip + cfeb * CSCConstants::NUM_DISTRIPS_PER_CFEB;
0085         int HalfStrip = 4 * chamberDistrip + bit2 * 2 + bit3;
0086         int output = 4 + bit2 * 2 + bit3;
0087         /*
0088          * Handles distrip logic; comparator output is for pairs of strips:
0089          * hit  bin  dec
0090          * x--- 100   4
0091          * -x-- 101   5
0092          * --x- 110   6
0093          * ---x 111   7
0094          *
0095          */
0096 
0097         if (debug)
0098           LogTrace("CSCComparatorData|CSCRawToDigi")
0099               << "fillComparatorOutputs: layer = " << layer << " timebin = " << tbin << " cfeb = " << cfeb
0100               << " distrip = " << chamberDistrip << " HalfStrip = " << HalfStrip << " Output " << output << std::endl;
0101         ///what is actually stored in comparator digis are 0/1 for left/right halfstrip for each strip
0102 
0103         ///constructing four bitted words for tbits on
0104         if (output == 4)
0105           tbinbitsS0HS0 = tbinbitsS0HS0 + (1 << tbin);
0106         if (output == 5)
0107           tbinbitsS0HS1 = tbinbitsS0HS1 + (1 << tbin);
0108         if (output == 6)
0109           tbinbitsS1HS0 = tbinbitsS1HS0 + (1 << tbin);
0110         if (output == 7)
0111           tbinbitsS1HS1 = tbinbitsS1HS1 + (1 << tbin);
0112 
0113         tbin += 2;
0114       }
0115     }  //end of loop over time bins
0116     //we do not have to check over the last couple of time bins if there are no hits since
0117     //comparators take 3 time bins
0118 
0119     // Store digis each of possible four halfstrips for given distrip:
0120     if (tbinbitsS0HS0 || tbinbitsS0HS1 || tbinbitsS1HS0 || tbinbitsS1HS1) {
0121       unsigned int cfeb_corr = cfeb;
0122       unsigned int distrip_corr = distrip;
0123 
0124       if (doStripSwapping) {
0125         // Fix ordering of strips and CFEBs in ME1/1.
0126         // SV, 27/05/08: keep CFEB=4 for ME1/a until CLCT trigger logic
0127         // stops combining it with the info from the other 4 CFEBs (ME1/b).
0128         //
0129         if (theFirmwareVersion >= 2013) {
0130           if (me1a && zplus) {
0131             distrip_corr = 7 - distrip;  // 0-7 -> 7-0
0132             cfeb_corr = 10 - cfeb;
0133           }
0134           if (me1b && !zplus) {
0135             distrip_corr = 7 - distrip;
0136             cfeb_corr = 3 - cfeb;
0137           }
0138         } else {
0139           // if ( me1a )           { cfeb_corr = 0; } // reset 4 to 0
0140           if (me1a && zplus) {
0141             distrip_corr = 7 - distrip;  // 0-7 -> 7-0
0142           }
0143           if (me1b && !zplus) {
0144             distrip_corr = 7 - distrip;
0145             cfeb_corr = 3 - cfeb;
0146           }
0147         }
0148       }
0149 
0150       int strip = 16 * cfeb_corr + 2 * distrip_corr + 1;
0151 
0152       if (debug)
0153         LogTrace("CSCComparatorData|CSCRawToDigi") << "fillComparatorOutputs: cfeb_corr = " << cfeb_corr
0154                                                    << " distrip_corr = " << distrip_corr << " strip = " << strip;
0155 
0156       if (doStripSwapping && ((me1a && zplus) || (me1b && !zplus))) {
0157         // Half-strips need to be flipped too.
0158         if (tbinbitsS1HS1)
0159           result.push_back(CSCComparatorDigi(strip, 0, tbinbitsS1HS1));
0160         if (tbinbitsS1HS0)
0161           result.push_back(CSCComparatorDigi(strip, 1, tbinbitsS1HS0));
0162         if (tbinbitsS0HS1)
0163           result.push_back(CSCComparatorDigi(strip + 1, 0, tbinbitsS0HS1));
0164         if (tbinbitsS0HS0)
0165           result.push_back(CSCComparatorDigi(strip + 1, 1, tbinbitsS0HS0));
0166       } else {
0167         if (tbinbitsS0HS0)
0168           result.push_back(CSCComparatorDigi(strip, 0, tbinbitsS0HS0));
0169         if (tbinbitsS0HS1)
0170           result.push_back(CSCComparatorDigi(strip, 1, tbinbitsS0HS1));
0171         if (tbinbitsS1HS0)
0172           result.push_back(CSCComparatorDigi(strip + 1, 0, tbinbitsS1HS0));
0173         if (tbinbitsS1HS1)
0174           result.push_back(CSCComparatorDigi(strip + 1, 1, tbinbitsS1HS1));
0175       }
0176       //uh oh ugly ugly ugly!
0177     }
0178   }  //end of loop over distrips
0179   return result;
0180 }
0181 
0182 std::vector<CSCComparatorDigi> CSCComparatorData::comparatorDigis(int layer) {
0183   assert(layer >= CSCDetId::minLayerId());
0184   assert(layer <= CSCDetId::maxLayerId());
0185 
0186   std::vector<CSCComparatorDigi> result;
0187   for (int cfeb = 0; cfeb < ncfebs_; ++cfeb) {
0188     std::vector<CSCComparatorDigi> oneCfebDigi = comparatorDigis(layer, cfeb);
0189     result.insert(result.end(), oneCfebDigi.begin(), oneCfebDigi.end());
0190   }
0191 
0192   return result;
0193 }
0194 
0195 void CSCComparatorData::add(const CSCComparatorDigi& digi, int layer) {
0196   int strip = digi.getStrip();
0197   int halfstrip = digi.getHalfStrip();
0198   int cfeb = digi.getCFEB();
0199   int distrip = digi.getDiStrip();
0200 
0201   // Check the distrip and half-strip number
0202   assert(cfeb < CSCConstants::MAX_CFEBS_RUN2);
0203   assert(distrip < CSCConstants::NUM_DISTRIPS_PER_CFEB);
0204   // note that half-strips are not staggered in the packer
0205   assert(halfstrip < CSCConstants::MAX_NUM_HALF_STRIPS_RUN2);
0206 
0207   std::vector<int> timeBinsOn = digi.getTimeBinsOn();
0208   for (std::vector<int>::const_iterator tbinItr = timeBinsOn.begin(); tbinItr != timeBinsOn.end(); ++tbinItr) {
0209     int tbin = *tbinItr;
0210     if (tbin >= 0 && tbin < ntbins_ - 2) {
0211       // First triad bit indicates the presence of the hit
0212       dataWord(cfeb, tbin, layer).set(distrip, true);
0213       // Second bit indicates which of the two strips contains the hit
0214       if (strip % 2 == 0)
0215         dataWord(cfeb, tbin + 1, layer).set(distrip, true);
0216       // Third bit indicates whether the hit is located on the left or on the
0217       // right side of the strip.
0218       if (digi.getComparator())
0219         dataWord(cfeb, tbin + 2, layer).set(distrip, true);
0220     }
0221   }
0222 }
0223 
0224 /***
0225  * Comparator packing version with ME11 strips swapping
0226  ***/
0227 void CSCComparatorData::add(const CSCComparatorDigi& digi, const CSCDetId& cid) {
0228   static const bool doStripSwapping = true;
0229   bool me1a = (cid.station() == 1) && (cid.ring() == 4);
0230   bool zplus = (cid.endcap() == 1);
0231   bool me1b = (cid.station() == 1) && (cid.ring() == 1);
0232 
0233   unsigned layer = cid.layer();
0234 
0235   int strip = digi.getStrip();
0236   int halfstrip = digi.getHalfStrip();
0237   int cfeb = digi.getCFEB();
0238   int distrip = digi.getDiStrip();
0239   int bit2 = (strip - 1) % 2;
0240   int bit3 = digi.getComparator();
0241 
0242   // Check the distrip and half-strip number
0243   if (theFirmwareVersion >= 2013) {
0244     assert(cfeb < CSCConstants::MAX_CFEBS_RUN2);
0245     assert(distrip < CSCConstants::NUM_DISTRIPS_PER_CFEB);
0246     // note that half-strips are not staggered in the packer
0247     assert(halfstrip < CSCConstants::MAX_NUM_HALF_STRIPS_RUN2);
0248   } else {
0249     assert(cfeb < CSCConstants::MAX_CFEBS_RUN1);
0250     assert(distrip < CSCConstants::NUM_DISTRIPS_PER_CFEB);
0251     // note that half-strips are not staggered in the packer
0252     assert(halfstrip < CSCConstants::MAX_NUM_HALF_STRIPS_RUN1);
0253   }
0254 
0255   // Lets try to do ME11 strip flipping
0256   if (doStripSwapping) {
0257     if (theFirmwareVersion >= 2013) {
0258       if ((me1a || (me1b && (cfeb > CSCConstants::NUM_CFEBS_ME1A_UNGANGED))) && zplus) {
0259         distrip = 7 - distrip;  // 0-7 -> 7-0
0260         cfeb = 10 - cfeb;
0261         bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
0262         bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
0263       }
0264       if (me1b && !zplus && (cfeb < CSCConstants::NUM_CFEBS_ME1B)) {
0265         distrip = 7 - distrip;
0266         cfeb = 3 - cfeb;
0267         bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
0268         bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
0269       }
0270     } else {
0271       if ((me1a || (me1b && (cfeb > CSCConstants::NUM_CFEBS_ME1A_UNGANGED))) && zplus) {
0272         distrip = 7 - distrip;  // 0-7 -> 7-0
0273         bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
0274         bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
0275       }
0276       if (me1b && !zplus && (cfeb < CSCConstants::NUM_CFEBS_ME1B)) {
0277         distrip = 7 - distrip;
0278         cfeb = 3 - cfeb;
0279         bit2 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) / 2;
0280         bit3 = ((31 - (halfstrip % CSCConstants::NUM_HALF_STRIPS_PER_CFEB)) % 4) % 2;
0281       }
0282     }
0283   }
0284 
0285   std::vector<int> timeBinsOn = digi.getTimeBinsOn();
0286   for (std::vector<int>::const_iterator tbinItr = timeBinsOn.begin(); tbinItr != timeBinsOn.end(); ++tbinItr) {
0287     int tbin = *tbinItr;
0288     if (tbin >= 0 && tbin < ntbins_ - 2) {
0289       // First triad bit indicates the presence of the hit
0290       dataWord(cfeb, tbin, layer).set(distrip, true);
0291       // Second bit indicates which of the two strips contains the hit
0292       // if (strip%2 == 0)
0293       if (bit2)
0294         dataWord(cfeb, tbin + 1, layer).set(distrip, true);
0295       // Third bit indicates whether the hit is located on the left or on the
0296       // right side of the strip.
0297       // if (digi.getComparator())
0298       if (bit3)
0299         dataWord(cfeb, tbin + 2, layer).set(distrip, true);
0300     }
0301   }
0302 }
0303 
0304 bool CSCComparatorData::check() const {
0305   bool result = true;
0306   for (int cfeb = 0; cfeb < ncfebs_; ++cfeb) {
0307     for (int tbin = 0; tbin < ntbins_; ++tbin) {
0308       for (int layer = CSCDetId::minLayerId(); layer <= CSCDetId::maxLayerId(); ++layer) {
0309         /// first do some checks
0310         const CSCComparatorDataWord& word = dataWord(cfeb, tbin, layer);
0311         bool wordIsGood = (word.tbin_ == tbin) && (word.cfeb_ == cfeb);
0312         result = result && wordIsGood;
0313         if (!wordIsGood && debug) {
0314           LogTrace("CSCComparatorData|CSCRawToDigi")
0315               << "Bad CLCT data  in layer " << layer << " expect CFEB " << cfeb << " tbin " << tbin;
0316           LogTrace("CSCComparatorData|CSCRawToDigi") << " See " << word.cfeb_ << " " << word.tbin_;
0317         }
0318       }
0319     }
0320   }
0321   if (!result)
0322     LogTrace("CSCComparatorData|CSCRawToDigi") << "++ Bad CLCT Data ++ ";
0323   return result;
0324 }
0325 
0326 void CSCComparatorData::dump() const {
0327   for (int i = 0; i < size_; i++) {
0328     printf("%04x %04x %04x %04x\n", theData[i + 3], theData[i + 2], theData[i + 1], theData[i]);
0329     i += 3;
0330   }
0331 }
0332 
0333 void CSCComparatorData::selfTest() {
0334   CSCComparatorData comparatorData(5, 16);
0335   // aim for output 4 in 5th time bin, = 0000000000010000
0336   CSCComparatorDigi comparatorDigi1(1, 0, 0x10);
0337   // aim for output 5 in 6th time bin, = 0000 0000 0010 0000
0338   CSCComparatorDigi comparatorDigi2(39, 1, 0x20);
0339   // aim for output 7 in 7th time bin, = 000 0000 0100 0000
0340   CSCComparatorDigi comparatorDigi3(80, 1, 0x40);
0341 
0342   comparatorData.add(comparatorDigi1, 1);
0343   comparatorData.add(comparatorDigi2, 4);
0344   comparatorData.add(comparatorDigi3, 6);
0345 
0346   CSCDetId layer1(1, 4, 1, 2, 1);
0347   CSCDetId layer4(1, 4, 1, 2, 4);
0348   CSCDetId layer6(1, 4, 1, 2, 6);
0349 
0350   std::vector<CSCComparatorDigi> digis1 = comparatorData.comparatorDigis(1);
0351   std::vector<CSCComparatorDigi> digis2 = comparatorData.comparatorDigis(4);
0352   std::vector<CSCComparatorDigi> digis3 = comparatorData.comparatorDigis(6);
0353 
0354   assert(digis1.size() == 1);
0355   assert(digis2.size() == 1);
0356   assert(digis3.size() == 1);
0357 
0358   assert(digis1[0].getStrip() == 1);
0359   assert(digis1[0].getComparator() == 0);
0360   assert(digis1[0].getTimeBin() == 4);
0361 
0362   assert(digis2[0].getStrip() == 39);
0363   assert(digis2[0].getComparator() == 1);
0364   assert(digis2[0].getTimeBin() == 5);
0365 
0366   assert(digis3[0].getStrip() == 80);
0367   assert(digis3[0].getComparator() == 1);
0368   assert(digis3[0].getTimeBin() == 6);
0369 }