Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include <memory>
0002 
0003 #include "EventFilter/EcalDigiToRaw/interface/TCCBlockFormatter.h"
0004 
0005 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
0006 
0007 #include "EventFilter/EcalRawToDigi/interface/DCCRawDataDefinitions.h"
0008 
0009 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0010 
0011 using namespace std;
0012 
0013 TCCBlockFormatter::TCCBlockFormatter(Config const& iC, Params const& iP) : BlockFormatter(iC, iP) {
0014   AllTPsamples_ = false;
0015 }
0016 
0017 void TCCBlockFormatter::DigiToRaw(const EcalTriggerPrimitiveDigi& trigprim,
0018                                   FEDRawData& rawdata,
0019                                   const EcalElectronicsMapping* TheMapping) {
0020   if (debug_)
0021     cout << "enter in TCCBlockFormatter::DigiToRaw " << endl;
0022 
0023   int HEADER_SIZE = 8 * 9;
0024   int bx = bx_;
0025   int lv1 = lv1_;
0026 
0027   const EcalTrigTowerDetId& detid = trigprim.id();
0028 
0029   if ((detid.subDet() == EcalBarrel) && (!doBarrel_))
0030     return;
0031   if ((detid.subDet() == EcalEndcap) && (!doEndCap_))
0032     return;
0033 
0034   int iDCC = TheMapping->DCCid(detid);
0035   int TCCid = TheMapping->TCCid(detid);
0036 
0037   if (TCCid < EcalElectronicsMapping::MIN_TCCID || TCCid > EcalElectronicsMapping::MAX_TCCID)
0038     cout << "Wrong TCCid in TCCBlockFormatter::DigiToRaw " << endl;
0039   bool IsEndCap = ((EcalElectronicsId::MIN_DCCID_EEM <= iDCC && iDCC <= EcalElectronicsId::MAX_DCCID_EEM) ||
0040                    (EcalElectronicsId::MIN_DCCID_EEP <= iDCC && iDCC <= EcalElectronicsId::MAX_DCCID_EEP));
0041 
0042   int FEDid = FEDNumbering::MINECALFEDID + iDCC;
0043 
0044   // note: row is a 64 bit word
0045   int NTT_max = 68;    // Barrel case
0046   int Nrows_TCC = 17;  // Barrel case    (without the header row)
0047   int NTCC = 1;        // Barrel case; number of TCC blocks
0048   int itcc_block = 1;  // Barrel case
0049 
0050   if (IsEndCap) {
0051     Nrows_TCC = 8;         // one row is a 64 bit word
0052     NTCC = 4;              // 4 TTC in EndCap case. Use some custom numbering since
0053     int pair = TCCid % 2;  // the TCCid is written to the RawData.
0054     int inner = (detid.ietaAbs() >= 22) ? 1 : 0;
0055     itcc_block = 2 * pair + inner + 1;
0056     if (inner == 1)
0057       NTT_max = 28;
0058     else
0059       NTT_max = 16;
0060   }
0061 
0062   int nsamples = trigprim.size();
0063   if (!AllTPsamples_)
0064     nsamples = 1;
0065 
0066   int iTT = TheMapping->iTT(detid);  // number of tp inside a fed
0067   if (debug_)
0068     cout << "This is a TrigTower  iDCC iTT iTCCBlock TCCid " << dec << iDCC << " " << iTT << " " << itcc_block << " "
0069          << TCCid << endl;
0070   if (debug_)
0071     cout << "ieta iphi " << dec << detid.ieta() << " " << detid.iphi() << endl;
0072   if (iTT <= 0 || iTT > NTT_max) {
0073     cout << "invalid iTT " << iTT << endl;
0074     return;
0075   }
0076 
0077   int FE_index;
0078 
0079   // rawdata points to the block which will be built for TCC data
0080   if ((int)rawdata.size() != HEADER_SIZE) {
0081     FE_index = rawdata.size() / 8 - NTCC * (Nrows_TCC + 1);  // as far as raw data have been generated
0082     FE_index++;                                              // infer position in TCC block
0083     if (debug_)
0084       cout << "TCCid already there. FE_index = " << FE_index << endl;
0085   } else {
0086     if (debug_)
0087       cout << "New TTCid added on Raw data, TTCid = " << dec << TCCid << " 0x" << hex << TCCid << endl;
0088     FE_index = rawdata.size() / 8;  // size in unites of 64 bits word
0089     int fe_index = FE_index;
0090     for (int iblock = 0; iblock < NTCC; iblock++) {  // do this once per fed in EB, four times in EE
0091       rawdata.resize(rawdata.size() + 8);
0092       unsigned char* ppData = rawdata.data();  // use this to navigate and create the binary
0093       ppData[8 * fe_index] = TCCid & 0xFF;     // fed_index increases in units of bytes
0094       ppData[8 * fe_index + 2] = bx & 0xFF;    // bx takes bits 0-11: 0-7+8-11
0095       ppData[8 * fe_index + 3] = (bx & 0xF00) >> 8;
0096       ppData[8 * fe_index + 3] |= 0x60;
0097       ppData[8 * fe_index + 4] = lv1 & 0xFF;          // same game done for lv1, which takes bits 0-11: 0-7+8-11
0098       ppData[8 * fe_index + 5] = (lv1 & 0xF00) >> 8;  // lv1
0099       ppData[8 * fe_index + 6] = NTT_max;
0100       ppData[8 * fe_index + 6] |= ((nsamples & 0x1) << 7);  // nsamples: number time samples
0101       ppData[8 * fe_index + 7] = ((nsamples & 0xE) >> 1);
0102       ppData[8 * fe_index + 7] |= 0x60;
0103       if (iblock == 0)
0104         FE_index++;
0105       fe_index += Nrows_TCC + 1;
0106       rawdata.resize(rawdata.size() + 8 * Nrows_TCC);  // 17 lines of TPG data in EB, 8 in EE
0107     }
0108     if (debug_)
0109       cout << "Added headers and empty lines : " << endl;
0110     if (debug_)
0111       print(rawdata);
0112 
0113     // -- put the B011 already, since for Endcap there can be empty
0114     // -- lines in the TCC and the SRP blocks
0115     unsigned char* ppData = rawdata.data();
0116     for (int iline = FE_index - 1; iline < FE_index + (Nrows_TCC + 1) * NTCC - 1; iline++) {
0117       ppData[8 * iline + 7] |= 0x60;
0118       ppData[8 * iline + 3] |= 0x60;
0119     }
0120   }
0121 
0122   unsigned char* pData = rawdata.data();
0123 
0124   // -- Now the TCC Block :
0125 
0126   int jTT = (iTT - 1);  // jTT is the TP number insided a block;
0127   int irow = jTT / 4 + (itcc_block - 1) *
0128                            (Nrows_TCC + 1);  // you fit 4 TP's per row; move forward if you're not in the first block;
0129   int ival = jTT % 4;  // for each block you have to skip, move of (Nrows_TCC +1) - 1 is for the TCC header
0130 
0131   // RTC required TP's tp follow global phi also in EB+, thus swap them inside the single TCC
0132   // here you could swap ival -> 3-ival to swap phi insied EB+ supermodules
0133   if (NUMB_SM_EB_PLU_MIN <= iDCC && iDCC <= NUMB_SM_EB_PLU_MAX) {
0134     ival = 3 - ival;
0135   }
0136 
0137   FE_index += irow;  // ival is location inside a TP row; varies between 0-3
0138 
0139   if (debug_)
0140     cout << "Now add tower " << dec << iTT << " irow ival " << dec << irow << " " << dec << ival << endl;
0141   if (debug_)
0142     cout << "new data will be added at line " << dec << FE_index << endl;
0143 
0144   int fg = trigprim.fineGrain();
0145   int et = trigprim.compressedEt();
0146   int ttflag = trigprim.ttFlag();
0147 
0148   if (debug_ && (ttflag != 0)) {
0149     cout << "in TCCBlock : this tower has a non zero flag" << endl;
0150     cout << "Fedid  iTT  flag " << dec << FEDid << " " << iTT << " "
0151          << "0x" << hex << ttflag << endl;
0152   }
0153   pData[8 * FE_index + ival * 2] =
0154       et & 0xFF;  // ival is location inside a TP row; varies between 0-3; tp goes in bits 0-7
0155   pData[8 * FE_index + ival * 2 + 1] = (ttflag << 1) + (fg & 0x1);  // fg follows in bit 8; ttfg is in bits 9-11
0156   if (IsEndCap) {
0157     // re-write the TCCid  and N_Tower_Max :
0158     int ibase = 8 * (FE_index - (int)(jTT / 4) - 1);
0159     pData[ibase] = TCCid & 0xFF;
0160     pData[ibase + 6] = NTT_max;
0161     pData[ibase + 6] |= ((nsamples & 0x1) << 7);
0162     pData[ibase + 7] |= ((nsamples & 0xE) >> 1);
0163   }
0164   if (debug_)
0165     cout << "pData[8*FE_index + ival*2+1] = " << hex << (int)pData[8 * FE_index + ival * 2 + 1] << endl;
0166   if (debug_)
0167     cout << "ttflag ttflag<<1 " << hex << ttflag << " " << hex << (ttflag << 1) << endl;
0168   if (debug_)
0169     cout << "fg&0x1 " << hex << (fg & 0x1) << endl;
0170   if (debug_)
0171     cout << "sum " << hex << ((ttflag << 1) + (fg & 0x1)) << endl;
0172   if (ival % 2 == 1)
0173     pData[8 * FE_index + ival * 2 + 1] |= 0x60;
0174   if (debug_)
0175     cout << "ttflag et fgbit " << hex << ttflag << " " << hex << et << " " << hex << fg << endl;
0176   if (debug_)
0177     print(rawdata);
0178 }