00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <DQM/DTMonitorClient/src/DTOccupancyTest.h>
00013 #include <DQM/DTMonitorClient/src/DTOccupancyClusterBuilder.h>
00014
00015 #include "FWCore/ServiceRegistry/interface/Service.h"
00016 #include "FWCore/Framework/interface/LuminosityBlock.h"
00017 #include "FWCore/Framework/interface/EventSetup.h"
00018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00019 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00020 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00021 #include "DQMServices/Core/interface/DQMStore.h"
00022 #include "DQMServices/Core/interface/MonitorElement.h"
00023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00024
00025 #include "TMath.h"
00026
00027 using namespace edm;
00028 using namespace std;
00029
00030
00031
00032
00033 DTOccupancyTest::DTOccupancyTest(const edm::ParameterSet& ps){
00034 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest]: Constructor";
00035
00036
00037 dbe = Service<DQMStore>().operator->();
00038
00039 lsCounter = 0;
00040
00041 writeRootFile = ps.getUntrackedParameter<bool>("writeRootFile", false);
00042 if(writeRootFile) {
00043 rootFile = new TFile("DTOccupancyTest.root","RECREATE");
00044 ntuple = new TNtuple("OccupancyNtuple", "OccupancyNtuple", "ls:wh:st:se:lay1MeanCell:lay1RMS:lay2MeanCell:lay2RMS:lay3MeanCell:lay3RMS:lay4MeanCell:lay4RMS:lay5MeanCell:lay5RMS:lay6MeanCell:lay6RMS:lay7MeanCell:lay7RMS:lay8MeanCell:lay8RMS:lay9MeanCell:lay9RMS:lay10MeanCell:lay10RMS:lay11MeanCell:lay11RMS:lay12MeanCell:lay12RMS");
00045 }
00046
00047
00048 tpMode = ps.getUntrackedParameter<bool>("testPulseMode", false);
00049
00050 runOnAllHitsOccupancies = ps.getUntrackedParameter<bool>("runOnAllHitsOccupancies", true);
00051 runOnNoiseOccupancies = ps.getUntrackedParameter<bool>("runOnNoiseOccupancies", false);
00052 runOnInTimeOccupancies = ps.getUntrackedParameter<bool>("runOnInTimeOccupancies", false);
00053 nMinEvts = ps.getUntrackedParameter<int>("nEventsCert", 5000);
00054
00055 }
00056
00057
00058
00059
00060 DTOccupancyTest::~DTOccupancyTest(){
00061 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << " destructor called" << endl;
00062
00063
00064 }
00065
00066
00067
00068
00069 void DTOccupancyTest::beginJob(){
00070 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest]: BeginJob";
00071
00072
00073 nevents = 0;
00074
00075
00076
00077 for(int wh = -2; wh <= 2; ++wh) {
00078 bookHistos(wh, string("Occupancies"), "OccupancySummary");
00079 }
00080
00081 dbe->setCurrentFolder(topFolder());
00082 string title = "Occupancy Summary";
00083 if(tpMode) {
00084 title = "Test Pulse Occupancy Summary";
00085 }
00086
00087 summaryHisto = dbe->book2D("OccupancySummary",title.c_str(),12,1,13,5,-2,3);
00088 summaryHisto->setAxisTitle("sector",1);
00089 summaryHisto->setAxisTitle("wheel",2);
00090
00091
00092 glbSummaryHisto = dbe->book2D("OccupancyGlbSummary",title.c_str(),12,1,13,5,-2,3);
00093 glbSummaryHisto->setAxisTitle("sector",1);
00094 glbSummaryHisto->setAxisTitle("wheel",2);
00095
00096
00097
00098 if(runOnAllHitsOccupancies) {
00099 nameMonitoredHisto = "OccupancyAllHits_perCh";
00100 } else if(runOnNoiseOccupancies) {
00101 nameMonitoredHisto = "OccupancyNoise_perCh";
00102 } else if(runOnInTimeOccupancies) {
00103 nameMonitoredHisto = "OccupancyInTimeHits_perCh";
00104 } else {
00105 nameMonitoredHisto = "OccupancyAllHits_perCh";
00106 }
00107
00108 }
00109
00110
00111
00112
00113 void DTOccupancyTest::beginRun(const edm::Run& run, const EventSetup& context){
00114
00115 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest]: BeginRun";
00116
00117
00118 context.get<MuonGeometryRecord>().get(muonGeom);
00119
00120 }
00121
00122
00123
00124
00125 void DTOccupancyTest::beginLuminosityBlock(LuminosityBlock const& lumiSeg, EventSetup const& context) {
00126 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") <<"[DTOccupancyTest]: Begin of LS transition";
00127 }
00128
00129
00130
00131
00132 void DTOccupancyTest::analyze(const Event& e, const EventSetup& context) {
00133 nevents++;
00134
00135
00136 }
00137
00138
00139
00140
00141 void DTOccupancyTest::endLuminosityBlock(LuminosityBlock const& lumiSeg, EventSetup const& context) {
00142 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest")
00143 <<"[DTOccupancyTest]: End of LS transition, performing the DQM client operation";
00144 lsCounter++;
00145
00146
00147
00148
00149 summaryHisto->Reset();
00150 glbSummaryHisto->Reset();
00151
00152
00153 vector<DTChamber*> chambers = muonGeom->chambers();
00154
00155 for(vector<DTChamber*>::const_iterator chamber = chambers.begin();
00156 chamber != chambers.end(); ++chamber) {
00157 DTChamberId chId = (*chamber)->id();
00158
00159 MonitorElement * chamberOccupancyHisto = dbe->get(getMEName(nameMonitoredHisto, chId));
00160
00161
00162 if(chamberOccupancyHisto != 0) {
00163
00164 TH2F* histo = chamberOccupancyHisto->getTH2F();
00165 float chamberPercentage = 1.;
00166 int result = runOccupancyTest(histo, chId, chamberPercentage);
00167 int sector = chId.sector();
00168
00169 if(sector == 13) {
00170 sector = 4;
00171 float resultSect4 = wheelHistos[chId.wheel()]->getBinContent(sector, chId.station());
00172 if(resultSect4 > result) {
00173 result = (int)resultSect4;
00174 }
00175 } else if(sector == 14) {
00176 sector = 10;
00177 float resultSect10 = wheelHistos[chId.wheel()]->getBinContent(sector, chId.station());
00178 if(resultSect10 > result) {
00179 result = (int)resultSect10;
00180 }
00181 }
00182
00183
00184 if((sector == 4 || sector == 10) && chId.station() == 4)
00185 chamberPercentage = chamberPercentage/2.;
00186
00187 wheelHistos[chId.wheel()]->setBinContent(sector, chId.station(),result);
00188 if(result > summaryHisto->getBinContent(sector, chId.wheel()+3)) {
00189 summaryHisto->setBinContent(sector, chId.wheel()+3, result);
00190 }
00191 glbSummaryHisto->Fill(sector, chId.wheel(), chamberPercentage*1./4.);
00192 } else {
00193 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest] ME: "
00194 << getMEName(nameMonitoredHisto, chId) << " not found!" << endl;
00195 }
00196
00197 }
00198
00199 string nEvtsName = "DT/EventInfo/Counters/nProcessedEventsDigi";
00200 MonitorElement * meProcEvts = dbe->get(nEvtsName);
00201
00202 if (meProcEvts) {
00203 int nProcEvts = meProcEvts->getFloatValue();
00204 glbSummaryHisto->setEntries(nProcEvts < nMinEvts ? 10. : nProcEvts);
00205 summaryHisto->setEntries(nProcEvts < nMinEvts ? 10. : nProcEvts);
00206 } else {
00207 glbSummaryHisto->setEntries(nMinEvts +1);
00208 summaryHisto->setEntries(nMinEvts + 1);
00209 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest] ME: "
00210 << nEvtsName << " not found!" << endl;
00211 }
00212
00213
00214
00215
00216
00217 if(writeRootFile) ntuple->AutoSave("SaveSelf");
00218
00219 }
00220
00221
00222 void DTOccupancyTest::endJob(){
00223
00224 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest] endjob called!";
00225 if(writeRootFile) {
00226 rootFile->cd();
00227 ntuple->Write();
00228 rootFile->Close();
00229 }
00230 }
00231
00232
00233
00234
00235 void DTOccupancyTest::bookHistos(const int wheelId, string folder, string histoTag) {
00236
00237 stringstream wheel; wheel << wheelId;
00238 dbe->setCurrentFolder(topFolder());
00239
00240
00241 string histoName = histoTag + "_W" + wheel.str();
00242
00243
00244 LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") <<"[DTOccupancyTest]: booking wheel histo:"
00245 << histoName
00246 << " (tag "
00247 << histoTag
00248 << ") in: "
00249 << topFolder() + "Wheel"+ wheel.str() + "/" + folder << endl;
00250
00251 string histoTitle = "Occupancy summary WHEEL: "+wheel.str();
00252 if(tpMode) {
00253 histoTitle = "TP Occupancy summary WHEEL: "+wheel.str();
00254 }
00255 wheelHistos[wheelId] = dbe->book2D(histoName,histoTitle,12,1,13,4,1,5);
00256 wheelHistos[wheelId]->setBinLabel(1,"MB1",2);
00257 wheelHistos[wheelId]->setBinLabel(2,"MB2",2);
00258 wheelHistos[wheelId]->setBinLabel(3,"MB3",2);
00259 wheelHistos[wheelId]->setBinLabel(4,"MB4",2);
00260 wheelHistos[wheelId]->setAxisTitle("sector",1);
00261 }
00262
00263
00264
00265 string DTOccupancyTest::getMEName(string histoTag, const DTChamberId& chId) {
00266
00267 stringstream wheel; wheel << chId.wheel();
00268 stringstream station; station << chId.station();
00269 stringstream sector; sector << chId.sector();
00270
00271
00272 string folderRoot = topFolder() + "Wheel" + wheel.str() +
00273 "/Sector" + sector.str() +
00274 "/Station" + station.str() + "/";
00275
00276 string folder = "Occupancies/";
00277
00278
00279 string histoName = histoTag
00280 + "_W" + wheel.str()
00281 + "_St" + station.str()
00282 + "_Sec" + sector.str();
00283
00284 string histoname = folderRoot + histoName;
00285
00286 return histoname;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 int DTOccupancyTest::runOccupancyTest(TH2F *histo, const DTChamberId& chId,
00300 float& chamberPercentage) {
00301 int nBinsX = histo->GetNbinsX();
00302
00303
00304 bool failSL = false;
00305 bool failLayer = false;
00306 bool failCells = false;
00307
00308
00309 if(histo->Integral() == 0) {
00310 chamberPercentage = 0;
00311 return 4;
00312 }
00313
00314 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << "--- Occupancy test for chamber: " << chId << endl;
00315
00316 int nSL = 3;
00317 if(chId.station() == 4) nSL = 2;
00318
00319
00320 float values[28];
00321 if(writeRootFile) {
00322 values[0] = lsCounter;
00323 values[1] = chId.wheel();
00324 values[2] = chId.station();
00325 values[3] = chId.sector();
00326 }
00327
00328
00329
00330
00331 double totalChamberOccupp = 0;
00332 double squaredLayerOccupSum = 0;
00333
00334 map<DTLayerId, pair<double, double> > averageCellOccupAndRMS;
00335 map<DTLayerId, double> layerOccupancyMap;
00336
00337 int index = 3;
00338 for(int slay = 1; slay <= 3; ++slay) {
00339
00340 if(chId.station() == 4 && slay == 2) {
00341 if(writeRootFile) {
00342 values[12] = -1;
00343 values[13] = -1;
00344 values[14] = -1;
00345 values[15] = -1;
00346 values[16] = -1;
00347 values[17] = -1;
00348 values[18] = -1;
00349 values[19] = -1;
00350 }
00351 index = 19;
00352 continue;
00353 }
00354
00355 int binYlow = ((slay-1)*4)+1;
00356 int binYhigh = binYlow+3;
00357 double slInteg = histo->Integral(1,nBinsX,binYlow,binYhigh);
00358 if(slInteg == 0) {
00359 chamberPercentage = 1.-1./(float)nSL;
00360 return 3;
00361 }
00362
00363 for(int lay = 1; lay <= 4; ++lay) {
00364 DTLayerId layID(chId,slay,lay);
00365
00366 int binY = binYlow+(lay-1);
00367
00368 double layerInteg = histo->Integral(1,nBinsX,binY,binY);
00369 squaredLayerOccupSum += layerInteg*layerInteg;
00370 totalChamberOccupp+= layerInteg;
00371
00372 layerOccupancyMap[layID] = layerInteg;
00373
00374
00375 int nWires = muonGeom->layer(layID)->specificTopology().channels();
00376 int firstWire = muonGeom->layer(layID)->specificTopology().firstChannel();
00377 double layerSquaredSum = 0;
00378
00379 histo->SetBinContent(nBinsX+1,binY,0.);
00380
00381 for(int cell = firstWire; cell != (nWires+firstWire); ++cell) {
00382 double cellOccup = histo->GetBinContent(cell,binY);
00383 layerSquaredSum+=cellOccup*cellOccup;
00384 }
00385
00386
00387
00388
00389 double averageCellOccup = layerInteg/nWires;
00390 double averageSquaredCellOccup = layerSquaredSum/nWires;
00391 double rmsCellOccup = sqrt(averageSquaredCellOccup - averageCellOccup*averageCellOccup);
00392 averageCellOccupAndRMS[layID] = make_pair(averageCellOccup, rmsCellOccup);
00393 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " " << layID
00394 << " average cell occ.: " << averageCellOccup
00395 << " RMS: " << rmsCellOccup << endl;
00396 if(writeRootFile) {
00397 index++;
00398 values[index] = averageCellOccup;
00399 index++;
00400 values[index] = rmsCellOccup;
00401 }
00402 }
00403 }
00404
00405
00406 if(writeRootFile) ntuple->Fill(values);
00407
00408
00409
00410
00411
00412 double minCellRMS = 99999999;
00413 double referenceCellOccup = -1;
00414
00415 DTOccupancyClusterBuilder builder;
00416
00417
00418 for(map<DTLayerId, pair<double, double> >::const_iterator layAndValues = averageCellOccupAndRMS.begin();
00419 layAndValues != averageCellOccupAndRMS.end(); layAndValues++) {
00420 DTLayerId lid = (*layAndValues).first;
00421
00422 double rms = (*layAndValues).second.second;
00423 double lOcc = layerOccupancyMap[lid];
00424 double avCellOcc = (*layAndValues).second.first;
00425 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " " << lid << " tot. occ: " << lOcc
00426 << " average cell occ: " << avCellOcc
00427 << " RMS: " << rms << endl;
00428
00429 if(avCellOcc != 0) {
00430 DTOccupancyPoint point(avCellOcc, rms, lid);
00431 builder.addPoint(point);
00432 } else {
00433 if(monitoredLayers.find(lid) == monitoredLayers.end()) monitoredLayers.insert(lid);
00434 }
00435 }
00436
00437 builder.buildClusters();
00438 referenceCellOccup = builder.getBestCluster().averageMean();
00439 minCellRMS = builder.getBestCluster().averageRMS();
00440
00441
00442
00443 double safeFactor = 3.;
00444
00445
00446 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " Reference cell occup.: " << referenceCellOccup
00447 << " RMS: " << minCellRMS << endl;
00448
00449
00450
00451
00452
00453
00454
00455
00456 int nFailingSLs = 0;
00457
00458
00459 for(int slay = 1; slay <= 3; ++slay) {
00460
00461 if(chId.station() == 4 && slay == 2) continue;
00462
00463 int binYlow = ((slay-1)*4)+1;
00464
00465
00466
00467 int nFailingLayers = 0;
00468
00469 for(int lay = 1; lay <= 4; ++lay) {
00470 DTLayerId layID(chId,slay,lay);
00471 int nWires = muonGeom->layer(layID)->specificTopology().channels();
00472 int firstWire = muonGeom->layer(layID)->specificTopology().firstChannel();
00473 int binY = binYlow+(lay-1);
00474
00475
00476 double layerInteg = histo->Integral(1,nBinsX,binY,binY);
00477
00478 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " layer: " << layID << " integral: " << layerInteg << endl;
00479
00480
00481 bool alreadyMonitored = false;
00482 if(monitoredLayers.find(layID) != monitoredLayers.end()) alreadyMonitored = true;
00483
00484
00485 if(layerInteg == 0) {
00486 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " fail layer: no entries" << endl;
00487
00488 if(!alreadyMonitored) monitoredLayers.insert(layID);
00489 nFailingLayers++;
00490 failLayer = true;
00491 histo->SetBinContent(nBinsX+1,binY,-1.);
00492
00493 continue;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 if(alreadyMonitored || builder.isProblematic(layID)) {
00507
00508
00509 if(monitoredLayers.find(layID) == monitoredLayers.end()) monitoredLayers.insert(layID);
00510
00511
00512 int totalDeadCells = 0;
00513 int nDeadCellsInARow = 1;
00514 int nDeadCellsInARowMax = 0;
00515 int nCellsZeroCount = 0;
00516 bool previousIsDead = false;
00517
00518 int interDeadCells = 0;
00519 for(int cell = firstWire; cell != (nWires+firstWire); ++cell) {
00520 double cellOccup = histo->GetBinContent(cell,binY);
00521 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " cell occup: " << cellOccup;
00522 if(cellOccup == 0 || cellOccup < (referenceCellOccup-safeFactor*sqrt(referenceCellOccup))) {
00523 if(cellOccup == 0) nCellsZeroCount++;
00524 totalDeadCells++;
00525 if(previousIsDead) nDeadCellsInARow++;
00526 previousIsDead = true;
00527 interDeadCells = 0;
00528 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " below reference" << endl;
00529 } else {
00530 previousIsDead = false;
00531 interDeadCells++;
00532
00533
00534 if(interDeadCells > 3) {
00535 if(nDeadCellsInARow > nDeadCellsInARowMax) nDeadCellsInARowMax = nDeadCellsInARow;
00536 nDeadCellsInARow = 1;
00537 }
00538 }
00539 }
00540 if(nDeadCellsInARow > nDeadCellsInARowMax) nDeadCellsInARowMax = nDeadCellsInARow;
00541 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " # wires: " << nWires
00542 << " # cells 0 count: " << nCellsZeroCount
00543 << " # dead cells in a row: " << nDeadCellsInARowMax
00544 << " total # of dead cells: " << totalDeadCells;
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 if((TMath::Erfc(referenceCellOccup/sqrt(referenceCellOccup)) < 10./(double)nWires &&
00557 nDeadCellsInARowMax>= 10.) ||
00558 (TMath::Erfc(referenceCellOccup/sqrt(referenceCellOccup)) < 0.5 &&
00559 totalDeadCells > nWires/2.)) {
00560 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " -> fail layer!" << endl;
00561 nFailingLayers++;
00562 failLayer = true;
00563 histo->SetBinContent(nBinsX+1,binY,-1.);
00564 } else if(referenceCellOccup > 10 &&
00565 nCellsZeroCount > nWires/3. &&
00566 (double)nCellsZeroCount/(double)nWires >
00567 2.*TMath::Erfc(referenceCellOccup/sqrt(referenceCellOccup))) {
00568 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " -> would fail cells!" << endl;
00569 LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " # of cells with 0 count: " << nCellsZeroCount
00570 << " # wires: " << nWires
00571 << " erfc: "
00572 << TMath::Erfc(referenceCellOccup/sqrt(referenceCellOccup))
00573 << endl;
00574
00575
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 }
00585 }
00586
00587 if( nFailingLayers == 4) {
00588 nFailingSLs++;
00589 failSL = true;
00590 }
00591 }
00592
00593
00594 if(nFailingSLs == nSL) {
00595 chamberPercentage = 0;
00596 return 4;
00597 } else {
00598 chamberPercentage = 1.-(float)nFailingSLs/(float)nSL;
00599 }
00600
00601
00602 if(failSL) return 3;
00603 if(failLayer) return 2;
00604 if(failCells) return 1;
00605
00606 return 0;
00607 }
00608
00609
00610 string DTOccupancyTest::topFolder() const {
00611 if(tpMode) return string("DT/10-TestPulses/");
00612 return string("DT/01-Digi/");
00613 }