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
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
00023
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
00039 useCondDb_ = false;
00040 try{
00041 if(params.getParameter<bool>("configFromCondDB")){
00042 useCondDb_ = true;
00043 }
00044 } catch(cms::Exception){
00045
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
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 if(useCondDb_){
00081
00082 edm::ESHandle<EcalSRSettings> hSr;
00083 eventSetup.get<EcalSRSettingsRcd>().get(hSr);
00084 settings_ = hSr.product();
00085 }
00086
00087
00088 EcalTrigPrimDigiCollection emptyTPColl;
00089 const EcalTrigPrimDigiCollection* trigPrims =
00090 (trigPrimBypass_ && trigPrimBypassMode_==0)?&emptyTPColl:getTrigPrims(event);
00091
00092
00093
00094 EBDigiCollection dummyEbDigiColl;
00095 EEDigiCollection dummyEeDigiColl;
00096
00097 const EBDigiCollection* ebDigis = produceDigis_?getEBDigis(event)
00098 :&dummyEbDigiColl;
00099 const EEDigiCollection* eeDigis = produceDigis_?getEEDigis(event)
00100 :&dummyEeDigiColl;
00101
00102
00103 auto_ptr<EBDigiCollection> selectedEBDigis;
00104 auto_ptr<EEDigiCollection> selectedEEDigis;
00105 auto_ptr<EBSrFlagCollection> ebSrFlags;
00106 auto_ptr<EESrFlagCollection> eeSrFlags;
00107
00108 if(produceDigis_){
00109 selectedEBDigis = auto_ptr<EBDigiCollection>(new EBDigiCollection);
00110 selectedEEDigis = auto_ptr<EEDigiCollection>(new EEDigiCollection);
00111 }
00112
00113 if(writeSrFlags_){
00114 ebSrFlags = auto_ptr<EBSrFlagCollection>(new EBSrFlagCollection);
00115 eeSrFlags = auto_ptr<EESrFlagCollection>(new EESrFlagCollection);
00116 }
00117
00118 if(suppressor_.get() == 0){
00119
00120 checkValidity(*settings_);
00121
00122
00123 suppressor_ = auto_ptr<EcalSelectiveReadoutSuppressor>(new EcalSelectiveReadoutSuppressor(params_, settings_));
00124
00125
00126 checkGeometry(eventSetup);
00127 checkTriggerMap(eventSetup);
00128 checkElecMap(eventSetup);
00129 }
00130
00131 suppressor_->run(eventSetup, *trigPrims, *ebDigis, *eeDigis,
00132 selectedEBDigis.get(), selectedEEDigis.get(),
00133 ebSrFlags.get(), eeSrFlags.get());
00134
00135 static int iEvent = 1;
00136 if(dumpFlags_>=iEvent){
00137 ofstream ttfFile("TTF.txt", (iEvent==1?ios::trunc:ios::app));
00138 suppressor_->printTTFlags(ttfFile, iEvent,
00139 iEvent==1?true:false);
00140
00141 ofstream srfFile("SRF.txt", (iEvent==1?ios::trunc:ios::app));
00142 if(iEvent==1){
00143 suppressor_->getEcalSelectiveReadout()->printHeader(srfFile);
00144 }
00145 srfFile << "# Event " << iEvent << "\n";
00146 suppressor_->getEcalSelectiveReadout()->print(srfFile);
00147 srfFile << "\n";
00148
00149 ofstream afFile("AF.txt", (iEvent==1?ios::trunc:ios::app));
00150 printSrFlags(afFile, *ebSrFlags, *eeSrFlags, iEvent,
00151 iEvent==1?true:false);
00152 }
00153
00154 ++iEvent;
00155
00156 if(produceDigis_){
00157
00158 event.put(selectedEBDigis, ebSRPdigiCollection_);
00159 event.put(selectedEEDigis, eeSRPdigiCollection_);
00160 }
00161
00162
00163 if(writeSrFlags_) {
00164 event.put(ebSrFlags, ebSrFlagCollection_);
00165 event.put(eeSrFlags, eeSrFlagCollection_);
00166 }
00167 }
00168
00169 const EBDigiCollection*
00170 EcalSelectiveReadoutProducer::getEBDigis(edm::Event& event) const
00171 {
00172 edm::Handle<EBDigiCollection> hEBDigis;
00173 event.getByLabel(digiProducer_, ebdigiCollection_, hEBDigis);
00174
00175
00176 const EBDigiCollection* result = hEBDigis.product();
00177 static bool firstCall= true;
00178 if(firstCall){
00179 checkWeights(event, hEBDigis.id());
00180 firstCall = false;
00181 }
00182 return result;
00183 }
00184
00185 const EEDigiCollection*
00186 EcalSelectiveReadoutProducer::getEEDigis(edm::Event& event) const
00187 {
00188 edm::Handle<EEDigiCollection> hEEDigis;
00189 event.getByLabel(digiProducer_, eedigiCollection_, hEEDigis);
00190
00191
00192 const EEDigiCollection* result = hEEDigis.product();
00193 static bool firstCall = true;
00194 if(firstCall){
00195 checkWeights(event, hEEDigis.id());
00196 firstCall = false;
00197 }
00198 return result;
00199 }
00200
00201 const EcalTrigPrimDigiCollection*
00202 EcalSelectiveReadoutProducer::getTrigPrims(edm::Event& event) const
00203 {
00204 edm::Handle<EcalTrigPrimDigiCollection> hTPDigis;
00205 event.getByLabel(trigPrimProducer_, trigPrimCollection_, hTPDigis);
00206 return hTPDigis.product();
00207 }
00208
00209
00210 void EcalSelectiveReadoutProducer::checkGeometry(const edm::EventSetup & eventSetup)
00211 {
00212 edm::ESHandle<CaloGeometry> hGeometry;
00213 eventSetup.get<CaloGeometryRecord>().get(hGeometry);
00214
00215 const CaloGeometry * pGeometry = &*hGeometry;
00216
00217
00218 if(pGeometry != theGeometry) {
00219 theGeometry = pGeometry;
00220 suppressor_->setGeometry(theGeometry);
00221 }
00222 }
00223
00224
00225 void EcalSelectiveReadoutProducer::checkTriggerMap(const edm::EventSetup & eventSetup)
00226 {
00227
00228 edm::ESHandle<EcalTrigTowerConstituentsMap> eTTmap;
00229 eventSetup.get<IdealGeometryRecord>().get(eTTmap);
00230
00231 const EcalTrigTowerConstituentsMap * pMap = &*eTTmap;
00232
00233
00234 if(pMap!= theTriggerTowerMap) {
00235 theTriggerTowerMap = pMap;
00236 suppressor_->setTriggerMap(theTriggerTowerMap);
00237 }
00238 }
00239
00240
00241 void EcalSelectiveReadoutProducer::checkElecMap(const edm::EventSetup & eventSetup)
00242 {
00243
00244 edm::ESHandle<EcalElectronicsMapping> eElecmap;
00245 eventSetup.get<EcalMappingRcd>().get(eElecmap);
00246
00247 const EcalElectronicsMapping * pMap = &*eElecmap;
00248
00249
00250 if(pMap!= theElecMap) {
00251 theElecMap = pMap;
00252 suppressor_->setElecMap(theElecMap);
00253 }
00254 }
00255
00256
00257 void EcalSelectiveReadoutProducer::printTTFlags(const EcalTrigPrimDigiCollection& tp, ostream& os) const{
00258 const char tccFlagMarker[] = { 'x', '.', 'S', '?', 'C', 'E', 'E', 'E', 'E'};
00259 const int nEta = EcalSelectiveReadout::nTriggerTowersInEta;
00260 const int nPhi = EcalSelectiveReadout::nTriggerTowersInPhi;
00261
00262
00263
00264
00265 os << "# TCC flag map\n#\n"
00266 "# +-->Phi " << tccFlagMarker[0+1] << ": 000 (low interest)\n"
00267 "# | " << tccFlagMarker[1+1] << ": 001 (mid interest)\n"
00268 "# | " << tccFlagMarker[2+1] << ": 010 (not valid)\n"
00269 "# V Eta " << tccFlagMarker[3+1] << ": 011 (high interest)\n"
00270 "# " << tccFlagMarker[4+1] << ": 1xx forced readout (Hw error)\n"
00271 "#\n";
00272
00273
00274 vector<vector<int> > ttf(nEta, vector<int>(nPhi, -1));
00275 for(EcalTrigPrimDigiCollection::const_iterator it = tp.begin();
00276 it != tp.end(); ++it){
00277 const EcalTriggerPrimitiveDigi& trigPrim = *it;
00278 if(trigPrim.size()>0){
00279 int iEta = trigPrim.id().ieta();
00280 int iEta0 = iEta<0?iEta+nEta/2:iEta+nEta/2-1;
00281 int iPhi0 = trigPrim.id().iphi() - 1;
00282 ttf[iEta0][iPhi0] = trigPrim.ttFlag();
00283 }
00284 }
00285 for(int iEta=0; iEta<nEta; ++iEta){
00286 for(int iPhi=0; iPhi<nPhi; ++iPhi){
00287 os << tccFlagMarker[ttf[iEta][iPhi]+1];
00288 }
00289 os << "\n";
00290 }
00291 }
00292
00293 void EcalSelectiveReadoutProducer::checkWeights(const edm::Event& evt,
00294 const edm::ProductID& noZsDigiId) const{
00295 const vector<float> & weights = settings_->dccNormalizedWeights_[0];
00296 int nFIRTaps = EcalSelectiveReadoutSuppressor::getFIRTapCount();
00297 static bool warnWeightCnt = true;
00298 if((int)weights.size() > nFIRTaps && warnWeightCnt){
00299 edm::LogWarning("Configuration") << "The list of DCC zero suppression FIR "
00300 "weights given in parameter dccNormalizedWeights is longer "
00301 "than the expected depth of the FIR filter :(" << nFIRTaps << "). "
00302 "The last weights will be discarded.";
00303 warnWeightCnt = false;
00304 }
00305
00306 if(weights.size()>0){
00307 int iMaxWeight = 0;
00308 double maxWeight = weights[iMaxWeight];
00309
00310 for(unsigned i=0; i<weights.size(); ++i){
00311 if(weights[i]>maxWeight){
00312 iMaxWeight = i;
00313 maxWeight = weights[iMaxWeight];
00314 }
00315 }
00316
00317
00318 int maxWeightBin = settings_->ecalDccZs1stSample_[0]
00319 + iMaxWeight;
00320
00321
00322 int binOfMax = 0;
00323 bool rc = getBinOfMax(evt, noZsDigiId, binOfMax);
00324
00325 if(rc && maxWeightBin!=binOfMax){
00326 edm::LogWarning("Configuration")
00327 << "The maximum weight of DCC zero suppression FIR filter is not "
00328 "applied to the expected maximum sample(" << binOfMax
00329 << (binOfMax==1?"st":(binOfMax==2?"nd":(binOfMax==3?"rd":"th")))
00330 << " time sample). This may indicate faulty 'dccNormalizedWeights' "
00331 "or 'ecalDccZs1sSample' parameters.";
00332 }
00333 }
00334 }
00335
00336 bool
00337 EcalSelectiveReadoutProducer::getBinOfMax(const edm::Event& evt,
00338 const edm::ProductID& noZsDigiId,
00339 int& binOfMax) const{
00340 bool rc;
00341 const edm::Provenance p=evt.getProvenance(noZsDigiId);
00342 edm::ParameterSet result = getParameterSet(p.psetID());
00343 vector<string> ebDigiParamList = result.getParameterNames();
00344 string bofm("binOfMaximum");
00345 if(find(ebDigiParamList.begin(), ebDigiParamList.end(), bofm)
00346 != ebDigiParamList.end()){
00347 binOfMax=result.getParameter<int>("binOfMaximum");
00348 rc = true;
00349 } else{
00350 rc = false;
00351 }
00352 return rc;
00353 }
00354
00355 void
00356 EcalSelectiveReadoutProducer::printSrFlags(ostream& os,
00357 const EBSrFlagCollection& ebSrFlags,
00358 const EESrFlagCollection& eeSrFlags,
00359 int iEvent,
00360 bool withHeader){
00361 const char srpFlagMarker[] = {'.', 'z', 'Z', 'F', '4','5','6','7'};
00362 if(withHeader){
00363 time_t t;
00364 time(&t);
00365 const char* date = ctime(&t);
00366 os << "#SRP flag map\n#\n"
00367 "# Generatied on: " << date << "\n#\n"
00368 "# +-->Phi/Y " << srpFlagMarker[0] << ": suppressed\n"
00369 "# | " << srpFlagMarker[1] << ": ZS 1\n"
00370 "# | " << srpFlagMarker[2] << ": ZS 2\n"
00371 "# V Eta/X " << srpFlagMarker[3] << ": full readout\n"
00372 "#\n";
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 if(iEvent>=0){
00406 os << "# Event " << iEvent << "\n";
00407 }
00408
00409
00410 const int nEndcaps = 2;
00411 const int nScX = 20;
00412 const int nScY = 20;
00413 int eeSrf[nEndcaps][nScX][nScY];
00414 for(size_t i=0; i < sizeof(eeSrf)/sizeof(int); ((int*)eeSrf)[i++] = -1){};
00415 for(EESrFlagCollection::const_iterator it = eeSrFlags.begin();
00416 it != eeSrFlags.end(); ++it){
00417 const EESrFlag& flag = *it;
00418 int iZ0 = flag.id().zside()>0?1:0;
00419 int iX0 = flag.id().ix()-1;
00420 int iY0 = flag.id().iy()-1;
00421 assert(iZ0>=0 && iZ0<nEndcaps);
00422 assert(iX0>=0 && iX0<nScX);
00423 assert(iY0>=0 && iY0<nScY);
00424 eeSrf[iZ0][iX0][iY0] = flag.value();
00425 }
00426 const int nEbTtEta = 34;
00427 const int nEeTtEta = 11;
00428 const int nTtEta = nEeTtEta*2+nEbTtEta;
00429 const int nTtPhi = 72;
00430 int ebSrf[nEbTtEta][nTtPhi];
00431 for(size_t i=0; i<sizeof(ebSrf)/sizeof(int); ((int*)ebSrf)[i++] = -1){};
00432 for(EBSrFlagCollection::const_iterator it = ebSrFlags.begin();
00433 it != ebSrFlags.end(); ++it){
00434
00435 const EBSrFlag& flag = *it;
00436 int iEta = flag.id().ieta();
00437 int iEta0 = iEta + nTtEta/2 - (iEta>=0?1:0);
00438 int iEbEta0 = iEta0 - nEeTtEta;
00439 int iPhi0 = flag.id().iphi() - 1;
00440 assert(iEbEta0>=0 && iEbEta0<nEbTtEta);
00441 assert(iPhi0>=0 && iPhi0<nTtPhi);
00442
00443
00444
00445
00446
00447
00448
00449 ebSrf[iEbEta0][iPhi0] = flag.value();
00450 }
00451
00452
00453
00454
00455
00456 for(int iX0=0; iX0<nScX; ++iX0){
00457 for(int iY0=0; iY0<nScY; ++iY0){
00458 int srFlag = eeSrf[0][iX0][iY0];
00459 assert(srFlag>=-1
00460 && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
00461 os << (srFlag==-1?' ':srpFlagMarker[srFlag]);
00462 }
00463 os << "\n";
00464 }
00465
00466
00467 for(int iEta0 = 0;
00468 iEta0 < nEbTtEta;
00469 ++iEta0){
00470 for(int iPhi0 = 0; iPhi0 < nTtPhi; ++iPhi0){
00471 int srFlag = ebSrf[iEta0][iPhi0];
00472 assert(srFlag>=-1
00473 && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
00474 os << (srFlag==-1?'?':srpFlagMarker[srFlag]);
00475 }
00476 os << "\n";
00477 }
00478
00479
00480 for(int iX0=0; iX0<nScX; ++iX0){
00481 for(int iY0=0; iY0<nScY; ++iY0){
00482 int srFlag = eeSrf[1][iX0][iY0];
00483 assert(srFlag>=-1
00484 && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
00485 os << (srFlag==-1?' ':srpFlagMarker[srFlag]);
00486 }
00487 os << "\n";
00488 }
00489
00490
00491 os << "\n";
00492 }
00493
00494 void EcalSelectiveReadoutProducer::checkValidity(const EcalSRSettings& settings){
00495 if(settings.dccNormalizedWeights_.size() != 1){
00496 throw cms::Exception("Configuration") << "Selective readout emulator, EcalSelectiveReadout, supports only single set of ZS weights. "
00497 "while the configuration contains " << settings.dccNormalizedWeights_.size() << " set(s)\n";
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 if(settings.dccNormalizedWeights_.size() != settings.ecalDccZs1stSample_.size()){
00511 throw cms::Exception("Configuration") << "Inconsistency between number of weigth sets ("
00512 << settings.dccNormalizedWeights_.size() << ") and "
00513 << "number of ecalDccZs1Sample values ("
00514 << settings.ecalDccZs1stSample_.size() << ").";
00515 }
00516 }