CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/SimCalorimetry/EcalSelectiveReadoutProducers/src/EcalSelectiveReadoutProducer.cc

Go to the documentation of this file.
00001 #include "SimCalorimetry/EcalSelectiveReadoutProducers/interface/EcalSelectiveReadoutProducer.h"
00002 #include "FWCore/Framework/interface/Event.h"
00003 #include "FWCore/Framework/interface/EventSetup.h"
00004 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00005 #include "Geometry/EcalMapping/interface/EcalMappingRcd.h"
00006 #include "FWCore/Framework/interface/ESHandle.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "CondFormats/DataRecord/interface/EcalSRSettingsRcd.h"
00009 //#include "DataFormats/EcalDigi/interface/EcalMGPASample.h"
00010 
00011 #include "SimCalorimetry/EcalSelectiveReadoutProducers/interface/EcalSRCondTools.h"
00012 
00013 #include <memory>
00014 #include <fstream>
00015 
00016 
00017 using namespace std;
00018 
00019 EcalSelectiveReadoutProducer::EcalSelectiveReadoutProducer(const edm::ParameterSet& params)
00020   : params_(params)
00021 {
00022   //settings:
00023   //  settings which are only in python config files:
00024   digiProducer_ = params.getParameter<string>("digiProducer");
00025   ebdigiCollection_ = params.getParameter<std::string>("EBdigiCollection");
00026   eedigiCollection_ = params.getParameter<std::string>("EEdigiCollection");
00027   ebSRPdigiCollection_ = params.getParameter<std::string>("EBSRPdigiCollection");
00028   eeSRPdigiCollection_ = params.getParameter<std::string>("EESRPdigiCollection");
00029   ebSrFlagCollection_ = params.getParameter<std::string>("EBSrFlagCollection");
00030   eeSrFlagCollection_ = params.getParameter<std::string>("EESrFlagCollection");
00031   trigPrimProducer_ = params.getParameter<string>("trigPrimProducer");
00032   trigPrimCollection_ = params.getParameter<string>("trigPrimCollection");
00033   trigPrimBypass_ = params.getParameter<bool>("trigPrimBypass");
00034   trigPrimBypassMode_ = params.getParameter<int>("trigPrimBypassMode");
00035   dumpFlags_ = params.getUntrackedParameter<int>("dumpFlags", 0);
00036   writeSrFlags_ = params.getUntrackedParameter<bool>("writeSrFlags", false);
00037   produceDigis_ = params.getUntrackedParameter<bool>("produceDigis", true);
00038   //   settings which can come from either condition database or python configuration file:
00039   useCondDb_ = false;
00040   try{
00041     if(params.getParameter<bool>("configFromCondDB")){
00042       useCondDb_ = true;
00043     }
00044   } catch(cms::Exception){
00045     /* pameter not found */
00046     edm::LogWarning("EcalSelectiveReadout") << "Parameter configFromCondDB of EcalSelectiveReadout module not found. "
00047       "Selective readout configuration will be read from python file.";
00048   }
00049   if(!useCondDb_){
00050     settingsFromFile_ = auto_ptr<EcalSRSettings>(new EcalSRSettings());
00051     EcalSRCondTools::importParameterSet(*settingsFromFile_, params);
00052     settings_ = settingsFromFile_.get();
00053   }
00054 
00055   //declares the products made by this producer:
00056   if(produceDigis_){
00057     produces<EBDigiCollection>(ebSRPdigiCollection_);
00058     produces<EEDigiCollection>(eeSRPdigiCollection_);
00059   }
00060 
00061   if (writeSrFlags_) {
00062     produces<EBSrFlagCollection>(ebSrFlagCollection_);
00063     produces<EESrFlagCollection>(eeSrFlagCollection_);
00064   }
00065 
00066   theGeometry = 0;
00067   theTriggerTowerMap = 0;
00068   theElecMap = 0;
00069 }
00070 
00071 
00072 
00073 EcalSelectiveReadoutProducer::~EcalSelectiveReadoutProducer()
00074 { }
00075 
00076 
00077 void
00078 EcalSelectiveReadoutProducer::produce(edm::Event& event, const edm::EventSetup& eventSetup)
00079 {
00080   //getting selective readout configuration:
00081   edm::ESHandle<EcalSRSettings> hSr;
00082   eventSetup.get<EcalSRSettingsRcd>().get(hSr);
00083   settings_ = hSr.product();
00084   
00085   //gets the trigger primitives:
00086   EcalTrigPrimDigiCollection emptyTPColl;
00087   const EcalTrigPrimDigiCollection* trigPrims =
00088     (trigPrimBypass_ && trigPrimBypassMode_==0)?&emptyTPColl:getTrigPrims(event);
00089 
00090 
00091   //gets the digis from the events:
00092   EBDigiCollection dummyEbDigiColl;
00093   EEDigiCollection dummyEeDigiColl;
00094 
00095   const EBDigiCollection* ebDigis = produceDigis_?getEBDigis(event)
00096     :&dummyEbDigiColl;
00097   const EEDigiCollection* eeDigis = produceDigis_?getEEDigis(event)
00098     :&dummyEeDigiColl;
00099 
00100   //runs the selective readout algorithm:
00101   auto_ptr<EBDigiCollection> selectedEBDigis;
00102   auto_ptr<EEDigiCollection> selectedEEDigis;
00103   auto_ptr<EBSrFlagCollection> ebSrFlags;
00104   auto_ptr<EESrFlagCollection> eeSrFlags;
00105 
00106   if(produceDigis_){
00107     selectedEBDigis = auto_ptr<EBDigiCollection>(new EBDigiCollection);
00108     selectedEEDigis = auto_ptr<EEDigiCollection>(new EEDigiCollection);
00109   }
00110 
00111   if(writeSrFlags_){
00112     ebSrFlags = auto_ptr<EBSrFlagCollection>(new EBSrFlagCollection);
00113     eeSrFlags = auto_ptr<EESrFlagCollection>(new EESrFlagCollection);
00114   }
00115 
00116   if(suppressor_.get() == 0){
00117     //Check the validity of EcalSRSettings
00118     checkValidity(*settings_);
00119     
00120     //instantiates the selective readout algorithm:
00121     suppressor_ = auto_ptr<EcalSelectiveReadoutSuppressor>(new EcalSelectiveReadoutSuppressor(params_, settings_));
00122 
00123     // check that everything is up-to-date
00124     checkGeometry(eventSetup);
00125     checkTriggerMap(eventSetup);
00126     checkElecMap(eventSetup);
00127   }
00128   
00129   suppressor_->run(eventSetup, *trigPrims, *ebDigis, *eeDigis,
00130                    selectedEBDigis.get(), selectedEEDigis.get(),
00131                    ebSrFlags.get(), eeSrFlags.get());
00132 
00133   static int iEvent = 1;
00134   if(dumpFlags_>=iEvent){
00135     ofstream ttfFile("TTF.txt", (iEvent==1?ios::trunc:ios::app));
00136     suppressor_->printTTFlags(ttfFile, iEvent,
00137                               iEvent==1?true:false);
00138 
00139     ofstream srfFile("SRF.txt", (iEvent==1?ios::trunc:ios::app));
00140     if(iEvent==1){
00141       suppressor_->getEcalSelectiveReadout()->printHeader(srfFile);
00142     }
00143     srfFile << "# Event " << iEvent << "\n";
00144     suppressor_->getEcalSelectiveReadout()->print(srfFile);
00145     srfFile << "\n";
00146 
00147     ofstream afFile("AF.txt", (iEvent==1?ios::trunc:ios::app));
00148     printSrFlags(afFile, *ebSrFlags, *eeSrFlags, iEvent,
00149                  iEvent==1?true:false);
00150   }
00151 
00152   ++iEvent; //event counter
00153 
00154   if(produceDigis_){
00155     //puts the selected digis into the event:
00156     event.put(selectedEBDigis, ebSRPdigiCollection_);
00157     event.put(selectedEEDigis, eeSRPdigiCollection_);
00158   }
00159 
00160   //puts the SR flags into the event:
00161   if(writeSrFlags_) {
00162     event.put(ebSrFlags, ebSrFlagCollection_);
00163     event.put(eeSrFlags, eeSrFlagCollection_);
00164   }
00165 }
00166 
00167 const EBDigiCollection*
00168 EcalSelectiveReadoutProducer::getEBDigis(edm::Event& event) const
00169 {
00170   edm::Handle<EBDigiCollection> hEBDigis;
00171   event.getByLabel(digiProducer_, ebdigiCollection_, hEBDigis);
00172   //product() method is called before id() in order to get an exception
00173   //if the handle is not available (check not done by id() method).
00174   const EBDigiCollection* result = hEBDigis.product();
00175   static bool firstCall= true;
00176   if(firstCall){
00177     checkWeights(event, hEBDigis.id());
00178     firstCall = false;
00179   }
00180   return result;
00181 }
00182 
00183 const EEDigiCollection*
00184 EcalSelectiveReadoutProducer::getEEDigis(edm::Event& event) const
00185 {
00186   edm::Handle<EEDigiCollection> hEEDigis;
00187   event.getByLabel(digiProducer_, eedigiCollection_, hEEDigis);
00188   //product() method is called before id() in order to get an exception
00189   //if the handle is not available (check not done by id() method).
00190   const EEDigiCollection* result = hEEDigis.product();
00191   static bool firstCall = true;
00192   if(firstCall){
00193     checkWeights(event, hEEDigis.id());
00194     firstCall = false;
00195   }
00196   return result;
00197 }
00198 
00199 const EcalTrigPrimDigiCollection*
00200 EcalSelectiveReadoutProducer::getTrigPrims(edm::Event& event) const
00201 {
00202   edm::Handle<EcalTrigPrimDigiCollection> hTPDigis;
00203   event.getByLabel(trigPrimProducer_, trigPrimCollection_, hTPDigis);
00204   return hTPDigis.product();
00205 }
00206 
00207 
00208 void EcalSelectiveReadoutProducer::checkGeometry(const edm::EventSetup & eventSetup)
00209 {
00210   edm::ESHandle<CaloGeometry> hGeometry;
00211   eventSetup.get<CaloGeometryRecord>().get(hGeometry);
00212 
00213   const CaloGeometry * pGeometry = &*hGeometry;
00214 
00215   // see if we need to update
00216   if(pGeometry != theGeometry) {
00217     theGeometry = pGeometry;
00218     suppressor_->setGeometry(theGeometry);
00219   }
00220 }
00221 
00222 
00223 void EcalSelectiveReadoutProducer::checkTriggerMap(const edm::EventSetup & eventSetup)
00224 {
00225 
00226    edm::ESHandle<EcalTrigTowerConstituentsMap> eTTmap;
00227    eventSetup.get<IdealGeometryRecord>().get(eTTmap);
00228 
00229    const EcalTrigTowerConstituentsMap * pMap = &*eTTmap;
00230 
00231   // see if we need to update
00232   if(pMap!= theTriggerTowerMap) {
00233     theTriggerTowerMap = pMap;
00234     suppressor_->setTriggerMap(theTriggerTowerMap);
00235   }
00236 }
00237 
00238 
00239 void EcalSelectiveReadoutProducer::checkElecMap(const edm::EventSetup & eventSetup)
00240 {
00241 
00242    edm::ESHandle<EcalElectronicsMapping> eElecmap;
00243    eventSetup.get<EcalMappingRcd>().get(eElecmap);
00244 
00245    const EcalElectronicsMapping * pMap = &*eElecmap;
00246 
00247   // see if we need to update
00248   if(pMap!= theElecMap) {
00249     theElecMap = pMap;
00250     suppressor_->setElecMap(theElecMap);
00251   }
00252 }
00253 
00254 
00255 void EcalSelectiveReadoutProducer::printTTFlags(const EcalTrigPrimDigiCollection& tp, ostream& os) const{
00256   const char tccFlagMarker[] = { 'x', '.', 'S', '?', 'C', 'E', 'E', 'E', 'E'};
00257   const int nEta = EcalSelectiveReadout::nTriggerTowersInEta;
00258   const int nPhi = EcalSelectiveReadout::nTriggerTowersInPhi;
00259 
00260   //static bool firstCall=true;
00261   //  if(firstCall){
00262   //  firstCall=false;
00263   os << "# TCC flag map\n#\n"
00264     "# +-->Phi            " << tccFlagMarker[0+1] << ": 000 (low interest)\n"
00265     "# |                  " << tccFlagMarker[1+1] << ": 001 (mid interest)\n"
00266     "# |                  " << tccFlagMarker[2+1] << ": 010 (not valid)\n"
00267     "# V Eta              " << tccFlagMarker[3+1] << ": 011 (high interest)\n"
00268     "#                    " << tccFlagMarker[4+1] << ": 1xx forced readout (Hw error)\n"
00269     "#\n";
00270   //}
00271 
00272   vector<vector<int> > ttf(nEta, vector<int>(nPhi, -1));
00273   for(EcalTrigPrimDigiCollection::const_iterator it = tp.begin();
00274       it != tp.end(); ++it){
00275     const EcalTriggerPrimitiveDigi& trigPrim = *it;
00276     if(trigPrim.size()>0){
00277       int iEta = trigPrim.id().ieta();
00278       int iEta0 = iEta<0?iEta+nEta/2:iEta+nEta/2-1;
00279       int iPhi0 = trigPrim.id().iphi() - 1;
00280       ttf[iEta0][iPhi0] = trigPrim.ttFlag();
00281     }
00282   }
00283   for(int iEta=0; iEta<nEta; ++iEta){
00284     for(int iPhi=0; iPhi<nPhi; ++iPhi){
00285       os << tccFlagMarker[ttf[iEta][iPhi]+1];
00286     }
00287     os << "\n";
00288   }
00289 }
00290 
00291 void EcalSelectiveReadoutProducer::checkWeights(const edm::Event& evt,
00292                                                 const edm::ProductID& noZsDigiId) const{
00293   const vector<float> & weights = settings_->dccNormalizedWeights_[0]; //params_.getParameter<vector<double> >("dccNormalizedWeights");
00294   int nFIRTaps = EcalSelectiveReadoutSuppressor::getFIRTapCount();
00295   static bool warnWeightCnt = true;
00296   if((int)weights.size() > nFIRTaps && warnWeightCnt){
00297       edm::LogWarning("Configuration") << "The list of DCC zero suppression FIR "
00298         "weights given in parameter dccNormalizedWeights is longer "
00299         "than the expected depth of the FIR filter :(" << nFIRTaps << "). "
00300         "The last weights will be discarded.";
00301       warnWeightCnt = false; //it's not needed to repeat the warning.
00302   }
00303 
00304   if(weights.size()>0){
00305     int iMaxWeight = 0;
00306     double maxWeight = weights[iMaxWeight];
00307     //looks for index of maximum weight
00308     for(unsigned i=0; i<weights.size(); ++i){
00309       if(weights[i]>maxWeight){
00310         iMaxWeight = i;
00311         maxWeight = weights[iMaxWeight];
00312       }
00313     }
00314 
00315     //position of time sample whose maximum weight is applied:
00316     int maxWeightBin = settings_->ecalDccZs1stSample_[0] //params_.getParameter<int>("ecalDccZs1stSample")
00317       + iMaxWeight;
00318     
00319     //gets the bin of maximum (in case of raw data it will not exist)
00320     int binOfMax = 0;
00321     bool rc = getBinOfMax(evt, noZsDigiId, binOfMax);
00322 
00323     if(rc && maxWeightBin!=binOfMax){
00324       edm::LogWarning("Configuration")
00325         << "The maximum weight of DCC zero suppression FIR filter is not "
00326         "applied to the expected maximum sample(" << binOfMax
00327         << (binOfMax==1?"st":(binOfMax==2?"nd":(binOfMax==3?"rd":"th")))
00328         << " time sample). This may indicate faulty 'dccNormalizedWeights' "
00329         "or 'ecalDccZs1sSample' parameters.";
00330     }
00331   }
00332 }
00333 
00334 bool
00335 EcalSelectiveReadoutProducer::getBinOfMax(const edm::Event& evt,
00336                                           const edm::ProductID& noZsDigiId,
00337                                           int& binOfMax) const{
00338   bool rc;
00339   const edm::Provenance p=evt.getProvenance(noZsDigiId);
00340   edm::ParameterSet result = getParameterSet(p.psetID());
00341   vector<string> ebDigiParamList = result.getParameterNames();
00342   string bofm("binOfMaximum");
00343   if(find(ebDigiParamList.begin(), ebDigiParamList.end(), bofm)
00344      != ebDigiParamList.end()){//bofm found
00345     binOfMax=result.getParameter<int>("binOfMaximum");
00346     rc = true;
00347   } else{
00348     rc = false;
00349   }
00350   return rc;
00351 }
00352 
00353 void
00354 EcalSelectiveReadoutProducer::printSrFlags(ostream& os,
00355                                            const EBSrFlagCollection& ebSrFlags,
00356                                            const EESrFlagCollection& eeSrFlags,
00357                                            int iEvent,
00358                                            bool withHeader){
00359   const char srpFlagMarker[] = {'.', 'z', 'Z', 'F', '4','5','6','7'};
00360   if(withHeader){
00361     time_t t;
00362     time(&t);
00363     const char* date = ctime(&t);
00364     os << "#SRP flag map\n#\n"
00365       "# Generatied on: " << date << "\n#\n"
00366       "# +-->Phi/Y " << srpFlagMarker[0] << ": suppressed\n"
00367       "# |         " << srpFlagMarker[1] << ": ZS 1\n"
00368       "# |         " << srpFlagMarker[2] << ": ZS 2\n"
00369       "# V Eta/X   " << srpFlagMarker[3] << ": full readout\n"
00370       "#\n";
00371   }
00372 
00373   //EE-,EB,EE+ map wil be written onto file in following format:
00374   //
00375   //      72
00376   // <-------------->
00377   //  20
00378   // <--->
00379   //  EEE                A             +-----> Y
00380   // EEEEE               |             |
00381   // EE EE               | 20   EE-    |
00382   // EEEEE               |             |
00383   //  EEE                V             V X
00384   // BBBBBBBBBBBBBBBBB   A
00385   // BBBBBBBBBBBBBBBBB   |             +-----> Phi
00386   // BBBBBBBBBBBBBBBBB   |             |
00387   // BBBBBBBBBBBBBBBBB   | 34  EB      |
00388   // BBBBBBBBBBBBBBBBB   |             |
00389   // BBBBBBBBBBBBBBBBB   |             V Eta
00390   // BBBBBBBBBBBBBBBBB   |
00391   // BBBBBBBBBBBBBBBBB   |
00392   // BBBBBBBBBBBBBBBBB   V
00393   //  EEE                A             +-----> Y
00394   // EEEEE               |             |
00395   // EE EE               | 20 EE+      |
00396   // EEEEE               |             |
00397   //  EEE                V             V X
00398   //
00399   //
00400   //
00401   //
00402   //event header:
00403   if(iEvent>=0){
00404     os << "# Event " << iEvent << "\n";
00405   }
00406 
00407   //retrieve flags:
00408   const int nEndcaps = 2;
00409   const int nScX = 20;
00410   const int nScY = 20;
00411   int eeSrf[nEndcaps][nScX][nScY];
00412   for(size_t i=0; i < sizeof(eeSrf)/sizeof(int); ((int*)eeSrf)[i++] = -1){};
00413   for(EESrFlagCollection::const_iterator it = eeSrFlags.begin();
00414       it != eeSrFlags.end(); ++it){
00415     const EESrFlag& flag = *it;
00416     int iZ0 = flag.id().zside()>0?1:0;
00417     int iX0 = flag.id().ix()-1;
00418     int iY0 = flag.id().iy()-1;
00419     assert(iZ0>=0 && iZ0<nEndcaps);
00420     assert(iX0>=0 && iX0<nScX);
00421     assert(iY0>=0 && iY0<nScY);
00422     eeSrf[iZ0][iX0][iY0] = flag.value();
00423   }
00424   const int nEbTtEta = 34;
00425   const int nEeTtEta = 11;
00426   const int nTtEta = nEeTtEta*2+nEbTtEta;
00427   const int nTtPhi = 72;
00428   int ebSrf[nEbTtEta][nTtPhi];
00429   for(size_t i=0; i<sizeof(ebSrf)/sizeof(int); ((int*)ebSrf)[i++] = -1){};
00430   for(EBSrFlagCollection::const_iterator it = ebSrFlags.begin();
00431       it != ebSrFlags.end(); ++it){
00432 
00433     const EBSrFlag& flag = *it;
00434     int iEta = flag.id().ieta();
00435     int iEta0 = iEta + nTtEta/2 - (iEta>=0?1:0); //0->55 from eta=-3 to eta=3
00436     int iEbEta0 = iEta0 - nEeTtEta;//0->33 from eta=-1.48 to eta=1.48
00437     int iPhi0 = flag.id().iphi() - 1;
00438     assert(iEbEta0>=0 && iEbEta0<nEbTtEta);
00439     assert(iPhi0>=0 && iPhi0<nTtPhi);
00440 
00441 //     cout << __FILE__ << ":" << __LINE__ << ": "
00442 //       <<  iEta << "\t" << flag.id().iphi() << " -> "
00443 //       << iEbEta0 << "\t" << iPhi0
00444 //       << "... Flag: " << flag.value() << "\n";
00445 
00446 
00447     ebSrf[iEbEta0][iPhi0] = flag.value();
00448   }
00449 
00450 
00451   //print flags:
00452 
00453   //EE-
00454   for(int iX0=0; iX0<nScX; ++iX0){
00455     for(int iY0=0; iY0<nScY; ++iY0){
00456       int srFlag = eeSrf[0][iX0][iY0];
00457       assert(srFlag>=-1
00458              && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
00459       os << (srFlag==-1?' ':srpFlagMarker[srFlag]);
00460     }
00461     os << "\n"; //one Y supercystal column per line
00462   } //next supercrystal X-index
00463 
00464   //EB
00465   for(int iEta0 = 0;
00466       iEta0 < nEbTtEta;
00467       ++iEta0){
00468     for(int iPhi0 = 0; iPhi0 < nTtPhi; ++iPhi0){
00469       int srFlag = ebSrf[iEta0][iPhi0];
00470       assert(srFlag>=-1
00471              && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
00472       os << (srFlag==-1?'?':srpFlagMarker[srFlag]);
00473     }
00474     os << "\n"; //one phi per line
00475   }
00476 
00477   //EE+
00478   for(int iX0=0; iX0<nScX; ++iX0){
00479     for(int iY0=0; iY0<nScY; ++iY0){
00480       int srFlag = eeSrf[1][iX0][iY0];
00481       assert(srFlag>=-1
00482              && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
00483       os << (srFlag==-1?' ':srpFlagMarker[srFlag]);
00484     }
00485     os << "\n"; //one Y supercystal column per line
00486   } //next supercrystal X-index
00487 
00488   //event trailer:
00489   os << "\n";
00490 }
00491 
00492 void EcalSelectiveReadoutProducer::checkValidity(const EcalSRSettings& settings){
00493   if(settings.dccNormalizedWeights_.size() != 1){
00494     throw cms::Exception("Configuration") << "Selective readout emulator, EcalSelectiveReadout, supports only single set of ZS weights. "
00495       "while the configuration contains " << settings.dccNormalizedWeights_.size() << " set(s)\n";
00496   }
00497   
00498 //   if(settings.dccNormalizedWeights_.size() != 1
00499 //      && settings.dccNormalizedWeights_.size() != 2
00500 //      && settings.dccNormalizedWeights_.size() != 54
00501 //      && settings.dccNormalizedWeights_.size() != 75848){
00502 //     throw cms::Exception("Configuration") << "Invalid number of DCC weight set (" << settings.dccNormalizedWeights_.size()
00503 //                                        << ") in condition object EcalSRSetting::dccNormalizedWeights_. "
00504 //                                        << "Valid counts are: 1 (single set), 2 (EB and EE), 54 (one per DCC) and 75848 "
00505 //       "(one per crystal)\n";
00506 //   }
00507   
00508   if(settings.dccNormalizedWeights_.size() != settings.ecalDccZs1stSample_.size()){
00509     throw cms::Exception("Configuration") << "Inconsistency between number of weigth sets ("
00510                                           << settings.dccNormalizedWeights_.size() << ") and "
00511                                           << "number of ecalDccZs1Sample values ("
00512                                           << settings.ecalDccZs1stSample_.size() << ").";
00513   }  
00514 }