CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/src/DQM/L1TMonitorClient/src/L1TOccupancyClient.cc

Go to the documentation of this file.
00001 #include "DQM/L1TMonitorClient/interface/L1TOccupancyClient.h"
00002 
00003 #include "FWCore/ServiceRegistry/interface/Service.h"
00004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00005 #include "FWCore/Framework/interface/ESHandle.h"
00006 #include "FWCore/Framework/interface/EventSetup.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "DQMServices/Core/interface/QReport.h"
00009 #include "DQMServices/Core/interface/DQMStore.h"
00010 #include "DQMServices/Core/interface/MonitorElement.h"
00011 #include "DataFormats/Histograms/interface/MEtoEDMFormat.h"
00012 #include <stdio.h>
00013 #include <sstream>
00014 #include <math.h>
00015 #include <vector>
00016 #include <TMath.h>
00017 #include <limits.h>
00018 #include <TFile.h>
00019 #include <TDirectory.h>
00020 #include <TProfile.h>
00021 
00022 using namespace std;
00023 using namespace edm;
00024 
00025 //____________________________________________________________________________
00026 // Function: L1TOccupancyClient
00027 // Description: This is the constructor, basic variable initialization
00028 // Inputs: 
00029 // * const edm::ParameterSet& ps = Parameter for this analyzer
00030 //____________________________________________________________________________
00031 L1TOccupancyClient::L1TOccupancyClient(const edm::ParameterSet& ps){
00032 
00033   
00034   // Get parameters
00035   parameters_ = ps;
00036   verbose_    = ps.getParameter<bool>                      ("verbose");
00037   tests_      = ps.getParameter<std::vector<ParameterSet> >("testParams");
00038 
00039   if(verbose_){cout << "[L1TOccupancyClient:] Called constructor" << endl;}
00040 
00041   // Get back-end interface
00042   dbe_      = Service<DQMStore>().operator->();   
00043 
00044 }
00045 
00046 //____________________________________________________________________________
00047 // Function: ~L1TOccupancyClient
00048 // Description: This is the destructor, basic variable deletion
00049 //____________________________________________________________________________
00050 L1TOccupancyClient::~L1TOccupancyClient(){
00051   if(verbose_){cout << "[L1TOccupancyClient:] Called destructor" << endl;}
00052 }
00053 
00054 //____________________________________________________________________________
00055 // Function: beginJob
00056 // Description: This will be run at the beginning of each job
00057 //____________________________________________________________________________
00058 void L1TOccupancyClient::beginJob(void){
00059 
00060   if(verbose_){cout << "[L1TOccupancyClient:] Called BeginJob" << endl;}
00061 
00062   // get backend interface  
00063   dbe_ = Service<DQMStore>().operator->();
00064 
00065   if (dbe_) {
00066     dbe_->setCurrentFolder("L1T/L1TOccupancy");
00067     dbe_->rmdir("L1T/L1TOccupancy");
00068   }
00069 }
00070 
00071 //____________________________________________________________________________
00072 // Function: endJob
00073 // Description: This will be run at the end of each job
00074 //____________________________________________________________________________
00075 void L1TOccupancyClient::endJob(){
00076 
00077   if(verbose_){cout << "[L1TOccupancyClient:] Called endJob" << endl;}
00078   
00079 }
00080 
00081 //____________________________________________________________________________
00082 // Function: beginRun
00083 // Description: This is will be run at the begining of each run
00084 // Inputs: 
00085 // * const Run&        r       = Run information 
00086 // * const EventSetup& context = Event Setup information
00087 //____________________________________________________________________________
00088 void L1TOccupancyClient::beginRun(const Run& r, const EventSetup& context){
00089 
00090   hservice_ = new L1TOccupancyClientHistogramService(parameters_,dbe_,verbose_); 
00091   
00092   if(verbose_){
00093     cout << "[L1TOccupancyClient:] Called beginRun" << endl;
00094 
00095     // In verbose mode we will produce an extra output file with several tests
00096     file_ = TFile::Open("DQM_L1TOccupancyClient_Snapshots_LS.root","RECREATE");
00097   }
00098   
00099   dbe_->setCurrentFolder("L1T/L1TOccupancy/");
00100   dbe_->setCurrentFolder("L1T/L1TOccupancy/Results");
00101   dbe_->setCurrentFolder("L1T/L1TOccupancy/BadCellValues");
00102   dbe_->setCurrentFolder("L1T/L1TOccupancy/Certification");
00103   
00104   // Loop over all tests in defined 
00105   for (vector<ParameterSet>::iterator it = tests_.begin(); it != tests_.end(); it++) {
00106 
00107     // If the test algorithm is XYSymmetry we create the necessary histograms 
00108     if((*it).getUntrackedParameter<string>("algoName","XYSymmetry")=="XYSymmetry") {
00109 
00110       // Getting Parameters for the test
00111       string       testName       = (*it).getParameter<string>         ("testName");
00112       ParameterSet algoParameters = (*it).getParameter<ParameterSet>   ("algoParams");
00113       string       histPath       = algoParameters.getParameter<string>("histPath");
00114       
00115       if(verbose_){
00116         cout << "[L1TOccupancyClient:] Monitored histogram path: " << histPath << endl;
00117       
00118         // Creating verbose file directory structure
00119         // test_name/test_name_Results, 
00120         // test_name/test_name_Histos
00121         // TDirectory *td  = file_->mkdir(testName.c_str()             ,testName.c_str());
00122         //FIXME: sub never used gcc361 warning
00123         //TDirectory *sub = td   ->mkdir((testName+"_Results").c_str(),string("_Results").c_str());
00124 
00125         //sub = td->mkdir((testName+"_Histos").c_str()      ,(testName+"_Histos").c_str());
00126         //sub = td->mkdir((testName+"_Histos_AllLS").c_str(),(testName+"_Histos_AllLS").c_str());
00127       }
00128       
00129       // Load histograms in service instance
00130       if(hservice_->loadHisto(testName,histPath)){
00131 
00132       
00133       
00134         // Mask channels specified in python file
00135         hservice_->setMaskedBins(testName,algoParameters.getParameter<vector<ParameterSet> >("maskedAreas")); 
00136 
00137       // Book MonitorElements
00138       // * Test results
00139       dbe_->setCurrentFolder("L1T/L1TOccupancy/Results");
00140       string          title = testName;
00141       MonitorElement* m     = dbe_->book2D(title.c_str(),hservice_->getDifferentialHistogram(testName));
00142       m->setTitle(title.c_str()); 
00143       m->Reset();
00144       meResults[title] = m; 
00145 
00146       // * Which cells are masked as bad
00147       dbe_->setCurrentFolder("L1T/L1TOccupancy/HistogramDiff");
00148       title = testName;
00149       m = dbe_->book2D(title.c_str(),hservice_->getDifferentialHistogram(testName));
00150       m->Reset();
00151       m->setTitle(title.c_str());
00152       meDifferential[title] = m;
00153       
00154       // * Fraction of bad cells
00155       dbe_->setCurrentFolder("L1T/L1TOccupancy/Certification");
00156       title = testName;
00157       m = dbe_->book1D(title.c_str(),title.c_str(),2500,-.5,2500.-.5);
00158       m->setTitle(title.c_str());
00159       meCertification[title] = m;
00160    
00161         mValidTests.push_back(&(*it));
00162         
00163       }
00164       
00165     }
00166   }
00167 }
00168 
00169 //____________________________________________________________________________
00170 // Function: endRun
00171 // Description: This is will be run at the end of each run
00172 // Inputs: 
00173 // * const Run&        r       = Run information 
00174 // * const EventSetup& context = Event Setup information
00175 //____________________________________________________________________________
00176 void L1TOccupancyClient::endRun(const Run& r, const EventSetup& context){
00177 
00178   if(verbose_){cout << "[L1TOccupancyClient:] Called endRun()" << endl;}
00179 
00180   // Loop over every test in python
00181   for (std::vector<ParameterSet*>::iterator it = mValidTests.begin(); it != mValidTests.end(); it++) {
00182 
00183     ParameterSet &test     = (**it);
00184     string       algo_name = test.getUntrackedParameter<string>("algoName","XYSymmetry");
00185     string       test_name = test.getParameter         <string>("testName");
00186     
00187     if(verbose_) {cout << "[L1TOccupancyClient:] Starting calculations for: " << algo_name << " on: " << test_name << endl;}
00188     
00189     if(algo_name == "XYSymmetry") {
00190 
00191       ParameterSet ps       = (**it).getParameter<ParameterSet>("algoParams");
00192       string       histPath = ps.getParameter<string>("histPath");
00193 
00194       vector<pair<int,double> > deadChannels;
00195       vector<pair<int,double> > statDev;
00196       bool enoughStats = false;
00197 
00198       // Make final block
00199       hservice_->updateHistogramEndRun(test_name);
00200 
00201       // Perform the test
00202       double dead = xySymmetry(ps,test_name,deadChannels,statDev,enoughStats);
00203       stringstream str;
00204       str << test_name << "_cumu_LS_EndRun";
00205 
00206       if(verbose_) {
00207         TH2F* cumulative_save = (TH2F*) hservice_->getDifferentialHistogram(test_name)->Clone(str.str().c_str());
00208 
00209         cumulative_save->SetTitle(str.str().c_str());
00210 
00211         TDirectory* td = file_->GetDirectory(test_name.c_str());
00212 
00213         td->cd(string(test_name+"_Histos_AllLS").c_str());
00214 
00215         cumulative_save->Write();
00216       }
00217       // If we have enough statistics, we can write test result 
00218       if(enoughStats) {
00219 
00220         // Make the result histogram
00221         printDeadChannels(deadChannels,meResults[test_name]->getTH2F(),statDev,test_name);
00222         
00223         if(verbose_) {
00224           TH2F* cumulative_save = (TH2F*) hservice_->getDifferentialHistogram(test_name)->Clone(str.str().c_str());
00225           cumulative_save->SetTitle(str.str().c_str());
00226           TDirectory* td = file_->GetDirectory(("DQM_L1TOccupancyClient_Snapshots_LS.root:/"+test_name).c_str());
00227           td->cd(string(test_name+"_Histos").c_str());
00228           cumulative_save->Write();
00229 
00230           // save the result histo
00231           TH2F* h2f = meResults[test_name]->getTH2F();
00232           stringstream str2;
00233           str2 << test_name << "_result_LS_EndRun";
00234           TH2F* dead_save = (TH2F*) h2f->Clone(str2.str().c_str());
00235         
00236           td->cd(string(test_name+"_Results").c_str());
00237           dead_save->SetTitle(str2.str().c_str());
00238           dead_save->Write();
00239         }
00240         
00241         // Updating test results
00242         meDifferential[test_name]->Reset();
00243         meDifferential[test_name]->getTH2F()->Add(hservice_->getDifferentialHistogram(test_name));
00244         
00245         vector<int> lsCertification = hservice_->getLSCertification(test_name);
00246 
00247         // Fill fraction of dead channels
00248         for(unsigned int i=0;i<lsCertification.size();i++){
00249           int bin = meCertification[test_name]->getTH1()->FindBin(lsCertification[i]);
00250           meCertification[test_name]->getTH1()->SetBinContent(bin,1-dead);
00251         }
00252         
00253         // Reset differential histo
00254         hservice_->resetHisto(test_name);
00255 
00256         if(verbose_) {cout << "Now we have enough statstics for " << test_name << endl;}
00257 
00258       }else{
00259         if(verbose_){cout << "we don't have enough statstics for " << test_name << endl;}
00260         
00261         // Getting LS which this test monitored
00262         vector<int> lsCertification = hservice_->getLSCertification(test_name);
00263 
00264         // Fill fraction of dead channels
00265         for(unsigned int i=0;i<lsCertification.size();i++){
00266           int bin = meCertification[test_name]->getTH1()->FindBin(lsCertification[i]);
00267           meCertification[test_name]->getTH1()->SetBinContent(bin,-1);
00268         }
00269       }
00270     }else {if(verbose_){cout << "No valid algorithm" << std::endl;}}
00271   }
00272 
00273   if(verbose_){file_->Close();}
00274  
00275   delete hservice_;
00276 
00277 }
00278 
00279 //____________________________________________________________________________
00280 // Function: beginLuminosityBlock
00281 // Description: This is will be run at the begining of each luminosity block
00282 // Inputs: 
00283 // * const LuminosityBlock& lumiSeg = Luminosity Block information 
00284 // * const EventSetup&      context = Event Setup information
00285 //____________________________________________________________________________
00286 void L1TOccupancyClient::beginLuminosityBlock(const LuminosityBlock& lumiSeg, const EventSetup& context) {
00287   if(verbose_){cout << "[L1TOccupancyClient:] Called beginLuminosityBlock()" << endl;}
00288 }
00289 
00290 //____________________________________________________________________________
00291 // Function: endLuminosityBlock
00292 // Description: This is will be run at the end of each luminosity block
00293 // Inputs: 
00294 // * const LuminosityBlock& lumiSeg = Luminosity Block information 
00295 // * const EventSetup&      context = Event Setup information
00296 //____________________________________________________________________________
00297 void L1TOccupancyClient::endLuminosityBlock(const edm::LuminosityBlock& lumiSeg, 
00298                                             const edm::EventSetup& c){
00299   
00300   int eventLS = lumiSeg.id().luminosityBlock();
00301 
00302   if(verbose_) {
00303     cout << "[L1TOccupancyClient:] Called endLuminosityBlock()" << endl;
00304     cout << "[L1TOccupancyClient:] Lumisection: " << eventLS << endl;
00305   }
00306   
00307   // Loop over every test in python
00308   for (std::vector<ParameterSet*>::const_iterator it = mValidTests.begin(); it != mValidTests.end(); it++) {
00309     
00310     ParameterSet &test     = (**it);
00311     string       algo_name = test.getUntrackedParameter<string>("algoName","XYSymmetry");
00312     string       test_name = test.getParameter         <string>("testName");
00313 
00314     if(verbose_) {cout << "[L1TOccupancyClient:] Starting calculations for " << algo_name << " on:" << test_name << endl;}
00315    
00316     if(algo_name == "XYSymmetry") {
00317 
00318       ParameterSet ps       = (**it).getParameter<ParameterSet>("algoParams");
00319       string       histPath = ps.getParameter<string>("histPath");
00320       
00321       vector<pair<int,double> > deadChannels;
00322       vector<pair<int,double> > statDev;
00323       bool enoughStats = false;
00324 
00325       // Update histo's data with data of this LS
00326       hservice_->updateHistogramEndLS(test_name,histPath,eventLS);
00327 
00328       // Perform the test
00329       double dead = xySymmetry(ps,test_name,deadChannels,statDev,enoughStats);
00330       stringstream str;
00331       str << test_name << "_cumu_LS_" << eventLS;
00332 
00333       if(verbose_) {
00334         TH2F* cumulative_save = (TH2F*) hservice_->getDifferentialHistogram(test_name)->Clone(str.str().c_str());
00335         cumulative_save->SetTitle(str.str().c_str());
00336         TDirectory* td = file_->GetDirectory(test_name.c_str());
00337         td->cd(string(test_name+"_Histos_AllLS").c_str());
00338         cumulative_save->Write();
00339       }
00340       
00341       // If we have enough statistics, we can write test result 
00342       if(enoughStats) {
00343 
00344         // Make the result histogram
00345         printDeadChannels(deadChannels,meResults[test_name]->getTH2F(),statDev,test_name);
00346         
00347         if(verbose_) {
00348           TH2F* cumulative_save = (TH2F*) hservice_->getDifferentialHistogram(test_name)->Clone(str.str().c_str());
00349           cumulative_save->SetTitle(str.str().c_str());
00350           TDirectory* td = file_->GetDirectory(("DQM_L1TOccupancyClient_Snapshots_LS.root:/"+test_name).c_str());
00351           td->cd(string(test_name+"_Histos").c_str());
00352           cumulative_save->Write();
00353 
00354           // save the result histo
00355           TH2F* h2f = meResults[test_name]->getTH2F();
00356           stringstream str2;
00357           str2 << test_name << "_result_LS_" << eventLS;
00358           TH2F* dead_save = (TH2F*) h2f->Clone(str2.str().c_str());
00359         
00360           td->cd(string(test_name+"_Results").c_str());
00361           dead_save->SetTitle(str2.str().c_str());
00362           dead_save->Write();
00363         }
00364         
00365         // Updating test results
00366         meDifferential[test_name]->Reset();
00367         meDifferential[test_name]->getTH2F()->Add(hservice_->getDifferentialHistogram(test_name));
00368         
00369         vector<int> lsCertification = hservice_->getLSCertification(test_name);
00370 
00371         // Fill fraction of dead channels
00372         for(unsigned int i=0;i<lsCertification.size();i++){
00373           int bin = meCertification[test_name]->getTH1()->FindBin(lsCertification[i]);
00374           meCertification[test_name]->getTH1()->SetBinContent(bin,1-dead);  
00375         }
00376                 
00377         // Reset differential histo
00378         hservice_->resetHisto(test_name);
00379 
00380         if(verbose_) {cout << "Now we have enough statstics for " << test_name << endl;}
00381 
00382       }else{if(verbose_){cout << "we don't have enough statstics for " << test_name << endl;}}
00383     }else {if(verbose_){cout << "No valid algorithm" << std::endl;}}
00384   }
00385 }
00386 
00387 //____________________________________________________________________________
00388 // Function: analyze
00389 // Description: This is will be run for every event
00390 // Inputs: 
00391 // * const Event&      e       = Event information 
00392 // * const EventSetup& context = Event Setup information
00393 //____________________________________________________________________________
00394 void L1TOccupancyClient::analyze(const Event& e, const EventSetup& context){}
00395 
00396 //____________________________________________________________________________
00397 // Function: xySymmetry
00398 // Description: This method preforms the XY Symmetry test
00399 // Inputs: 
00400 // * ParameterSet                     ps           = Parameters for the test 
00401 // * std::string                      test_name    = Test name of the test to be executed
00402 // * std::vector< pair<int,double> >& deadChannels = Vector of 
00403 // * std::vector< pair<int,double> >& statDev      = 
00404 // * bool&                            enoughStats  = 
00405 // Outputs:
00406 // * double = fraction of bins that failed test, DeadChannels in vector, in: ParameterSet of test parameters
00407 //____________________________________________________________________________
00408 double L1TOccupancyClient::xySymmetry(ParameterSet                ps, 
00409                                       string                      iTestName, 
00410                                       vector< pair<int,double> >& deadChannels, 
00411                                       vector< pair<int,double> >& statDev, 
00412                                       bool&                       enoughStats){
00413   
00414   // Getting differential histogram for this this thes
00415   TH2F* diffHist = hservice_->getDifferentialHistogram(iTestName);
00416   
00417   int    pAxis              = ps.getUntrackedParameter<int>   ("axis",1);
00418   int    pAverageMode       = ps.getUntrackedParameter<int>   ("averageMode",2); // 1=arith. mean, 2=median
00419   int    nBinsX             = diffHist->GetNbinsX();           // actual number of bins x
00420   int    nBinsY             = diffHist->GetNbinsY();           // actual number of bins y
00421   
00422   // Axis==1 : Means symmetry axis is vertical
00423   if(pAxis==1){
00424     
00425     int maxBinStrip, centralBinStrip; // x-coordinate of strips
00426     
00427     maxBinStrip = nBinsX;
00428     
00429     // If takeCenter=true  determine central bin of the pAxis
00430     // If takeCenter=false determine the bin to use based user input
00431     if(ps.getUntrackedParameter<bool>("takeCenter",true)){centralBinStrip = nBinsX / 2 + 1;}
00432     else {
00433       double pAxisSymmetryValue = ps.getParameter         <double>("axisSymmetryValue");
00434       getBinCoordinateOnAxisWithValue(diffHist, pAxisSymmetryValue, centralBinStrip, 1);  
00435     }
00436     
00437     // Assuming odd number of strips --> first comparison is middle strip to itself
00438     int upBinStrip  = centralBinStrip;
00439     int lowBinStrip = centralBinStrip; 
00440 
00441     // If even number decrease lowBinstrip by one
00442     if(nBinsX%2==0){lowBinStrip--;}
00443     
00444     // Do we have enough statistics? Min(Max(strip_i,strip_j))>threshold
00445     double* maxAvgs = new double[maxBinStrip-upBinStrip+1];
00446     int nActualStrips=0; //number of strips that are not fully masked
00447     for(int i=0, j=upBinStrip, k=lowBinStrip;j<=maxBinStrip;i++,j++,k--) {
00448       double avg1 = getAvrg(diffHist,iTestName,pAxis,nBinsY,j,pAverageMode);
00449       double avg2 = getAvrg(diffHist,iTestName,pAxis,nBinsY,k,pAverageMode);
00450       
00451       // Protection for when both strips are masked
00452       if(!hservice_->isStripMasked(iTestName,j,pAxis) && !hservice_->isStripMasked(iTestName,k,pAxis)) {
00453         maxAvgs[i] = TMath::Max(avg1,avg2);
00454         nActualStrips++;
00455       }
00456     }
00457     
00458     vector<double> defaultMu0up;
00459     defaultMu0up.push_back(13.7655);
00460     defaultMu0up.push_back(184.742);
00461     defaultMu0up.push_back(50735.3);
00462     defaultMu0up.push_back(-97.6793);
00463         
00464     TF1* tf = new TF1("myFunc","[0]*(TMath::Log(x*[1]+[2]))+[3]",10.,11000.);
00465     vector<double> params = ps.getUntrackedParameter< vector<double> >("params_mu0_up",defaultMu0up);
00466     for(unsigned int i=0;i<params.size();i++) {tf->SetParameter(i,params[i]);}
00467     int statsup = (int)tf->Eval(hservice_->getNBinsHistogram(iTestName));
00468 
00469     vector<double> defaultMu0low;
00470     defaultMu0low.push_back(2.19664);
00471     defaultMu0low.push_back(1.94546);
00472     defaultMu0low.push_back(-99.3263);
00473     defaultMu0low.push_back(19.388);
00474     
00475     params = ps.getUntrackedParameter<vector<double> >("params_mu0_low",defaultMu0low);
00476     for(unsigned int i=0;i<params.size();i++) {tf->SetParameter(i,params[i]);}
00477     int statslow = (int)tf->Eval(hservice_->getNBinsHistogram(iTestName));
00478     
00479     if(verbose_) {
00480       cout << "nbins: "   << hservice_->getNBinsHistogram(iTestName) << endl;
00481       cout << "statsup= " << statsup << ", statslow= " << statslow << endl;
00482     }
00483     
00484     enoughStats = TMath::MinElement(nActualStrips,maxAvgs)>TMath::Max(statsup,statslow);
00485     if(verbose_) {
00486       cout << "stats: " << TMath::MinElement(nActualStrips,maxAvgs) << ", statsAvg: " << diffHist->GetEntries()/hservice_->getNBinsHistogram(iTestName) << ", threshold: " << TMath::Max(statsup,statslow) << endl;
00487     }
00488     
00489     //if enough statistics
00490     //make the test
00491     if(enoughStats) {
00492       for(;upBinStrip<=maxBinStrip;upBinStrip++,lowBinStrip--) {
00493         double avg = getAvrg(diffHist, iTestName, pAxis, nBinsY, upBinStrip, pAverageMode);
00494         compareWithStrip(diffHist,iTestName,lowBinStrip,nBinsY,pAxis,avg,ps,deadChannels); //compare with lower side
00495         
00496         avg = getAvrg(diffHist, iTestName, pAxis, nBinsY, lowBinStrip, pAverageMode);
00497         compareWithStrip(diffHist,iTestName,upBinStrip,nBinsY,pAxis,avg,ps,deadChannels); //compare with upper side
00498       }
00499     }
00500   }
00501   
00502   // pAxis==2 : Means symetry pAxis is horizontal
00503   else if(pAxis==2) {
00504     int maxBinStrip, centralBinStrip; //x-coordinate of strips
00505     
00506     maxBinStrip = nBinsY;
00507     
00508     // Determine center of diagram: either with set pAxis or middle of diagram
00509     if(ps.getUntrackedParameter<bool>("takeCenter",true)){centralBinStrip = nBinsY / 2 + 1;}
00510     else {
00511       double pAxisSymmetryValue = ps.getParameter<double>("axisSymmetryValue");
00512       getBinCoordinateOnAxisWithValue(diffHist, pAxisSymmetryValue, centralBinStrip, 2);
00513       
00514     }
00515     
00516     //assuming odd number of strips --> first comparison is middle strip to itself
00517     int lowBinStrip = centralBinStrip, upBinStrip = centralBinStrip;
00518     
00519     //if even number
00520     if(nBinsX%2==0) {
00521       //decrease lowBinstrip by one
00522       lowBinStrip--; 
00523     }
00524     
00525     //do we have enough statistics? Min(Max(strip_i,strip_j))>threshold
00526     double* maxAvgs = new double[maxBinStrip-upBinStrip+1];
00527     int nActualStrips = 0;
00528     for(int i=0, j=upBinStrip, k=lowBinStrip;j<=maxBinStrip;i++,j++,k--) {
00529       double avg1 = getAvrg(diffHist, iTestName, pAxis, nBinsX, j, pAverageMode);
00530       double avg2 = getAvrg(diffHist, iTestName, pAxis, nBinsX, k, pAverageMode);
00531       if(!hservice_->isStripMasked(iTestName,j,pAxis) && !hservice_->isStripMasked(iTestName,k,pAxis)) {
00532         maxAvgs[i] = TMath::Max(avg1,avg2);
00533         nActualStrips++;
00534       }
00535     }
00536     
00537     vector<double> defaultMu0up;
00538     defaultMu0up.push_back(13.7655);
00539     defaultMu0up.push_back(184.742);
00540     defaultMu0up.push_back(50735.3);
00541     defaultMu0up.push_back(-97.6793);
00542         
00543     vector<double> params = ps.getUntrackedParameter<std::vector<double> >("params_mu0_up",defaultMu0up);
00544     TF1* tf = new TF1("myFunc","[0]*(TMath::Log(x*[1]+[2]))+[3]",10.,11000.);
00545     for(unsigned int i=0;i<params.size();i++) {
00546       tf->SetParameter(i,params[i]);
00547     }
00548     int statsup = (int)tf->Eval(hservice_->getNBinsHistogram(iTestName));
00549     
00550     vector<double> defaultMu0low;
00551     defaultMu0low.push_back(2.19664);
00552     defaultMu0low.push_back(1.94546);
00553     defaultMu0low.push_back(-99.3263);
00554     defaultMu0low.push_back(19.388);
00555 
00556     params = ps.getUntrackedParameter<std::vector<double> >("params_mu0_low",defaultMu0low);
00557     for(unsigned int i=0;i<params.size();i++) {
00558       tf->SetParameter(i,params[i]);
00559     }
00560     int statslow = (int)tf->Eval(hservice_->getNBinsHistogram(iTestName));
00561     if(verbose_) {
00562       cout << "statsup= " << statsup << ", statslow= " << statslow << endl;
00563     }
00564     enoughStats = TMath::MinElement(nActualStrips,maxAvgs)>TMath::Max(statsup,statslow);
00565     if(verbose_) {
00566       cout << "stats: " << TMath::MinElement(nActualStrips,maxAvgs) << ", statsAvg: " << diffHist->GetEntries()/hservice_->getNBinsHistogram(iTestName) << ", threshold: " << TMath::Max(statsup,statslow) << endl;
00567     }
00568     
00569     //if we have enough statistics
00570     //make the test
00571     if(enoughStats) {
00572       for(;upBinStrip<=maxBinStrip;upBinStrip++,lowBinStrip--) {
00573         double avg = getAvrg(diffHist, iTestName, pAxis, nBinsX, upBinStrip, pAverageMode);
00574         compareWithStrip(diffHist,iTestName, lowBinStrip,nBinsX,pAxis,avg,ps,deadChannels); //compare with lower side
00575         
00576         avg = getAvrg(diffHist, iTestName, pAxis, nBinsX, lowBinStrip, pAverageMode);
00577         compareWithStrip(diffHist,iTestName, upBinStrip,nBinsX,pAxis,avg,ps,deadChannels); //compare with upper side
00578       }
00579     }
00580   }
00581   else {if(verbose_){cout << "Invalid axis" << endl;}}
00582     
00583   return (deadChannels.size()-hservice_->getNBinsMasked(iTestName))*1.0/hservice_->getNBinsHistogram(iTestName);
00584 }
00585 
00586 //____________________________________________________________________________
00587 // Function: getAvrg
00588 // Description: Calculate strip average with method iAvgMode, where strip is 
00589 // prependicular to iAxis at bin iBinStrip of histogram iHist
00590 // Inputs: 
00591 // * TH2F*  iHist     = Histogram to be tested
00592 // * string iTestName = Name of the test
00593 // * int    iAxis     = Axis prependicular to plot symmetry
00594 // * int    iNBins     = Number of bins in the strip
00595 // * int    iBinStrip = Bin corresponding to the strip in iAxis
00596 // * int    iAvgMode  = Type of average mode 1) Average 2) Median
00597 // Outputs:
00598 // * double = Average of input strip
00599 //____________________________________________________________________________
00600 double L1TOccupancyClient::getAvrg(TH2F* iHist, string iTestName, int iAxis, int iNBins, int iBinStrip, int iAvgMode) {
00601 
00602   double avg = 0.0;
00603   TH1D* proj = NULL;
00604   TH2F* histo = (TH2F*) iHist->Clone();
00605 
00606   std::vector<double> values;
00607   int marked;
00608 
00609   if(iAxis==1) {
00610 
00611     switch(iAvgMode) {
00612 
00613       // arithmetic average
00614       case 1: 
00615         marked = hservice_->maskBins(iTestName,histo,iBinStrip,iAxis);
00616         proj   = histo->ProjectionX();
00617         avg    = proj->GetBinContent(iBinStrip)/(iNBins-marked);
00618         break;
00619 
00620       // median
00621       case 2:
00622         marked = hservice_->maskBins(iTestName,histo,iBinStrip,iAxis);
00623         proj = histo->ProjectionY("_py",iBinStrip,iBinStrip);
00624         for(int i=0;i<iNBins;i++) {
00625           values.push_back(proj->GetBinContent(i+1));
00626         }
00627         avg = TMath::Median(iNBins,&values[0]);
00628         break;
00629       default:
00630         if(verbose_){cout << "Invalid averaging mode!" << endl;}
00631         break;
00632     }
00633   }
00634   else if(iAxis==2) {
00635 
00636     switch(iAvgMode) {
00637       // arithmetic average
00638       case 1:
00639         marked = hservice_->maskBins(iTestName,histo,iBinStrip,iAxis);
00640         proj = histo->ProjectionY();
00641         avg = proj->GetBinContent(iBinStrip)/(iNBins-marked);
00642         break;
00643       // median
00644       case 2:
00645         marked = hservice_->maskBins(iTestName,histo,iBinStrip,iAxis);
00646         proj = histo->ProjectionX("_px",iBinStrip,iBinStrip);
00647         for(int i=0;i<iNBins;i++) {
00648           values.push_back(proj->GetBinContent(i+1));
00649         }
00650       
00651         avg = TMath::Median(iNBins,&values[0]);
00652         break;
00653       default: 
00654         if(verbose_) { cout << "invalid averaging mode!" << endl;}
00655         break;
00656     }
00657   }
00658   else {
00659     if(verbose_) {cout << "invalid axis" << endl;}
00660   }
00661   delete histo;
00662   delete proj;
00663   return avg;
00664 }
00665 
00666 //____________________________________________________________________________
00667 // Function: printDeadChannels
00668 // Description: 
00669 // Inputs: 
00670 // * vector< pair<int,double> > iDeadChannels     = List of bin that are masked of failed tthe test
00671 // * TH2F*                      oHistDeadChannels = Histogram where test results should be printed
00672 // * vector< pair<int,double> > statDev           = ???
00673 // * string                     iTestName         = Name of the test
00674 //____________________________________________________________________________
00675 void L1TOccupancyClient::printDeadChannels(vector< pair<int,double> > iDeadChannels, TH2F* oHistDeadChannels, vector<std::pair<int,double> > statDev, string iTestName) {
00676 
00677   // Reset the dead channels histogram
00678   oHistDeadChannels->Reset();
00679   if(verbose_) {cout << "suspect or masked channels of " << iTestName << ": ";}
00680 
00681   int x,y,z;
00682   float chi2 = 0.0;
00683 
00684   // put all bad (value=1) and masked (value=-1) cells in histo
00685   for (std::vector<pair<int,double> >::const_iterator it = iDeadChannels.begin(); it != iDeadChannels.end(); it++) {
00686 
00687     int bin = (*it).first;
00688     oHistDeadChannels->GetBinXYZ(bin,x,y,z);
00689 
00690     if(hservice_->isMasked(iTestName,x,y)){
00691       oHistDeadChannels->SetBinContent(bin,-1); 
00692       if(verbose_){printf("(%4i,%4i) Masked\n",x,y);}
00693     }
00694     else{
00695       oHistDeadChannels->SetBinContent(bin, 1); 
00696       if(verbose_){printf("(%4i,%4i) Failed test\n",x,y);}
00697     }
00698   }
00699 
00700   // FIXME: Is this needed?
00701   for (std::vector<pair<int,double> >::const_iterator it = statDev.begin(); it != statDev.end(); it++) {
00702     double dev = (*it).second;
00703     chi2 += dev;
00704   }
00705   //put total chi2 in float
00706 
00707   if(verbose_) {
00708    cout << "total number of suspect channels: " << (iDeadChannels.size()-(hservice_->getNBinsMasked(iTestName))) << endl;
00709   }
00710 }
00711 
00712 //____________________________________________________________________________
00713 // Function: compareWithStrip
00714 // Description: Evaluates statistical compatibility of a strip (cell by cell) against a given average
00715 // Inputs: 
00716 // * TH2F*                      iHist      = Histogram to be tested
00717 // * string                     iTestName  = Which test to apply
00718 // * int                        iBinStrip  = Bin Coordinate (in bin units) of the stripo
00719 // * int                        iNBins     = Number of Bins in the strip
00720 // * int                        iAxis      = Which Axis is prependicular to the plot symmetry.
00721 // * double                     iAvg       = Average of the strip
00722 // * ParameterSet               iPS        = Parameters for the test
00723 // * vector<pair<int,double> >& oChannels  = Output of bin that are masked or failed the test
00724 // Outputs:
00725 // * int = Number of dead channels
00726 //____________________________________________________________________________
00727 int L1TOccupancyClient::compareWithStrip(TH2F* iHist, string iTestName, int iBinStrip, int iNBins, int iAxis, double iAvg, ParameterSet iPS, vector<pair<int,double> >& oChannels) {
00728 
00729   int dead = 0;
00730   
00731   //
00732   if(iAxis==1) {
00733         
00734     // Get and set parameters for working curves
00735     TF1* fmuup  = new TF1("fmuup" ,"TMath::Log(TMath::PoissonI(x,[0])/TMath::PoissonI(x,[1]))",-10000.,10000.);
00736     TF1* fmulow = new TF1("fmulow","TMath::Log(TMath::PoissonI(x,[0])/TMath::PoissonI(x,[1]))",-10000.,10000.);
00737     fmuup ->SetParameter(0,iAvg*iPS.getUntrackedParameter<double>("factorup",2.0));
00738     fmuup ->SetParameter(1,iAvg);
00739     fmulow->SetParameter(0,iAvg*iPS.getUntrackedParameter<double>("factorlow",0.1));
00740     fmulow->SetParameter(1,iAvg);
00741     
00742     TF1* fchi = new TF1("fchi","[0]*x**2+[1]*x+[2]",0.,1500.);
00743     
00744     // Evaluate sigma up
00745     vector<double> defaultChi2up;
00746     defaultChi2up.push_back(5.45058e-05);
00747     defaultChi2up.push_back(0.268756);
00748     defaultChi2up.push_back(-11.7515);
00749     
00750     vector<double> params = iPS.getUntrackedParameter< vector<double> >("params_chi2_up",defaultChi2up);
00751     for(unsigned int i=0; i<params.size(); i++){fchi->SetParameter(i,params[i]);}
00752     double sigma_up = fchi->Eval(iAvg);
00753 
00754     // Evaluate sigma low
00755     vector<double> defaultChi2low;
00756     defaultChi2low.push_back(4.11095e-05);
00757     defaultChi2low.push_back(0.577451);
00758     defaultChi2low.push_back(-10.378);
00759     
00760     params = iPS.getUntrackedParameter< vector<double> >("params_chi2_low",defaultChi2low);
00761     for(unsigned int i=0; i<params.size(); i++){fchi->SetParameter(i,params[i]);}
00762     double sigma_low = fchi->Eval(iAvg);
00763     
00764     if(verbose_){cout << "binstrip= " << iBinStrip << ", sigmaup= " << sigma_up << ", sigmalow= " << sigma_low << endl;}
00765     
00766     for(int i=1;i<=iNBins;i++) {
00767       if(verbose_) {
00768         cout << "    " << i << " binContent: up:" << fmuup ->Eval(iHist->GetBinContent(iBinStrip,i)) 
00769                             << " low: "           << fmulow->Eval(iHist->GetBinContent(iBinStrip,i)) << endl;
00770       }
00771       
00772       // Evaluate chi2 for cells
00773       double muup  = fmuup ->Eval(iHist->GetBinContent(iBinStrip,i));
00774       double mulow = fmulow->Eval(iHist->GetBinContent(iBinStrip,i));
00775       
00776       // If channel is masked -> set it to value -1
00777       if(hservice_->isMasked(iTestName,iBinStrip,i)) {
00778         oChannels.push_back(pair<int,double>(iHist->GetBin(iBinStrip,i),-1.0));
00779       }
00780       //else perform test
00781       else if(muup  > sigma_up || 
00782               mulow > sigma_low || 
00783               ((fabs(muup)  == std::numeric_limits<double>::infinity()) && (
00784                 fabs(mulow) == std::numeric_limits<double>::infinity()))) {
00785         dead++;
00786         oChannels.push_back(pair<int,double>(iHist->GetBin(iBinStrip,i),abs(iHist->GetBinContent(iBinStrip,i)-iAvg)/iAvg));
00787       }
00788     }
00789   }
00790   // 
00791   else if(iAxis==2){
00792         
00793     //get and set parameters for working curves
00794     TF1* fmuup  = new TF1("fmuup" ,"TMath::Log(TMath::PoissonI(x,[0])/TMath::PoissonI(x,[1]))",-10000.,10000.);
00795     TF1* fmulow = new TF1("fmulow","TMath::Log(TMath::PoissonI(x,[0])/TMath::PoissonI(x,[1]))",-10000.,10000.);
00796     fmuup ->SetParameter(0,iAvg*iPS.getUntrackedParameter<double>("factorup",2.0));
00797     fmuup ->SetParameter(1,iAvg);
00798     fmulow->SetParameter(0,iAvg*iPS.getUntrackedParameter<double>("factorlow",0.1));
00799     fmulow->SetParameter(1,iAvg);
00800     
00801     TF1* fchi = new TF1("fchi","[0]*x**2+[1]*x+[2]",0.,1500.);
00802     
00803     // Evaluate sigma up
00804     vector<double> defaultChi2up;
00805     defaultChi2up.push_back(5.45058e-05);
00806     defaultChi2up.push_back(0.268756);
00807     defaultChi2up.push_back(-11.7515);
00808     
00809     vector<double> params = iPS.getUntrackedParameter<vector<double> >("params_chi2_up",defaultChi2up);
00810     for(unsigned int i=0;i<params.size();i++){fchi->SetParameter(i,params[i]);}
00811     double sigma_up = fchi->Eval(iAvg);
00812 
00813     // Evaluate sigma low
00814     vector<double> defaultChi2low;
00815     defaultChi2low.push_back(4.11095e-05);
00816     defaultChi2low.push_back(0.577451);
00817     defaultChi2low.push_back(-10.378);
00818 
00819     params = iPS.getUntrackedParameter<vector<double> >("params_chi2_low",defaultChi2low);
00820     for(unsigned int i=0;i<params.size();i++){fchi->SetParameter(i,params[i]);}
00821     double sigma_low = fchi->Eval(iAvg);
00822     
00823     if(verbose_) {cout << "binstrip= " << iBinStrip << ", sigmaup= " << sigma_up << ", sigmalow= " << sigma_low << endl;}
00824 
00825     for(int i=1;i<=iNBins;i++) {
00826       if(verbose_) {
00827         cout << "    " << i << " binContent: up:" << fmuup ->Eval(iHist->GetBinContent(i,iBinStrip)) 
00828                             << " low: "           << fmulow->Eval(iHist->GetBinContent(i,iBinStrip)) << endl;
00829       }
00830       
00831       //evaluate chi2 for cells
00832       double muup  = fmuup ->Eval(iHist->GetBinContent(i,iBinStrip));
00833       double mulow = fmulow->Eval(iHist->GetBinContent(i,iBinStrip));
00834       
00835       //if channel is masked -> set it to value -1
00836       if(hservice_->isMasked(iTestName,i,iBinStrip)) {
00837         oChannels.push_back(pair<int,double>(iHist->GetBin(iBinStrip,i),-1.0));
00838       }
00839       //else perform test
00840       else if(muup > sigma_up ||  
00841               mulow > sigma_low || 
00842             ((fabs(muup) == std::numeric_limits<double>::infinity()) && 
00843             (fabs(mulow) == std::numeric_limits<double>::infinity()))) {
00844         dead++;
00845         oChannels.push_back(pair<int,double>(iHist->GetBin(i,iBinStrip),abs(iHist->GetBinContent(i,iBinStrip)-iAvg)/iAvg));
00846       }
00847     }
00848   }
00849   else {if(verbose_) {cout << "invalid axis" << endl;}}
00850   
00851   return dead;
00852 }
00853 
00854 //____________________________________________________________________________
00855 // Function: getBinCoordinateOnAxisWithValue
00856 // Description: Returns the bin global bin number with the iValue in the iAxis 
00857 // Inputs: 
00858 // * TH2F*  iHist          = Histogram to be tested
00859 // * double iValue         = Value to be evaluated in the histogram iHist
00860 // * int&   oBinCoordinate = (output) bin number (X or Y) for iValue 
00861 // * int    iAxis          = Axis to be used
00862 //____________________________________________________________________________
00863 void L1TOccupancyClient::getBinCoordinateOnAxisWithValue(TH2F* iHist, double iValue, int& oBinCoordinate, int iAxis) {
00864 
00865   int nBinsX = iHist->GetNbinsX(); //actual number of bins x
00866   int nBinsY = iHist->GetNbinsY(); //actual number of bins y
00867   
00868   if(iAxis==1){
00869     int global = iHist->GetXaxis()->FindFixBin(iValue);
00870     
00871     // If parameter exceeds axis' value: set to maximum number of bins in x-axis
00872     if(global > nBinsX*nBinsY) {global = iHist->GetXaxis()->GetLast();}
00873     
00874     // Get coordinates of bin
00875     int y,z;
00876     iHist->GetBinXYZ(global,oBinCoordinate,y,z);
00877   }
00878   else if(iAxis==2){
00879     int global = iHist->GetYaxis()->FindFixBin(iValue);
00880     
00881     // If parameter exceeds axis' value: set to maximum number of bins in x-axis
00882     if(global > nBinsX*nBinsY) {global = iHist->GetYaxis()->GetLast();}
00883     
00884     // Get coordinates of bin
00885     int x,z;
00886     iHist->GetBinXYZ(global,x,oBinCoordinate,z);
00887   }
00888 }
00889 
00890 //define this as a plug-in
00891 DEFINE_FWK_MODULE(L1TOccupancyClient);