Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-09-10 10:03:12

0001 #include "SimCalorimetry/EcalElectronicsEmulation/interface/EcalFEtoDigi.h"
0002 
0003 EcalFEtoDigi::EcalFEtoDigi(const edm::ParameterSet &iConfig)
0004     : tpgLutGroupToken_(esConsumes()),
0005       tpgLutIdMapToken_(esConsumes()),
0006       basename_(iConfig.getUntrackedParameter<std::string>("FlatBaseName", "ecal_tcc_")),
0007       useIdentityLUT_(iConfig.getUntrackedParameter<bool>("UseIdentityLUT", false)),
0008       sm_(iConfig.getUntrackedParameter<int>("SuperModuleId", -1)),
0009       fileEventOffset_(iConfig.getUntrackedParameter<int>("FileEventOffset", 0)),
0010       debug_(iConfig.getUntrackedParameter<bool>("debugPrintFlag", false)) {
0011   singlefile = (sm_ == -1) ? false : true;
0012 
0013   produces<EcalTrigPrimDigiCollection>();
0014   produces<EcalTrigPrimDigiCollection>("formatTCP");
0015 }
0016 
0017 /// method called to produce the data
0018 void EcalFEtoDigi::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0019   /// event counter
0020   static int current_bx = -1;
0021   current_bx++;
0022 
0023   /// re-read input (needed in case of event-by-event input production)
0024   // readInput();
0025 
0026   if (debug_)
0027     std::cout << "[EcalFEtoDigi::produce] producing event " << current_bx << std::endl;
0028 
0029   std::unique_ptr<EcalTrigPrimDigiCollection> e_tpdigis(new EcalTrigPrimDigiCollection);
0030   std::unique_ptr<EcalTrigPrimDigiCollection> e_tpdigisTcp(new EcalTrigPrimDigiCollection);
0031 
0032   std::vector<TCCinput>::const_iterator it;
0033 
0034   for (int i = 0; i < N_SM; i++) {
0035     if (!singlefile)
0036       sm_ = i + 1;
0037 
0038     for (it = inputdata_[i].begin(); it != inputdata_[i].end(); it++) {
0039       if (!(*it).is_current(current_bx + fileEventOffset_))
0040         continue;
0041       else if (debug_ && (*it).input != 0)
0042         std::cout << "[EcalFEtoDigi] "
0043                   << "\tsupermodule:" << sm_ << "\tevent: " << current_bx << "\tbx: " << (*it).bunchCrossing
0044                   << "\tvalue:0x" << std::setfill('0') << std::setw(4) << std::hex << (*it).input << std::setfill(' ')
0045                   << std::dec << std::endl;
0046 
0047       /// create EcalTrigTowerDetId
0048       const EcalTrigTowerDetId e_id = create_TTDetId(*it);
0049 
0050       // EcalElectronicsMapping theMapping;
0051       // const EcalTrigTowerDetId  e_id
0052       //= theMapping.getTrigTowerDetId(SMidToTCCid(sm_),(*it).tower);
0053       // EcalElectronicsMapping::getTrigTowerDetId(int TCCid, int iTT)
0054 
0055       /// create EcalTriggerPrimitiveDigi
0056       EcalTriggerPrimitiveDigi *e_digi = new EcalTriggerPrimitiveDigi(e_id);
0057       EcalTriggerPrimitiveDigi *e_digiTcp = new EcalTriggerPrimitiveDigi(e_id);
0058 
0059       /// create EcalTriggerPrimitiveSample
0060       EcalTriggerPrimitiveSample e_sample = create_TPSample(*it, iSetup);
0061       EcalTriggerPrimitiveSample e_sampleTcp = create_TPSampleTcp(*it, iSetup);
0062 
0063       /// set sample
0064       e_digi->setSize(1);  // set sampleOfInterest to 0
0065       e_digi->setSample(0, e_sample);
0066 
0067       /// add to EcalTrigPrimDigiCollection
0068       e_tpdigis->push_back(*e_digi);
0069 
0070       /// set sample (uncompressed format)
0071       e_digiTcp->setSize(1);  // set sampleOfInterest to 0
0072       e_digiTcp->setSample(0, e_sampleTcp);
0073 
0074       /// add to EcalTrigPrimDigiCollection (uncompressed format)
0075       e_tpdigisTcp->push_back(*e_digiTcp);
0076 
0077       if (debug_)
0078         outfile << (*it).tower << '\t' << (*it).bunchCrossing << '\t' << std::setfill('0') << std::hex << "0x"
0079                 << std::setw(4) << (*it).input << '\t' << "0" << std::dec << std::setfill(' ') << std::endl;
0080 
0081       /// print & debug
0082       if (debug_ && (*it).input != 0)
0083         std::cout << "[EcalFEtoDigi] debug id: " << e_digi->id() << "\n\t" << std::dec
0084                   << "\tieta: " << e_digi->id().ieta() << "\tiphi: " << e_digi->id().iphi()
0085                   << "\tsize: " << e_digi->size() << "\tfg: " << (e_digi->fineGrain() ? 1 : 0) << std::hex << "\tEt: 0x"
0086                   << e_digi->compressedEt() << " (0x" << (*it).get_energy() << ")"
0087                   << "\tttflag: 0x" << e_digi->ttFlag() << std::dec << std::endl;
0088 
0089       delete e_digi;
0090       delete e_digiTcp;
0091     }
0092 
0093     if (singlefile)
0094       break;
0095   }
0096 
0097   /// in case no info was found for the event:need to create something
0098   if (e_tpdigis->empty()) {
0099     std::cout << "[EcalFEtoDigi] creating empty collection for the event!\n";
0100     EcalTriggerPrimitiveDigi *e_digi = new EcalTriggerPrimitiveDigi();
0101     e_tpdigis->push_back(*e_digi);
0102   }
0103 
0104   iEvent.put(std::move(e_tpdigis));
0105   iEvent.put(std::move(e_tpdigisTcp), "formatTCP");
0106 }
0107 
0108 /// open and read in input (flat) data file
0109 void EcalFEtoDigi::readInput() {
0110   if (debug_)
0111     std::cout << "\n[EcalFEtoDigi::readInput] Reading input data\n";
0112 
0113   if (!singlefile)
0114     sm_ = -1;
0115   for (int i = 0; i < N_SM; i++)
0116     inputdata_[i].clear();
0117 
0118   std::stringstream s;
0119   int tcc;
0120 
0121   for (int i = 0; i < N_SM; i++) {
0122     tcc = (sm_ == -1) ? SMidToTCCid(i + 1) : SMidToTCCid(sm_);
0123 
0124     s.str("");
0125     s << basename_ << tcc << ".txt";
0126 
0127     std::ifstream f(s.str().c_str());
0128 
0129     if (debug_) {
0130       std::cout << "  opening " << s.str().c_str() << "..." << std::endl;
0131       if (!f.good())
0132         std::cout << " skipped!";
0133       std::cout << std::endl;
0134     }
0135     // if (!f.good() || f.eof())
0136     //  throw cms::Exception("BadInputFile")
0137     //  << "EcalFEtoDigi: cannot open file " << s.str().c_str() << std::endl;
0138 
0139     int n_bx = 0;
0140     int tt;
0141     int bx;
0142     unsigned val;
0143     int dummy;
0144 
0145     while (f.good()) {
0146       if (f.eof())
0147         break;
0148       tt = 0;
0149       bx = -1;
0150       val = 0x0;
0151       dummy = 0;
0152       f >> tt >> bx >> std::hex >> val >> std::dec >> dummy;
0153       if (bx == -1 || bx < fileEventOffset_)
0154         continue;
0155       if (!n_bx || (bx != (inputdata_[i].back()).bunchCrossing))
0156         n_bx++;
0157       TCCinput ttdata(tt, bx, val);
0158       inputdata_[i].push_back(ttdata);
0159 
0160       if (debug_ && val != 0)
0161         printf("\treading tower:%d  bx:%d input:0x%x dummy:%2d\n", tt, bx, val, dummy);
0162     }
0163 
0164     f.close();
0165 
0166     if (sm_ != -1)
0167       break;
0168   }
0169 
0170   if (debug_)
0171     std::cout << "[EcalFEtoDigi::readInput] Done reading." << std::endl;
0172 
0173   return;
0174 }
0175 
0176 /// create EcalTrigTowerDetId from input data (line)
0177 EcalTrigTowerDetId EcalFEtoDigi::create_TTDetId(TCCinput data) {
0178   // (EcalBarrel only)
0179   static const int kTowersInPhi = 4;
0180 
0181   int iTT = data.tower;
0182   int zside = (sm_ > 18) ? -1 : +1;
0183   int SMid = sm_;
0184 
0185   int jtower = iTT - 1;
0186   int etaTT = jtower / kTowersInPhi + 1;
0187   int phiTT;
0188   if (zside < 0)
0189     phiTT = (SMid - 19) * kTowersInPhi + jtower % kTowersInPhi;
0190   else
0191     phiTT = (SMid - 1) * kTowersInPhi + kTowersInPhi - (jtower % kTowersInPhi) - 1;
0192 
0193   phiTT++;
0194   // needed as phi=0 (iphi=1) is at middle of lower SMs (1 and 19), need shift
0195   // by 2
0196   phiTT = phiTT - 2;
0197   if (phiTT <= 0)
0198     phiTT = 72 + phiTT;
0199 
0200   /// construct the EcalTrigTowerDetId object
0201   if (debug_ && data.get_energy() != 0)
0202     printf(
0203         "[EcalFEtoDigi] Creating EcalTrigTowerDetId "
0204         "(SMid,itt)=(%d,%d)->(eta,phi)=(%d,%d) \n",
0205         SMid,
0206         iTT,
0207         etaTT,
0208         phiTT);
0209 
0210   EcalTrigTowerDetId e_id(zside, EcalBarrel, etaTT, phiTT, 0);
0211 
0212   return e_id;
0213 }
0214 
0215 /// create EcalTriggerPrimitiveSample from input data (line)
0216 EcalTriggerPrimitiveSample EcalFEtoDigi::create_TPSample(TCCinput data, const edm::EventSetup &evtSetup) {
0217   int tower = create_TTDetId(data).rawId();
0218   int Et = data.get_energy();
0219   bool tt_fg = data.get_fg();
0220   // unsigned input = data.input;
0221   // int  Et    = input & 0x3ff; //get bits 0-9
0222   // bool tt_fg = input & 0x400; //get bit number 10
0223 
0224   /// setup look up table
0225   unsigned int lut_[1024];
0226   if (!useIdentityLUT_)
0227     getLUT(lut_, tower, evtSetup);
0228   else
0229     for (int i = 0; i < 1024; i++)
0230       lut_[i] = i;  // identity lut!
0231 
0232   /// compress energy 10 -> 8  bit
0233   int lut_out = lut_[Et];
0234   int ttFlag = (lut_out & 0x700) >> 8;
0235   int cEt = (lut_out & 0xff);
0236 
0237   /// crate sample
0238   if (debug_ && data.get_energy() != 0)
0239     printf(
0240         "[EcalFEtoDigi] Creating sample; input:0x%X (Et:0x%x) cEt:0x%x "
0241         "fg:%d ttflag:0x%x \n",
0242         data.input,
0243         Et,
0244         cEt,
0245         tt_fg,
0246         ttFlag);
0247 
0248   EcalTriggerPrimitiveSample e_sample(cEt, tt_fg, ttFlag);
0249 
0250   return e_sample;
0251 }
0252 
0253 /// create EcalTriggerPrimitiveSample in tcp format (uncomrpessed energy)
0254 EcalTriggerPrimitiveSample EcalFEtoDigi::create_TPSampleTcp(TCCinput data, const edm::EventSetup &evtSetup) {
0255   int tower = create_TTDetId(data).rawId();
0256   int Et = data.get_energy();
0257   bool tt_fg = data.get_fg();
0258 
0259   /// setup look up table
0260   unsigned int lut_[1024];
0261   if (!useIdentityLUT_)
0262     getLUT(lut_, tower, evtSetup);
0263   else
0264     for (int i = 0; i < 1024; i++)
0265       lut_[i] = i;  // identity lut!
0266 
0267   int lut_out = lut_[Et];
0268   int ttFlag = (lut_out & 0x700) >> 8;
0269   int tcpdata = ((ttFlag & 0x7) << 11) | ((tt_fg & 0x1) << 10) | (Et & 0x3ff);
0270 
0271   EcalTriggerPrimitiveSample e_sample(tcpdata);
0272 
0273   return e_sample;
0274 }
0275 
0276 /// method called once each job just before starting event loop
0277 void EcalFEtoDigi::beginJob() {
0278   /// check SM numbering convetion: 1-38
0279   /// [or -1 flag to indicate all sm's are to be read in]
0280   if (sm_ != -1 && (sm_ < 1 || sm_ > 36))
0281     throw cms::Exception("EcalFEtoDigiInvalidDetId") << "EcalFEtoDigi: Adapt SM numbering convention.\n";
0282 
0283   /// debug: open file for recreating input copy
0284   if (debug_)
0285     outfile.open("inputcopy.txt");
0286 
0287   readInput();
0288 }
0289 
0290 /// method called once each job just after ending the event loop
0291 void EcalFEtoDigi::endJob() {
0292   if (outfile.is_open())
0293     outfile.close();
0294 }
0295 
0296 /// translate input supermodule id into TCC id (barrel)
0297 int EcalFEtoDigi::SMidToTCCid(const int smid) const { return (smid <= 18) ? smid + 55 - 1 : smid + 37 - 19; }
0298 
0299 /// return the LUT from eventSetup
0300 void EcalFEtoDigi::getLUT(unsigned int *lut, const int towerId, const edm::EventSetup &evtSetup) const {
0301   const EcalTPGGroups::EcalTPGGroupsMap &lutGrpMap = evtSetup.getData(tpgLutGroupToken_).getMap();
0302   EcalTPGGroups::EcalTPGGroupsMapItr itgrp = lutGrpMap.find(towerId);
0303   uint32_t lutGrp = 999;
0304   if (itgrp != lutGrpMap.end())
0305     lutGrp = itgrp->second;
0306 
0307   const EcalTPGLutIdMap::EcalTPGLutMap &lutMap = evtSetup.getData(tpgLutIdMapToken_).getMap();
0308   EcalTPGLutIdMap::EcalTPGLutMapItr itLut = lutMap.find(lutGrp);
0309   if (itLut != lutMap.end()) {
0310     const unsigned int *theLut = (itLut->second).getLut();
0311     for (unsigned int i = 0; i < 1024; i++)
0312       lut[i] = theLut[i];
0313   }
0314 }