CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/DQM/DTMonitorClient/src/DTOccupancyTest.cc

Go to the documentation of this file.
00001 
00002 
00003 /*
00004  *  See header file for a description of this class.
00005  *
00006  *  $Date: 2011/06/10 13:50:12 $
00007  *  $Revision: 1.17 $
00008  *  \author G. Cerminara - University and INFN Torino
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   // Get the DQM service
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   // switch on the mode for running on test pulses (different top folder)
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   // Event counter
00073   nevents = 0;
00074 
00075   // Book the summary histos
00076   //   - one summary per wheel
00077   for(int wh = -2; wh <= 2; ++wh) { // loop over wheels
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   //   - global summary with alarms
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   //   - global summary with percentages
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   // assign the name of the input histogram
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 { // default is AllHits histo
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   // Get the geometry
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 //   if(nevents%1000)
00135 //     LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest]: "<<nevents<<" events";
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   // Reset the global summary
00149   summaryHisto->Reset();
00150   glbSummaryHisto->Reset();
00151 
00152   // Get all the DT chambers
00153   vector<DTChamber*> chambers = muonGeom->chambers();
00154 
00155   for(vector<DTChamber*>::const_iterator chamber = chambers.begin();
00156       chamber != chambers.end(); ++chamber) {  // Loop over all chambers
00157     DTChamberId chId = (*chamber)->id();
00158 
00159     MonitorElement * chamberOccupancyHisto = dbe->get(getMEName(nameMonitoredHisto, chId));     
00160 
00161     // Run the tests on the plot for the various granularities
00162     if(chamberOccupancyHisto != 0) {
00163       // Get the 2D histo
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       // the 2 MB4 of Sect 4 and 10 count as half a chamber
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   // Fill the global summary
00214   // Check for entire sectors off and report them on the global summary
00215   //FIXME: TODO
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   // Set the current folder
00237   stringstream wheel; wheel << wheelId; 
00238   dbe->setCurrentFolder(topFolder());
00239 
00240   // build the histo name
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   // build the histo name
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 // Run a test on the occupancy of the chamber
00293 // Return values:
00294 // 0 -> all ok
00295 // 1 -> # consecutive dead channels > N
00296 // 2 -> dead layer
00297 // 3 -> dead SL
00298 // 4 -> dead chamber
00299 int DTOccupancyTest::runOccupancyTest(TH2F *histo, const DTChamberId& chId,
00300                                       float& chamberPercentage) {
00301   int nBinsX = histo->GetNbinsX();
00302 
00303   // Reset the error flags
00304   bool failSL = false;
00305   bool failLayer = false;
00306   bool failCells = false;
00307 
00308   // Check that the chamber has digis
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   // set the # of SLs
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   // Compute the average occupancy per layer and its RMS
00329   // we also look of the layer with the smallest RMS in order to find a reference value
00330   // for the cell occupancy 
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) { // loop over SLs
00339     // Skip layer 2 on MB4
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     // check the SL occupancy
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) { // loop over layers
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       // We look for the distribution of hits within the layer
00375       int nWires = muonGeom->layer(layID)->specificTopology().channels();
00376       int firstWire = muonGeom->layer(layID)->specificTopology().firstChannel();
00377       double layerSquaredSum = 0;
00378       // reset the alert bit in the plot (used by render plugins)
00379       histo->SetBinContent(nBinsX+1,binY,0.);
00380 
00381       for(int cell = firstWire; cell != (nWires+firstWire); ++cell) { // loop over cells
00382         double cellOccup = histo->GetBinContent(cell,binY);
00383         layerSquaredSum+=cellOccup*cellOccup;
00384       }
00385       
00386 
00387 
00388       // compute the average cell occpuancy and RMS
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 //   double averageLayerOcc = totalChamberOccupp/(nSL*4);
00409 //   double averageSquaredLayeroccup = squaredLayerOccupSum/(nSL*4);
00410 //   double layerOccupRMS = sqrt(averageSquaredLayeroccup - averageLayerOcc*averageLayerOcc);
00411 
00412   double minCellRMS = 99999999;
00413   double referenceCellOccup = -1;
00414 
00415   DTOccupancyClusterBuilder builder;
00416 
00417   // find the cell reference value
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]; // FIXME: useless
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 //   set<DTLayerId> bestLayers getLayerIDs()
00442 
00443   double safeFactor = 3.;
00444 //   if(minCellRMS > referenceCellOccup) safeFactor = 5;
00445 
00446   LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " Reference cell occup.: " << referenceCellOccup
00447                                                     << " RMS: " << minCellRMS << endl;
00448   
00449   // Set a warning for particularly high RMS: noise can "mask" dead channels
00450 //   bool rmsWarning = false;
00451 //   if(layerOccupRMS > averageLayerOcc) {
00452 //     cout << " Warning RMS is too big: monitoring all layers" << endl;
00453 //     rmsWarning = true;
00454 //   }  
00455 
00456   int nFailingSLs = 0;
00457 
00458   // Check the layer occupancy
00459   for(int slay = 1; slay <= 3; ++slay) { // loop over SLs
00460     // Skip layer 2 on MB4
00461     if(chId.station() == 4 && slay == 2) continue;
00462 
00463     int binYlow = ((slay-1)*4)+1;
00464 //     int binYhigh = binYlow+3;
00465 
00466 
00467     int nFailingLayers = 0;
00468 
00469     for(int lay = 1; lay <= 4; ++lay) { // loop over layers
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       // compute the integral of the layer occupancy
00476       double layerInteg = histo->Integral(1,nBinsX,binY,binY);
00477 
00478       LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << "     layer: " << layID << " integral: " << layerInteg << endl;
00479 
00480       // Check if in the list of layers which are monitored
00481       bool alreadyMonitored = false;
00482       if(monitoredLayers.find(layID) != monitoredLayers.end()) alreadyMonitored = true;
00483 
00484 
00485       if(layerInteg == 0) { // layer is dead (no need to go further
00486         LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << "     fail layer: no entries" << endl;
00487         // Add it to the list of of monitored layers
00488         if(!alreadyMonitored) monitoredLayers.insert(layID);
00489         nFailingLayers++;
00490         failLayer = true;
00491         histo->SetBinContent(nBinsX+1,binY,-1.);
00492         // go to next layer
00493         continue;
00494       }
00495 
00496 
00497       
00498 //       double avCellOccInLayer = averageCellOccupAndRMS[layID].first;
00499 //       double cellOccupRMS =  averageCellOccupAndRMS[layID].second;
00500 //       if(monitoredLayers.find(layID) != monitoredLayers.end() ||
00501 //       layerInteg == 0 ||
00502 //       layerInteg < (averageLayerOcc - 3*layerOccupRMS) ||
00503 //       cellOccupRMS > avCellOccInLayer ||
00504 //       avCellOccInLayer < referenceCellOccup/3.) { // check the layer
00505 
00506         if(alreadyMonitored || builder.isProblematic(layID)) { // check the layer
00507 
00508           // Add it to the list of of monitored layers
00509           if(monitoredLayers.find(layID) == monitoredLayers.end()) monitoredLayers.insert(layID);
00510 
00511 //      if(layerInteg != 0) { // check # of dead cells
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) { // loop over cells
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               // 3 cells not dead between a group of dead cells don't break the count
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           // Count dead cells
00548 //        if(TMath::Erf(referenceCellOccup/sqrt(referenceCellOccup)) > 2./3. &&
00549 //           nDeadCellsInARowMax >  nWires/3.
00550 //           && nDeadCellsInARowMax <  2*nWires/3.) {
00551 //          cout << " -> fail cells!" << endl;
00552 
00553 //          failCells = true;
00554 //          histo->SetBinContent(nBinsX+1,binY,-1.);
00555 //        } else
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 //            failCells = true;
00575 //            histo->SetBinContent(nBinsX+1,binY,-1.);
00576           }
00577 
00578 //      } else { // all layer is dead
00579 //        LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << "     fail layer: no entries" << endl;
00580 //        nFailingLayers++;
00581 //        failLayer = true;
00582 //        histo->SetBinContent(nBinsX+1,binY,-1.);
00583 //      }
00584       }
00585     }
00586     // Check if the whole layer is off
00587     if( nFailingLayers == 4) {
00588       nFailingSLs++;
00589       failSL = true;
00590     }
00591   }
00592 
00593   // All the chamber is off
00594   if(nFailingSLs == nSL) {
00595     chamberPercentage = 0;
00596     return 4;
00597   } else {
00598     chamberPercentage = 1.-(float)nFailingSLs/(float)nSL;
00599   }
00600 
00601   // FIXME add check on cells
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 }