Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:10

0001 /*  
0002  *
0003  *  \author  N. Marinelli IASA 
0004  *  \author G. Della Ricca
0005  *  \author G. Franzoni
0006  *  \author A. Ghezzi
0007  *
0008  */
0009 
0010 #include "EcalTB07DaqFormatter.h"
0011 #include <DataFormats/FEDRawData/interface/FEDRawData.h>
0012 #include <DataFormats/EcalDetId/interface/EBDetId.h>
0013 #include <DataFormats/EcalDetId/interface/EEDetId.h>
0014 #include <DataFormats/EcalDetId/interface/EcalTrigTowerDetId.h>
0015 #include <DataFormats/EcalDigi/interface/EBDataFrame.h>
0016 #include <DataFormats/EcalDigi/interface/EEDataFrame.h>
0017 #include <DataFormats/EcalDigi/interface/EcalDigiCollections.h>
0018 
0019 #include <EventFilter/EcalTBRawToDigi/interface/EcalDCCHeaderRuntypeDecoder.h>
0020 #include <DataFormats/EcalDigi/interface/EcalTriggerPrimitiveDigi.h>
0021 #include <DataFormats/EcalDigi/interface/EcalTriggerPrimitiveSample.h>
0022 #include <FWCore/ParameterSet/interface/FileInPath.h>
0023 
0024 #include "DCCDataParser.h"
0025 #include "DCCEventBlock.h"
0026 #include "DCCTowerBlock.h"
0027 #include "DCCTCCBlock.h"
0028 #include "DCCXtalBlock.h"
0029 #include "DCCDataMapper.h"
0030 
0031 #include <iostream>
0032 #include <string>
0033 
0034 EcalTB07DaqFormatter::EcalTB07DaqFormatter(std::string tbName,
0035                                            int cryIcMap[68][5][5],
0036                                            int tbStatusToLocation[71],
0037                                            int tbTowerIDToLocation[201]) {
0038   LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter";
0039   std::vector<uint32_t> parameters;
0040   parameters.push_back(10);  // parameters[0] is the xtal samples
0041   parameters.push_back(1);   // parameters[1] is the number of trigger time samples for TPG's
0042   parameters.push_back(68);  // parameters[2] is the number of TT
0043   parameters.push_back(68);  // parameters[3] is the number of SR Flags
0044   parameters.push_back(1);   // parameters[4] is the dcc id
0045   parameters.push_back(1);   // parameters[5] is the sr id
0046   parameters.push_back(1);   // parameters[6] is the tcc1 id
0047   parameters.push_back(2);   // parameters[7] is the tcc2 id
0048   parameters.push_back(3);   // parameters[8] is the tcc3 id
0049   parameters.push_back(4);   // parameters[9] is the tcc4 id
0050 
0051   theParser_ = new DCCTBDataParser(parameters);
0052 
0053   tbName_ = tbName;
0054 
0055   for (int i = 0; i < 68; ++i)
0056     for (int j = 0; j < 5; ++j)
0057       for (int k = 0; k < 5; ++k)
0058         cryIcMap_[i][j][k] = cryIcMap[i][j][k];
0059 
0060   for (int i = 0; i < 71; ++i)
0061     tbStatusToLocation_[i] = tbStatusToLocation[i];
0062 
0063   for (int i = 0; i < 201; ++i)
0064     tbTowerIDToLocation_[i] = tbTowerIDToLocation[i];
0065 }
0066 
0067 void EcalTB07DaqFormatter::interpretRawData(const FEDRawData& fedData,
0068                                             EBDigiCollection& digicollection,
0069                                             EEDigiCollection& eeDigiCollection,
0070                                             EcalPnDiodeDigiCollection& pndigicollection,
0071                                             EcalRawDataCollection& DCCheaderCollection,
0072                                             EBDetIdCollection& dccsizecollection,
0073                                             EcalElectronicsIdCollection& ttidcollection,
0074                                             EcalElectronicsIdCollection& blocksizecollection,
0075                                             EBDetIdCollection& chidcollection,
0076                                             EBDetIdCollection& gaincollection,
0077                                             EBDetIdCollection& gainswitchcollection,
0078                                             EcalElectronicsIdCollection& memttidcollection,
0079                                             EcalElectronicsIdCollection& memblocksizecollection,
0080                                             EcalElectronicsIdCollection& memgaincollection,
0081                                             EcalElectronicsIdCollection& memchidcollection,
0082                                             EcalTrigPrimDigiCollection& tpcollection) {
0083   const unsigned char* pData = fedData.data();
0084   int length = fedData.size();
0085   bool shit = true;
0086   unsigned int tower = 0;
0087   int ch = 0;
0088   int strip = 0;
0089 
0090   LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0091                                 << "size " << length;
0092 
0093   // mean + 3sigma estimation needed when switching to 0suppressed data
0094   digicollection.reserve(kCrystals);
0095   eeDigiCollection.reserve(kCrystals);
0096   pnAllocated = false;
0097 
0098   theParser_->parseBuffer(reinterpret_cast<const uint32_t*>(pData), static_cast<uint32_t>(length), shit);
0099 
0100   std::vector<DCCTBEventBlock*>& dccEventBlocks = theParser_->dccEvents();
0101 
0102   // Access each DCCTB block
0103   for (std::vector<DCCTBEventBlock*>::iterator itEventBlock = dccEventBlocks.begin();
0104        itEventBlock != dccEventBlocks.end();
0105        itEventBlock++) {
0106     bool _displayParserMessages = false;
0107     if ((*itEventBlock)->eventHasErrors() && _displayParserMessages) {
0108       edm::LogWarning("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0109                                            << "errors found from parser... ";
0110       edm::LogWarning("EcalTB07RawToDigi") << (*itEventBlock)->eventErrorString();
0111       edm::LogWarning("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0112                                            << "... errors from parser notified";
0113     }
0114 
0115     // getting the fields of the DCC header
0116     EcalDCCHeaderBlock theDCCheader;
0117 
0118     theDCCheader.setId(46);  // tb EE unpacker: forced to 46 to match EE region used at h2
0119     int fedId = (*itEventBlock)->getDataField("FED/DCC ID");
0120     theDCCheader.setFedId(fedId);  // fed id as found in raw data (0... 35 at tb )
0121 
0122     theDCCheader.setRunNumber((*itEventBlock)->getDataField("RUN NUMBER"));
0123     short trigger_type = (*itEventBlock)->getDataField("TRIGGER TYPE");
0124     short zs = (*itEventBlock)->getDataField("ZS");
0125     short tzs = (*itEventBlock)->getDataField("TZS");
0126     short sr = (*itEventBlock)->getDataField("SR");
0127     bool dataIsSuppressed;
0128 
0129     // if zs&&tzs the suppression algo is used in DCC, the data are not suppressed and zs-bits are set
0130     if (zs && !(tzs))
0131       dataIsSuppressed = true;
0132     else
0133       dataIsSuppressed = false;
0134 
0135     if (trigger_type > 0 && trigger_type < 5) {
0136       theDCCheader.setBasicTriggerType(trigger_type);
0137     } else {
0138       edm::LogWarning("EcalTB07RawToDigiTriggerType") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0139                                                       << "unrecognized TRIGGER TYPE: " << trigger_type;
0140     }
0141     theDCCheader.setLV1((*itEventBlock)->getDataField("LV1"));
0142     theDCCheader.setOrbit((*itEventBlock)->getDataField("ORBIT COUNTER"));
0143     theDCCheader.setBX((*itEventBlock)->getDataField("BX"));
0144     theDCCheader.setErrors((*itEventBlock)->getDataField("DCC ERRORS"));
0145     theDCCheader.setSelectiveReadout(sr);
0146     theDCCheader.setZeroSuppression(zs);
0147     theDCCheader.setTestZeroSuppression(tzs);
0148     theDCCheader.setSrpStatus((*itEventBlock)->getDataField("SR_CHSTATUS"));
0149 
0150     std::vector<short> theTCCs;
0151     for (int i = 0; i < MAX_TCC_SIZE; i++) {
0152       char TCCnum[20];
0153       sprintf(TCCnum, "TCC_CHSTATUS#%d", i + 1);
0154       std::string TCCnumS(TCCnum);
0155       theTCCs.push_back((*itEventBlock)->getDataField(TCCnumS));
0156     }
0157     theDCCheader.setTccStatus(theTCCs);
0158 
0159     std::vector<DCCTBTCCBlock*> tccBlocks = (*itEventBlock)->tccBlocks();
0160 
0161     for (std::vector<DCCTBTCCBlock*>::iterator itTCCBlock = tccBlocks.begin(); itTCCBlock != tccBlocks.end();
0162          itTCCBlock++) {
0163       std::vector<std::pair<int, bool> > TpSamples = (*itTCCBlock)->triggerSamples();
0164       // std::vector of 3 bits
0165       std::vector<int> TpFlags = (*itTCCBlock)->triggerFlags();
0166 
0167       // there have always to be 68 primitives and flags, per FED
0168       if (TpSamples.size() == 68 && TpFlags.size() == 68) {
0169         for (int i = 0; i < ((int)TpSamples.size()); i++) {
0170           int etaTT = (i) / kTowersInPhi + 1;
0171           int phiTT = (i) % kTowersInPhi + 1;
0172 
0173           // follow HB convention in iphi
0174           phiTT = 3 - phiTT;
0175           if (phiTT <= 0)
0176             phiTT = phiTT + 72;
0177 
0178           EcalTriggerPrimitiveSample theSample(TpSamples[i].first, TpSamples[i].second, TpFlags[i]);
0179 
0180           EcalTrigTowerDetId idtt(2, EcalBarrel, etaTT, phiTT, 0);
0181           EcalTriggerPrimitiveDigi thePrimitive(idtt);
0182           thePrimitive.setSize(1);  // hard coded
0183           thePrimitive.setSample(0, theSample);
0184 
0185           tpcollection.push_back(thePrimitive);
0186 
0187           LogDebug("EcalTB07RawToDigiTpg")
0188               << "@SUBS=EcalTB07DaqFormatter::interpretRawData"
0189               << "tower: " << (i + 1) << " primitive: " << TpSamples[i].first << " flag: " << TpSamples[i].second;
0190 
0191           LogDebug("EcalTB07RawToDigiTpg") << "@SUBS=EcalTB07DaqFormatter::interpretRawData"
0192                                            << "tower: " << (i + 1) << " flag: " << TpFlags[i];
0193         }  // end loop on tower primitives
0194 
0195       }  // end if
0196       else {
0197         edm::LogWarning("EcalTB07RawToDigiTpg")
0198             << "68 elements not found for TpFlags or TpSamples, collection will be empty";
0199       }
0200     }
0201 
0202     short TowerStatus[MAX_TT_SIZE + 1];
0203     char buffer[25];
0204     std::vector<short> theTTstatus;
0205     for (int i = 1; i < MAX_TT_SIZE + 1; i++) {
0206       sprintf(buffer, "FE_CHSTATUS#%d", i);
0207       std::string Tower(buffer);
0208       TowerStatus[i] = (*itEventBlock)->getDataField(Tower);
0209       theTTstatus.push_back(TowerStatus[i]);
0210       //std::cout << "tower " << i << " has status " <<  TowerStatus[i] << std::endl;
0211     }
0212     bool checkTowerStatus = TowerStatus[1] == 0 && TowerStatus[2] == 0 && TowerStatus[3] == 0 && TowerStatus[4] == 0;
0213     for (int i = 5; i < MAX_TT_SIZE + 1; ++i)
0214       checkTowerStatus = checkTowerStatus && TowerStatus[i] == 1;
0215     if (!checkTowerStatus) {
0216       for (int i = 1; i < MAX_TT_SIZE + 1; ++i) {
0217         std::cout << "tower " << i << " has status " << TowerStatus[i] << std::endl;
0218       }
0219     }
0220 
0221     theDCCheader.setFEStatus(theTTstatus);
0222 
0223     EcalDCCTBHeaderRuntypeDecoder theRuntypeDecoder;
0224     uint32_t DCCruntype = (*itEventBlock)->getDataField("RUN TYPE");
0225     theRuntypeDecoder.Decode(DCCruntype, &theDCCheader);
0226     //DCCHeader filled!
0227     DCCheaderCollection.push_back(theDCCheader);
0228 
0229     // add three more DCC headers (EE region used at h4)
0230     EcalDCCHeaderBlock hdr = theDCCheader;
0231     hdr.setId(04);
0232     DCCheaderCollection.push_back(hdr);
0233     hdr.setId(05);
0234     DCCheaderCollection.push_back(hdr);
0235     hdr.setId(06);
0236     DCCheaderCollection.push_back(hdr);
0237 
0238     std::vector<DCCTBTowerBlock*> dccTowerBlocks = (*itEventBlock)->towerBlocks();
0239     LogDebug("EcalTB07RawToDigi") << "@SUBS=EcalTB07DaqFormatter::interpretRawData"
0240                                   << "dccTowerBlocks size " << dccTowerBlocks.size();
0241 
0242     _expTowersIndex = 0;
0243     _numExpectedTowers = 0;
0244     for (int v = 0; v < 71; v++) {
0245       _ExpectedTowers[v] = 99999;
0246     }
0247 
0248     // note: these are the tower statuses handled at the moment - to be completed
0249     // staus==0:   tower expected;
0250     // staus==9:   Synk error LV1, tower expected;
0251     // staus==10:  Synk error BX, tower expected;
0252     // status==1, 2, 3, 4, 5:  tower not expected
0253     for (int u = 1; u < (kTriggerTowersAndMem + 1); u++) {
0254       // map status array to expected tower array
0255       //int towerMap[kTriggerTowersAndMem+1];
0256       //for (int i=0; i<kTriggerTowersAndMem; ++i ) towerMap[i] = i;
0257       //towerMap[1] = 6;
0258       //towerMap[2] = 2;
0259       //towerMap[3] = 1;
0260       //towerMap[4] = 5;
0261 
0262       if (TowerStatus[u] == 0 || TowerStatus[u] == 9 || TowerStatus[u] == 10) {
0263         _ExpectedTowers[_expTowersIndex] = tbStatusToLocation_[u];
0264         _expTowersIndex++;
0265         _numExpectedTowers++;
0266       }
0267     }
0268     // resetting counter of expected towers
0269     _expTowersIndex = 0;
0270 
0271     // if number of dccEventBlocks NOT same as expected stop
0272     if (!(dccTowerBlocks.size() == _numExpectedTowers)) {
0273       // we probably always want to know if this happens
0274       edm::LogWarning("EcalTB07RawToDigiNumTowerBlocks")
0275           << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0276           << "number of TowerBlocks found (" << dccTowerBlocks.size() << ") differs from expected ("
0277           << _numExpectedTowers << ") skipping event";
0278 
0279       EBDetId idsm(1, 1);
0280       dccsizecollection.push_back(idsm);
0281 
0282       return;
0283     }
0284 
0285     // Access the Tower block
0286     for (std::vector<DCCTBTowerBlock*>::iterator itTowerBlock = dccTowerBlocks.begin();
0287          itTowerBlock != dccTowerBlocks.end();
0288          itTowerBlock++) {
0289       tower = (*itTowerBlock)->towerID();
0290       // here is "correct" h2 map
0291       //if ( tower == 1  ) tower = 6;
0292       //if ( tower == 71 ) tower = 2;
0293       //if ( tower == 80 ) tower = 1;
0294       //if ( tower == 45 ) tower = 5;
0295       tower = tbTowerIDToLocation_[tower];
0296 
0297       // checking if tt in data is the same as tt expected
0298       // else skip tower and increment problem counter
0299 
0300       // dccId set to 46 in order to match 'real' CMS positio at H2
0301 
0302       EcalElectronicsId idtt(46, _ExpectedTowers[_expTowersIndex], 1, 1);
0303 
0304       if (!(tower == _ExpectedTowers[_expTowersIndex])) {
0305         if (_ExpectedTowers[_expTowersIndex] <= 68) {
0306           edm::LogWarning("EcalTB07RawToDigiTowerId")
0307               << "@SUBS=EcalTB07DaqFormatter::interpretRawData"
0308               << "TTower id found (=" << tower << ") different from expected (=" << _ExpectedTowers[_expTowersIndex]
0309               << ") " << (_expTowersIndex + 1) << "-th tower checked"
0310               << "\n Real hardware id is " << (*itTowerBlock)->towerID();
0311 
0312           //  report on failed tt_id for regular tower block
0313           ttidcollection.push_back(idtt);
0314         } else {
0315           edm::LogWarning("EcalTB07RawToDigiTowerId")
0316               << "@SUB=EcalTB07DaqFormatter:interpretRawData"
0317               << "DecodeMEM: tower " << tower << " is not the same as expected "
0318               << ((int)_ExpectedTowers[_expTowersIndex]) << " (according to DCC header channel status)";
0319 
0320           // report on failed tt_id for mem tower block
0321           // chosing channel 1 as representative
0322           EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], 1, 1);
0323           memttidcollection.push_back(id);
0324         }
0325 
0326         ++_expTowersIndex;
0327         continue;
0328       }  // if TT id found  different than expected
0329 
0330       /*********************************
0331        //    tt: 1 ... 68: crystal data
0332        *********************************/
0333       if (0 < (*itTowerBlock)->towerID() && ((*itTowerBlock)->towerID() < (kTriggerTowers + 1) ||
0334                                              (*itTowerBlock)->towerID() == 71 || (*itTowerBlock)->towerID() == 80)) {
0335         std::vector<DCCTBXtalBlock*>& xtalDataBlocks = (*itTowerBlock)->xtalBlocks();
0336 
0337         // if there is no zero suppression, tower block must have have 25 channels in it
0338         if ((!dataIsSuppressed) && (xtalDataBlocks.size() != kChannelsPerTower)) {
0339           edm::LogWarning("EcalTB07RawToDigiTowerSize")
0340               << "EcalTB07DaqFormatter::interpretRawData, no zero suppression "
0341               << "wrong tower block size is: " << xtalDataBlocks.size() << " at LV1 "
0342               << (*itEventBlock)->getDataField("LV1") << " for TT " << _ExpectedTowers[_expTowersIndex];
0343           // report on wrong tt block size
0344           blocksizecollection.push_back(idtt);
0345 
0346           ++_expTowersIndex;
0347           continue;
0348         }
0349 
0350         short cryInTower = 0;
0351 
0352         short expStripInTower;
0353         short expCryInStrip;
0354         short expCryInTower = 0;
0355 
0356         // Access the Xstal data
0357         for (std::vector<DCCTBXtalBlock*>::iterator itXtalBlock = xtalDataBlocks.begin();
0358              itXtalBlock != xtalDataBlocks.end();
0359              itXtalBlock++) {  //loop on crys of a  tower
0360 
0361           strip = (*itXtalBlock)->stripID();
0362           ch = (*itXtalBlock)->xtalID();
0363           cryInTower = (strip - 1) * kChannelsPerCard + (ch - 1);
0364 
0365           expStripInTower = expCryInTower / 5 + 1;
0366           expCryInStrip = expCryInTower % 5 + 1;
0367 
0368           // FIXME: waiting for geometry to do (TT, strip,chNum) <--> (SMChId)
0369           // short abscissa = (_ExpectedTowers[_expTowersIndex]-1)  /4;
0370           // short ordinate = (_ExpectedTowers[_expTowersIndex]-1)  %4;
0371           // temporarily choosing central crystal in trigger tower
0372           // int cryIdInSM  = 45 + ordinate*5 + abscissa * 100;
0373 
0374           // in case of 0 zuppressed data, check that cryInTower constantly grows
0375           if (dataIsSuppressed) {
0376             if (strip < 1 || 5 < strip || ch < 1 || 5 < ch) {
0377               int sm = 1;  // hardcoded because of test  beam
0378               for (int StripInTower_ = 1; StripInTower_ < 6; StripInTower_++) {
0379                 for (int CryInStrip_ = 1; CryInStrip_ < 6; CryInStrip_++) {
0380                   int ic = cryIc(tower, StripInTower_, CryInStrip_);
0381                   EBDetId idExp(sm, ic, 1);
0382                   chidcollection.push_back(idExp);
0383                 }
0384               }
0385 
0386               edm::LogWarning("EcalTB07RawToDigiChId")
0387                   << "EcalTB07DaqFormatter::interpretRawData with zero suppression, "
0388                   << " wrong channel id, since out of range: "
0389                   << "\t strip: " << strip << "\t channel: " << ch << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
0390                   << "\t at LV1 : " << (*itEventBlock)->getDataField("LV1");
0391 
0392               expCryInTower++;
0393               continue;
0394             }
0395 
0396             // correct ordering
0397             if (cryInTower >= expCryInTower) {
0398               expCryInTower = cryInTower + 1;
0399             }
0400 
0401             // cry_id wrong because of incorrect ordering within trigger tower
0402             else {
0403               edm::LogWarning("EcalTB07RawToDigiChId")
0404                   << "EcalTB07DaqFormatter::interpretRawData with zero suppression, "
0405                   << " based on ch ordering within tt, wrong channel id: "
0406                   << "\t strip: " << strip << "\t channel: " << ch << "\t cryInTower " << cryInTower
0407                   << "\t expCryInTower: " << expCryInTower << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
0408                   << "\t at LV1: " << (*itEventBlock)->getDataField("LV1");
0409 
0410               int sm = 1;  // hardcoded because of test  beam
0411               for (int StripInTower_ = 1; StripInTower_ < 6; StripInTower_++) {
0412                 for (int CryInStrip_ = 1; CryInStrip_ < 6; CryInStrip_++) {
0413                   int ic = cryIc(tower, StripInTower_, CryInStrip_);
0414                   EBDetId idExp(sm, ic, 1);
0415                   chidcollection.push_back(idExp);
0416                 }
0417               }
0418 
0419               // chennel with id which does not follow correct odering
0420               expCryInTower++;
0421               continue;
0422 
0423             }  // end 'ch_id does not respect growing order'
0424 
0425           }  // end   if zero supression
0426 
0427           else {
0428             // checking that ch and strip are within range and cryInTower is as expected
0429             if (cryInTower != expCryInTower || strip < 1 || kStripsPerTower < strip || ch < 1 ||
0430                 kChannelsPerStrip < ch) {
0431               int ic = cryIc(tower, expStripInTower, expCryInStrip);
0432               int sm = 1;  // hardcoded because of test  beam
0433               EBDetId idExp(sm, ic, 1);
0434 
0435               edm::LogWarning("EcalTB07RawToDigiChId")
0436                   << "EcalTB07DaqFormatter::interpretRawData no zero suppression "
0437                   << " wrong channel id for channel: " << expCryInStrip << "\t strip: " << expStripInTower
0438                   << "\t in TT: " << _ExpectedTowers[_expTowersIndex]
0439                   << "\t at LV1: " << (*itEventBlock)->getDataField("LV1")
0440                   << "\t   (in the data, found channel:  " << ch << "\t strip:  " << strip << " ).";
0441 
0442               // report on wrong channel id
0443               chidcollection.push_back(idExp);
0444 
0445               // there has been unexpected crystal id, dataframe not to go to the Event
0446               expCryInTower++;
0447               continue;
0448 
0449             }  // if channel in data does not equal expected channel
0450 
0451             expCryInTower++;
0452 
0453           }  // end 'not zero suppression'
0454 
0455           // data  to be stored in EBDataFrame, identified by EBDetId
0456           int ic = cryIc(tower, strip, ch);
0457           int sm = 1;
0458           EBDetId id(sm, ic, 1);
0459           // EE data to be stored in EEDataFrame, identified by EEDetId
0460           // eeId(int i, int j, int iz (+1/-1), int mode = XYMODE)
0461           int ix = getEE_ix(tower, strip, ch);
0462           int iy = getEE_iy(tower, strip, ch);
0463 
0464           int iz = 1;
0465           if (tbName_ == "h4")
0466             iz = -1;
0467           EEDetId eeId(ix, iy, iz);
0468 
0469           // here data frame go into the Event
0470           // removed later on (with a pop_back()) if gain==0 or if forbidden-gain-switch
0471           digicollection.push_back(id);
0472           eeDigiCollection.push_back(eeId);
0473           EBDataFrame theFrame(digicollection.back());
0474           EEDataFrame eeFrame(eeDigiCollection.back());
0475 
0476           std::vector<int> xtalDataSamples = (*itXtalBlock)->xtalDataSamples();
0477           //theFrame.setSize(xtalDataSamples.size()); // if needed, to be changed when constructing digicollection
0478           //eeFrame. setSize(xtalDataSamples.size()); // if needed, to be changed when constructing eeDigicollection
0479 
0480           // gain cannot be 0, checking for that
0481           bool gainIsOk = true;
0482           unsigned gain_mask = 12288;  //12th and 13th bit
0483           std::vector<int> xtalGain;
0484 
0485           for (unsigned short i = 0; i < xtalDataSamples.size(); ++i) {
0486             theFrame.setSample(i, xtalDataSamples[i]);
0487             eeFrame.setSample(i, xtalDataSamples[i]);
0488 
0489             if ((xtalDataSamples[i] & gain_mask) == 0) {
0490               gainIsOk = false;
0491             }
0492 
0493             xtalGain.push_back(0);
0494             xtalGain[i] |= (xtalDataSamples[i] >> 12);
0495           }
0496 
0497           if (!gainIsOk) {
0498             edm::LogWarning("EcalTB07RawToDigiGainZero")
0499                 << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0500                 << " gain==0 for strip: " << expStripInTower << "\t channel: " << expCryInStrip
0501                 << "\t in TT: " << _ExpectedTowers[_expTowersIndex] << "\t ic: " << ic
0502                 << "\t at LV1: " << (*itEventBlock)->getDataField("LV1");
0503             // report on gain==0
0504             gaincollection.push_back(id);
0505 
0506             // there has been a gain==0, dataframe not to go to the Event
0507             digicollection.pop_back();
0508             eeDigiCollection.pop_back();
0509             continue;  //         expCryInTower already incremented
0510           }
0511 
0512           // looking for forbidden gain transitions
0513 
0514           short firstGainWrong = -1;
0515           short numGainWrong = 0;
0516 
0517           for (unsigned short i = 0; i < xtalGain.size(); i++) {
0518             if (i > 0 && xtalGain[i - 1] > xtalGain[i]) {
0519               numGainWrong++;  // counting forbidden gain transitions
0520 
0521               if (firstGainWrong == -1) {
0522                 firstGainWrong = i;
0523                 edm::LogWarning("EcalTB07RawToDigiGainSwitch")
0524                     << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0525                     << "channelHasGainSwitchProblem: crystal eta = " << id.ieta() << " phi = " << id.iphi();
0526               }
0527               edm::LogWarning("EcalTB07RawToDigiGainSwitch")
0528                   << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0529                   << "channelHasGainSwitchProblem: sample = " << (i - 1) << " gain: " << xtalGain[i - 1]
0530                   << " sample: " << i << " gain: " << xtalGain[i];
0531             }
0532           }
0533 
0534           if (numGainWrong > 0) {
0535             gainswitchcollection.push_back(id);
0536 
0537             edm::LogWarning("EcalTB07RawToDigiGainSwitch")
0538                 << "@SUB=EcalTB07DaqFormatter:interpretRawData"
0539                 << "channelHasGainSwitchProblem: more than 1 wrong transition";
0540 
0541             for (unsigned short i1 = 0; i1 < xtalDataSamples.size(); ++i1) {
0542               int countADC = 0x00000FFF;
0543               countADC &= xtalDataSamples[i1];
0544               LogDebug("EcalTB07RawToDigi") << "Sample " << i1 << " ADC " << countADC << " Gain " << xtalGain[i1];
0545             }
0546 
0547             // there has been a forbidden gain transition,  dataframe not to go to the Event
0548             digicollection.pop_back();
0549             eeDigiCollection.pop_back();
0550             continue;  //         expCryInTower already incremented
0551 
0552           }  // END of:   'if there is a forbidden gain transition'
0553 
0554         }  // end loop on crystals within a tower block
0555 
0556         _expTowersIndex++;
0557       }  // end: tt1 ... tt68, crystal data
0558 
0559       /******************************************************************
0560        //    tt 69 and 70:  two mem boxes, holding PN0 ... PN9
0561        ******************************************************************/
0562       else if ((*itTowerBlock)->towerID() == 69 || (*itTowerBlock)->towerID() == 70) {
0563         LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0564                                       << "processing mem box num: " << (*itTowerBlock)->towerID();
0565 
0566         // if tt 69 or 70 found, allocate Pn digi collection
0567         if (!pnAllocated) {
0568           pndigicollection.reserve(kPns);
0569           pnAllocated = true;
0570         }
0571 
0572         DecodeMEM((*itTowerBlock),
0573                   pndigicollection,
0574                   memttidcollection,
0575                   memblocksizecollection,
0576                   memgaincollection,
0577                   memchidcollection);
0578 
0579       }  // end of < if it is a mem box>
0580 
0581       // wrong tt id
0582       else {
0583         edm::LogWarning("EcalTB07RawToDigiTowerId")
0584             << "@SUB=EcalTB07DaqFormatter::interpretRawData"
0585             << " processing tt with ID not existing ( " << (*itTowerBlock)->towerID() << ")";
0586         ++_expTowersIndex;
0587         continue;
0588       }  // end: tt id error
0589 
0590     }  // end loop on trigger towers
0591 
0592   }  // end loop on events
0593 }
0594 
0595 void EcalTB07DaqFormatter::DecodeMEM(DCCTBTowerBlock* towerblock,
0596                                      EcalPnDiodeDigiCollection& pndigicollection,
0597                                      EcalElectronicsIdCollection& memttidcollection,
0598                                      EcalElectronicsIdCollection& memblocksizecollection,
0599                                      EcalElectronicsIdCollection& memgaincollection,
0600                                      EcalElectronicsIdCollection& memchidcollection) {
0601   LogDebug("EcalTB07RawToDigi") << "@SUB=EcalTB07DaqFormatter::DecodeMEM"
0602                                 << "in mem " << towerblock->towerID();
0603 
0604   int tower_id = towerblock->towerID();
0605   int mem_id = tower_id - 69;
0606 
0607   // initializing container
0608   for (int st_id = 0; st_id < kStripsPerTower; st_id++) {
0609     for (int ch_id = 0; ch_id < kChannelsPerStrip; ch_id++) {
0610       for (int sa = 0; sa < 11; sa++) {
0611         memRawSample_[st_id][ch_id][sa] = -1;
0612       }
0613     }
0614   }
0615 
0616   // check that tower block id corresponds to mem boxes
0617   if (tower_id != 69 && tower_id != 70) {
0618     edm::LogWarning("EcalTB07RawToDigiTowerId") << "@SUB=EcalTB07DaqFormatter:decodeMem"
0619                                                 << "DecodeMEM: this is not a mem box tower (" << tower_id << ")";
0620     ++_expTowersIndex;
0621     return;
0622   }
0623 
0624   /******************************************************************************
0625    // getting the raw hits from towerBlock while checking tt and ch data structure 
0626    ******************************************************************************/
0627   std::vector<DCCTBXtalBlock*>& dccXtalBlocks = towerblock->xtalBlocks();
0628   std::vector<DCCTBXtalBlock*>::iterator itXtal;
0629 
0630   // checking mem tower block fo size
0631   if (dccXtalBlocks.size() != kChannelsPerTower) {
0632     LogDebug("EcalTB07RawToDigiDccBlockSize")
0633         << "@SUB=EcalTB07DaqFormatter:decodeMem"
0634         << " wrong dccBlock size, namely: " << dccXtalBlocks.size() << ", for mem " << _ExpectedTowers[_expTowersIndex];
0635 
0636     // reporting mem-tt block size problem
0637     // chosing channel 1 as representative as a dummy...
0638     EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], 1, 1);
0639     memblocksizecollection.push_back(id);
0640 
0641     ++_expTowersIndex;
0642     return;  // if mem tt block size not ok - do not build any Pn digis
0643   }
0644 
0645   // loop on channels of the mem block
0646   int cryCounter = 0;
0647   int strip_id = 0;
0648   int xtal_id = 0;
0649 
0650   for (itXtal = dccXtalBlocks.begin(); itXtal < dccXtalBlocks.end(); itXtal++) {
0651     strip_id = (*itXtal)->getDataField("STRIP ID");
0652     xtal_id = (*itXtal)->getDataField("XTAL ID");
0653     int wished_strip_id = cryCounter / kStripsPerTower;
0654     int wished_ch_id = cryCounter % kStripsPerTower;
0655 
0656     if ((wished_strip_id + 1) != ((int)strip_id) || (wished_ch_id + 1) != ((int)xtal_id)) {
0657       LogDebug("EcalTB07RawToDigiChId") << "@SUB=EcalTB07DaqFormatter:decodeMem"
0658                                         << " in mem " << towerblock->towerID() << ", expected:\t strip"
0659                                         << (wished_strip_id + 1) << " cry " << (wished_ch_id + 1) << "\tfound: "
0660                                         << "  strip " << strip_id << "  cry " << xtal_id;
0661 
0662       // report on crystal with unexpected indices
0663       EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], wished_strip_id, wished_ch_id);
0664       memchidcollection.push_back(id);
0665     }
0666 
0667     // Accessing the 10 time samples per Xtal:
0668     memRawSample_[wished_strip_id][wished_ch_id][1] = (*itXtal)->getDataField("ADC#1");
0669     memRawSample_[wished_strip_id][wished_ch_id][2] = (*itXtal)->getDataField("ADC#2");
0670     memRawSample_[wished_strip_id][wished_ch_id][3] = (*itXtal)->getDataField("ADC#3");
0671     memRawSample_[wished_strip_id][wished_ch_id][4] = (*itXtal)->getDataField("ADC#4");
0672     memRawSample_[wished_strip_id][wished_ch_id][5] = (*itXtal)->getDataField("ADC#5");
0673     memRawSample_[wished_strip_id][wished_ch_id][6] = (*itXtal)->getDataField("ADC#6");
0674     memRawSample_[wished_strip_id][wished_ch_id][7] = (*itXtal)->getDataField("ADC#7");
0675     memRawSample_[wished_strip_id][wished_ch_id][8] = (*itXtal)->getDataField("ADC#8");
0676     memRawSample_[wished_strip_id][wished_ch_id][9] = (*itXtal)->getDataField("ADC#9");
0677     memRawSample_[wished_strip_id][wished_ch_id][10] = (*itXtal)->getDataField("ADC#10");
0678 
0679     cryCounter++;
0680   }  // end loop on crystals of mem dccXtalBlock
0681 
0682   // tower accepted and digi read from all 25 channels.
0683   // Increase counter of expected towers before unpacking in the 5 PNs
0684   ++_expTowersIndex;
0685 
0686   /************************************************************
0687    // unpacking and 'cooking' the raw numbers to get PN sample
0688    ************************************************************/
0689   int tempSample = 0;
0690   int memStoreIndex = 0;
0691   int ipn = 0;
0692   for (memStoreIndex = 0; memStoreIndex < 500; memStoreIndex++) {
0693     data_MEM[memStoreIndex] = -1;
0694   }
0695 
0696   for (int strip = 0; strip < kStripsPerTower; strip++) {            // loop on strips
0697     for (int channel = 0; channel < kChannelsPerStrip; channel++) {  // loop on channels
0698 
0699       if (strip % 2 == 0) {
0700         ipn = mem_id * 5 + channel;
0701       } else {
0702         ipn = mem_id * 5 + 4 - channel;
0703       }
0704 
0705       for (int sample = 0; sample < kSamplesPerChannel; sample++) {
0706         tempSample = memRawSample_[strip][channel][sample + 1];
0707 
0708         int new_data = 0;
0709         if (strip % 2 == 1) {
0710           // 1) if strip number is even, 14 bits are reversed in order
0711           for (int ib = 0; ib < 14; ib++) {
0712             new_data <<= 1;
0713             new_data = new_data | (tempSample & 1);
0714             tempSample >>= 1;
0715           }
0716         } else {
0717           new_data = tempSample;
0718         }
0719 
0720         // 2) flip 11th bit for AD9052 still there on MEM !
0721         // 3) mask with 1 1111 1111 1111
0722         new_data = (new_data ^ 0x800) & 0x3fff;  // (new_data  XOR 1000 0000 0000) & 11 1111 1111 1111
0723         // new_data = (new_data ^ 0x800) & 0x1fff;    // (new_data  XOR 1000 0000 0000) & 1 1111 1111 1111
0724 
0725         //(Bit 12) == 1 -> Gain 16;    (Bit 12) == 0 -> Gain 1
0726         // gain in mem can be 1 or 16 encoded resp. with 0 ir 1 in the 13th bit.
0727         // checking and reporting if there is any sample with gain==2,3
0728         short sampleGain = (new_data & 0x3000) / 4096;
0729         if (sampleGain == 2 || sampleGain == 3) {
0730           EcalElectronicsId id(1, (int)_ExpectedTowers[_expTowersIndex], strip, channel);
0731           memgaincollection.push_back(id);
0732 
0733           edm::LogWarning("EcalTB07RawToDigiGainZero")
0734               << "@SUB=EcalTB07DaqFormatter:decodeMem"
0735               << "in mem " << towerblock->towerID() << " :\t strip: " << (strip + 1) << " cry: " << (channel + 1)
0736               << " has 14th bit non zero! Gain results: " << sampleGain << ".";
0737 
0738           continue;
0739         }  // end 'if gain is zero'
0740 
0741         memStoreIndex = ipn * 50 + strip * kSamplesPerChannel + sample;
0742         // storing in data_MEM also the gain bits
0743         data_MEM[memStoreIndex] = new_data & 0x3fff;
0744 
0745       }  // loop on samples
0746     }  // loop on strips
0747   }  // loop on channels
0748 
0749   for (int pnId = 0; pnId < kPnPerTowerBlock; pnId++)
0750     pnIsOkInBlock[pnId] = true;
0751   // if anything was wrong with mem_tt_id or mem_tt_size: you would have already exited
0752   // otherwise, if any problem with ch_gain or ch_id: must not produce digis for the pertaining Pn
0753 
0754   if (!(memgaincollection.empty() && memchidcollection.empty())) {
0755     for (EcalElectronicsIdCollection::const_iterator idItr = memgaincollection.begin();
0756          idItr != memgaincollection.end();
0757          ++idItr) {
0758       int ch = (*idItr).channelId();
0759       ch = (ch - 1) / 5;
0760       pnIsOkInBlock[ch] = false;
0761     }
0762 
0763     for (EcalElectronicsIdCollection::const_iterator idItr = memchidcollection.begin();
0764          idItr != memchidcollection.end();
0765          ++idItr) {
0766       int ch = (*idItr).channelId();
0767       ch = (ch - 1) / 5;
0768       pnIsOkInBlock[ch] = false;
0769     }
0770 
0771   }  // end: if any ch_gain or ch_id problems exclude the Pn's from digi production
0772 
0773   // looping on PN's of current mem box
0774   for (int pnId = 1; pnId < (kPnPerTowerBlock + 1); pnId++) {
0775     // if present Pn has any of its 5 channels with problems, do not produce digi for it
0776     if (!pnIsOkInBlock[pnId - 1])
0777       continue;
0778 
0779     // second argument is DccId which is set to 46 to match h2 data in global CMS geometry
0780     EcalPnDiodeDetId PnId(2, 46, pnId + kPnPerTowerBlock * mem_id);
0781     EcalPnDiodeDigi thePnDigi(PnId);
0782 
0783     thePnDigi.setSize(kSamplesPerPn);
0784 
0785     for (int sample = 0; sample < kSamplesPerPn; sample++) {
0786       EcalFEMSample thePnSample(data_MEM[(mem_id) * 250 + (pnId - 1) * kSamplesPerPn + sample]);
0787       thePnDigi.setSample(sample, thePnSample);
0788     }
0789     pndigicollection.push_back(thePnDigi);
0790   }
0791 }
0792 
0793 std::pair<int, int> EcalTB07DaqFormatter::cellIndex(int tower_id, int strip, int ch) {
0794   int xtal = (strip - 1) * 5 + ch - 1;
0795   //  std::cout << " cellIndex input xtal " << xtal << std::endl;
0796   std::pair<int, int> ind;
0797 
0798   int eta = (tower_id - 1) / kTowersInPhi * kCardsPerTower;
0799   int phi = (tower_id - 1) % kTowersInPhi * kChannelsPerCard;
0800 
0801   if (rightTower(tower_id))
0802     eta += xtal / kCardsPerTower;
0803   else
0804     eta += (kCrystalsPerTower - 1 - xtal) / kCardsPerTower;
0805 
0806   if ((rightTower(tower_id) && (xtal / kCardsPerTower) % 2 == 1) ||
0807       (!rightTower(tower_id) && (xtal / kCardsPerTower) % 2 == 0))
0808 
0809     phi += (kChannelsPerCard - 1 - xtal % kChannelsPerCard);
0810   else
0811     phi += xtal % kChannelsPerCard;
0812 
0813   ind.first = eta + 1;
0814   ind.second = phi + 1;
0815 
0816   //  std::cout << "  EcalTB07DaqFormatter::cell_index eta " << ind.first << " phi " << ind.second << " " << std::endl;
0817 
0818   return ind;
0819 }
0820 
0821 int EcalTB07DaqFormatter::getEE_ix(int tower, int strip, int ch) {
0822   // H2 -- ix is in [-90, -80], and iy is in [-5; 5]
0823   int ic = cryIc(tower, strip, ch);
0824   int ix = 0;
0825   if (tbName_ == "h2")
0826     ix = 95 - (ic - 1) / 20;
0827 
0828   if (tbName_ == "h4")
0829     ix = 35 - (ic - 1) % 20;
0830 
0831   return ix;
0832 }
0833 int EcalTB07DaqFormatter::getEE_iy(int tower, int strip, int ch) {
0834   int ic = cryIc(tower, strip, ch);
0835   int iy = 0;
0836   if (tbName_ == "h2")
0837     iy = 46 + (ic - 1) % 20;
0838 
0839   if (tbName_ == "h4")
0840     iy = 51 + (int)((ic - 1) / 20);
0841 
0842   return iy;
0843 }
0844 
0845 int EcalTB07DaqFormatter::cryIc(int tower, int strip, int ch) {
0846   if (strip < 1 || 5 < strip || ch < 1 || 5 < ch || 68 < tower) {
0847     edm::LogWarning("EcalTB07RawToDigiChId") << "EcalTB07DaqFormatter::interpretRawData (cryIc) "
0848                                              << " wrong channel id, since out of range: "
0849                                              << "\t strip: " << strip << "\t channel: " << ch << "\t in TT: " << tower;
0850     return -1;
0851   }
0852 
0853   // YM
0854   return cryIcMap_[tower - 1][strip - 1][ch - 1];
0855   //std::pair<int,int> cellInd= EcalTB07DaqFormatter::cellIndex(tower, strip, ch);
0856   //return cellInd.second + (cellInd.first-1)*kCrystalsInPhi;
0857 }
0858 
0859 bool EcalTB07DaqFormatter::rightTower(int tower) const {
0860   if ((tower > 12 && tower < 21) || (tower > 28 && tower < 37) || (tower > 44 && tower < 53) ||
0861       (tower > 60 && tower < 69))
0862     return true;
0863   else
0864     return false;
0865 }
0866 
0867 bool EcalTB07DaqFormatter::leftTower(int tower) const { return !rightTower(tower); }