CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/EventFilter/EcalDigiToRaw/src/TCCBlockFormatter.cc

Go to the documentation of this file.
00001 #include <memory>
00002 
00003 #include "EventFilter/EcalDigiToRaw/interface/TCCBlockFormatter.h"
00004 
00005 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
00006 
00007 #include "EventFilter/EcalRawToDigi/interface/DCCRawDataDefinitions.h"
00008 
00009 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00010 
00011 
00012 using namespace std;
00013 
00014 
00015 TCCBlockFormatter::TCCBlockFormatter() {
00016 
00017  AllTPsamples_ = false;
00018 }
00019 
00020 TCCBlockFormatter::~TCCBlockFormatter() {
00021 
00022 }
00023 
00024 void TCCBlockFormatter::DigiToRaw(const EcalTriggerPrimitiveDigi& trigprim, 
00025                                   FEDRawData& rawdata, const EcalElectronicsMapping* TheMapping)
00026 {
00027 
00028   if (debug_) cout << "enter in TCCBlockFormatter::DigiToRaw " << endl;
00029 
00030   int HEADER_SIZE = 8 * 9;
00031   int bx = *pbx_;
00032   int lv1 = *plv1_;
00033 
00034 
00035         const EcalTrigTowerDetId& detid = trigprim.id();
00036 
00037            if ( (detid.subDet() == EcalBarrel) && (! doBarrel_) ) return;
00038            if ( (detid.subDet() == EcalEndcap) && (! doEndCap_) ) return;
00039 
00040         int iDCC = TheMapping -> DCCid(detid);
00041         int TCCid = TheMapping -> TCCid(detid);
00042 
00043 
00044         if (TCCid < EcalElectronicsMapping::MIN_TCCID || TCCid > EcalElectronicsMapping::MAX_TCCID) 
00045                 cout << "Wrong TCCid in TCCBlockFormatter::DigiToRaw " << endl;
00046         bool IsEndCap = ( (EcalElectronicsId::MIN_DCCID_EEM <= iDCC && iDCC <= EcalElectronicsId::MAX_DCCID_EEM) ||
00047                           (EcalElectronicsId::MIN_DCCID_EEP <= iDCC && iDCC <= EcalElectronicsId::MAX_DCCID_EEP) );
00048 
00049         int FEDid = FEDNumbering::MINECALFEDID + iDCC;
00050 
00051         // note: row is a 64 bit word
00052         int NTT_max = 68;       // Barrel case
00053         int Nrows_TCC = 17;     // Barrel case    (without the header row)
00054         int NTCC = 1;           // Barrel case; number of TCC blocks
00055         int itcc_block = 1;     // Barrel case
00056 
00057         if (IsEndCap) {
00058                 Nrows_TCC = 8;          // one row is a 64 bit word
00059                 NTCC = 4;               // 4 TTC in EndCap case. Use some custom numbering since
00060                 int pair = TCCid % 2;   // the TCCid is written to the RawData.
00061                 int inner = ( detid.ietaAbs() >= 22) ? 1 : 0;
00062                 itcc_block = 2 * pair + inner + 1;
00063                 if (inner == 1) NTT_max = 28;
00064                 else NTT_max = 16;
00065         }
00066 
00067         
00068         int nsamples = trigprim.size();
00069         if (! AllTPsamples_) nsamples = 1;
00070 
00071         int iTT = TheMapping -> iTT(detid);   // number of tp inside a fed
00072         if (debug_) cout << "This is a TrigTower  iDCC iTT iTCCBlock TCCid " << dec << 
00073                 iDCC << " " << iTT << " " << itcc_block << " " << TCCid << endl;
00074         if (debug_) cout << "ieta iphi " << dec << detid.ieta() << " " << detid.iphi() << endl;
00075         if (iTT <= 0 || iTT > NTT_max)  {
00076                 cout << "invalid iTT " << iTT << endl;
00077                 return;
00078         }
00079 
00080         int FE_index;
00081         
00082         // rawdata points to the block which will be built for TCC data  
00083         if ((int)rawdata.size() != HEADER_SIZE) {
00084           FE_index = rawdata.size() / 8 - NTCC*(Nrows_TCC+1);         // as far as raw data have been generated 
00085           FE_index ++;                                                // infer position in TCC block
00086           if (debug_) cout << "TCCid already there. FE_index = " << FE_index << endl;
00087         }
00088         else {
00089                 if (debug_) cout << "New TTCid added on Raw data, TTCid = " << dec << TCCid << " 0x" << hex << TCCid << endl;
00090                 FE_index = rawdata.size() / 8;                    // size in unites of 64 bits word
00091                 int fe_index = FE_index;
00092                 for (int iblock=0; iblock < NTCC; iblock++) {     // do this once per fed in EB, four times in EE
00093                    rawdata.resize (rawdata.size() + 8);
00094                    unsigned char* ppData = rawdata.data();        // use this to navigate and create the binary
00095                    ppData[8*fe_index] = TCCid & 0xFF;             // fed_index increases in units of bytes
00096                    ppData[8*fe_index+2] = bx & 0xFF;              // bx takes bits 0-11: 0-7+8-11
00097                    ppData[8*fe_index+3] = (bx & 0xF00)>>8;
00098                    ppData[8*fe_index+3] |= 0x60;
00099                    ppData[8*fe_index+4] = lv1 & 0xFF;             // same game done for lv1, which takes bits 0-11: 0-7+8-11 
00100                    ppData[8*fe_index+5] = (lv1 & 0xF00)>>8;       // lv1
00101                    ppData[8*fe_index+6] = NTT_max;
00102                    ppData[8*fe_index+6] |= ((nsamples & 0x1)<<7); // nsamples: number time samples
00103                    ppData[8*fe_index+7] = ((nsamples & 0xE)>>1);
00104                    ppData[8*fe_index+7] |= 0x60;
00105                    if (iblock == 0) FE_index ++;
00106                    fe_index += Nrows_TCC+1;
00107                    rawdata.resize (rawdata.size() + 8*Nrows_TCC);    // 17 lines of TPG data in EB, 8 in EE
00108                 }
00109                 if (debug_) cout << "Added headers and empty lines : " << endl;
00110                 if (debug_) print(rawdata);
00111 
00112                 // -- put the B011 already, since for Endcap there can be empty
00113                 // -- lines in the TCC and the SRP blocks
00114                 unsigned char* ppData = rawdata.data();
00115                 for (int iline=FE_index-1; iline < FE_index + (Nrows_TCC+1)*NTCC -1 ; iline++) {
00116                  ppData[8*iline + 7] |= 0x60;
00117                  ppData[8*iline + 3] |= 0x60;
00118                 }
00119         }
00120 
00121         unsigned char* pData = rawdata.data();
00122 
00123         // -- Now the TCC Block :
00124 
00125         int jTT = (iTT-1);                                // jTT is the TP number insided a block;
00126         int irow = jTT/4 + (itcc_block-1)*(Nrows_TCC+1);  // you fit 4 TP's per row; move forward if you're not in the first block;
00127         int ival = jTT % 4;                               // for each block you have to skip, move of (Nrows_TCC +1) - 1 is for the TCC header
00128 
00129         // RTC required TP's tp follow global phi also in EB+, thus swap them inside the single TCC 
00130         // here you could swap ival -> 3-ival to swap phi insied EB+ supermodules  
00131         if(NUMB_SM_EB_PLU_MIN <= iDCC && iDCC <= NUMB_SM_EB_PLU_MAX)
00132           {ival = 3-ival;}
00133 
00134         FE_index += irow;                                 // ival is location inside a TP row; varies between 0-3
00135 
00136         if (debug_) cout << "Now add tower " << dec << iTT << " irow ival " << dec << irow << " " << dec << ival << endl;
00137         if (debug_) cout << "new data will be added at line " << dec << FE_index << endl;
00138 
00139         int fg = trigprim.fineGrain();
00140         int et = trigprim.compressedEt();
00141         int ttflag = trigprim.ttFlag();
00142 
00143         if (debug_ && (ttflag != 0)) {
00144                 cout << "in TCCBlock : this tower has a non zero flag" << endl;
00145                 cout << "Fedid  iTT  flag " << dec << FEDid << " " << iTT << " " << "0x" << hex << ttflag << endl;
00146         }
00147         pData[8*FE_index + ival*2] = et & 0xFF;                   // ival is location inside a TP row; varies between 0-3; tp goes in bits 0-7
00148         pData[8*FE_index + ival*2+1] = (ttflag<<1) + (fg&0x1);    // fg follows in bit 8; ttfg is in bits 9-11 
00149         if (IsEndCap) {
00150                 // re-write the TCCid  and N_Tower_Max :
00151                 int ibase = 8*(FE_index - (int)(jTT/4) -1);
00152                 pData[ibase] = TCCid & 0xFF;
00153                 pData[ibase+6] = NTT_max;
00154                 pData[ibase+6] |= ((nsamples & 0x1)<<7);
00155                 pData[ibase+7] |= ((nsamples & 0xE)>>1);
00156         }
00157         if (debug_) cout << "pData[8*FE_index + ival*2+1] = " << hex << (int)pData[8*FE_index + ival*2+1] << endl;
00158         if (debug_) cout << "ttflag ttflag<<1 " << hex << ttflag << " " << hex << (ttflag<<1) << endl;
00159         if (debug_) cout << "fg&0x1 " << hex << (fg&0x1) << endl;
00160         if (debug_) cout << "sum " << hex << ( (ttflag<<1) + (fg&0x1) ) << endl;
00161         if (ival %2 == 1) pData[8*FE_index + ival*2+1] |= 0x60;
00162         if (debug_) cout << "ttflag et fgbit " << hex << ttflag << " " << hex << et << " " << hex << fg << endl;
00163         if (debug_) print(rawdata);
00164 
00165         
00166 }
00167 
00168