Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:28

0001 #ifndef SIMCALORIMETRY_ECALTRIGPRIMALGOS_ECALTRIGPRIMFUNCTIONALALGO_h
0002 #define SIMCALORIMETRY_ECALTRIGPRIMALGOS_ECALTRIGPRIMFUNCTIONALALGO_h
0003 /** \class EcalTrigPrimFunctionalAlgo
0004  *
0005  * EcalTrigPrimFunctionalAlgo is the main algorithm class for TPG
0006  * It coordinates all the aother algorithms
0007  * Structure is as close as possible to electronics
0008  *
0009  *
0010  * \author Ursula Berthon, Stephanie Baffioni, LLR Palaiseau
0011  *
0012  * \version   1st Version may 2006
0013  * \version   2nd Version jul 2006
0014  * \version   3rd Version sep 2007  introducing new Records closer to the db
0015 
0016  *
0017  ************************************************************/
0018 #include <iostream>
0019 #include <sys/time.h>
0020 #include <vector>
0021 
0022 #include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h"
0023 
0024 #include "SimCalorimetry/EcalTrigPrimAlgos/interface/EcalFenixStrip.h"
0025 #include "SimCalorimetry/EcalTrigPrimAlgos/interface/EcalFenixTcp.h"
0026 
0027 #include "DataFormats/Common/interface/SortedCollection.h"
0028 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
0029 
0030 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0031 
0032 #include <map>
0033 #include <utility>
0034 #include <string>
0035 
0036 /** Main Algo for Ecal trigger primitives. */
0037 
0038 class EcalTrigTowerDetId;
0039 class ETPCoherenceTest;
0040 class EcalTriggerPrimitiveSample;
0041 class CaloSubdetectorGeometry;
0042 class EBDataFrame;
0043 class EEDataFrame;
0044 class EcalElectronicsMapping;
0045 
0046 class EcalTrigPrimFunctionalAlgo {
0047 public:
0048   //Not barrelOnly
0049   EcalTrigPrimFunctionalAlgo(const EcalTrigTowerConstituentsMap *eTTmap,
0050                              const CaloSubdetectorGeometry *endcapGeometry,
0051                              const EcalElectronicsMapping *theMapping,
0052                              int binofmax,
0053                              bool tcpFormat,
0054                              bool debug,
0055                              bool famos,
0056                              bool TPinfoPrintout);
0057 
0058   //barrel only
0059   explicit EcalTrigPrimFunctionalAlgo(const EcalElectronicsMapping *theMapping,
0060                                       int binofmax,
0061                                       bool tcpFormat,
0062                                       bool debug,
0063                                       bool famos,
0064                                       bool TPinfoPrintout);
0065 
0066   virtual ~EcalTrigPrimFunctionalAlgo();
0067 
0068   void run(const EBDigiCollection *col, EcalTrigPrimDigiCollection &result, EcalTrigPrimDigiCollection &resultTcp);
0069   void run(const EEDigiCollection *col, EcalTrigPrimDigiCollection &result, EcalTrigPrimDigiCollection &resultTcp);
0070   void run_part1_EB(EBDigiCollection const *col);
0071   void run_part1_EE(EEDigiCollection const *col);
0072   template <class Coll>
0073   void run_part2(Coll const *col,
0074                  std::vector<std::vector<std::pair<int, std::vector<typename Coll::Digi>>>> &towerMap,
0075                  EcalTrigPrimDigiCollection &result,
0076                  EcalTrigPrimDigiCollection &resultTcp);
0077 
0078   void setPointers(const EcalTPGLinearizationConst *ecaltpLin,
0079                    const EcalTPGPedestals *ecaltpPed,
0080                    const EcalTPGSlidingWindow *ecaltpgSlidW,
0081                    const EcalTPGWeightIdMap *ecaltpgWeightMap,
0082                    const EcalTPGWeightGroup *ecaltpgWeightGroup,
0083                    const EcalTPGOddWeightIdMap *ecaltpgOddWeightMap,
0084                    const EcalTPGOddWeightGroup *ecaltpgOddWeightGroup,
0085                    const EcalTPGFineGrainStripEE *ecaltpgFgStripEE,
0086                    const EcalTPGCrystalStatus *ecaltpgBadX,
0087                    const EcalTPGStripStatus *ecaltpgStripStatus,
0088                    const EcalTPGTPMode *ecaltpgTPMode) {
0089     estrip_->setPointers(ecaltpPed,
0090                          ecaltpLin,
0091                          ecaltpgWeightMap,
0092                          ecaltpgWeightGroup,
0093                          ecaltpgOddWeightMap,
0094                          ecaltpgOddWeightGroup,
0095                          ecaltpgSlidW,
0096                          ecaltpgFgStripEE,
0097                          ecaltpgBadX,
0098                          ecaltpgStripStatus,
0099                          ecaltpgTPMode);
0100   }
0101   void setPointers2(const EcalTPGFineGrainEBGroup *ecaltpgFgEBGroup,
0102                     const EcalTPGLutGroup *ecaltpgLutGroup,
0103                     const EcalTPGLutIdMap *ecaltpgLut,
0104                     const EcalTPGFineGrainEBIdMap *ecaltpgFineGrainEB,
0105                     const EcalTPGFineGrainTowerEE *ecaltpgFineGrainTowerEE,
0106                     const EcalTPGTowerStatus *ecaltpgBadTT,
0107                     const EcalTPGSpike *ecaltpgSpike,
0108                     const EcalTPGTPMode *ecaltpgTPMode) {
0109     etcp_->setPointers(ecaltpgFgEBGroup,
0110                        ecaltpgLutGroup,
0111                        ecaltpgLut,
0112                        ecaltpgFineGrainEB,
0113                        ecaltpgFineGrainTowerEE,
0114                        ecaltpgBadTT,
0115                        ecaltpgSpike,
0116                        ecaltpgTPMode);
0117   }
0118 
0119 private:
0120   void init();
0121   template <class T>
0122   void initStructures(std::vector<std::vector<std::pair<int, std::vector<T>>>> &towMap);
0123   template <class T>
0124   void clean(std::vector<std::vector<std::pair<int, std::vector<T>>>> &towerMap);
0125   template <class Coll>
0126   void fillMap(Coll const *col, std::vector<std::vector<std::pair<int, std::vector<typename Coll::Digi>>>> &towerMap);
0127   int findStripNr(const EBDetId &id);
0128   int findStripNr(const EEDetId &id);
0129 
0130   // FIXME: temporary until hashedIndex works alsom for endcap
0131   int getIndex(const EBDigiCollection *, EcalTrigTowerDetId &id) { return id.hashedIndex(); }
0132   // mind that eta is continuous between barrel+endcap
0133   int getIndex(const EEDigiCollection *, EcalTrigTowerDetId &id) {
0134     int ind = (id.ietaAbs() - 18) * 72 + id.iphi();
0135     if (id.zside() < 0)
0136       ind += 792;
0137     return ind;
0138   }
0139 
0140   std::unique_ptr<EcalFenixStrip> estrip_;
0141   std::unique_ptr<EcalFenixTcp> etcp_;
0142 
0143   const EcalTrigTowerConstituentsMap *eTTmap_ = nullptr;
0144   const CaloSubdetectorGeometry *theEndcapGeometry_ = nullptr;
0145   const EcalElectronicsMapping *theMapping_;
0146 
0147   float threshold;
0148 
0149   int binOfMaximum_;
0150   int maxNrSamples_;
0151 
0152   bool tcpFormat_;
0153   bool barrelOnly_;
0154   bool debug_;
0155   bool famos_;
0156   bool tpInfoPrintout_;
0157 
0158   static const unsigned int nrSamples_;        // nr samples to write, should not be changed since by
0159                                                // convention the size means that it is coming from simulation
0160   static const unsigned int maxNrSamplesOut_;  // to be placed in the intermediate samples
0161   static const unsigned int maxNrTowers_;      // would be better to get from somewhere..
0162   static const unsigned int maxNrTPs_;         // would be better to get from
0163                                                // somewhere..
0164 
0165   int nrTowers_;  // nr of towers found by fillmap method
0166 
0167   // data structures kept during the whole run
0168   std::vector<std::vector<int>> striptp_;
0169   std::vector<std::vector<std::pair<int, std::vector<EBDataFrame>>>> towerMapEB_;
0170   std::vector<std::vector<std::pair<int, std::vector<EEDataFrame>>>> towerMapEE_;
0171   std::vector<std::pair<int, EcalTrigTowerDetId>> hitTowers_;
0172   std::vector<EcalTriggerPrimitiveSample> towtp_;
0173   std::vector<EcalTriggerPrimitiveSample> towtp2_;
0174 
0175   enum { nbMaxStrips_ = 5 };
0176   enum { nbMaxXtals_ = 5 };
0177 };
0178 
0179 //=================================== implementations
0180 //=============================================
0181 
0182 template <class Coll>
0183 void EcalTrigPrimFunctionalAlgo::run_part2(
0184     Coll const *col,
0185     std::vector<std::vector<std::pair<int, std::vector<typename Coll::Digi>>>> &towerMap,
0186     EcalTrigPrimDigiCollection &result,
0187     EcalTrigPrimDigiCollection &resultTcp) {
0188   typedef typename Coll::Digi Digi;
0189 
0190   // prepare writing of TP-s
0191 
0192   int firstSample = binOfMaximum_ - 1 - nrSamples_ / 2;
0193   int lastSample = binOfMaximum_ - 1 + nrSamples_ / 2;
0194   int nrTP = 0;
0195   std::vector<typename Coll::Digi> dummy;
0196   EcalTriggerPrimitiveDigi tptow[2];
0197   EcalTriggerPrimitiveDigi tptowTcp[2];
0198 
0199   estrip_->getFGVB()->setbadStripMissing(false);
0200 
0201   for (int itow = 0; itow < nrTowers_; ++itow) {
0202     int index = hitTowers_[itow].first;
0203     const EcalTrigTowerDetId &thisTower = hitTowers_[itow].second;
0204 
0205     if (tpInfoPrintout_) {
0206       edm::LogVerbatim("EcalTPG") << "+++++++++++++++++++++++++++++++++++++++++++++++++";
0207       edm::LogVerbatim("EcalTPG") << "on Tower " << itow << " of " << nrTowers_;
0208       edm::LogVerbatim("EcalTPG") << "Tower ieta, iphi: " << thisTower.ieta() << ", " << thisTower.iphi();
0209     }
0210 
0211     // loop over all strips assigned to this trigger tower
0212     int nstr = 0;
0213     for (unsigned int i = 0; i < towerMap[itow].size(); ++i) {
0214       std::vector<Digi> &df = (towerMap[index])[i].second;  // vector of dataframes for this strip,
0215                                                             // size; nr of crystals/strip
0216 
0217       if ((towerMap[index])[i].first > 0) {
0218         if (tpInfoPrintout_) {
0219           edm::LogVerbatim("EcalTPG") << "-------------------------------------------------";
0220           edm::LogVerbatim("EcalTPG") << "on Strip index " << i;
0221         }
0222         estrip_->process(df, (towerMap[index])[i].first, striptp_[nstr++]);
0223       }
0224     }  // loop over strips in one tower
0225 
0226     bool isInInnerRings = false;
0227     if (thisTower.subDet() == EcalEndcap && (thisTower.ietaAbs() == 27 || thisTower.ietaAbs() == 28))
0228       isInInnerRings = true;
0229     etcp_->process(dummy, striptp_, nstr, towtp_, towtp2_, isInInnerRings, thisTower);
0230 
0231     // prepare TP-s
0232     // special treatment for 2 inner endcap rings
0233     int nrTowers;
0234     if (isInInnerRings) {
0235       nrTowers = 2;
0236       int phi = 2 * ((thisTower.iphi() - 1) / 2);
0237       tptow[0] = EcalTriggerPrimitiveDigi(
0238           EcalTrigTowerDetId(thisTower.zside(), thisTower.subDet(), thisTower.ietaAbs(), phi + 1));
0239       tptow[1] = EcalTriggerPrimitiveDigi(
0240           EcalTrigTowerDetId(thisTower.zside(), thisTower.subDet(), thisTower.ietaAbs(), phi + 2));
0241 
0242       if (tcpFormat_) {
0243         tptowTcp[0] = EcalTriggerPrimitiveDigi(
0244             EcalTrigTowerDetId(thisTower.zside(), thisTower.subDet(), thisTower.ietaAbs(), phi + 1));
0245         tptowTcp[1] = EcalTriggerPrimitiveDigi(
0246             EcalTrigTowerDetId(thisTower.zside(), thisTower.subDet(), thisTower.ietaAbs(), phi + 2));
0247       }
0248     } else {
0249       nrTowers = 1;
0250       tptow[0] = EcalTriggerPrimitiveDigi(thisTower);
0251       if (tcpFormat_)
0252         tptowTcp[0] = EcalTriggerPrimitiveDigi(thisTower);
0253     }
0254 
0255     // now fill in
0256     for (int nrt = 0; nrt < nrTowers; nrt++) {
0257       (tptow[nrt]).setSize(nrSamples_);
0258       if (towtp_.size() < nrSamples_) {  // FIXME: only once
0259         edm::LogWarning("") << "Too few samples produced, nr is " << towtp_.size();
0260         break;
0261       }
0262       int isam = 0;
0263       for (int i = firstSample; i <= lastSample; ++i) {
0264         tptow[nrt].setSample(isam++, EcalTriggerPrimitiveSample(towtp_[i]));
0265       }
0266       nrTP++;
0267       LogDebug("EcalTPG") << " For tower " << itow << " created TP nr " << nrTP << " with Et "
0268                           << tptow[nrt].compressedEt();
0269       result.push_back(tptow[nrt]);
0270     }
0271 
0272     if (tcpFormat_) {
0273       for (int nrt = 0; nrt < nrTowers; nrt++) {
0274         tptowTcp[nrt].setSize(nrSamples_);
0275         if (towtp2_.size() < nrSamples_) {  // FIXME: only once
0276           edm::LogWarning("") << "Too few samples produced, nr is " << towtp2_.size();
0277           break;
0278         }
0279         int isam = 0;
0280         for (int i = firstSample; i <= lastSample; ++i) {
0281           if (nrTowers <= 1)
0282             tptowTcp[nrt].setSample(isam++, EcalTriggerPrimitiveSample(towtp2_[i]));
0283           else {
0284             int et = towtp2_[i].compressedEt() / 2;
0285             tptowTcp[nrt].setSample(isam++,
0286                                     EcalTriggerPrimitiveSample(et, towtp2_[i].fineGrain(), towtp2_[i].ttFlag()));
0287           }
0288         }
0289         resultTcp.push_back(tptowTcp[nrt]);
0290       }
0291     }
0292   }
0293   return;
0294 }
0295 
0296 template <class Coll>
0297 void EcalTrigPrimFunctionalAlgo::fillMap(
0298     Coll const *col, std::vector<std::vector<std::pair<int, std::vector<typename Coll::Digi>>>> &towerMap) {
0299   typedef typename Coll::Digi Digi;
0300 
0301   // implementation for Barrel and Endcap
0302 
0303   if (col) {
0304     nrTowers_ = 0;
0305     LogDebug("EcalTPG") << "Fill mapping, Collection size = " << col->size();
0306     for (unsigned int i = 0; i < col->size(); ++i) {
0307       Digi samples((*col)[i]);
0308       EcalTrigTowerDetId coarser =
0309           eTTmap_ ? (*eTTmap_).towerOf(samples.id()) : EcalTrigTowerConstituentsMap::barrelTowerOf(samples.id());
0310       int index = getIndex(col, coarser);
0311       int stripnr = findStripNr(samples.id());
0312 
0313       int filled = 0;
0314       for (unsigned int ij = 0; ij < towerMap[index].size(); ++ij)
0315         filled += towerMap[index][ij].first;
0316       if (!filled) {
0317         hitTowers_[nrTowers_++] = std::pair<int, EcalTrigTowerDetId>(index, coarser);
0318       }
0319 
0320       // FIXME: temporary protection
0321       int ncryst = towerMap[index][stripnr - 1].first;
0322       if (ncryst >= nbMaxXtals_) {
0323         edm::LogError("EcalTrigPrimFunctionAlgo")
0324             << "! Too many xtals for TT " << coarser << " stripnr " << stripnr << " xtalid " << samples.id();
0325         continue;
0326       }
0327       ((towerMap[index])[stripnr - 1].second)[ncryst] = samples;
0328       (towerMap[index])[stripnr - 1].first++;
0329     }
0330 
0331     LogDebug("EcalTPG") << "fillMap"
0332                         << "[EcalTrigPrimFunctionalAlgo] (found " << col->size() << " frames in " << towerMap.size()
0333                         << " towers) ";
0334   } else {
0335     LogDebug("EcalTPG") << "FillMap - FillMap Collection size=0 !!!!";
0336   }
0337 }
0338 
0339 template <class T>
0340 void EcalTrigPrimFunctionalAlgo::clean(std::vector<std::vector<std::pair<int, std::vector<T>>>> &towMap) {
0341   // clean internal data structures
0342   for (unsigned int i = 0; i < maxNrTowers_; ++i)
0343     for (int j = 0; j < nbMaxStrips_; ++j)
0344       (towMap[i])[j].first = 0;
0345   return;
0346 }
0347 
0348 template <class T>
0349 void EcalTrigPrimFunctionalAlgo::initStructures(std::vector<std::vector<std::pair<int, std::vector<T>>>> &towMap) {
0350   // initialise internal data structures
0351 
0352   std::vector<T> vec0(nbMaxXtals_);
0353   std::vector<std::pair<int, std::vector<T>>> vec1(nbMaxStrips_);
0354   for (int i = 0; i < nbMaxStrips_; ++i)
0355     vec1[i] = std::pair<int, std::vector<T>>(0, vec0);
0356   towMap.resize(maxNrTowers_);
0357   for (unsigned int i = 0; i < maxNrTowers_; ++i)
0358     towMap[i] = vec1;
0359 
0360   std::vector<int> vecint(maxNrSamples_);
0361   striptp_.resize(nbMaxStrips_);
0362   for (int i = 0; i < nbMaxStrips_; ++i)
0363     striptp_[i] = vecint;
0364 }
0365 
0366 #endif