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
00081 edm::ESHandle<EcalSRSettings> hSr;
00082 eventSetup.get<EcalSRSettingsRcd>().get(hSr);
00083 settings_ = hSr.product();
00084
00085
00086 EcalTrigPrimDigiCollection emptyTPColl;
00087 const EcalTrigPrimDigiCollection* trigPrims =
00088 (trigPrimBypass_ && trigPrimBypassMode_==0)?&emptyTPColl:getTrigPrims(event);
00089
00090
00091
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
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
00118 checkValidity(*settings_);
00119
00120
00121 suppressor_ = auto_ptr<EcalSelectiveReadoutSuppressor>(new EcalSelectiveReadoutSuppressor(params_, settings_));
00122
00123
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;
00153
00154 if(produceDigis_){
00155
00156 event.put(selectedEBDigis, ebSRPdigiCollection_);
00157 event.put(selectedEEDigis, eeSRPdigiCollection_);
00158 }
00159
00160
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
00173
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
00189
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
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
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
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
00261
00262
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];
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;
00302 }
00303
00304 if(weights.size()>0){
00305 int iMaxWeight = 0;
00306 double maxWeight = weights[iMaxWeight];
00307
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
00316 int maxWeightBin = settings_->ecalDccZs1stSample_[0]
00317 + iMaxWeight;
00318
00319
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()){
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
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 if(iEvent>=0){
00404 os << "# Event " << iEvent << "\n";
00405 }
00406
00407
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);
00436 int iEbEta0 = iEta0 - nEeTtEta;
00437 int iPhi0 = flag.id().iphi() - 1;
00438 assert(iEbEta0>=0 && iEbEta0<nEbTtEta);
00439 assert(iPhi0>=0 && iPhi0<nTtPhi);
00440
00441
00442
00443
00444
00445
00446
00447 ebSrf[iEbEta0][iPhi0] = flag.value();
00448 }
00449
00450
00451
00452
00453
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";
00462 }
00463
00464
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";
00475 }
00476
00477
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";
00486 }
00487
00488
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
00499
00500
00501
00502
00503
00504
00505
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 }