CMS 3D CMS Logo

EcalSelectiveReadoutSuppressor.cc

Go to the documentation of this file.
00001 #include "SimCalorimetry/EcalSelectiveReadoutAlgos/interface/EcalSelectiveReadoutSuppressor.h"
00002 #include "SimCalorimetry/EcalSelectiveReadoutAlgos/src/EcalSelectiveReadout.h"
00003 #include "DataFormats/EcalDigi/interface/EEDataFrame.h"
00004 #include "DataFormats/EcalDigi/interface/EBDataFrame.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 
00007 //#include "FWCore/Framework/interface/Selector.h"
00008 #include "FWCore/Framework/interface/ESHandle.h"
00009 
00010 // Geometry
00011 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00012 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00013 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00014 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00015 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00016 
00017 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00018 
00019 //exceptions:
00020 #include "FWCore/Utilities/interface/Exception.h"
00021 
00022 #include <limits>
00023 #include <cmath>
00024 #include <iostream>
00025 
00026 using namespace boost;
00027 using namespace std;
00028 
00029 const int EcalSelectiveReadoutSuppressor::nFIRTaps = 6;
00030 
00031 EcalSelectiveReadoutSuppressor::EcalSelectiveReadoutSuppressor(const edm::ParameterSet & params):
00032   firstFIRSample(params.getParameter<int>("ecalDccZs1stSample")),
00033   weights(params.getParameter<vector<double> >("dccNormalizedWeights")),
00034   symetricZS(params.getParameter<bool>("symetricZS"))
00035 {
00036   
00037   double adcToGeV = params.getParameter<double>("ebDccAdcToGeV");
00038   thrUnit[BARREL] = adcToGeV/4.; //unit=1/4th ADC count
00039   
00040   adcToGeV = params.getParameter<double>("eeDccAdcToGeV");
00041   thrUnit[ENDCAP] = adcToGeV/4.; //unit=1/4th ADC count
00042   ecalSelectiveReadout
00043     = auto_ptr<EcalSelectiveReadout>(new EcalSelectiveReadout
00044                                      (params.getParameter<int>("deltaEta"),
00045                                       params.getParameter<int>("deltaPhi")));
00046   initCellThresholds(params.getParameter<double>("srpBarrelLowInterestChannelZS"),
00047                      params.getParameter<double>("srpEndcapLowInterestChannelZS"),
00048                      params.getParameter<double>("srpBarrelHighInterestChannelZS"),
00049                      params.getParameter<double>("srpEndcapHighInterestChannelZS")
00050                      );
00051   trigPrimBypass_ = params.getParameter<bool>("trigPrimBypass");
00052   trigPrimBypassWithPeakFinder_
00053     = params.getParameter<bool>("trigPrimBypassWithPeakFinder");
00054   trigPrimBypassLTH_ = params.getParameter<double>("trigPrimBypassLTH");
00055   trigPrimBypassHTH_ = params.getParameter<double>("trigPrimBypassHTH");
00056   if(trigPrimBypass_){
00057     edm::LogWarning("Digitization") << "Beware a simplified trigger primitive "
00058       "computation is used for the ECAL selective readout";
00059   }
00060 }
00061 
00062 
00063 void EcalSelectiveReadoutSuppressor::setTriggerMap(const EcalTrigTowerConstituentsMap * map){
00064   theTriggerMap = map;
00065   ecalSelectiveReadout->setTriggerMap(map);
00066 }
00067 
00068 
00069 void EcalSelectiveReadoutSuppressor::setGeometry(const CaloGeometry * caloGeometry) 
00070 {
00071 #ifndef ECALSELECTIVEREADOUT_NOGEOM
00072    ecalSelectiveReadout->setGeometry(caloGeometry);
00073 #endif
00074 }
00075 
00076 
00077 void EcalSelectiveReadoutSuppressor::initCellThresholds(double barrelLowInterest,
00078                                                         double endcapLowInterest,
00079                                                         double barrelHighInterest,
00080                                                         double endcapHighInterest){
00081   //center, neighbour and single RUs are grouped into a single
00082   //'high interest' group
00083   int lowInterestThr[2]; //index for BARREL/ENDCAP
00084   int lowInterestSrFlag[2];
00085   int highInterestThr[2];
00086   int highInterestSrFlag[2];
00087   
00088   lowInterestThr[BARREL] = internalThreshold(barrelLowInterest, BARREL);
00089   lowInterestSrFlag[BARREL] = thr2Srf(lowInterestThr[BARREL],
00090                                       EcalSrFlag::SRF_ZS1);
00091   
00092   highInterestThr[BARREL] = internalThreshold(barrelHighInterest, BARREL);
00093   highInterestSrFlag[BARREL] = thr2Srf(highInterestThr[BARREL],
00094                                        EcalSrFlag::SRF_ZS2);
00095   
00096   lowInterestThr[ENDCAP] = internalThreshold(endcapLowInterest, ENDCAP);
00097   lowInterestSrFlag[ENDCAP] = thr2Srf(lowInterestThr[ENDCAP],
00098                                       EcalSrFlag::SRF_ZS2);
00099 
00100   highInterestThr[ENDCAP] = internalThreshold(endcapHighInterest, ENDCAP); 
00101   highInterestSrFlag[ENDCAP] = thr2Srf(highInterestThr[ENDCAP],
00102                                        EcalSrFlag::SRF_ZS2);
00103   
00104   for(int iSubDet = 0; iSubDet<2; ++iSubDet){
00105     //low interest
00106     zsThreshold[iSubDet][0] = lowInterestThr[iSubDet];
00107     srFlags[iSubDet][0] = lowInterestSrFlag[iSubDet];
00108 
00109     //single->high interest
00110     zsThreshold[iSubDet][1] = highInterestThr[iSubDet];
00111     srFlags[iSubDet][1] = highInterestSrFlag[iSubDet];
00112 
00113     //neighbour->high interest
00114     zsThreshold[iSubDet][2] = highInterestThr[iSubDet];
00115     srFlags[iSubDet][2] = highInterestSrFlag[iSubDet];
00116 
00117     //center->high interest
00118     zsThreshold[iSubDet][3] = highInterestThr[iSubDet];
00119     srFlags[iSubDet][3] = highInterestSrFlag[iSubDet];
00120   }
00121 }
00122 
00123 int EcalSelectiveReadoutSuppressor::thr2Srf(int thr, int zsFlag) const{
00124   if(thr==numeric_limits<int>::max()){
00125     return EcalSrFlag::SRF_SUPPRESS;
00126   }
00127   if(thr==numeric_limits<int>::min()){
00128     return EcalSrFlag::SRF_FULL;
00129   } 
00130   return zsFlag;
00131 }
00132 
00133 int EcalSelectiveReadoutSuppressor::internalThreshold(double thresholdInGeV,
00134                                                       int iSubDet) const{
00135   double thr_ = thresholdInGeV / thrUnit[iSubDet];
00136   //treating over- and underflows, threshold is coded on 11+1 signed bits
00137   //an underflow threshold is considered here as if NoRO DCC switch is on
00138   //an overflow threshold is considered here as if ForcedRO DCC switch in on
00139   //Beware that conparison must be done on a double type, because conversion
00140   //cast to an int of a double higher than MAX_INT is undefined.
00141   int thr;
00142   if(thr_>=0x7FF+.5){
00143     thr = numeric_limits<int>::max();
00144   } else if(thr_<=-0x7FF-.5){
00145     thr = numeric_limits<int>::min();
00146   } else{
00147     thr = lround(thr_);
00148   }
00149   return thr;
00150 }
00151 
00152 //This implementation  assumes that int is coded on at least 28-bits,
00153 //which in pratice should be always true.
00154 bool EcalSelectiveReadoutSuppressor::accept(edm::DataFrame const & frame,
00155                                             int thr){
00156   //FIR filter weights:
00157   const vector<int>& w = getFIRWeigths();
00158   
00159   //accumulator used to compute weighted sum of samples
00160   int acc = 0;
00161   bool gain12saturated = false;
00162   const int gain12 = 0x01; 
00163   const int lastFIRSample = firstFIRSample + nFIRTaps - 1;
00164   //LogDebug("DccFir") << "DCC FIR operation: ";
00165   int iWeight = 0;
00166   for(int iSample=firstFIRSample-1;
00167       iSample<lastFIRSample; ++iSample, ++iWeight){
00168     if(iSample>=0 && iSample < (int)frame.size()){
00169       EcalMGPASample sample(frame[iSample]);
00170       if(sample.gainId()!=gain12) gain12saturated = true;
00171       //LogTrace("DccFir") << (iSample>=firstFIRSample?"+":"") << sample.adc()
00172       //                 << "*(" << w[iWeight] << ")";
00173       acc+=sample.adc()*w[iWeight];
00174     } else{
00175       edm::LogWarning("DccFir") << __FILE__ << ":" << __LINE__ <<
00176         ": Not enough samples in data frame or 'ecalDccZs1stSample' module "
00177         "parameter is not valid...";
00178     }
00179   }
00180 
00181   if(symetricZS){//cut on absolute value
00182     if(acc<0) acc = -acc;
00183   }
00184   
00185   //LogTrace("DccFir") << "\n";
00186   //discards the 8 LSBs 
00187   //(result of shift operator on negative numbers depends on compiler
00188   //implementation, therefore the value is offset to make sure it is positive
00189   //before performing the bit shift).
00190   acc = ((acc + (1<<30)) >>8) - (1 <<(30-8));
00191 
00192   //ZS passed if weigthed sum acc above ZS threshold or if
00193   //one sample has a lower gain than gain 12 (that is gain 12 output
00194   //is saturated)
00195   
00196   const bool result = (acc >= thr) || gain12saturated;
00197   
00198   //LogTrace("DccFir") << "acc: " << acc << "\n"
00199   //                   << "threshold: " << thr << " ("
00200   //                   << thr*thrUnit[((EcalDataFrame&)frame).id().subdetId()==EcalBarrel?0:1]
00201   //                   << "GeV)\n"
00202   //                   << "saturated: " << (gain12saturated?"yes":"no") << "\n"
00203   //                   << "ZS passed: " << (result?"yes":"no")
00204   //                   << (symetricZS?" (symetric cut)":"") << "\n";
00205   
00206   return result;
00207 }
00208 
00209 void EcalSelectiveReadoutSuppressor::run(const edm::EventSetup& eventSetup,   
00210                                          const EcalTrigPrimDigiCollection & trigPrims,
00211                                          EBDigiCollection & barrelDigis,
00212                                          EEDigiCollection & endcapDigis){
00213   EBDigiCollection selectedBarrelDigis;
00214   EEDigiCollection selectedEndcapDigis;
00215   EBSrFlagCollection ebSrFlags;
00216   EESrFlagCollection eeSrFlags;
00217   
00218   run(eventSetup, trigPrims, barrelDigis, endcapDigis,
00219       selectedBarrelDigis, selectedEndcapDigis, ebSrFlags, eeSrFlags);
00220   
00221 //replaces the input with the suppressed version
00222   barrelDigis.swap(selectedBarrelDigis);
00223   endcapDigis.swap(selectedEndcapDigis);  
00224 }
00225 
00226 
00227 void
00228 EcalSelectiveReadoutSuppressor::run(const edm::EventSetup& eventSetup,
00229                                     const EcalTrigPrimDigiCollection & trigPrims,
00230                                     const EBDigiCollection & barrelDigis,
00231                                     const EEDigiCollection & endcapDigis,
00232                                     EBDigiCollection& selectedBarrelDigis,
00233                                     EEDigiCollection& selectedEndcapDigis,
00234                                     EBSrFlagCollection& ebSrFlags,
00235                                     EESrFlagCollection& eeSrFlags){
00236   if(!trigPrimBypass_){//normal mode
00237     setTtFlags(trigPrims);
00238   } else{//debug mode, run w/o TP digis
00239     setTtFlags(eventSetup, barrelDigis, endcapDigis);
00240   }
00241 
00242   ecalSelectiveReadout->runSelectiveReadout0(ttFlags);  
00243   
00244   selectedBarrelDigis.reserve(barrelDigis.size()/20);
00245   selectedEndcapDigis.reserve(endcapDigis.size()/20);
00246 
00247   // do barrel first
00248   for(EBDigiCollection::const_iterator digiItr = barrelDigis.begin();
00249       digiItr != barrelDigis.end(); ++digiItr){
00250     int interestLevel
00251       = ecalSelectiveReadout->getCrystalInterest(EBDigiCollection::DetId(digiItr->id()));
00252     if(accept(*digiItr, zsThreshold[BARREL][interestLevel])){
00253       selectedBarrelDigis.push_back(digiItr->id(), digiItr->begin());
00254     } 
00255   }
00256   
00257   // and endcaps
00258   for(EEDigiCollection::const_iterator digiItr = endcapDigis.begin();
00259       digiItr != endcapDigis.end(); ++digiItr){
00260     int interestLevel = ecalSelectiveReadout->getCrystalInterest(EEDigiCollection::DetId(digiItr->id()));
00261     if(accept(*digiItr, zsThreshold[ENDCAP][interestLevel])){
00262       selectedEndcapDigis.push_back(digiItr->id(), digiItr->begin());
00263     }
00264   }
00265   
00266   ebSrFlags.reserve(34*72);
00267   eeSrFlags.reserve(624);
00268   //SR flags:
00269   for(int iZ = -1; iZ <=1; iZ+=2){ //-1=>EE-, EB-, +1=>EE+, EB+
00270     //barrel:
00271     for(unsigned iEta = 1; iEta <= nBarrelTriggerTowersInEta/2; ++iEta){
00272       for(unsigned iPhi = 1; iPhi <= nTriggerTowersInPhi; ++iPhi){
00273         const EcalTrigTowerDetId id(iZ, EcalBarrel, iEta, iPhi);
00274         EcalSelectiveReadout::towerInterest_t interest
00275           = ecalSelectiveReadout->getTowerInterest(id);
00276         if(interest<0){
00277           throw cms::Exception("EcalSelectiveReadout")
00278             << __FILE__ << ":" << __LINE__ << ": " << "unknown SR flag. for "
00279             << " TT " << id << ". Most probably a bug.";
00280         }
00281         int flag;
00282         if(interest==EcalSelectiveReadout::FORCED_RO){
00283           flag = EcalSrFlag::SRF_FORCED_MASK | EcalSrFlag::SRF_FULL;
00284         } else{
00285           flag = srFlags[BARREL][interest];
00286         }
00287         ebSrFlags.push_back(EBSrFlag(id, flag));
00288       }//next iPhi
00289     } //next barrel iEta
00290 
00291     //endcap:
00292     EcalScDetId id;
00293     for(int iX = 1; iX <= 20; ++iX){
00294       for(int iY = 1; iY <= 20; ++iY){
00295         if (EcalScDetId::validDetId(iX, iY, iZ))
00296           id = EcalScDetId(iX, iY, iZ);
00297         else
00298           continue;
00299         
00300         EcalSelectiveReadout::towerInterest_t interest
00301           = ecalSelectiveReadout->getSuperCrystalInterest(id);
00302         if(interest>=0){//negative no SC at (iX,iY) coordinates
00303           int flag;
00304           if(interest==EcalSelectiveReadout::FORCED_RO){
00305             flag = EcalSrFlag::SRF_FORCED_MASK | EcalSrFlag::SRF_FULL;
00306           } else{
00307             flag = srFlags[BARREL][interest];
00308           }
00309           eeSrFlags.push_back(EESrFlag(id, flag));
00310         } else{
00311           cout << __FILE__ << ":" << __LINE__ << ": "
00312                <<  "negative interest in EE for SC "
00313                << id << "\n";
00314         }
00315       } //next iY
00316     } //next iX
00317   }
00318 }
00319 
00320 
00321 void EcalSelectiveReadoutSuppressor::setTtFlags(const EcalTrigPrimDigiCollection & trigPrims){
00322   for(size_t iEta0 = 0; iEta0 < nTriggerTowersInEta; ++iEta0){
00323     for(size_t iPhi0 = 0; iPhi0 < nTriggerTowersInPhi; ++iPhi0){
00324       ttFlags[iEta0][iPhi0] = EcalSelectiveReadout::TTF_FORCED_RO_OTHER1;
00325     }
00326   }
00327   for(EcalTrigPrimDigiCollection::const_iterator trigPrim = trigPrims.begin();
00328       trigPrim != trigPrims.end(); ++trigPrim){
00329     int iEta =  trigPrim->id().ieta();
00330     unsigned int iEta0;
00331     if(iEta<0){ //z- half ECAL: transforming ranges -28;-1 => 0;27
00332       iEta0 = iEta + nTriggerTowersInEta/2;
00333     } else{ //z+ halfECAL: transforming ranges 1;28 => 28;55
00334       iEta0 = iEta + nTriggerTowersInEta/2 - 1;
00335     }
00336 
00337     unsigned int iPhi0 = trigPrim->id().iphi() - 1;
00338     ttFlags[iEta0][iPhi0] =
00339       (EcalSelectiveReadout::ttFlag_t) trigPrim->ttFlag();
00340   }
00341 }
00342 
00343 
00344 vector<int> EcalSelectiveReadoutSuppressor::getFIRWeigths() {
00345   if(firWeights.size()==0){
00346     firWeights = vector<int>(nFIRTaps, 0); //default weight: 0;
00347     const static int maxWeight = 0xEFF; //weights coded on 11+1 signed bits
00348     for(unsigned i=0; i < min((size_t)nFIRTaps,weights.size()); ++i){ 
00349       firWeights[i] = lround(weights[i] * (1<<10));
00350       if(abs(firWeights[i])>maxWeight){//overflow
00351         firWeights[i] = firWeights[i]<0?-maxWeight:maxWeight;
00352       }
00353     }
00354   }
00355   return firWeights;
00356 }
00357 
00358 void
00359 EcalSelectiveReadoutSuppressor::setTtFlags(const edm::EventSetup& es,
00360                                            const EBDigiCollection& ebDigis,
00361                                            const EEDigiCollection& eeDigis){
00362   double trigPrim[nTriggerTowersInEta][nTriggerTowersInPhi];
00363 
00364   //ecal geometry:
00365 //  static const CaloSubdetectorGeometry* eeGeometry = 0;
00366 //  static const CaloSubdetectorGeometry* ebGeometry = 0;
00367   const CaloSubdetectorGeometry* eeGeometry = 0;
00368   const CaloSubdetectorGeometry* ebGeometry = 0;
00369 //  if(eeGeometry==0 || ebGeometry==0){
00370     edm::ESHandle<CaloGeometry> geoHandle;
00371     es.get<CaloGeometryRecord>().get(geoHandle);
00372     eeGeometry
00373       = (*geoHandle).getSubdetectorGeometry(DetId::Ecal, EcalEndcap);
00374     ebGeometry
00375       = (*geoHandle).getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
00376 //  }
00377 
00378   //init trigPrim array:
00379   bzero(trigPrim, sizeof(trigPrim));
00380         
00381   for(EBDigiCollection::const_iterator it = ebDigis.begin();
00382       it != ebDigis.end(); ++it){
00383     EBDataFrame frame(*it);
00384     const EcalTrigTowerDetId& ttId = theTriggerMap->towerOf(frame.id());
00385 //      edm:::LogDebug("TT") << __FILE__ << ":" << __LINE__ << ": " 
00386 //       <<  ((EBDetId&)frame.id()).ieta()
00387 //       << "," << ((EBDetId&)frame.id()).iphi()
00388 //       << " -> " << ttId.ieta() << "," << ttId.iphi() << "\n";
00389     const int iTTEta0 = iTTEta2cIndex(ttId.ieta());
00390     const int iTTPhi0 = iTTPhi2cIndex(ttId.iphi());
00391     double theta = ebGeometry->getGeometry(frame.id())->getPosition().theta();
00392     double e = frame2Energy(frame);
00393     if(!trigPrimBypassWithPeakFinder_
00394        || ((frame2Energy(frame,-1) < e) && (frame2Energy(frame, 1) < e))){
00395       trigPrim[iTTEta0][iTTPhi0] += e*sin(theta);
00396     }
00397   }
00398 
00399   for(EEDigiCollection::const_iterator it = eeDigis.begin();
00400       it != eeDigis.end(); ++it){
00401     EEDataFrame frame(*it);
00402     const EcalTrigTowerDetId& ttId = theTriggerMap->towerOf(frame.id());
00403     const int iTTEta0 = iTTEta2cIndex(ttId.ieta());
00404     const int iTTPhi0 = iTTPhi2cIndex(ttId.iphi());
00405 //     cout << __FILE__ << ":" << __LINE__ << ": EE xtal->TT "
00406 //       <<  ((EEDetId&)frame.id()).ix()
00407 //       << "," << ((EEDetId&)frame.id()).iy()
00408 //       << " -> " << ttId.ieta() << "," << ttId.iphi() << "\n";
00409     double theta = eeGeometry->getGeometry(frame.id())->getPosition().theta();
00410     double e = frame2Energy(frame);
00411     if(!trigPrimBypassWithPeakFinder_
00412        || ((frame2Energy(frame,-1) < e) && (frame2Energy(frame, 1) < e))){
00413       trigPrim[iTTEta0][iTTPhi0] += e*sin(theta);
00414     }
00415   }
00416 
00417   //dealing with pseudo-TT in two inner EE eta-ring:
00418   int innerTTEtas[] = {0, 1, 54, 55};
00419   for(unsigned iRing = 0; iRing < sizeof(innerTTEtas)/sizeof(innerTTEtas[0]);
00420       ++iRing){
00421     int iTTEta0 = innerTTEtas[iRing];
00422     //this detector eta-section is divided in only 36 phi bins
00423     //For this eta regions,
00424     //current tower eta numbering scheme is inconsistent. For geometry
00425     //version 133:
00426     //- TT are numbered from 0 to 72 for 36 bins
00427     //- some TT have an even index, some an odd index
00428     //For geometry version 125, there are 72 phi bins.
00429     //The code below should handle both geometry definition.
00430     //If there are 72 input trigger primitives for each inner eta-ring,
00431     //then the average of the trigger primitive of the two pseudo-TT of
00432     //a pair (nEta, nEta+1) is taken as Et of both pseudo TTs.
00433     //If there are only 36 input TTs for each inner eta ring, then half
00434     //of the present primitive of a pseudo TT pair is used as Et of both
00435     //pseudo TTs.
00436 
00437     for(unsigned iTTPhi0 = 0; iTTPhi0 < nTriggerTowersInPhi-1; iTTPhi0 += 2){
00438       double et = .5*(trigPrim[iTTEta0][iTTPhi0]
00439                       +trigPrim[iTTEta0][iTTPhi0+1]);
00440       //divides the TT into 2 phi bins in order to match with 72 phi-bins SRP
00441       //scheme or average the Et on the two pseudo TTs if the TT is already
00442       //divided into two trigger primitives.
00443       trigPrim[iTTEta0][iTTPhi0] = et;
00444       trigPrim[iTTEta0][iTTPhi0+1] = et;
00445     }
00446   }
00447     
00448   for(unsigned iTTEta0 = 0; iTTEta0 < nTriggerTowersInEta; ++iTTEta0){
00449     for(unsigned iTTPhi0 = 0; iTTPhi0 < nTriggerTowersInPhi; ++iTTPhi0){
00450       if(trigPrim[iTTEta0][iTTPhi0] > trigPrimBypassHTH_){
00451         ttFlags[iTTEta0][iTTPhi0] = EcalSelectiveReadout::TTF_HIGH_INTEREST;
00452       } else if(trigPrim[iTTEta0][iTTPhi0] > trigPrimBypassLTH_){
00453         ttFlags[iTTEta0][iTTPhi0] = EcalSelectiveReadout::TTF_MID_INTEREST;
00454       } else{
00455         ttFlags[iTTEta0][iTTPhi0] = EcalSelectiveReadout::TTF_LOW_INTEREST;
00456       }
00457       
00458       // cout /*LogDebug("TT")*/
00459       //        << "ttFlags[" << iTTEta0 << "][" << iTTPhi0 << "] = "
00460       //        << ttFlags[iTTEta0][iTTPhi0] << "\n";
00461     }
00462   }
00463 }
00464 
00465 template<class T>
00466 double EcalSelectiveReadoutSuppressor::frame2Energy(const T& frame,
00467                                                     int offset) const{
00468   //we have to start by 0 in order to handle offset=-1
00469   //(however Fenix FIR has AFAK only 5 taps)
00470   double weights[] = {0., -1/3., -1/3., -1/3., 0., 1.};   
00471 
00472   double adc2GeV = 0.;
00473   if(typeid(frame) == typeid(EBDataFrame)){
00474     adc2GeV = 0.035;
00475   } else if(typeid(frame) == typeid(EEDataFrame)){
00476     adc2GeV = 0.060;
00477   } else{ //T is an invalid type!
00478     //TODO: replace message by a cms exception
00479     cerr << "Severe error. "
00480          << __FILE__ << ":" << __LINE__ << ": "
00481          << "this is a bug. Please report it.\n";
00482   }
00483     
00484   double acc = 0;
00485 
00486   const int n = min<int>(frame.size(), sizeof(weights)/sizeof(weights[0]));
00487 
00488   double gainInv[] = {12., 1., 6., 12.};
00489 
00490 
00491   //cout << __PRETTY_FUNCTION__ << ": ";
00492   for(int i=offset; i < n; ++i){
00493     int iframe = i + offset;
00494     if(iframe>=0 && iframe<frame.size()){
00495       acc += weights[i]*frame[iframe].adc()
00496         *gainInv[frame[iframe].gainId()]*adc2GeV;
00497       //cout << (iframe>offset?"+":"")
00498       //     << frame[iframe].adc() << "*" << gainInv[frame[iframe].gainId()]
00499       //     << "*" << adc2GeV << "*(" << weights[i] << ")";
00500     }
00501   }
00502   //cout << "\n";
00503   return acc;
00504 }
00505 
00506 void EcalSelectiveReadoutSuppressor::printTTFlags(ostream& os, int iEvent,
00507                                                   bool withHeader) const{
00508   const char tccFlagMarker[] = { '?', '.', 'S', '?', 'C', 'E', 'E', 'E', 'E'};
00509   const int nEta = EcalSelectiveReadout::nTriggerTowersInEta;
00510   const int nPhi = EcalSelectiveReadout::nTriggerTowersInPhi;
00511   
00512   if(withHeader){
00513     os << "# TCC flag map\n#\n"
00514       "# +-->Phi            " << tccFlagMarker[1+0] << ": 000 (low interest)\n"
00515       "# |                  " << tccFlagMarker[1+1] << ": 001 (mid interest)\n"
00516       "# |                  " << tccFlagMarker[1+2] << ": 010 (not valid)\n"
00517       "# V Eta              " << tccFlagMarker[1+3] << ": 011 (high interest)\n"
00518       "#                    " << tccFlagMarker[1+4] << ": 1xx forced readout (Hw error)\n";
00519   }
00520 
00521   if(iEvent>=0){
00522     os << "#\n#Event " << iEvent << "\n";
00523   }
00524   
00525   for(int iEta=0; iEta<nEta; ++iEta){
00526     for(int iPhi=0; iPhi<nPhi; ++iPhi){
00527       os << tccFlagMarker[ttFlags[iEta][iPhi]+1];
00528     }
00529     os << "\n";
00530   }
00531 }
00532   

Generated on Tue Jun 9 17:46:16 2009 for CMSSW by  doxygen 1.5.4