CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/SimCalorimetry/EcalTrigPrimAlgos/interface/EcalTrigPrimFunctionalAlgo.h

Go to the documentation of this file.
00001 #ifndef EcalTrigPrimFunctionalAlgo_h
00002 #define EcalTrigPrimFunctionalAlgo_h
00003 
00018 #include <sys/time.h>
00019 #include <iostream>
00020 #include <vector>
00021 
00022 #include "Geometry/CaloTopology/interface/EcalTrigTowerConstituentsMap.h"
00023 
00024 #include "SimCalorimetry/EcalTrigPrimAlgos/interface/EcalFenixStrip.h"
00025 #include "SimCalorimetry/EcalTrigPrimAlgos/interface/EcalFenixTcp.h"
00026 
00027 #include "DataFormats/Common/interface/SortedCollection.h"
00028 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
00029 
00030 #include "FWCore/Framework/interface/EventSetup.h"
00031 #include "FWCore/Framework/interface/ESHandle.h"
00032 
00033 #include <map>
00034 #include <utility>
00035 
00039 class EcalTrigTowerDetId;
00040 class ETPCoherenceTest;
00041 class EcalTriggerPrimitiveSample;
00042 class CaloSubdetectorGeometry;
00043 class EBDataFrame;
00044 class EEDataFrame;
00045 class EcalElectronicsMapping;
00046 
00047  
00048 class EcalTrigPrimFunctionalAlgo
00049 {  
00050  public:
00051   
00052   explicit EcalTrigPrimFunctionalAlgo(const edm::EventSetup & setup, int binofmax, bool tcpFormat, bool barrelOnly, bool debug, bool famos);
00053 
00054   virtual ~EcalTrigPrimFunctionalAlgo();
00055 
00056   void run(const edm::EventSetup &, const EBDigiCollection *col, EcalTrigPrimDigiCollection & result, EcalTrigPrimDigiCollection & resultTcp);
00057   void run(const edm::EventSetup&,  const EEDigiCollection *col, EcalTrigPrimDigiCollection & result, EcalTrigPrimDigiCollection & resultTcp);
00058   void run_part1_EB(EBDigiCollection const * col);
00059   void run_part1_EE(EEDigiCollection const * col);
00060   template <class Coll> 
00061     void run_part2(const edm::EventSetup &, Coll const * col, 
00062                    std::vector<std::vector<std::pair<int,std::vector<typename Coll::Digi> > > > &towerMap,
00063                    EcalTrigPrimDigiCollection & result,
00064                    EcalTrigPrimDigiCollection & resultTcp);
00065 
00066   void setPointers(const EcalTPGLinearizationConst *ecaltpLin,const EcalTPGPedestals *ecaltpPed,const EcalTPGSlidingWindow * ecaltpgSlidW,const EcalTPGWeightIdMap * ecaltpgWeightMap,const EcalTPGWeightGroup * ecaltpgWeightGroup,const EcalTPGFineGrainStripEE * ecaltpgFgStripEE, const EcalTPGCrystalStatus * ecaltpgBadX, const EcalTPGStripStatus * ecaltpgStripStatus)  {
00067     estrip_->setPointers(ecaltpPed,ecaltpLin,ecaltpgWeightMap,ecaltpgWeightGroup,ecaltpgSlidW,ecaltpgFgStripEE,ecaltpgBadX,ecaltpgStripStatus);
00068 
00069   }
00070   void setPointers2(  const EcalTPGFineGrainEBGroup * ecaltpgFgEBGroup,
00071                       const EcalTPGLutGroup * ecaltpgLutGroup,
00072                       const EcalTPGLutIdMap * ecaltpgLut,
00073                       const EcalTPGFineGrainEBIdMap * ecaltpgFineGrainEB,
00074                       const EcalTPGFineGrainTowerEE * ecaltpgFineGrainTowerEE,
00075                       const EcalTPGTowerStatus * ecaltpgBadTT,
00076                       const EcalTPGSpike * ecaltpgSpike){
00077    
00078   etcp_->setPointers(ecaltpgFgEBGroup,ecaltpgLutGroup,ecaltpgLut,ecaltpgFineGrainEB,ecaltpgFineGrainTowerEE,ecaltpgBadTT,ecaltpgSpike);
00079   }
00080 
00081  private:
00082 
00083   void init(const edm::EventSetup&);
00084   template <class T>  
00085     void initStructures(std::vector<std::vector<std::pair<int,std::vector<T> > > > & towMap);
00086   template <class T> 
00087     void clean(std::vector<std::vector<std::pair<int,std::vector<T> > > > &towerMap);
00088   template <class Coll> 
00089     void fillMap(Coll const * col, std::vector<std::vector<std::pair<int,std::vector<typename Coll::Digi> > > > &towerMap);
00090   int findStripNr(const EBDetId &id);
00091   int findStripNr(const EEDetId &id);
00092 
00093   // FIXME: temporary until hashedIndex works alsom for endcap
00094   int getIndex(const  EBDigiCollection *, EcalTrigTowerDetId& id) {return id.hashedIndex();}
00095   // mind that eta is continuous between barrel+endcap
00096   int getIndex(const  EEDigiCollection *, EcalTrigTowerDetId& id) {
00097     int ind=(id.ietaAbs()-18)*72 + id.iphi();
00098     if (id.zside()<0) ind+=792;
00099     return ind;
00100   }
00101 
00102   EcalFenixStrip * estrip_;
00103   EcalFenixTcp * etcp_;
00104 
00105   edm::ESHandle<EcalTrigTowerConstituentsMap> eTTmap_;
00106   const CaloSubdetectorGeometry *theEndcapGeometry;
00107   const EcalElectronicsMapping* theMapping_;
00108 
00109   float threshold;
00110 
00111   int binOfMaximum_;
00112   int maxNrSamples_;
00113 
00114   bool tcpFormat_;
00115   bool barrelOnly_;
00116   bool debug_;  
00117   bool famos_;  
00118 
00119   static const unsigned int nrSamples_; //nr samples to write, should not be changed since by convention the size means that it is coming from simulation
00120   static const unsigned int maxNrSamplesOut_; //to be placed in the intermediate samples
00121   static const unsigned int maxNrTowers_; //would be better to get from somewhere..
00122   static const unsigned int maxNrTPs_; //would be better to get from somewhere..
00123 
00124   int nrTowers_;   // nr of towers found by fillmap method
00125 
00126   // data structures kept during the whole run
00127   std::vector<std::vector<int> > striptp_;
00128   std::vector<std::vector<std::pair<int,std::vector<EBDataFrame> > > > towerMapEB_;
00129   std::vector<std::vector<std::pair<int,std::vector<EEDataFrame> > > > towerMapEE_;
00130   std::vector<std::pair<int,EcalTrigTowerDetId> > hitTowers_;
00131   std::vector<EcalTriggerPrimitiveSample> towtp_;
00132   std::vector<EcalTriggerPrimitiveSample> towtp2_;
00133 
00134   enum {nbMaxStrips_=5};
00135   enum {nbMaxXtals_=5};
00136 };
00137 
00138 //=================================== implementations =============================================
00139 
00140 template <class Coll> 
00141 void EcalTrigPrimFunctionalAlgo::run_part2(const edm::EventSetup &setup,Coll const * col, std::vector<std::vector<std::pair<int,std::vector<typename Coll::Digi> > > > &towerMap,
00142                                            EcalTrigPrimDigiCollection & result,
00143                                            EcalTrigPrimDigiCollection & resultTcp)
00144 {
00145   typedef typename Coll::Digi Digi;
00146  
00147   // prepare writing of TP-s
00148 
00149   int firstSample = binOfMaximum_-1 -nrSamples_/2;
00150   int lastSample = binOfMaximum_-1 +nrSamples_/2;
00151   int nrTP=0;
00152   std::vector<typename Coll::Digi> dummy;
00153   EcalTriggerPrimitiveDigi tptow[2];
00154   EcalTriggerPrimitiveDigi tptowTcp[2];
00155 
00156   for(int itow=0;itow<nrTowers_;++itow) 
00157     {
00158 
00159       int index=hitTowers_[itow].first;
00160       const EcalTrigTowerDetId &thisTower=hitTowers_[itow].second;
00161 
00162       // loop over all strips assigned to this trigger tower
00163       int nstr=0;
00164       for(unsigned int i = 0; i < towerMap[itow].size();++i)
00165         {
00166           std::vector<Digi> &df = (towerMap[index])[i].second;//vector of dataframes for this strip, size; nr of crystals/strip
00167 
00168           if ((towerMap[index])[i].first > 0) {  
00169             estrip_->process(setup,df,(towerMap[index])[i].first,striptp_[nstr++]);
00170           }
00171         }//loop over strips in one tower
00172 
00173       bool isInInnerRings=false;
00174       if (thisTower.subDet()==EcalEndcap && (thisTower.ietaAbs()==27 || thisTower.ietaAbs()==28 )) isInInnerRings=true;
00175       etcp_->process(setup,dummy,striptp_,nstr,towtp_,towtp2_,isInInnerRings,thisTower);
00176 
00177       // prepare TP-s
00178       // special treatment for 2 inner endcap rings
00179       int nrTowers;
00180       if (isInInnerRings)
00181         {
00182           nrTowers=2;
00183           int phi=2*((thisTower.iphi()-1)/2);
00184           tptow[0]=EcalTriggerPrimitiveDigi(EcalTrigTowerDetId(thisTower.zside(),thisTower.subDet(),thisTower.ietaAbs(),phi+1));
00185           tptow[1]=EcalTriggerPrimitiveDigi(EcalTrigTowerDetId(thisTower.zside(),thisTower.subDet(),thisTower.ietaAbs(),phi+2));
00186 
00187           if (tcpFormat_){
00188             tptowTcp[0]=EcalTriggerPrimitiveDigi(EcalTrigTowerDetId(thisTower.zside(),thisTower.subDet(),thisTower.ietaAbs(),phi+1));
00189             tptowTcp[1]=EcalTriggerPrimitiveDigi(EcalTrigTowerDetId(thisTower.zside(),thisTower.subDet(),thisTower.ietaAbs(),phi+2));
00190           }
00191         }else {
00192           nrTowers=1;
00193           tptow[0]=EcalTriggerPrimitiveDigi(thisTower);
00194           if (tcpFormat_)   tptowTcp[0]=EcalTriggerPrimitiveDigi(thisTower);
00195         }
00196 
00197       // now fill in
00198       for (int nrt=0;nrt<nrTowers;nrt++) {
00199         (tptow[nrt]).setSize(nrSamples_);
00200         if (towtp_.size()<nrSamples_)  {  //FIXME: only once
00201           edm::LogWarning("") <<"Too few samples produced, nr is "<<towtp_.size();
00202           break;
00203         }
00204         int isam=0;
00205         for (int i=firstSample;i<=lastSample;++i) {
00206           tptow[nrt].setSample(isam++,EcalTriggerPrimitiveSample(towtp_[i]));
00207         }
00208         nrTP++; 
00209         LogDebug("EcalTPG") <<" For tower "<<itow<<" created TP nr "<<nrTP<<" with Et "<<tptow[nrt].compressedEt();
00210         result.push_back(tptow[nrt]);
00211       }
00212 
00213       if (tcpFormat_) {
00214 
00215         for (int nrt=0;nrt<nrTowers;nrt++) {
00216           tptowTcp[nrt].setSize(nrSamples_);
00217           if (towtp2_.size()<nrSamples_)  {  //FIXME: only once
00218             edm::LogWarning("") <<"Too few samples produced, nr is "<<towtp2_.size();
00219             break;
00220           }
00221           int isam=0;
00222           for (int i=firstSample;i<=lastSample;++i) {
00223             if (nrTowers<=1)  tptowTcp[nrt].setSample(isam++,EcalTriggerPrimitiveSample(towtp2_[i]));
00224             else {
00225               int et=towtp2_[i].compressedEt()/2;
00226               tptowTcp[nrt].setSample(isam++,EcalTriggerPrimitiveSample(et,towtp2_[i].fineGrain(),towtp2_[i].ttFlag()));
00227             }
00228           }
00229           resultTcp.push_back(tptowTcp[nrt]);
00230         }
00231       }
00232     } 
00233   return;
00234 }
00235 
00236 template <class Coll> 
00237 void EcalTrigPrimFunctionalAlgo::fillMap(Coll const * col, 
00238                                          std::vector<std::vector<std::pair<int,std::vector<typename Coll::Digi> > > > &towerMap)
00239 {
00240   typedef typename Coll::Digi Digi;
00241 
00242   // implementation for Barrel and Endcap
00243 
00244   if (col) {
00245     nrTowers_=0;
00246     LogDebug("EcalTPG") <<"Fill mapping, Collection size = "<<col->size();
00247     for(unsigned int i = 0; i < col->size() ; ++i) {
00248       Digi samples((*col)[i]); 
00249       EcalTrigTowerDetId coarser=(*eTTmap_).towerOf(samples.id());
00250       int index=getIndex(col,coarser);
00251       int stripnr=findStripNr(samples.id());
00252 
00253       int filled=0;
00254       for (unsigned int ij=0;ij<towerMap[index].size();++ij) filled+=towerMap[index][ij].first;
00255       if (!filled) {
00256         hitTowers_[nrTowers_++]=std::pair <int,EcalTrigTowerDetId>(index,coarser);
00257       }
00258 
00259       //FIXME: temporary protection
00260       int ncryst=towerMap[index][stripnr-1].first;
00261       if (ncryst>=nbMaxXtals_ ) {
00262         edm::LogError("EcalTrigPrimFunctionAlgo")<<"! Too many xtals for TT "<<coarser<<" stripnr "<<stripnr<<" xtalid "<<samples.id() ;
00263         continue;
00264       }
00265       ((towerMap[index])[stripnr-1].second)[ncryst]=samples;
00266       (towerMap[index])[stripnr-1].first++;
00267     }
00268   
00269     LogDebug("EcalTPG")<<"fillMap"<<"[EcalTrigPrimFunctionalAlgo] (found " 
00270                        << col->size() << " frames in "<< towerMap.size() << " towers) ";
00271   }
00272   else {
00273     LogDebug("EcalTPG")<<"FillMap - FillMap Collection size=0 !!!!";
00274   }
00275 }
00276 
00277 template <class T> 
00278 void EcalTrigPrimFunctionalAlgo::clean( std::vector<std::vector<std::pair<int,std::vector<T> > > > & towMap) {  
00279   // clean internal data structures
00280   for (unsigned int i=0;i<maxNrTowers_;++i) 
00281     for (int j=0;j<nbMaxStrips_ ;++j) (towMap[i])[j].first=0;
00282   return;
00283 }
00284  
00285 template <class T> 
00286 void EcalTrigPrimFunctionalAlgo::initStructures( std::vector<std::vector<std::pair<int,std::vector<T> > > > & towMap) {  
00287   //initialise internal data structures
00288 
00289   std::vector <T> vec0(nbMaxXtals_ );
00290   std::vector<std::pair<int,std::vector<T> > > vec1(nbMaxStrips_);
00291   for (int i=0;i<nbMaxStrips_ ;++i) vec1[i]=std::pair<int,std::vector<T> >(0,vec0);
00292   towMap.resize(maxNrTowers_); 
00293   for (unsigned int i=0;i<maxNrTowers_;++i) towMap[i]=vec1;
00294   
00295   std::vector<int> vecint(maxNrSamples_);
00296   striptp_.resize(nbMaxStrips_);
00297   for (int i=0;i<nbMaxStrips_;++i) striptp_[i]=vecint;
00298   
00299 }
00300 
00301 #endif