CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/FastSimulation/L1CaloTriggerProducer/src/FastL1Region.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    FastL1CaloSim
00004 // Class:      FastL1Region
00005 // 
00013 //
00014 // Original Author:  Chi Nhan Nguyen
00015 //         Created:  Mon Feb 19 13:25:24 CST 2007
00016 // $Id: FastL1Region.cc,v 1.23 2009/03/23 11:41:28 chinhan Exp $
00017 //
00018 
00019 
00020 #include "FastSimulation/L1CaloTriggerProducer/interface/FastL1Region.h"
00021 
00022 FastL1Region::FastL1Region() 
00023 {
00024   Towers = CaloTowerCollection(16);
00025 
00026   jetE = 0.;
00027   jetEt = 0.;
00028 
00029   id = 999;
00030   ieta = 999;
00031   iphi = 999;
00032 
00033   tauBit = false;
00034   quietBit = false;
00035   mipBit = false;
00036   for(int i=0;i<16;i++) {
00037     hcfgBit[i] = false;
00038     fgBit[i] = false;
00039     hOeBit[i] = false;
00040     for (int j=0;j<25;j++) {
00041       EMCrystalEnergy[i][j] = 0. ; // 16x25 Crystals
00042     }
00043   }
00044 
00045   // default values
00046   Config.EMSeedEnThreshold = 2.;
00047   Config.EMActiveLevel = 3.;
00048   Config.HadActiveLevel = 3.;
00049   Config.noTauVetoLevel = 10000.;       
00050   Config.hOeThreshold = 0.05;
00051   Config.FGEBThreshold = 0.8;
00052   Config.noFGThreshold = 50.;
00053   Config.FGEEThreshold = 0.8;
00054   Config.MuonNoiseLevel = 2.;
00055   Config.EMNoiseLevel = 2.;
00056   Config.HadNoiseLevel = 2.;
00057   Config.QuietRegionThreshold = 2.;  
00058   Config.JetSeedEtThreshold = 2.;  
00059   Config.CrystalEBThreshold = 0.09;
00060   Config.CrystalEEThreshold = 0.45;
00061 
00062   Config.TowerEMLSB = 1.;
00063   Config.TowerHadLSB = 1.;
00064   Config.EMLSB = 1.;
00065   Config.JetLSB = 1.;
00066 
00067   Config.TowerEBThreshold = 0.2;
00068   Config.TowerEEThreshold = 0.45;
00069   Config.TowerHBThreshold = 0.9;
00070   Config.TowerHEThreshold = 1.4;
00071 
00072   Config.TowerEBScale = 1.0;
00073   Config.TowerEEScale = 1.0;
00074   Config.TowerHBScale = 1.0;
00075   Config.TowerHEScale = 1.0;
00076 
00077 
00078   //Config.EmInputs;
00079   //Config.xTowerInput;
00080 
00081 }
00082 
00083 
00084 FastL1Region::~FastL1Region() 
00085 {
00086 }
00087 
00088 
00089 void
00090 FastL1Region::SetParameters(L1Config iconfig) 
00091 { 
00092   Config = iconfig;
00093 }
00094 
00095 void 
00096 FastL1Region::SetRegionEnergy()
00097 {
00098   sumE = CalcSumE();
00099   sumEt = CalcSumEt();
00100 }
00101 
00102 void 
00103 FastL1Region::SetRegionBits(edm::Event const& e)
00104 {
00105   SetTauBit(e);
00106   SetQuietBit();
00107   SetMIPBit();
00108 }
00109 
00110 void 
00111 FastL1Region::SetTowerBits()
00112 {
00113   SetFGBit();
00114   SetHOEBit();
00115   SetHCFGBit();
00116 }
00117 
00118 //
00119 void
00120 FastL1Region::FillEMCrystals(const CaloTowerConstituentsMap* theTowerConstituentsMap,
00121                              const CaloTopology* calotopo,
00122                              const CaloGeometry* cGeom,
00123                              const EcalRecHitCollection* ec0,
00124                              const EcalRecHitCollection* ec1,
00125                              FastL1RegionMap* m_RMap) 
00126 {
00127   //std::vector< std::pair <std::string,std::string> > la;
00128   //la.resize(2);
00130   //la[0].first = "ecalRecHit";
00131   //la[0].second = "EcalRecHitsEB";
00133   //la[1].first = "ecalRecHit";
00134   //la[1].second = "EcalRecHitsEE";
00135 
00136 
00137   double ethres = Config.CrystalEBThreshold;
00138 
00139   // EB
00140   //e.getByLabel(la[0].first,la[0].second,ec);
00141   //e.getByLabel(Config.EmInputs.at(0),ec);
00142 
00143   ethres = Config.CrystalEBThreshold;
00144   for(EcalRecHitCollection::const_iterator ecItr = ec0->begin();
00145       ecItr != ec0->end(); ++ecItr) {
00146     //CaloRecHit recHit = (CaloRecHit)(*ecItr);
00147     if (ecItr->energy()<ethres) continue;
00148 
00149     EBDetId detId = ecItr->detid();
00150 
00151     //int hiphi = detId.tower_iphi();
00152     int hieta = detId.tower_ieta();
00153     int eieta = detId.ieta();
00154     int eiphi = detId.iphi();
00155     int crIeta = 999;
00156     if (hieta>0)
00157       crIeta = (eieta-1)%5;
00158     else
00159       crIeta = 4 + (eieta+1)%5;
00160     int crIphi = (eiphi - 1)%5;
00161     
00162     //const GlobalPoint gP = cGeom->getPosition(detId);
00163 
00164     //CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
00165     // loop over towers
00166     for(int i=0;i<16;i++) {
00167       //int hiphi = m_RMap->convertFromECal_to_HCal_iphi(detId.tower_iphi());
00168       //int hiphi = m_RMap->convertFromHCal_to_ECal_iphi(detId.tower_iphi());
00169       int hiphi = detId.tower_iphi();
00170       if ( !Towers[i].id().iphi()==hiphi ||  !Towers[i].id().ieta()==hieta ) continue;
00171       EMCrystalEnergy[i][crIeta + 5*crIphi] = ecItr->energy();
00172     }  
00173   }
00174   
00175   // After having filled crsystal info set all veto bits
00176   SetTowerBits();
00177  
00178   // EE FG bits are filled here!!!
00179   //e.getByLabel(la[1].first,la[1].second,ec);
00180 
00181   if (GetiEta()==4 || GetiEta()==5 ||  GetiEta()==6 ||  
00182       GetiEta()==15 || GetiEta()==16 || GetiEta()==17 ) {
00183     
00184     //e.getByLabel(Config.EmInputs.at(1),ec);
00185     ethres = Config.CrystalEEThreshold;
00186     double towerEnergy[16];
00187     // loop over towers
00188     for(int i=0;i<16;i++) {
00189       fgBit[i] = false; // re-iniate
00190             
00191       //if (Towers[i].hadEt()>Config.HadNoiseLevel && Towers[i].emEt()>Config.EMNoiseLevel ) {
00192       if (Towers[i].emEt()>=Config.EMNoiseLevel ) {
00193       //if (Towers[i].emEnergy()>Config.EMNoiseLevel ) {
00194         //towerEnergy[i]  = Towers[i].hadEt() + Towers[i].emEt(); 
00195         towerEnergy[i]  = Towers[i].hadEnergy() + Towers[i].emEnergy(); 
00196       } else {
00197         fgBit[i] = false;
00198         continue;
00199       }
00200 
00201       // EB/EE transition area: unset fg bits
00202       // if (std::abs(Towers[i].id().ieta())==16 || std::abs(Towers[i].id().ieta())==17) {
00203       // fgBit[i] = false;
00204       // continue;
00205       // }
00206       if (Towers[i].emEt()>Config.noFGThreshold) {
00207         fgBit[i] = false;
00208         continue;
00209       }
00210       
00211       //CaloRecHit maxRecHit;
00212       //CaloRecHit maxRecHit2;
00213       double maxRecHit=-1.;
00214       double maxRecHit2=-1.;
00215       DetId maxDetId;
00216 
00217       double max2En = 0.;
00218       
00219       for(EcalRecHitCollection::const_iterator ecItr = ec1->begin();
00220           ecItr != ec1->end(); ++ecItr) {
00221         //CaloRecHit recHit = (CaloRecHit)(*ecItr);
00222         if (ecItr->energy()<ethres) continue;
00223         
00224         EEDetId detId = ecItr->detid();
00225         
00226         CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
00227         //int hiphi = m_RMap->convertFromECal_to_HCal_iphi(towerDetId.iphi());
00228         int hiphi = towerDetId.iphi();
00229         if (Towers[i].id().iphi()==hiphi && 
00230             Towers[i].id().ieta()==towerDetId.ieta() ) {        
00231           if (maxRecHit<ecItr->energy()) {
00232             maxRecHit = ecItr->energy();
00233             maxDetId = detId;
00234           }     
00235         }
00236       } 
00237 
00238       std::vector<DetId> westV = calotopo->west(maxDetId);
00239       std::vector<DetId> eastV = calotopo->east(maxDetId);
00240       std::vector<DetId> southV = calotopo->south(maxDetId);
00241       std::vector<DetId> northV = calotopo->north(maxDetId);
00242       for(EcalRecHitCollection::const_iterator ecItr = ec1->begin();
00243           ecItr != ec1->end(); ++ecItr) {
00244         //CaloRecHit recHit = (CaloRecHit)(*ecItr);
00245         if (ecItr->energy()<ethres) continue;
00246         
00247         EEDetId detId = ecItr->detid();
00248         
00249         CaloTowerDetId towerDetId = theTowerConstituentsMap->towerOf(detId);
00250         //int hiphi = m_RMap->convertFromECal_to_HCal_iphi(towerDetId.iphi());
00251         int hiphi = towerDetId.iphi();
00252         if (Towers[i].id().iphi()==hiphi && 
00253             Towers[i].id().ieta()==towerDetId.ieta() ) {
00254           if ( 
00255               (!westV.empty() && detId==westV[0]) || 
00256               (!eastV.empty() && detId==eastV[0]) || 
00257               (!northV.empty() && detId==northV[0]) || 
00258               (!southV.empty() && detId==southV[0]) 
00259               ) {
00260             if (maxRecHit2<ecItr->energy()) {
00261               maxRecHit2 = ecItr->energy();
00262             }   
00263             max2En += ecItr->energy();
00264           }
00265         }
00266       }  
00267       
00268       double eeThres = Config.FGEEThreshold;
00269       //double totE = maxRecHit.energy() + max2En;
00270       double totE = maxRecHit + maxRecHit2;
00271       if (towerEnergy[i]>(Config.TowerEEThreshold)) {
00272         //double totE = maxRecHit.energy() + maxRecHit2.energy();
00273         //if (totE/towerEnergy[i]<Config.FGEBThreshold) fgBit[i] = true;    
00274         if (totE/towerEnergy[i]<eeThres) fgBit[i] = true;    
00275       }
00276             
00277     }
00278   }
00279    
00280  
00281 }
00282 
00283 //
00284 void
00285 FastL1Region::FillTowerZero(const CaloTower& t, int& tid) 
00286 {
00287   Towers[tid] = CaloTower(t);
00288   //std::cout<<"--- "<<Towers[tid].emEt()<<" "<<Towers[tid].hadEt()<<std::endl;
00289 }
00290 
00291 void
00292 FastL1Region::FillTower(const CaloTower& t, int& tid, edm::ESHandle<CaloGeometry> &cGeom) 
00293 {
00294   double EThres = 0.;
00295   double HThres = 0.;
00296   double EBthres = Config.TowerEBThreshold;
00297   double HBthres = Config.TowerHBThreshold;
00298   double EEthres = Config.TowerEEThreshold;
00299   double HEthres = Config.TowerHEThreshold;
00300   
00301   if(std::abs(t.eta())<2.322) {
00302     EThres = EBthres;
00303   } else {
00304     EThres = EEthres;
00305   }
00306   if(std::abs(t.eta())<2.322) {
00307     HThres = HBthres;
00308   } else {
00309     HThres = HEthres;
00310   }
00311 
00312   double upperThres = 1024.;
00313   double emet = RCTEnergyTrunc(t.emEt(),Config.TowerEMLSB,upperThres);
00314   double hadet = RCTEnergyTrunc(t.hadEt(),Config.TowerHadLSB,upperThres);
00315   //double eme = RCTEnergyTrunc(t.emEnergy(),Config.TowerEMLSB,upperThres);
00316   //double hade = RCTEnergyTrunc(t.hadEnergy(),Config.TowerHadLSB,upperThres);
00317 
00318   if ( emet<EThres) emet = 0.;
00319   if ( hadet<HThres) hadet = 0.;
00320   //if ( eme<EThres) emet = 0.;
00321   //if ( hade<HThres) hadet = 0.;
00322  
00323   GlobalPoint gP = cGeom->getPosition(t.id());
00324   math::XYZTLorentzVector lvec(t.px(),t.py(),t.px(),t.energy());
00325   //Towers[tid] = CaloTower(t);
00326   //Towers[tid] = CaloTower(t.id(),t.momentum(),emet,hadet,t.outerEt(),0,0);
00327   Towers[tid] = CaloTower(t.id(),emet,hadet,t.outerEt(),0,0,lvec,gP,gP);
00328 }
00329 
00330 
00331 //
00332 void
00333 FastL1Region::FillTower_Scaled(const CaloTower& t, int& tid, bool doRCTTrunc,edm::ESHandle<CaloGeometry> &cGeom) 
00334 {
00335 
00336   double EThres = 0.;
00337   double HThres = 0.;
00338   double EBthres = Config.TowerEBThreshold;
00339   double HBthres = Config.TowerHBThreshold;
00340   double EEthres = Config.TowerEEThreshold;
00341   double HEthres = Config.TowerHEThreshold;
00342   
00343   if(std::abs(t.eta())<2.322) {
00344     EThres = EBthres;
00345   } else {
00346     EThres = EEthres;
00347   }
00348   if(std::abs(t.eta())<2.322) {
00349     HThres = HBthres;
00350   } else {
00351     HThres = HEthres;
00352   }
00353 
00354   double emScale = 1.0;
00355   double hadScale = 1.0;
00356   //double outerScale = 1.0;
00357 
00358   if (std::abs(t.eta()>1.3050) && std::abs(t.eta())<3.0) {
00359     hadScale = Config.TowerHEScale;
00360     emScale = Config.TowerEEScale;
00361   }
00362   if (std::abs(t.eta()<1.3050)) {
00363     hadScale = Config.TowerHBScale;
00364     emScale = Config.TowerEBScale;
00365   }
00366 
00367   double emet = emScale * t.emEt();
00368   double hadet = hadScale * t.hadEt();
00369   double eme = emScale * t.emEnergy();
00370   double hade = hadScale * t.hadEnergy();
00371 
00372   if (doRCTTrunc) {
00373     double upperThres = 1024.;
00374     emet = RCTEnergyTrunc(emet,Config.TowerEMLSB,upperThres);
00375     hadet = RCTEnergyTrunc(hadet,Config.TowerHadLSB,upperThres);
00376     eme = RCTEnergyTrunc(eme,Config.TowerEMLSB,upperThres);
00377     hade = RCTEnergyTrunc(hade,Config.TowerHadLSB,upperThres);
00378   }
00379   if ( emet<EThres) emet = 0.;
00380   if ( hadet<HThres) hadet = 0.;
00381   //if ( eme<EThres) emet = 0.;
00382   //if ( hade<HThres) hadet = 0.;
00383 
00384   /* 
00385   if (t.emEt()>0. || t.hadEt()>0.) {
00386     std::cout<<"+++ "
00387              <<t.emEt()<<" "<<t.hadEt()<<" "
00388              <<t.eta()<<" "<<t.phi()<<" "
00389              <<std::endl;
00390   }
00391   */
00392 
00393   //Towers[tid] = CaloTower(t);
00394   //Towers[tid] = CaloTower(t.id(),t.momentum(),emet,hadet,0.,0,0);
00395   //edm::ESHandle<CaloGeometry> cGeom; 
00396   //c.get<CaloGeometryRecord>().get(cGeom);    
00397   GlobalPoint gP = cGeom->getPosition(t.id());
00398   math::XYZTLorentzVector lvec(t.px(),t.py(),t.px(),t.energy());
00399   //Towers[tid] = CaloTower(t);
00400   //Towers[tid] = CaloTower(t.id(),t.momentum(),emet,hadet,t.outerEt(),0,0);
00401   Towers[tid] = CaloTower(t.id(),emet,hadet,t.outerEt(),0,0,lvec,gP,gP);
00402   
00403   //std::cout<<tid<<"  "<<Towers[tid].emEt()<< " " <<Towers[tid].hadEt()<< std::endl;
00404 
00405 }
00406 
00407 void 
00408 FastL1Region::SetHOEBit()
00409 {
00410   double fracThres = Config.hOeThreshold;
00411 
00412   for (int i=0; i<16; i++) {
00413     //if (Towers[i].hadEt()>Config.HadNoiseLevel && Towers[i].emEt()>Config.EMNoiseLevel ) {
00414     if (Towers[i].hadEnergy()>Config.HadNoiseLevel && Towers[i].emEnergy()>Config.EMNoiseLevel ) {
00415       if((Towers[i].hadEt()/Towers[i].emEt()) > fracThres) {
00416         hOeBit[i] = true;
00417       }
00418     }
00419   }
00420 }
00421 
00422 void 
00423 FastL1Region::SetQuietBit()
00424 {
00425   if (SumEt()<Config.QuietRegionThreshold)
00426     quietBit = true;
00427 }
00428 
00429 void 
00430 FastL1Region::SetHCFGBit()
00431 {
00432   // temporary: check definition 
00433   // if (Tower->hadEt>100GeV) hcfgBit = true; ????
00434   //for (int i=0; i<16; i++) {
00435   //}
00436 }
00437 
00438 void 
00439 FastL1Region::SetMIPBit()
00440 {
00441   if (quietBit)
00442   for (int i=0; i<16; i++) {
00443     if (hcfgBit) {
00444       mipBit = true;
00445       return;
00446     }
00447   }
00448 }
00449 
00450 void 
00451 FastL1Region::SetFGBit(int twrid,bool FGBIT)
00452 {
00453   fgBit[twrid] = FGBIT;
00454 }
00455 void 
00456 FastL1Region::SetHCFGBit(int twrid,bool FGBIT)
00457 {
00458   ;
00459 }
00460 void 
00461 FastL1Region::SetHOEBit(int twrid,bool FGBIT)
00462 {
00463   hOeBit[twrid] = FGBIT;
00464 }
00465 
00466 void 
00467 FastL1Region::SetFGBit()
00468 {
00469   double ratioCut = Config.FGEBThreshold;
00470 
00471   double stripEnergy[16][5];
00472   double duostripEnergy[16][4];
00473   double towerEnergy[16];
00474 
00475   if (GetiEta()>=7 && GetiEta()<=14) {
00476     //Barrel
00477     for (int i=0; i<16; i++) {
00478       //if (Towers[i].hadEt()>Config.HadNoiseLevel && Towers[i].emEt()>Config.EMNoiseLevel ) {
00479       if (Towers[i].emEt()>Config.EMNoiseLevel ) {
00480         //towerEnergy[i]  = Towers[i].hadEt() + Towers[i].emEt(); 
00481         towerEnergy[i]  = Towers[i].hadEnergy() + Towers[i].emEnergy(); 
00482       } else {
00483         fgBit[i] = false;
00484         continue;
00485       }
00486 
00487       // EB/EE transition area: unset fg bits
00488       //if (std::abs(Towers[i].id().ieta())==16 || std::abs(Towers[i].id().ieta())==17) {
00489       //fgBit[i] = false;
00490       //continue;
00491       //}
00492       if (Towers[i].emEt()>Config.noFGThreshold) {
00493         fgBit[i] = false;
00494         continue;
00495       }
00496 
00497       bool fgflag = false;
00498         for (int j=0; j<5; j++) {
00499         stripEnergy[i][j] = EMCrystalEnergy[i][j] + EMCrystalEnergy[i][j+5] + EMCrystalEnergy[i][j+10] + 
00500           EMCrystalEnergy[i][j+15] + EMCrystalEnergy[i][j+20];
00501       }
00502       for (int j=0; j<4; j++) {
00503         duostripEnergy[i][j] = stripEnergy[i][j] + stripEnergy[i][j+1];
00504         if (towerEnergy[i]>(Config.TowerEBThreshold)) {
00505           //std::cout<<duostripEnergy[i][j]<<" |"<<towerEnergy[i]<<" |"<<duostripEnergy[i][j]/towerEnergy[i]<<std::endl;
00506           if ( (duostripEnergy[i][j] / towerEnergy[i]) > ratioCut) {
00507             fgflag = true;
00508           } 
00509           //std::cout<<duostripEnergy[i][j]<<" | "<<towerEnergy[i]<<": "<<duostripEnergy[i][j]/towerEnergy[i]<<std::endl;       
00510         }
00511       }
00512 
00513       if (fgflag) { 
00514         fgBit[i] = false;
00515       } else {
00516         fgBit[i] = true;
00517       }
00518       //std::cout<<GetiEta()<<" | "<<i<<": "<<fgBit[i]<<std::endl;
00519       //std::cout<<"********************************************"<<std::endl;
00520     }
00521   } else {
00522     // Endcap FG bit is already filled in fillEMCrystals()!!! 
00523   }
00524   
00525 }
00526 
00527 
00528 void 
00529 FastL1Region::SetTauBit(edm::Event const& iEvent)
00530 {
00531   float emThres = Config.EMActiveLevel;
00532   float hadThres = Config.HadActiveLevel;
00533 
00534   if (doBitInfo) BitInfo.setIsolationVeto(false);       
00535   if (doBitInfo) BitInfo.setTauVeto(false);     
00536   if (doBitInfo) BitInfo.setEmTauVeto(false);   
00537   if (doBitInfo) BitInfo.setHadTauVeto(false);  
00538 
00539   // init pattern containers
00540   unsigned emEtaPat = 0;
00541   unsigned emPhiPat = 0;
00542   unsigned hadEtaPat = 0;
00543   unsigned hadPhiPat = 0;
00544   unsigned one = 1;
00545 
00546 
00547   // fill hits as bit pattern
00548   for (int i=0; i<16; i++) {
00549     if(Towers[i].emEt() > emThres) {
00550       emEtaPat |= (one << (unsigned)(i%4));
00551       emPhiPat |= (one << (unsigned)(i/4));
00552     }
00553 
00554     if( Towers[i].hadEt() > hadThres) {
00555       hadEtaPat |= (one << (unsigned)(i%4));
00556       hadPhiPat |= (one << (unsigned)(i/4));
00557     }
00558 
00559   }
00560 
00561   // Patterns with two or less contiguous bits set are passed
00562   // rest are vetoed; 5=0101;7=0111;9=1001;10=1010;11=1011;13=1101;14=1110;15=1111
00563   //  --- Alternate patterns
00564   //  --- 9=1001;15=1111
00565   static std::vector<unsigned> vetoPatterns;
00566   if(vetoPatterns.size() == 0) {
00567     vetoPatterns.push_back(5);
00568     vetoPatterns.push_back(7);
00569     vetoPatterns.push_back(9);
00570     vetoPatterns.push_back(10);
00571     vetoPatterns.push_back(11);
00572     vetoPatterns.push_back(13);
00573     vetoPatterns.push_back(14);
00574     vetoPatterns.push_back(15);
00575   }
00576 
00577 
00578   for(std::vector<unsigned>::iterator i = vetoPatterns.begin();
00579       i != vetoPatterns.end();  i++) {
00580     unsigned etaPattern = emEtaPat | hadEtaPat;
00581     unsigned phiPattern = emPhiPat | hadPhiPat;
00582 
00583     //  em pattern
00584     if(emEtaPat == *i || emPhiPat == *i) {
00585       if (doBitInfo) BitInfo.setEmTauVeto(true);
00586     }
00587     //  had pattern
00588     if(hadEtaPat == *i || hadPhiPat == *i) {
00589       if (doBitInfo) BitInfo.setHadTauVeto(true);
00590     }
00591 
00592     if(etaPattern == *i || phiPattern == *i) // combined pattern
00593       //if(emEtaPat == *i || emPhiPat == *i || hadEtaPat == *i || hadPhiPat == *i)
00594       {
00595         tauBit = true;
00596         if (doBitInfo) BitInfo.setTauVeto(true);        
00597         return;
00598       }  
00599   }
00600   
00601   tauBit = false;
00602   
00603 }
00604 
00605 
00606 int 
00607 FastL1Region::HighestEtTowerID()
00608 {
00609   int hid = -1;
00610   double tmpet=0.;
00611   for (int i=0; i<16; i++) {
00612     if ( (Towers[i].emEt()+Towers[i].hadEt()) > tmpet) {
00613       tmpet = (Towers[i].emEt()+Towers[i].hadEt());
00614       hid = i;
00615     }
00616   }
00617 
00618   if (doBitInfo) BitInfo.setHighestEtTowerID (hid);      
00619 
00620   return hid;
00621 }
00622 
00623 int 
00624 FastL1Region::HighestEmEtTowerID()
00625 {
00626   int hid = -1;
00627   double tmpet=0.;
00628   for (int i=0; i<16; i++) {
00629     if ( (Towers[i].emEt()) > tmpet) {
00630       tmpet = (Towers[i].emEt());
00631       hid = i;
00632     }
00633   }
00634 
00635   if (doBitInfo) BitInfo.setHighestEmEtTowerID (hid);    
00636   return hid;
00637 }
00638 
00639 int 
00640 FastL1Region::HighestHadEtTowerID()
00641 {
00642   int hid = -1;
00643   double tmpet=0.;
00644   for (int i=0; i<16; i++) {
00645     if ( (Towers[i].hadEt()) > tmpet) {
00646       tmpet = (Towers[i].hadEt());
00647       hid = i;
00648     }
00649   }
00650 
00651   if (doBitInfo) BitInfo.setHighestHadEtTowerID (hid);   
00652   return hid;
00653 }
00654 
00655 double 
00656 FastL1Region::CalcSumEt()
00657 {
00658   double sumet=0;
00659   for (int i=0; i<16; i++) {
00660     sumet += Towers[i].emEt();
00661     sumet += Towers[i].hadEt();
00662   }
00663 
00664   return sumet;
00665 }
00666 
00667 double 
00668 FastL1Region::CalcSumEmEt()
00669 {
00670   double sumet=0;
00671   for (int i=0; i<16; i++) {
00672     sumet += Towers[i].emEt();
00673   }
00674 
00675   return sumet;
00676 }
00677 
00678 double 
00679 FastL1Region::CalcSumHadEt()
00680 {
00681   double sumet=0;
00682   for (int i=0; i<16; i++) {
00683     sumet += Towers[i].hadEt();
00684   }
00685 
00686   return sumet;
00687 }
00688 
00689 double 
00690 FastL1Region::CalcSumE()
00691 {
00692   double sume=0;
00693   for (int i=0; i<16; i++) {
00694     sume += Towers[i].emEnergy();
00695     sume += Towers[i].hadEnergy();
00696 
00697   }
00698   return sume;
00699 }
00700 
00701 double 
00702 FastL1Region::CalcSumEmE()
00703 {
00704   double sume=0;
00705   for (int i=0; i<16; i++) {
00706     sume += Towers[i].emEnergy();
00707   }
00708   return sume;
00709 }
00710 
00711 double 
00712 FastL1Region::CalcSumHadE()
00713 {
00714   double sume=0;
00715   for (int i=0; i<16; i++) {
00716     sume += Towers[i].hadEnergy();
00717   }
00718   return sume;
00719 }
00720 
00721 
00722 std::pair<double, double>
00723 FastL1Region::getRegionCenterEtaPhi(const edm::EventSetup& c)
00724 {
00725   edm::ESHandle<CaloGeometry> cGeom; 
00726   //c.get<IdealGeometryRecord>().get(cGeom);    
00727   c.get<CaloGeometryRecord>().get(cGeom);    
00728 
00729   const GlobalPoint gP1 = cGeom->getPosition(Towers[5].id());
00730   //const GlobalPoint gP2 = cGeom->getPosition(Towers[6].id());
00731   //const GlobalPoint gP3 = cGeom->getPosition(Towers[10].id());
00732 
00733   double eta = gP1.eta();  
00734   double phi = gP1.phi();
00735   
00736   return std::pair<double, double>(eta, phi);
00737 }
00738 
00739 
00740 // test filling of FastL1Region
00741 void 
00742 FastL1Region::Dump()
00743 {
00744 
00745   // test tower filling:
00746   /*
00747   CaloTowerCollection::const_iterator t;
00748   int count = 0;
00749   for (t=Towers.begin(); t!=Towers.end(); t++) {
00750     std::cout << count << ") " << t->energy() << " | " << t->eta()  << " | " << t->phi() << std::endl;
00751     count++;
00752   }
00753   std::cout << std::endl;
00754   */
00755 
00756   // test region neighbours:
00757   std::cout << this->GetNWId() << " "  << this->GetNorthId() << " "  << this->GetNEId() << std::endl;
00758   std::cout << this->GetWestId() << " "  << this->GetId() << " "  << this->GetEastId() << std::endl;
00759   std::cout << this->GetSWId() << " "  << this->GetSouthId() << " "  << this->GetSEId() << std::endl;
00760   std::cout << std::endl;
00761 
00762 }
00763 
00764 int 
00765 FastL1Region::GetNorthId() 
00766 { if (iphi != 17) return ((iphi+1)*22 + ieta); else return ieta; }
00767 
00768 
00769 int 
00770 FastL1Region::GetSouthId() 
00771 { if (iphi != 0) return ((iphi-1)*22 + ieta); else return (17*22 + ieta); }
00772 
00773 int 
00774 FastL1Region::GetWestId() 
00775 { if (ieta != 0) return (iphi*22 + ieta-1); else return 999; }
00776 
00777 int 
00778 FastL1Region::GetEastId() 
00779 { if (ieta != 21) return (iphi*22 + ieta+1); else return 999; }
00780   
00781 int 
00782 FastL1Region::GetNWId() 
00783 { 
00784   if (ieta != 0) {
00785     if (iphi != 17) 
00786       return ((iphi+1)*22 + ieta-1); 
00787     else
00788       return (ieta-1);  
00789   } else {
00790     return 999; 
00791   }
00792 }
00793 
00794 int 
00795 FastL1Region::GetSWId() 
00796 { 
00797   if (ieta != 0) {
00798     if (iphi != 0) 
00799       return ((iphi-1)*22 + ieta-1); 
00800     else
00801       return (17*22 + ieta-1);  
00802   } else {
00803     return 999; 
00804   }
00805 }
00806 
00807 int FastL1Region::GetNEId() 
00808 { 
00809   if (ieta != 21) {
00810     if (iphi != 17) 
00811       return ((iphi+1)*22 + ieta+1); 
00812     else
00813       return (ieta+1);  
00814   } else {
00815     return 999; 
00816   }
00817 }
00818 
00819 int 
00820 FastL1Region::GetSEId() 
00821 { 
00822   if (ieta != 21) {
00823     if (iphi != 0) 
00824       return ((iphi-1)*22 + ieta+1); 
00825     else
00826       return (17*22 + ieta+1);  
00827   } else {
00828     return 999; 
00829   }
00830 }
00831 
00832 double 
00833 corrJetEt(double et, double eta)
00834 {
00835   return corrJetEt1(et,eta);
00836   //return corrJetEt2(et,eta);
00837 }
00838 
00839 
00840 // Jet Calibration from CMSSW_1_3_0
00841 double 
00842 corrJetEt2(double et, double eta)
00843 {
00844   const int NUMBER_ETA_VALUES = 11;
00845   std::vector< std::vector<float> > m_calibFunc;
00846 
00847   m_calibFunc.resize(NUMBER_ETA_VALUES);
00848 
00849   // still fill manually 
00850   m_calibFunc.at(0).push_back(1);
00851   m_calibFunc.at(0).push_back(1);
00852   m_calibFunc.at(0).push_back(2);
00853 
00854   m_calibFunc.at(1).push_back(1);
00855   m_calibFunc.at(1).push_back(2);
00856   m_calibFunc.at(1).push_back(2);
00857 
00858   m_calibFunc.at(2).push_back(2);
00859   m_calibFunc.at(2).push_back(2);
00860   m_calibFunc.at(2).push_back(2);
00861   m_calibFunc.at(2).push_back(2);
00862   m_calibFunc.at(2).push_back(3);
00863   m_calibFunc.at(2).push_back(3);
00864 
00865   m_calibFunc.at(3).push_back(1);
00866   m_calibFunc.at(3).push_back(1);
00867   m_calibFunc.at(3).push_back(3);
00868 
00869   m_calibFunc.at(4).push_back(1);
00870   m_calibFunc.at(4).push_back(3);
00871   m_calibFunc.at(4).push_back(3);
00872   m_calibFunc.at(4).push_back(6);
00873   m_calibFunc.at(4).push_back(6);
00874   m_calibFunc.at(4).push_back(6);
00875   m_calibFunc.at(4).push_back(6);
00876   m_calibFunc.at(4).push_back(6);
00877 
00878   m_calibFunc.at(5).push_back(3);
00879   m_calibFunc.at(5).push_back(3);
00880   m_calibFunc.at(5).push_back(3);
00881 
00882   m_calibFunc.at(6).push_back(1);
00883   m_calibFunc.at(6).push_back(1);
00884   m_calibFunc.at(6).push_back(4);
00885 
00886   m_calibFunc.at(7).push_back(1);
00887   m_calibFunc.at(7).push_back(4);
00888   m_calibFunc.at(7).push_back(4);
00889 
00890   m_calibFunc.at(8).push_back(4);
00891   m_calibFunc.at(8).push_back(4);
00892   m_calibFunc.at(8).push_back(4);
00893   m_calibFunc.at(8).push_back(1);
00894   m_calibFunc.at(8).push_back(1);
00895   m_calibFunc.at(8).push_back(1);
00896 
00897   m_calibFunc.at(9).push_back(1);
00898   m_calibFunc.at(9).push_back(1);
00899   m_calibFunc.at(9).push_back(5);
00900 
00901   m_calibFunc.at(10).push_back(1);
00902   m_calibFunc.at(10).push_back(5);
00903   m_calibFunc.at(10).push_back(5);
00904 
00905 
00906   double etabin[12] = { 0.0, 0.348, 0.696, 1.044, 1.392, 1.74, 2.172, 3.0,
00907                         3.33, 3.839, 4.439, 5.115};
00908   int BinID = 0;
00909   for(int i = 0; i < 11; i++){
00910     if(std::abs(eta) >= etabin[i] && eta < etabin[i+1])
00911       BinID = i;
00912   }
00913 
00914   double corrEt = 0;
00915   for (unsigned i=0; i<m_calibFunc.at(BinID).size();i++){
00916     corrEt += m_calibFunc.at(BinID).at(i)*pow(et,(int)i); 
00917   }
00918   
00919   uint16_t jetEtOut = (uint16_t)corrEt;
00920   
00921   if(jetEtOut < 1024) {
00922     return (double)jetEtOut;
00923   }
00924   return (double)1023;
00925 
00926 }
00927 
00928 // Jet Calibration from Frederick(Helsinki), Monika/Creighton (Wisconsin)
00929 double 
00930 corrJetEt1(double et, double eta)
00931 {
00932   double etabin[23] = {-5.115, -4.439, -3.839, -3.33, 
00933                         -3.0, -2.172, -1.74, -1.392, -1.044, -0.696, -0.348, 
00934                         0.0, 0.348, 0.696, 1.044, 1.392, 1.74, 2.172, 3.0,
00935                         3.33, 3.839, 4.439, 5.115};
00936 
00937   int BinID = 0;
00938       
00939   double domainbin_L[22] = {6.52223337753073373e+00,6.64347505748981959e+00,6.78054870174118296e+00,6.75191887554567405e+00,
00940                             6.60891660595437802e+00,6.57813476381055473e+00,6.96764764481347232e+00,6.77192746888150943e+00,
00941                             7.16209661824076260e+00,7.09640803784948027e+00,7.29886808171882517e+00,7.29883431473330546e+00,
00942                             7.24561741344293875e+00,7.05381822724987995e+00,6.52340799679028827e+00,6.96091042775473401e+00,
00943                             6.69803071767842262e+00,7.79138848427964259e+00,6.78565437835616603e+00,6.71201461174192904e+00,
00944                             6.60832257380386334e+00,6.54875448717649267e+00};
00945 
00946   double domainbin_U[22] = {8.90225568813317558e+00,1.24483653543590922e+01,1.32037091554958987e+01,1.70036104608977681e+01,
00947                             3.54325008263432011e+01,4.28758696753095450e+01,4.73079850563588025e+01,4.74182802251108981e+01,
00948                             4.62509826468679748e+01,5.02198002212212913e+01,4.69817029938948352e+01,4.77263481299233732e+01,
00949                             4.86083837976362076e+01,4.80105593452927337e+01,5.11550616006504200e+01,4.90703092811585861e+01,
00950                             4.11879629179572788e+01,3.21820720507165845e+01,1.71844078553560529e+01,1.33158534849654764e+01,
00951                             1.43586396719878149e+01,1.08629843894704248e+01};
00952 
00953   double A[22] = {2.03682,-4.36824,-4.45258,-6.76524,-22.5984,-24.5289,-24.0313,-22.1896,-21.7818,-22.9882,-20.3321,
00954                   -21.0595,-22.1007,-22.658,-23.6898,-24.8888,-23.3246,-21.5343,-6.41221,-4.58952,-3.17222,0.637666};
00955 
00956   double B[22] = {0.226303,0.683099,0.704578,0.704623,0.825928,0.80086,0.766475,0.726059,0.760964,0.792227,0.789188,0.795219,
00957                   0.781097,0.768022,0.740101,0.774782,0.788106,0.814502,0.686877,0.709556,0.628581,0.317453};
00958   
00959   double C[22] = {0.00409083,0.000235995,8.22958e-05,2.47567e-05,0.000127995,0.000132914,0.000133342,0.000133035,0.000125993,
00960                   8.25968e-05,9.94442e-05,9.11652e-05,0.000109351,0.000115883,0.00011112,0.000122559,0.00015868,0.000152601,
00961                   0.000112927,6.29999e-05,0.000741798,0.00274605};
00962 
00963   double D[22] = {8.24022,7.55916,7.16448,6.31577,5.96339,5.31203,5.35456,4.95243,5.34809,4.93339,5.05723,5.08575,5.18643,5.15202,
00964                   4.48249,5.2734,5.51785,8.00182,6.21742,6.96692,7.22975,8.12257};
00965   
00966   double E[22] = {-0.343598,-0.294067,-0.22529,-0.0718625,0.004164,0.081987,0.124964,0.15006,0.145201,0.182151,0.187525,0.184763,
00967                   0.170689,0.155268,0.174603,0.133432,0.0719798,-0.0921457,-0.0525274,-0.208415,-0.253542,-0.318476};
00968 
00969   double F[22] = {0.0171799,0.0202499,0.0186897,0.0115477,0.00603883,0.00446235,0.00363449,0.00318894,0.00361997,0.00341508,
00970                   0.00366392,0.0036545,0.00352303,0.00349116,0.00294891,0.00353187,0.00460384,0.00711028,0.0109351,0.0182924,
00971                   0.01914,0.0161094};
00972 
00973   for(int i = 0; i < 22; i++){
00974     if(eta > etabin[i] && eta <= etabin[i+1])
00975       BinID = i;
00976   }
00977 
00978   if(et >= domainbin_U[BinID]){
00979     return 2*(et-A[BinID])/(B[BinID]+sqrt(B[BinID]*B[BinID]-4*A[BinID]*C[BinID]+4*et*C[BinID]));
00980   }
00981   else if(et > domainbin_L[BinID]){
00982     return 2*(et-D[BinID])/(E[BinID]+sqrt(E[BinID]*E[BinID]-4*D[BinID]*F[BinID]+4*et*F[BinID]));
00983   }
00984   else return et;
00985 }
00986 
00987 
00988 // EM correction from ORCA for cmsim 133
00989 double 
00990 //corrEmEt(double et, double eta) {
00991 corrEmEt(double et, int eta) {
00992 
00993 
00994   const int nscales = 32;
00995   /*
00996   const int nscales = 27;
00997   double etalimit[nscales] = { 0.0,0.087,0.174,0.261,0.348,0.435,0.522,0.609,0.696,0.783,0.870,0.957,
00998                           1.044,1.131,1.218,1.305,1.392,1.479,1.566,1.653,1.740,1.830,1.930,
00999                           2.043,2.172,2.322,2.500};
01000   */
01001 
01002   double scfactor[nscales] = { 
01003     1.00,1.01,1.02,1.02,1.02,1.06,1.04,1.04,1.05,1.09,1.10,1.10,1.15,
01004     1.20,1.27,1.29,1.32,1.52,1.52,1.48,1.40,1.32,1.26,1.21,1.17,1.15, 
01005     1.15,1.15,1.15,1.15,1.15,1.15};
01006 
01007   /*
01008   double scale=1.;
01009   for (int i=0;i<nscales;i++) {
01010     if (std::abs(eta)<etalimit[i]) {
01011       scale = scfactor[i];
01012     }
01013   }
01014     return (scale*et);
01015   */
01016 
01017   if (eta>=0 && eta <=28)
01018     return (scfactor[eta]*et);
01019   else
01020     return et;
01021 }
01022 
01023 
01024 // Rounding the Et info for simulating the regional Et resolution
01025 double 
01026 RCTEnergyTrunc(double et, double LSB, double thres) {
01027 
01028   //return et;
01029   if (et>=thres) return thres;
01030 
01031   //et += LSB/2.;
01032   //double ret = (int)(et / LSB) * LSB + LSB;
01033   int iEt = (int)(et / LSB);
01034   double ret =  (double)iEt * LSB;
01035 
01036   return ret;
01037 }
01038 
01039 
01040 double 
01041 GCTEnergyTrunc(double et, double LSB, bool doEM) {
01042 
01043   //return et;
01044 
01045   //double L1CaloEmEtScaleLSB = LSB;
01046   //double L1CaloRegionEtScaleLSB = LSB;
01047 
01048   //if (et>0.) et += LSB/2.; // round up
01049 
01050   double L1CaloEmThresholds[64] = { 
01051     0.,     1.,     2.,     3.,     4.,     5.,     6.,     7.,     8.,     9., 
01052     10.,    11.,    12.,    13.,    14.,    15.,    16.,    17.,    18.,    19., 
01053     20.,    21.,    22.,    23.,    24.,    25.,    26.,    27.,    28.,    29., 
01054     30.,    31.,    32.,    33.,    34.,    35.,    36.,    37.,    38.,    39., 
01055     40.,    41.,    42.,    43.,    44.,    45.,    46.,    47.,    48.,    49.,
01056     50.,    51.,    52.,    53.,    54.,    55.,    56.,    57.,    58.,    59., 
01057     60.,    61.,    62.,    63.
01058   };
01059  
01060   double L1CaloJetThresholds[64] = {       
01061     0.,     10.,    12.,    14.,    15.,    18.,    20.,    22.,    24.,    25.,
01062     28.,    30.,    32.,    35.,    37.,    40.,    45.,    50.,    55.,    60.,    
01063     65.,    70.,    75.,    80.,    85.,    90.,    100.,   110.,   120.,   125.,   
01064     130.,   140.,   150.,   160.,   170.,   175.,   180.,   190.,   200.,   215.,   
01065     225.,   235.,   250.,   275.,   300.,   325.,   350.,   375.,   400.,   425.,   
01066     450.,   475.,   500.,   525.,   550.,   575.,   600.,   625.,   650.,   675.,   
01067     700.,   725.,   750.,   775.
01068   };
01069   
01070 
01071 
01072   double L1CaloThresholds[64];
01073   if (doEM) {
01074     for (int i=0;i<64;i++)
01075       L1CaloThresholds[i] = L1CaloEmThresholds[i];
01076   } else {
01077     for (int i=0;i<64;i++)
01078       L1CaloThresholds[i] = L1CaloJetThresholds[i];
01079   }
01080 
01081 
01082   double ret = 0.;
01083   for (int i=63;i>0;i--) {
01084     if (et>=(L1CaloThresholds[i])) {
01085       if (i==63) {
01086         ret = L1CaloThresholds[63];
01087       } else {
01088         /*
01089         double minL = std::abs(et - L1CaloThresholds[i]); 
01090         double minU = std::abs(et - L1CaloThresholds[i+1]); 
01091         if (minL<minU)
01092           ret = L1CaloThresholds[i];
01093         else
01094           ret = L1CaloThresholds[i+1];
01095         */
01096         /*
01097         if (doEM) {
01098           ret = L1CaloThresholds[i];
01099         } else {
01100           ret = L1CaloThresholds[i+1];
01101         }
01102         */
01103         ret = L1CaloThresholds[i];
01104       }
01105       break;
01106     }
01107   }
01108   return ret;
01109 }
01110 
01111 
01112