Beispiel #1
1
TH1* GetOne(UShort_t sNN, const TString& trigger)
{
  Long_t   p = gROOT->ProcessLine(Form("Drawer::GetStack(0, \"pp\", %d, "
				       "\"%s\", false, true)", 
				       sNN, trigger.Data()));
  THStack* s = (THStack*)p;
  TList*   l = s->GetHists();
  TH1*     h = 0;
  TIter    n(l);
  l->ls();
  while ((h = static_cast<TH1*>(n()))) {
    TString m(h->GetName());
    if (m.EqualTo("dndetaForward_all")) break;
  }

  if (h) {
    switch (sNN) { 
    case  900: h->SetTitle("900GeV");  h->SetMarkerColor(kRed+2);   break;
    case 2760: h->SetTitle("2.76TeV"); h->SetMarkerColor(kGreen+2); break;
    case 7000: h->SetTitle("7TeV");    h->SetMarkerColor(kBlue+2);  break;
    case 8000: h->SetTitle("8TeV");    h->SetMarkerColor(kBlack);   break;
    }
  }

  return h;
}
Beispiel #2
0
void fancyMerge( std::string beam, std::string target, std::string energy, std::string physlist, bool doScale=false )
{
      
   std::string output = beam + target + energy + "GeV" + physlist + ".root" ;
   
   targetFile = TFile::Open( output.c_str(), "RECREATE" );
   
   double scale = 1./32.;
   
   // std::string input = beam + target + model + energy + "GeV-1.root";
   // std::string input = "../t23-bld/harp-histo-no-res-decays/" + beam + target + energy + "GeV" + physlist +"-1.root";

   // std::string input = "../t23-bld/harp-histo/" + beam + target + energy + "GeV" + physlist +"-1.root";

   std::string input = "../t23-bld/na49-histo/" + beam + target + energy + "GeV" + physlist +"-1.root";
   
   TFile* iFile1 = TFile::Open( input.c_str() );
   TIter  next( iFile1->GetListOfKeys() );
   TKey*  key = (TKey*)next();
   TH1* h = 0;
   while ( key )
   {   
         if ( !(TClass::GetClass(key->GetClassName())->InheritsFrom(TH1::Class())) ) continue;
         const char* kName = key->GetName();
         h = (TH1*)key->ReadObj();
         const char* hName = h->GetName();
         std::cout << " histoname = " << hName << std::endl;
	 TH1F* h1 = h->Clone();
	 for ( int id=2; id<=32; id++ )
	 {
	    // std::string input_t = "../t23-bld/harp-histo-no-res-decays/" + beam + target + energy + "GeV" + physlist + "-" ;
	    // std::string input_t = "../t23-bld/harp-histo/" + beam + target + energy + "GeV" + physlist + "-" ;
	    std::string input_t = "../t23-bld/na49-histo/" + beam + target + energy + "GeV" + physlist + "-" ;
            char buf[5];
            sprintf( buf, "%i", id );
            input_t.append( buf ); 
            input_t += ".root"; 
	    TFile* iFile_t = TFile::Open( input_t.c_str() );
	    TH1F* h_t = (TH1F*)iFile_t->Get( h->GetName() );
	    h1->Add( h_t );  
	    iFile_t->Close();
	 }
	 if ( doScale )
	 {
	    if (!(strcmp(key->GetClassName(),"TProfile"))) h1->Scale( scale );
	 }
	 targetFile->cd();
	 h1->Write();
         key = (TKey*)next();
   }
   
   targetFile->Close();
     
   return;

}
void counts(int run, int lumistart, int lumiend, string type, map<string,vector<tripletI> > &cnt, vector<tripletD> &cntref, string hlttype, bool docnt, bool doref) {
   TString filename = basedir + Form("/DQM_V0001_HLTpb_R000%i.root",run);
   TFile *f = new TFile(filename);
   if (!f->IsOpen()) {
      cout << "Error, could not open " << filename << endl;
      return;
   }
   TString tdirname = Form("DQMData/Run %i/HLT/Run summary/TriggerRates/",run) + TString(type);
   f->cd(tdirname);
   TProfile *hlumi = (TProfile*) f->Get(Form("DQMData/Run %i/HLT/Run summary/LumiMonitoring/lumiVsLS",run));
   if (extrapol) extrapolate(hlumi);

   // if HLT: accept, error, pass L1 seed, pass prescaler, reject

   TIter next(gDirectory->GetListOfKeys());
   TKey *key;
   while ((key = (TKey*)next())) {
      TClass *cl = gROOT->GetClass(key->GetClassName());
      
      // it must be an histogram
      if (!cl->InheritsFrom("TH1")) continue;
      TH1 *h = (TH1*)key->ReadObj();

      // the name must match one of the requested patterns
      bool match=false; TString hname(h->GetName());
      for (vector<TRegexp>::const_iterator it=patterns.begin(); it!=patterns.end(); it++) {
         if (hname(*it).Length()!=0) {
            match=true;
            break;
         }
      }
      if (!match) continue;

      int nlumis = (lumiend+1-lumistart);

      if (extrapol) extrapolate(h);

      if (type != "HLT") fill(cnt[h->GetName()], h, run, lumistart, lumiend, docnt);
      else {
         string htitle(h->GetTitle());
         if (htitle.find(hlttype) == string::npos) continue;
         else {
            TString thepath; Ssiz_t from=0; TString(htitle).Tokenize(thepath,from," ");
            fill(cnt[thepath.Data()], h, run, lumistart, lumiend, docnt);
         }
      }
   }

   if (doref) {
      fill(cntref, hlumi, run, lumistart, lumiend);
   }

   f->Close();
   delete f;
}
Beispiel #4
0
// echo object at mouse position
void exec1()
{
   //example of macro called when a pad is redrawn
   //one must create a TExec object in the following way
   // TExec ex("ex",".x exec1.C");
   // ex.Draw();
   // this macro prints the bin number and the bin content when one clicks
   //on the histogram contour of any histogram in a pad
   //Author: Rene Brun
   
   if (!gPad) {
      Error("exec1", "gPad is null, you are not supposed to run this macro");
      return;
   }
   
   int event = gPad->GetEvent();
   if (event != 11) return;
   int px = gPad->GetEventX();
   TObject *select = gPad->GetSelected();
   if (!select) return;
   if (select->InheritsFrom(TH1::Class())) {
      TH1 *h = (TH1*)select;
      Float_t xx = gPad->AbsPixeltoX(px);
      Float_t x  = gPad->PadtoX(xx);
      Int_t binx = h->GetXaxis()->FindBin(x);
      printf("event=%d, hist:%s, bin=%d, content=%f\n",event,h->GetName(),binx,h->GetBinContent(binx));
   }
}
Beispiel #5
0
  void initialize( const char* countdbfn = "counts.root" )
  {
    XSWeightTool::update( "Xsection8TeV_bkg_v4.txt" );
    XSWeightTool::update( "Xsection8TeV_sig_v4.txt" );
    // XSWeightTool::print();

    using namespace std;

    TFile* f = TFile::Open( countdbfn, "read" );
    if( f == NULL || f->IsZombie() )
    {
      return;
    }

    TIter next( f->GetListOfKeys() ); 
    TKey *key;
    int nhist = 0;
    while( (key = (TKey*)next()) ) {
      nhist++;
      // cout << "Key " << nhist << endl;
      // cout << " Classname " << key->GetClassName() << endl;
      // cout << " Title " <<key->GetTitle() << endl;
      if( key->ReadObj()->InheritsFrom( TH1::Class() ) )
      {
	TH1* h = (TH1*)( key->ReadObj() );
	long run_num = TString( h->GetName() ).Atoi();
	num_events[run_num] = h->GetBinContent( 1 );
	// cout << " Run, # of events : " << run_num << ", " <<  h->GetBinContent( 21 ) << endl;
      }
    }
    // cout << "Done" << endl;
  }
Beispiel #6
0
// -----------------------------------------------------------------------------
//
TH1* getHisto( std::string nameFile,
	       std::string nameHist,
	       std::string Dirname, 
	       int rebin ) {
  std::string name = nameFile;
  TFile* file =  new TFile(name.c_str());
  if (file) { std::cout << "Opened file: " << file->GetName() << std::endl; }
  else { 
    std::cout << "Could not find file: " << name << std::endl; 
    return 0; 
  }
  
  TDirectory* dir = (TDirectory*)file->Get(Dirname.c_str());
  if (dir) { std::cout << "Opened dir: " << dir->GetName() << std::endl; }
  else { 
    std::cout << "Could not find dir: " << Dirname << std::endl; 
    return 0; 
  }
  
  int low = 375;
  TH1* hist = 0;
  if ( false || nameHist.find("HtMultiplicity_HT375") == std::string::npos ) { 
    hist = (TH1*)dir->Get(nameHist.c_str());
  } else {
    
    for ( uint ii = low; ii <= 975; ii+=100 ) {
      std::stringstream tmp; tmp << "HtMultiplicity_HT" << ii << nameHist.substr(20);
      if ( !hist ) { 
	dir->cd();
	TH1D* temp = (TH1D*)dir->Get( "HtMultiplicity_HT375_aT0" );
	//TH1D* temp = (TH1D*)file->Get( tmp.str().c_str() );
	if (temp) { hist = (TH1D*)temp->Clone(); } 
	else { std::cout << "1 Unable to retrieve histo with name " << tmp.str() << std::endl; }
      } else { 
	dir->cd();
	TH1D* temp = (TH1D*)dir->Get( tmp.str().c_str() );
	if (temp) { hist->Add( (TH1D*)temp ); } 
	else { std::cout << "2 Unable to retrieve histo with name " << tmp.str() << std::endl; }
      }
    }

  }
  if (hist) { std::cout << "Opened histo: " << hist->GetName() << std::endl; }
  else { 
    std::cout << "Could not find histo: " << nameHist << std::endl; 
    return 0; 
  }

  hist->SetLineWidth(3);
  if ( rebin > 0 ) { hist->Rebin(rebin); }
  hist->GetXaxis()->SetTitleSize(0.055);
  hist->GetYaxis()->SetTitleSize(0.055);
  hist->GetXaxis()->SetLabelSize(0.05);
  hist->GetYaxis()->SetLabelSize(0.05);
  hist->SetStats(kFALSE);
  return hist;
}
RooHistN::RooHistN(const TH1 &data1, const TH1 &data2, Double_t nominalBinWidth, Double_t nSigma, Double_t xErrorFrac) :
  TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
{
  // Create a histogram from the asymmetry between the specified TH1 objects
  // which may have fixed or variable bin widths, but which must both have
  // the same binning. The asymmetry is calculated as (1-2)/(1+2). Error bars are
  // calculated using Binomial statistics. Prints a warning and rounds
  // any bins with non-integer contents. Use the optional parameter to
  // specify the confidence level in units of sigma to use for
  // calculating error bars. The nominal bin width specifies the
  // default used by addAsymmetryBin(), and is used to set the relative
  // normalization of bins with different widths. If not set, the
  // nominal bin width is calculated as range/nbins.

  initialize();
  // copy the first input histogram's name and title
  SetName(data1.GetName());
  SetTitle(data1.GetTitle());
  // calculate our nominal bin width if necessary
  if(_nominalBinWidth == 0) {
    const TAxis *axis= ((TH1&)data1).GetXaxis();
    if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
  }
  setYAxisLabel(Form("Asymmetry (%s - %s)/(%s + %s)",
		     data1.GetName(),data2.GetName(),data1.GetName(),data2.GetName()));
  // initialize our contents from the input histogram contents
  Int_t nbin= data1.GetNbinsX();
  if(data2.GetNbinsX() != nbin) {
    coutE(InputArguments) << "RooHistN::RooHistN: histograms have different number of bins" << endl;
    return;
  }
  for(Int_t bin= 1; bin <= nbin; bin++) {
    Axis_t x= data1.GetBinCenter(bin);
    if(fabs(data2.GetBinCenter(bin)-x)>1e-10) {
      coutW(InputArguments) << "RooHistN::RooHistN: histograms have different centers for bin " << bin << endl;
    }
    Stat_t y1= data1.GetBinContent(bin);
    Stat_t y2= data2.GetBinContent(bin);
    addAsymmetryBin(x,roundBin(y1),roundBin(y2),data1.GetBinWidth(bin),xErrorFrac);
  }
  // we do not have a meaningful number of entries
  _entries= -1;
}
Beispiel #8
0
TH1 *MillePedeTrees::CreateHist(const char *exp, const char *selection, const char *hDef,
                                Option_t* opt)
{
  TH1 *h = this->Draw(exp, selection, hDef, "goff");

  TH1 *hResult = static_cast<TH1*>(h->Clone(Form("%sC", h->GetName())));
  if (opt) hResult->SetOption(opt);

  return hResult;
}
Beispiel #9
0
void DrawTree( TTree& tree, TH1& hist, const char* branchname, 
               const std::string condition, const char* append = "") {

  gROOT->cd();

  std::string plot = std::string(branchname);
  plot.append(append);
  plot.append(hist.GetName());

  tree.Draw( plot.c_str(), condition.c_str(), "goff" );
}
Beispiel #10
0
TProfile *MillePedeTrees::CreateHistProf(const char *expX, const char *expY, const char *selection,
                                         const char *hDef, Option_t* opt)
{

  const TString combExpr(Form("%s:%s", expY, expX));
  TH1 *h = this->Draw(combExpr, selection, hDef, "goff prof");

  TProfile *hResult = static_cast<TProfile*>(h->Clone(Form("%sClone", h->GetName())));
  if (opt) hResult->SetOption(opt);

  return hResult;
}
Beispiel #11
0
void
HistoCompare::PVCompute(TH1 * oldHisto , TH1 * newHisto , TText * te )
{

  myoldHisto1 = oldHisto;
  mynewHisto1 = newHisto;
  myte = te;

  Double_t *res;

  Double_t mypv = myoldHisto1->Chi2Test(mynewHisto1,"WW",res);
  TString title = myoldHisto1->GetName();
  printRes(title, mypv, myte);
  return;

}
Beispiel #12
0
TH1* merge_histos(TList *sourcelist){
  TH1 *htot;

  TFile *first_source = (TFile*)sourcelist->First();
  TDirectory *current_sourcedir = gDirectory;
  //gain time, do not add the objects in the list in memory
  Bool_t status = TH1::AddDirectoryStatus();
  TH1::AddDirectory(kFALSE);
  
  
  // loop over all keys in this directory
  TChain *globChain = 0;
  TIter nextkey( current_sourcedir->GetListOfKeys() );
  TKey *key, *oldkey=0;
  while ( (key = (TKey*)nextkey())) {

    //keep only the highest cycle number for each key
    if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue;
    
    // read object from first source file
    TObject *obj = key->ReadObj();
    
    // if the object is named "tot_edp_hbcoil" merge it
    if ( obj->FindObject("Tot_Edep_HBCoil")) {

      //      cout << "Merging histogram " << obj->GetName() << endl;
      htot = (TH1*)obj;
      
      // loop over all source files and add the content of the
      // correspondant histogram to the one pointed to by "h1"
      TFile *nextsource = (TFile*)sourcelist->After( first_source );
      while ( nextsource ) {
	// make sure we are at the correct directory level by cd'ing to path
	TKey *key2 = (TKey*)gDirectory->GetListOfKeys()->FindObject(htot->GetName());
	if (key2) {
	  TH1 *htemp = (TH1*)key2->ReadObj();
	  htot->Add(htemp);
	  delete htemp;
	}
	
	nextsource = (TFile*)sourcelist->After( nextsource );
      }
    }   
  }

  return htot;
}
void showTauIsolation(TFile* inputFile, const TString& dqmDirectory, const TString& meName,
		      const char* dqmSubDirectoryTauJet, const char* dqmSubDirectoryMuon, const char* dqmSubDirectoryElectron,
		      TCanvas* canvas, TPostScript* ps, const char* outputFileLabel, bool useLogScale)
{
  canvas->SetLogy(useLogScale);

  TLegend legend(0.74, 0.71, 0.89, 0.89, "", "brNDC"); 
  legend.SetBorderSize(0);
  legend.SetFillColor(0);

  TH1* meTauJet = getMonitorElement(inputFile, dqmDirectory, dqmSubDirectoryTauJet, meName);
  meTauJet->SetMarkerStyle(20);
  meTauJet->SetMarkerColor(kRed);
  meTauJet->SetLineColor(kRed);
  meTauJet->Draw("e1p");
  legend.AddEntry(meTauJet, "#tau-Jet", "p");

  if ( dqmSubDirectoryMuon != "" ) {
    TH1* meMuon = getMonitorElement(inputFile, dqmDirectory, dqmSubDirectoryMuon, meName);
    meMuon->SetMarkerStyle(21);
    meMuon->SetMarkerColor(kBlue);
    meMuon->SetLineColor(kBlue);
    meMuon->Draw("e1psame");
    legend.AddEntry(meMuon, "#mu", "p");
  }

  if ( dqmSubDirectoryElectron != "" ) {
    TH1* meElectron = getMonitorElement(inputFile, dqmDirectory, dqmSubDirectoryElectron, meName);
    meElectron->SetMarkerStyle(23);
    meElectron->SetMarkerColor(kGreen);
    meElectron->SetLineColor(kGreen);
    meElectron->Draw("e1psame");
    legend.AddEntry(meElectron, "e", "p");
  }

  legend.Draw();

  canvas->Update();
  TString outputFileName = TString("plot").Append(meTauJet->GetName()).Append("_").Append(outputFileLabel).Append(".png");
  canvas->Print(outputFileName.Data());
  //ps->NewPage();
}
Beispiel #14
0
void exec1()
{
   if (!gPad) {
      Error("exec1", "gPad is null, you are not supposed to run this macro");
      return;
   }

   int event = gPad->GetEvent();
   if (event != 11) return;
   int px = gPad->GetEventX();
   TObject *select = gPad->GetSelected();
   if (!select) return;
   if (select->InheritsFrom(TH1::Class())) {
      TH1 *h = (TH1*)select;
      Float_t xx = gPad->AbsPixeltoX(px);
      Float_t x  = gPad->PadtoX(xx);
      Int_t binx = h->GetXaxis()->FindBin(x);
      printf("event=%d, hist:%s, bin=%d, content=%f\n",event,h->GetName(),binx,h->GetBinContent(binx));
   }
}
Beispiel #15
0
  // Do the loop here, so that we can use options like "errors"
  void Draw( const TString & xTitle = "", const TString & yTitle = "", const bool errors = false ) {

    // Create a new THStack so that it handle tha maximum
    // THStack stack(name_, title_);
    THStack * stack = new THStack(name_, title_);

    int colorIndex = 0;
    if( !(histoList_.empty()) ) {
      std::vector<TH1*>::iterator histoIter = histoList_.begin();
      for( ; histoIter != histoList_.end(); ++histoIter, ++colorIndex ) {
        TH1 * histo = *histoIter;
        if(errors) histo->Sumw2();
        // histo->SetNormFactor(1);
        if( colorIndex < 4 ) histo->SetLineColor(colors_[colorIndex]);
        else histo->SetLineColor(colorIndex);
        // Draw and get the maximum value
        TString normalizedHistoName(histo->GetName());
        TH1 * normalizedHisto = (TH1*)histo->Clone(normalizedHistoName+"clone");
        normalizedHisto->Scale(1/normalizedHisto->Integral());
        stack->Add(normalizedHisto);
      }
      // Take the maximum of all the drawed histograms
      // First we need to draw the histogram, or getAxis() will return 0... (see root code...)
      canvas_->Draw();
      canvas_->cd();
      stack->Draw("nostack");
      stack->GetYaxis()->SetTitleOffset(1.2);
      stack->GetYaxis()->SetTitle(yTitle);
      stack->GetXaxis()->SetTitle(xTitle);
      stack->GetXaxis()->SetTitleColor(kBlack);
      stack->Draw("nostack");
      legend_->Draw("same");

      canvas_->Update();
      canvas_->Draw();
      canvas_->ForceUpdate();
      //canvas_->Print("test.pdf");
      canvas_->Write();

    }
  }
TH1* getHistogram(TFile* inputFile, const TString& meName, TObjArray& processes, const TString& region)
{
  TH1* histogram_sum = 0;
  
  int numProcesses = processes.GetEntries();
  for ( int iProcess = 0; iProcess < numProcesses; ++iProcess ) {
    TObjString* process = dynamic_cast<TObjString*>(processes.At(iProcess));
    assert(process);
    TH1* histogram = getHistogram(inputFile, meName, process->GetString(), region);
    if ( !histogram_sum ) {
      TString histogramName_sum = histogram->GetName();
      histogramName_sum = histogramName_sum.ReplaceAll(process->GetString(), "sum");
      histogram_sum = (TH1*)histogram->Clone(histogramName_sum.Data());
      if ( !histogram_sum->GetSumw2N() ) histogram_sum->Sumw2();
    } else {
      histogram_sum->Add(histogram);
    }
  }

  return histogram_sum;
}
Beispiel #17
0
RooHistN::RooHistN(const TH1 &data, Double_t nominalBinWidth, Double_t nSigma, RooAbsData::ErrorType etype, Double_t xErrorFrac) :
  TGraphAsymmErrors(), _nominalBinWidth(nominalBinWidth), _nSigma(nSigma), _rawEntries(-1)
{
  // Create a histogram from the contents of the specified TH1 object
  // which may have fixed or variable bin widths. Error bars are
  // calculated using Poisson statistics. Prints a warning and rounds
  // any bins with non-integer contents. Use the optional parameter to
  // specify the confidence level in units of sigma to use for
  // calculating error bars. The nominal bin width specifies the
  // default used by addBin(), and is used to set the relative
  // normalization of bins with different widths. If not set, the
  // nominal bin width is calculated as range/nbins.

  initialize();
  // copy the input histogram's name and title
  SetName(data.GetName());
  SetTitle(data.GetTitle());
  // calculate our nominal bin width if necessary
  if(_nominalBinWidth == 0) {
    const TAxis *axis= ((TH1&)data).GetXaxis();
    if(axis->GetNbins() > 0) _nominalBinWidth= (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
  }
  // TH1::GetYaxis() is not const (why!?)
  setYAxisLabel(const_cast<TH1&>(data).GetYaxis()->GetTitle());
  
  // initialize our contents from the input histogram's contents
  Int_t nbin= data.GetNbinsX();
  for(Int_t bin= 1; bin <= nbin; bin++) {
    Axis_t x= data.GetBinCenter(bin);
    Stat_t y= data.GetBinContent(bin);
    Stat_t dy = data.GetBinError(bin) ;
    if (etype==RooAbsData::Poisson) {
      addBin(x,roundBin(y),data.GetBinWidth(bin),xErrorFrac);
    } else {
      addBinWithError(x,y,dy,dy,data.GetBinWidth(bin),xErrorFrac);
    }
  }
  // add over/underflow bins to our event count
  _entries+= data.GetBinContent(0) + data.GetBinContent(nbin+1);
}
void boostcontrolplots( TDirectory *boostdir ) {

   const Int_t nPlots = 4;

   Int_t width  = 900;
   Int_t height = 600;
   char cn[100];
   const TString titName = boostdir->GetName();
   sprintf( cn, "cv_%s", titName.Data() );
   TCanvas *c = new TCanvas( cn,  Form( "%s Control Plots", titName.Data() ),
                             width, height ); 
   c->Divide(2,2);


   const TString titName = boostdir->GetName();

   TString hname[nPlots]={"Booster_BoostWeight","Booster_MethodWeight","Booster_ErrFraction","Booster_OrigErrFraction"};

   for (Int_t i=0; i<nPlots; i++){
      Int_t color = 4; 
      TPad * cPad = (TPad*)c->cd(i+1);
      TH1 *h = (TH1*) boostdir->Get(hname[i]);
      TString plotname = h->GetName();
      h->SetMaximum(h->GetMaximum()*1.3);
      h->SetMinimum( 0 );
      h->SetMarkerColor(color);
      h->SetMarkerSize( 0.7 );
      h->SetMarkerStyle( 24 );
      h->SetLineWidth(1);
      h->SetLineColor(color);
      h->Draw();
      c->Update();
   }

   // write to file
   TString fname = Form( "plots/%s_ControlPlots", titName.Data() );
   TMVAGlob::imgconv( c, fname );
   
}
Beispiel #19
0
void writeFile(const char* inRootFile)
{
  TFile inRoot(inRootFile);
  if(!inRoot.IsOpen()){
    cout << "Cannot open " << inRootFile << endl;
    return;
  }
  TIterator* iterator = inRoot.GetListOfKeys()->MakeIterator();
  TKey* key;

  TString outText = inRootFile;
  outText.Replace(0,outText.Last('/')+1,"");

  ofstream os(outText.Data());

  char buf[500];

  int count(0);
  while( (key=dynamic_cast<TKey*>(iterator->Next())) != 0){
    cout << key->GetName() << endl;
    TH1* h = (TH1*)inRoot.Get(key->GetName());
    if(h->GetDimension()!=1) continue;

    if(++count>1) break;

    int nBin = h->GetNbinsX();
    os << "name: " << h->GetName() << endl
       << "title: " << h->GetTitle() << endl
       << "bins: " << h->GetNbinsX() << endl
       << "min: " << h->GetXaxis()->GetBinLowEdge(1) 
       << ", max: " << h->GetXaxis()->GetBinUpEdge(h->GetNbinsX()) << endl;

    for(int i=1; i<=nBin; i++){
      os << "bin: " << i << " value: " << (float)h->GetBinContent(i)
	 << " error: " << (float)h->GetBinError(i) << endl;
    }
  }
   
}
Beispiel #20
0
cmsListDir( const TObjString * firstdirname, const TDirectory * firstDir )
 {
  TObjArray * dirs = new TObjArray ;
  dirs->AddLast(new TPair(firstdirname,firstDir)) ;
  TList * keys ;
  TKey * key ;
  TH1 * histo ;
  TIter nextDir(dirs) ;
  TPair * pair ;
  const TObjString * dirname ;
  const TDirectory * dir ;
  while (pair = (TPair *)nextDir())
   {
    dirname = (TObjString *)pair->Key() ;
    dir = (TDirectory *)pair->Value() ;
    keys = dir->GetListOfKeys() ;
    TIter nextKey(keys) ;
    while (key = (TKey *)nextKey())
     {
      obj = key->ReadObj() ;
      if (obj->IsA()->InheritsFrom("TDirectory"))
       {
        dirs->AddLast(new TPair(new TObjString(dirname->String()+"/"+obj->GetName()),obj)) ;
       }
      else if (obj->IsA()->InheritsFrom("TH1"))
       {
        histo = (TH1 *)obj ;
        std::cout
          <<"Histo "<<dirname->String()<<"/"<<histo->GetName()
          <<" has "<<histo->GetEffectiveEntries()<<" entries"
          <<" of mean value "<<histo->GetMean()
          <<std::endl ;
       }
      else
       { std::cout<<"What is "<<obj->GetName()<<" ?"<<std::endl ; }
     }
   }
 }
void patBJetTracks_efficiencies()
{
	// define proper canvas style
	setNiceStyle();
	gStyle->SetOptStat(0);

	// open file
	TFile* file = new TFile("analyzePatBJetTracks.root");

	TLegend *legend[3] = { 0, 0, 0 };

	// draw canvas with efficiencies

	TCanvas *canv;
	canv = new TCanvas("canv0", "hand-crafted track counting efficiencies", 800, 300);
	canv->Divide(3, 1);

	TH1 *total = (TH1*)file->Get(Form("%s/flavours", directory));
	TH1 *effVsCutB = 0;
	unsigned int i = 0;
	for(const char **flavour = flavours; *flavour; flavour++, i++) {
		TH1 *h = (TH1*)file->Get(Form("%s/trackIPSig_%s", directory, *flavour));
		TH1 *discrShape = (TH1*)h->Clone(Form("%s_discrShape", h->GetName()));
		discrShape->Scale(1.0 / discrShape->Integral());
		discrShape->SetMaximum(discrShape->GetMaximum() * 5);
		TH1 *effVsCut = computeEffVsCut(h, total->GetBinContent(4 - i));
		TH1 *effVsBEff = 0;

		if (flavour == flavours)	// b-jets
			effVsCutB = effVsCut;
		else
			effVsBEff = computeEffVsBEff(effVsCut, effVsCutB);

		discrShape->SetTitle("discriminator shape");
		effVsCut->SetTitle("efficiency versus discriminator cut");
		if (effVsBEff)
			effVsBEff->SetTitle("mistag versus b efficiency");

		setHistStyle(discrShape);
		setHistStyle(effVsCut);
		setHistStyle(effVsBEff);

		canv->cd(1);
		gPad->SetLogy(1);
		gPad->SetGridy(1);
		discrShape->SetLineColor(i + 1);
		discrShape->SetMarkerColor(i + 1);
		discrShape->Draw(i > 0 ? "same" : "");
		if (!legend[0])
			legend[0] = new TLegend(0.5, 0.7, 0.78, 0.88);
		legend[0]->AddEntry(discrShape, *flavour);

		canv->cd(2);
		gPad->SetLogy(1);
		gPad->SetGridy(1);
		effVsCut->SetLineColor(i + 1);
		effVsCut->SetMarkerColor(i + 1);
		effVsCut->Draw(i > 0 ? "same" : "");
		if (!legend[1])
			legend[1] = new TLegend(0.12, 0.12, 0.40, 0.30);
		legend[1]->AddEntry(effVsCut, *flavour);

		if (!effVsBEff)
			continue;
		canv->cd(3);
		gPad->SetLogy(1);
		gPad->SetGridx(1);
		gPad->SetGridy(1);
		effVsBEff->SetLineColor(i + 1);
		effVsBEff->SetMarkerColor(i + 1);
		effVsBEff->Draw(i > 1 ? "same" : "");
		if (!legend[2])
			legend[2] = new TLegend(0.12, 0.7, 0.40, 0.88);
		legend[2]->AddEntry(effVsBEff, *flavour);
	}

	canv->cd(1);
	legend[0]->Draw();

	canv->cd(2);
	legend[1]->Draw();

	canv->cd(3);
	legend[2]->Draw();

	////////////////////////////////////////////

	// canvas to compare negative tagger with light flavour mistag

	TCanvas *canv;
	canv = new TCanvas("canv1", "comparing light flavour mistag with negative tagger", 530, 300);
	canv->Divide(2, 1);

	TH1 *h1 = (TH1*)file->Get(Form("%s/trackIPSig_udsg", directory));
	TH1 *h2 = (TH1*)file->Get(Form("%s/negativeIPSig_all", directory));
	h2 = invertHisto(h2);	// invert x-axis

	TH1 *discrShape1 = (TH1*)h1->Clone("discrShape1");
	TH1 *discrShape2 = (TH1*)h2->Clone("discrShape2");

	discrShape1->Scale(1.0 / discrShape1->Integral());
	discrShape1->SetMaximum(discrShape1->GetMaximum() * 5);
	discrShape2->Scale(1.0 / discrShape2->Integral());

	TH1 *effVsCut1 = computeEffVsCut(h1, total->GetBinContent(2));
	TH1 *effVsCut2 = computeEffVsCut(h2, total->GetBinContent(1));

	discrShape1->SetTitle("discriminator shape");
	effVsCut1->SetTitle("efficiency versus discriminator cut");

	setHistStyle(discrShape1);
	setHistStyle(discrShape2);
	setHistStyle(effVsCut1);
	setHistStyle(effVsCut2);

	canv->cd(1);
	gPad->SetLogy(1);
	gPad->SetGridy(1);
	discrShape1->SetLineColor(1);
	discrShape1->SetMarkerColor(1);
	discrShape2->SetLineColor(2);
	discrShape2->SetMarkerColor(2);

	discrShape1->Draw();
	discrShape2->Draw("same");

	TLegend *l = new TLegend(0.5, 0.7, 0.78, 0.88);
	l->AddEntry(discrShape1, "udsg");
	l->AddEntry(discrShape2, "inv. neg");
	l->Draw();

	canv->cd(2);
	gPad->SetLogy(1);
	gPad->SetGridy(1);
	effVsCut1->SetLineColor(1);
	effVsCut1->SetMarkerColor(1);
	effVsCut2->SetLineColor(2);
	effVsCut2->SetMarkerColor(2);

	effVsCut1->Draw();
	effVsCut2->Draw("same");

	l = new TLegend(0.5, 0.7, 0.78, 0.88);
	l->AddEntry(effVsCut1, "udsg");
	l->AddEntry(effVsCut2, "inv. neg");
	l->Draw();
}
Beispiel #22
0
void recurseOverKeys(TDirectory *target, TString imageType) {

//  TString path( (char*)strstr( target->GetPath(), ":" ) );
//  path.Remove( 0, 2 );

//  cout << path << endl;

//  sourceFile->cd( path );
    target->cd();
    TDirectory *current_sourcedir = gDirectory;

    TKey *key;
    TIter nextkey(current_sourcedir->GetListOfKeys());
    TCanvas *canvasDefault = new TCanvas();

    while ( (key = (TKey*)nextkey() ) ) {

        TObject* obj = key->ReadObj();

        if (obj->IsA()->InheritsFrom("TH1") ) {

            // **************************
            // Plot & Save this Histogram
            TH1* h = (TH1*)obj;
            h->SetStats(displayStatsBox);

            TString histName = h->GetName();

            // Now to label the X-axis!
//      if (autoLabelXaxis) {
//	if ( histName.Contains("Phi") ) {
//	  h->GetXaxis()->SetTitle("#phi");
//	} else if ( histName.Contains("Eta") ) {
//	  h->GetXaxis()->SetTitle("#eta");
//	} else if ( histName.Contains("Pt") ) {
//	  h->GetXaxis()->SetTitle("p_{T} (GeV)");
//	} else if ( histName.Contains("Et") ) {
//	  h->GetXaxis()->SetTitle("E_{T} (GeV)");
//	}
//      }

//      h->SetLineColor(lineColor);
//      h->SetLineWidth(lineWidth);


            // ********************************
            // A trick to decide whether to have log or no-log y axis
            // get hist max y value
            if (autoLogYaxis) {
                Double_t testYvalue = h->GetMaximum();
                //cout << testYvalue << endl;

                if (testYvalue > 1.0) {
                    Double_t maxy = log10(testYvalue);

                    // get hist min y value
                    Double_t miny = log10(h->GetMinimum(1.0));

                    // log scale if more than 3 powers of 10 between low and high bins
                    if ( (maxy-miny) > 3.0 ) {
                        canvasDefault->SetLogy(1);
                    }
                }
            }
            // End of log or no-log y axis decision
            // ********************************

            h->Draw(drawOptions1D);
            canvasDefault->Modified();
            canvasDefault->Update();

//      gPad->Print(outputFolder+path+"/"+histName+outputType);
            TString outputFolder = "images/";
            gPad->Print(outputFolder+histName+"."+imageType);
            // To store the root file name in image file name:
            //canvasDefault->Print(outputFolder+histFileName+histName+outputType);
//      if (printOutput) cout << outputFolder+path+"/"+histName+outputType << endl;

            canvasDefault->SetLogy(0); // reset to no-log - prevents errors
            // **************************

        } else if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) {
            // it's a subdirectory

            cout << "Found subdirectory " << obj->GetName() << endl;
//      gSystem->MakeDirectory(outputFolder+path+"/"+obj->GetName());

            // obj is now the starting point of another round of merging
            // obj still knows its depth within the target file via
            // GetPath(), so we can still figure out where we are in the recursion
            recurseOverKeys((TDirectory*)obj, imageType);

        } // end of IF a TDriectory
    } // end of LOOP over keys
}
Beispiel #23
0
//void makeHist(const int sample, const int dataset=1)
void makeHist(const string title="")
{
	vector<Hist> hist2print;
	TPaveText *tx = new TPaveText(.05,.1,.95,.8);
//	tx->AddText("Using Deafult JERs for all jets");
//	tx->AddText("Using b-Jet JERs");

/*	string title("QCD MG:");

	//if (sample==1) title += "NJet(70/50/30>=2/4/5), #slash{E}_{T}>175, Triplet>1, 80<TopMass<270, TOP+0.5*BJET>500, MT2>300, #Delta#Phi(.5,.5,.3), BJets>=1";
	if (sample==1)      title += "All Stop cuts applied (use default JERs for all jets)";
	else if (sample==2) title += "All Stop cuts applied + Inverted #Delta#Phi (use default JERs for all jets)";
	else if (sample==3) title += "All Stop cuts applied (use b-Jet JERs)";
	else if (sample==4) title += "All Stop cuts applied + Inverted #Delta#Phi (use b-Jet JERs)";
	else if (sample==5) title += "No cuts applied";
*/
	unsigned bitMaskArray[] = {0,1,2,3,129,130,131,195,257,258,269,323};
	vector<unsigned> vBitMaskArray(bitMaskArray, bitMaskArray + sizeof(bitMaskArray) / sizeof(unsigned));



	stringstream unclmet_title;
	unclmet_title << title << "Unclutered MET";
	hist2print.push_back(Hist("met",title,2,0.0, 400.0,1));
	hist2print.push_back(Hist("unclmet",unclmet_title.str().c_str(),2,0.0, 100.0,1));
	hist2print.push_back(Hist("mht",title,2,0.0, 400.0,1));
	hist2print.push_back(Hist("ht",title,2,0,2000,1));
	hist2print.push_back(Hist("njet30eta5p0",title,1,0,15,1));
	hist2print.push_back(Hist("nbjets",title,1,0,10,1));
//	hist2print.push_back(Hist("bjetPt",title,2));
	hist2print.push_back(Hist("M123",title,2));
//	hist2print.push_back(Hist("M23overM123",title));
	hist2print.push_back(Hist("MT2",title,2));
	hist2print.push_back(Hist("MTb",title,4));
	hist2print.push_back(Hist("MTt",title,4));
	hist2print.push_back(Hist("MTb_p_MTt",title,2,400,1000,1));
	//hist2print.push_back(Hist("jet1_pt",title,2));
	//hist2print.push_back("bjetPt");
//	hist2print.push_back(Hist("bjetMass",title,2,0,200));
//	hist2print.push_back(Hist("dphimin",title,4));


	TFile *outRootFile = new TFile("Merged.root");

	/*TPad *c1=0, *c2=0;
	TCanvas *c = GetCanvas(c1, c2);
	if (c ==NULL|| c1 == 0 ||c2 == 0)
	{
		cout << " A drawing pad is null !"<< endl;
		cout << "c = " << c << endl;
		cout << "c1 = " << c1 << endl;
		cout << "c2 = " << c2 << endl;
		assert(false);
	}*/
   TCanvas *c = new TCanvas("c1");
   c->Range(0,0,1,1);
   c->SetBorderSize(2);
   c->SetFrameFillColor(0);
  
// ------------>Primitives in pad: c1_1
   TPad *c1_1 = new TPad("c1_1", "c1_1",0.01,0.30,0.99,0.99);
   c1_1->Draw();
   c1_1->cd();
   c1_1->SetBorderSize(2);
   c1_1->SetTickx(1);
   c1_1->SetTicky(1);
   c1_1->SetTopMargin(0.1);
   c1_1->SetBottomMargin(0.0);
   //c1_1->SetFrameFillColor(3);
	//c1_1->SetLogy();
  
  c->cd();
// ------------>Primitives in pad: c1_2
   TPad *c1_2 = new TPad("c1_2", "c1_2",0.01,0.01,0.99,0.30);
   c1_2->Draw();
   c1_2->cd();
   c1_2->SetBorderSize(2);
   c1_2->SetTickx(1);
   c1_2->SetTicky(1);
   c1_2->SetTopMargin(0.0);
   c1_2->SetBottomMargin(0.24);
   c1_2->SetFrameFillColor(0);
	c1_2->SetGridx();
	c1_2->SetGridy();
	c->cd();
	gStyle->SetOptStat(0);
	gPad->Print("samples.eps[");

	for (unsigned i=0;i<vBitMaskArray.size(); ++i)
	{
		unsigned mask = vBitMaskArray.at(i);
		for (unsigned ihist=0; ihist < hist2print.size(); ++ihist)
		{
			stringstream path, reco_hist_name, gen_hist_name, smear_hist_name;
			stringstream reco_hist, gen_hist, smear_hist;
			stringstream folder;
			folder << "Hist/Mask"<< mask << "HT0to8000MHT0to8000/";
			//cout << "folder = " << folder.str() << endl;

			/*	if ((hist2print.at(ihist).Name()).find("Jet"))
				{
				reco_hist_name << folder.str() << "reco" << hist2print.at(ihist).Name() << "_copy";
				reco_hist << folder.str() << "reco" << hist2print.at(ihist).Name();
				smear_hist_name << folder.str() << "smeared" << hist2print.at(ihist).Name() << "_copy";
				smear_hist << folder.str() << "smeared" << hist2print.at(ihist).Name();
				gen_hist_name << folder.str() << "gen" << hist2print.at(ihist).Name() << "_copy";
				gen_hist << folder.str() << "gen" << hist2print.at(ihist).Name();
				} else
				*/	{
					reco_hist_name << folder.str() << "reco_" << hist2print.at(ihist).Name() << "_copy";
					reco_hist << folder.str() << "reco_" << hist2print.at(ihist).Name();
					smear_hist_name << folder.str() << "smeared_" << hist2print.at(ihist).Name() << "_copy";
					smear_hist << folder.str() << "smeared_" << hist2print.at(ihist).Name();
					gen_hist_name << folder.str() << "gen_" << hist2print.at(ihist).Name() << "_copy";
					gen_hist << folder.str() << "gen_" << hist2print.at(ihist).Name();
				}

				TH1* hreco = (TH1*) (outRootFile->Get(reco_hist.str().c_str()));
				if (hreco == NULL) { cout << "hreco = " << reco_hist.str() << " was not found!" << endl; assert(false); } 
				hreco->SetDirectory(0);
				TH1* hsmear = (TH1*) (outRootFile->Get(smear_hist.str().c_str()));
				if (hsmear == NULL) { cout << "hsmear = " << smear_hist.str() << " was not found!" << endl; assert(false); } 
				hsmear->SetDirectory(0);
				TH1* hgen = (TH1*) (outRootFile->Get(gen_hist.str().c_str()));
				//->Clone(gen_hist_name.str().c_str()));
				if (hgen == NULL) { cout << "hgen = " << gen_hist.str() << " was not found!" << endl; assert(false); } 
				hgen->SetDirectory(0);

				hreco->Sumw2();
				hsmear->Sumw2();
				hgen->Sumw2();

				const int rebin = hist2print.at(ihist).Rebin();
				const string title = hist2print.at(ihist).Title();
				const double xmin = hist2print.at(ihist).Xmin();
				const double xmax = hist2print.at(ihist).Xmax();

				if (rebin>1)
				{
					hreco->Rebin(rebin);
					hsmear->Rebin(rebin);
					hgen->Rebin(rebin);
				}
				if (title.length()>0)
				{
					hreco->SetTitle(title.c_str());
					hsmear->SetTitle(title.c_str());
					hgen->SetTitle(title.c_str());
				}
				if (xmin != LargeNegNum || xmax != LargeNegNum)
				{
					hreco->GetXaxis()->SetRangeUser(xmin,xmax);
					hsmear->GetXaxis()->SetRangeUser(xmin,xmax);
					hgen->GetXaxis()->SetRangeUser(xmin,xmax);
				}

				const double reco_max_y  = hreco->GetBinContent(hreco->GetMaximumBin());
				const double smear_max_y = hsmear->GetBinContent(hsmear->GetMaximumBin());
				const double y_max = max(reco_max_y, smear_max_y);
				double y_min = 9999.0;
				for (unsigned bin=1; bin<hreco->GetNbinsX(); ++bin)
				{
					const double v1 = hreco->GetBinContent(bin);
					const double v2 = hsmear->GetBinContent(bin);
					const double minv = min(v1,v2);
					if (minv != 0 && minv < y_min) y_min = minv;
					
				}

				cout << hreco->GetName() << "->ymin/max = " << y_min << "(" << y_min/2.0 << ")/" << y_max << "(" << y_max*2.0 << ")" << endl;
				hreco->GetYaxis()->SetRangeUser(y_min/2.0, y_max*2.0);
				hsmear->GetYaxis()->SetRangeUser(y_min/2.0, y_max*2.0);


				hgen->SetLineColor(kBlue);
				hgen->SetMarkerColor(kBlue);
				hgen->SetMarkerStyle(24);
				hgen->SetLineWidth(2);
				hsmear->SetLineColor(kRed);
				hsmear->SetMarkerColor(kRed);
				hsmear->SetMarkerStyle(24);
				hsmear->SetLineWidth(2);
				hreco->SetLineWidth(2);
				hreco->SetMarkerStyle(kDot);
				hreco->SetLineColor(kBlack);
				hreco->SetMarkerColor(kBlack);
				//hreco->GetXaxis()->SetRangeUser(0,300);
				//hsmear->GetXaxis()->SetRangeUser(0,300);


				hreco->GetYaxis()->CenterTitle(1);
				hreco->SetLabelFont(42,"XYZ");
				hreco->SetTitleFont(42,"XYZ");
				hreco->GetYaxis()->SetTitleOffset(0.8);
				hreco->SetLabelSize(0.05,"XYZ");
				hreco->SetTitleSize(0.06,"XYZ");


				TH1 *hsmeartoreco_ratio = (TH1*) (hsmear->Clone("hsmear_copy"));
				hsmeartoreco_ratio->Divide(hreco);
				hsmeartoreco_ratio->SetTitle("");
				hsmeartoreco_ratio->GetYaxis()->SetTitle("Smear/Reco");
				hsmeartoreco_ratio->GetYaxis()->SetRangeUser(0,2.);

				hsmeartoreco_ratio->GetYaxis()->SetTitleOffset(0.4);
				hsmeartoreco_ratio->GetXaxis()->SetTitleOffset(0.9);
				hsmeartoreco_ratio->GetYaxis()->CenterTitle(1);
				hsmeartoreco_ratio->GetXaxis()->CenterTitle(1);
				hsmeartoreco_ratio->SetLabelSize(0.125,"XYZ");
				hsmeartoreco_ratio->SetTitleSize(0.125,"XYZ");
				//	hsmeartoreco_ratio->SetLabelFont(labelfont,"XYZ");
				//	hsmeartoreco_ratio->SetTitleFont(titlefont,"XYZ");
				hsmeartoreco_ratio->GetXaxis()->SetTickLength(0.07);



				stringstream recoleg,smearleg, genleg;
				const double sum_reco  = hreco->Integral(1, hreco->GetNbinsX()+1);
				const double sum_smear = hsmear->Integral(1, hsmear->GetNbinsX()+1);
				const double sum_gen   = hgen->Integral(1, hgen->GetNbinsX()+1);
				const double err_reco  = StatErr(hreco);
				const double err_smear = StatErr(hsmear);


				cout << setprecision(1) << fixed;

				recoleg << "Reco (" << sum_reco << "#pm" << err_reco << ")";
				smearleg << "Smear (" << sum_smear << "#pm" << err_smear << ")";
				genleg << "Gen (" << sum_gen << ")";
				cout <<  smear_hist_name.str() << "::reco/smear = " << sum_reco << "/" << sum_smear << endl;

				TLegend *l2 = new TLegend(0.6,0.6,0.9,0.9);
				l2->AddEntry(hreco, recoleg.str().c_str());
				//l2->AddEntry(hgen, genleg.str().c_str());
				l2->AddEntry(hsmear, smearleg.str().c_str());

				c1_1->cd();
				gPad->SetLogy(hist2print.at(ihist).LogY());

				hreco->DrawCopy();
				//hgen->DrawCopy("same");
				hsmear->DrawCopy("same");
				l2->Draw();
				//tx->Draw();
				c1_2->cd();
				hsmeartoreco_ratio->DrawCopy();
				c->cd();
				gPad->Print("samples.eps");

		}
	}

	gPad->Print("samples.eps]");
}
Beispiel #24
0
void  drawPlots(canvasSet_t& cs,bool savePlots2file)
{
  wCanvas_t *wc0 = cs.canvases[0];
  unsigned npads = wc0->npadsx*wc0->npadsy;
  unsigned npadsall = cs.ncanvases*npads;

  if (!npads) {
    if (gl_verbose) cout << "Nothing to draw, guess I'm done." << endl;
    return; // no pads to draw on.

  } else if (!wc0->pads.size()) {

    /********************************************************
     * CHECK MULTIPAD OPTION, ASSIGN HISTOS TO PADS/CANVASES
     ********************************************************/

    if (wc0->multipads.size()) {
      npadsall = assignHistos2Multipad(cs);
    } else {
      cerr << "npads>0, but no pad specs supplied, exiting." << endl;
      return; // no pads to draw on.
    }
  } else if (cs.ncanvases>1) {
    npadsall = assignPads2Canvases(cs);
  } else {
    npadsall = std::min(npadsall,(unsigned)wc0->pads.size());
  }

  wc0->c1->cd();

  if (gl_verbose)
    cout << "Drawing on " << npadsall << " pad(s)" << endl;

  wLegend_t *wleg = NULL;

  /***************************************************
   * LOOP OVER PADS...
   ***************************************************/

  //vector<vector<string> >::const_iterator it;
  for (unsigned ipad = 0; ipad< npadsall; ipad++) {

    if (gl_verbose) cout << "Drawing pad# " << ipad+1 << endl;

    unsigned ipadc =  ipad % npads;
    unsigned cnum  = (ipad / npads) + 1;

    wCanvas_t *wc = cs.canvases[cnum-1];

    if (!ipadc) {
      if (cnum-1) { // first canvas already created
	wc->c1 = new TCanvas(wc->title.c_str(),wc->title.c_str(),
			     wc->padxdim*wc->npadsx,
			     wc->padydim*wc->npadsy);
	float left = wc->leftmargin;
	float bot  = wc->bottommargin;
	float rhgt = 1-wc->rightmargin;
	float top  = 1-wc->topmargin;
	wc->motherpad = new TPad("mother","",left,bot,rhgt,top);
	wc->c1->SetFillColor(wc->fillcolor);
	wc->motherpad->SetFillColor(wc->fillcolor);
	wc->motherpad->Draw();
	wc->motherpad->cd();
	wc->motherpad->Divide(wc->npadsx,wc->npadsy); // , wc->padxmargin,wc->padymargin);
      }

      /***************************************************
       * CHECK FOR LATEX OBJECTS ON THE CANVAS
       ***************************************************/
      
      wc->c1->cd();
      for (unsigned j=0; j<wc->latex_ids.size(); j++) {
	string& lid = wc->latex_ids[j];
	map<string,TLatex *>::const_iterator it = glmap_id2latex.find(lid);
	if (it == glmap_id2latex.end()) {
	  cerr << "ERROR: latex id " << lid << " never defined in layout" << endl;
	  exit (-1);
	}
	TLatex *ltx = it->second;
	ltx->Draw();
	wc->c1->Update();
      }
    }

    wPad_t *& wp = wc->pads[ipadc];
    wp->vp = wc->motherpad->cd(ipadc+1);

    if (!wp->histo_ids.size() &&
	!wp->stack_ids.size() &&
	!wp->graph_ids.size() &&
	!wp->macro_ids.size()) {
      cerr << "ERROR: pad #" << ipadc+1 << " has no ids defined for it";
      cerr << ", continuing to the next" << endl;
      continue;
    }


#if 0
    /***************************************************
     * Draw the frame first:
     * (Fix up frame since it can't be auto-scaled:)
     ***************************************************/
    string& hid0 = wp->histo_ids[0];
    map<string,wTH1 *>::const_iterator it = glmap_id2histo.find(hid0);
    if (it == glmap_id2histo.end()) {
      cerr << "ERROR: id0 " << hid0 << " never defined in layout" << endl;
      return;
    }
    wTH1 *myHisto = it->second;
    TH1  *h = myHisto->histo();

    if (wp->hframe->histo()->GetXaxis()->GetXmin() <=
	wp->hframe->histo()->GetXaxis()->GetXmax())
      wp->hframe->histo()->GetXaxis()->SetRangeUser(h->GetXaxis()->GetXmin(),
						    h->GetXaxis()->GetXmax());
    if (wp->hframe->histo()->GetYaxis()->GetXmin() <= 
	wp->hframe->histo()->GetYaxis()->GetXmax())
      wp->hframe->histo()->GetYaxis()->SetRangeUser(h->GetYaxis()->GetXmin(),
						    h->GetYaxis()->GetXmax());

    wp->hframe->SetStats(0);
    //wp->hframe->Draw("AXIS");
#endif

    /***************************************************
     * Check for external macros to run on the pad
     ***************************************************/
    for (size_t i=0; i<wp->macro_ids.size(); i++) {
      map<string,string>::const_iterator it = glmap_objpath2id.find(wp->macro_ids[i]);
      if (it != glmap_objpath2id.end()) {
	string path = it->second;
	int error;
	gROOT->Macro(path.c_str(), &error, kTRUE); // update current pad
	if (error) {
	  static const char *errorstr[] = {
	    "kNoError","kRecoverable","kDangerous","kFatal","kProcessing" };
	  cerr << "ERROR: error returned from macro: " << errorstr[error] << endl;
	}
      } else {
	cerr << "ERROR: macro id " << wp->macro_ids[i];
	cerr << " never defined in layout" << endl;
      }
    }
    /***************************************************
     * Check for existence of a legend, create it
     ***************************************************/
    bool drawlegend = false;

    if (wp->legid.size()) {
      map<string,wLegend_t *>::const_iterator it=glmap_id2legend.find(wp->legid);
      if (it != glmap_id2legend.end()) {
	drawlegend = true;
	wleg = it->second;
      } else {
	cerr << "ERROR: legend id " << wp->legid;
	cerr << " never defined in layout" << endl;
      }
    } else {
      // Maybe gPad already *has* a legend from macros...
      TPave *testing = (TPave *)gPad->GetPrimitive("TPave");
      if (testing &&
	  !strcmp(testing->IsA()->GetName(),"TLegend")) {
	TLegend *pullTheOtherOne = (TLegend *)testing;
	if (gl_verbose) cout << "Found legend from macro" << endl;
	wleg = new wLegend_t();
	wleg->leg = pullTheOtherOne;
	drawlegend = true;
      }
    }

    /***************************************************
     * LOOP OVER STACKS DEFINED FOR PAD...
     ***************************************************/

    if (wp->stack_ids.size()) {
      wStack_t *ws=NULL;
      for (unsigned j = 0; j < wp->stack_ids.size(); j++) {
	string& sid = wp->stack_ids[j];
	map<string,wStack_t *>::const_iterator it = glmap_id2stack.find(sid);
	if (it == glmap_id2stack.end()) {
	  cerr << "ERROR: stack id " << sid << " never defined in layout" << endl;
	  exit (-1);
	}

	bool firstInPad = !j;

	ws = it->second;
	if (!ws) { cerr<< "find returned NULL stack pointer for " << sid << endl; continue; }

	// Add the histos in the stack to any legend that exists

	//
	if (drawlegend) {
	  for (size_t i=0; i<ws->v_histos.size(); i++) {
	    wTH1 *wh = ws->v_histos[i];
	    wh->ApplySavedStyle();
	    if(wh->GetLegendEntry().size())
	      wh->Add2Legend(wleg->leg);
	  }
	}

	string drawopt("");
	if (ws->sum->GetDrawOption().size()) {
	  drawopt = ws->sum->GetDrawOption();
	  cout << "drawopt stored with histo = " << drawopt << endl;
	}

	drawInPad(wp, ws, firstInPad, drawopt);

	wp->vp->Update();
      }
    } // stack loop

    /***************************************************
     * LOOP OVER HISTOS DEFINED FOR PAD...
     ***************************************************/

    for (unsigned j = 0; j < wp->histo_ids.size(); j++) {
      string& hid = wp->histo_ids[j];
      map<string,wTH1 *>::const_iterator it = glmap_id2histo.find(hid);
      if (it == glmap_id2histo.end()) {
	cerr << "ERROR: histo id " << hid << " never defined in layout" << endl;
	exit (-1);
      }

      wTH1 *myHisto = it->second;
      
      if (myHisto) {
	bool firstInPad = !j && !wp->stack_ids.size();
	if (gl_verbose) {
	  cout << "Drawing " << hid << " => ";
	  cout << myHisto->histo()->GetName() << endl;
	  cout << "firstInPad = " << firstInPad << endl;
	}
	drawInPad(wp,*myHisto,firstInPad);

	myHisto->DrawFits("same");
	if (drawlegend && myHisto->GetLegendEntry().size()) {
	  if (wleg->drawoption.size()) myHisto->SetDrawOption(wleg->drawoption);
	  myHisto->Add2Legend(wleg->leg);
	}
	if (myHisto->statsAreOn()) {
	  myHisto->DrawStats();
	  wp->vp->Update();
	}

	myHisto->ApplySavedStyle();
	wp->vp->Update();
      }
    } // histos loop

    /***************************************************
     * LOOP OVER HISTOS DEFINED FOR ALTERNATE Y-AXIS
     ***************************************************/

    Float_t rightmax=0.0,rightmin=0.0;
    Float_t scale=0.0;
    for (unsigned j = 0; j < wp->altyh_ids.size(); j++) {
      string& hid = wp->altyh_ids[j];
      map<string,wTH1 *>::const_iterator it = glmap_id2histo.find(hid);
      if (it == glmap_id2histo.end()) {
	cerr << "ERROR: histo id " << hid << " never defined in layout" << endl;
	exit (-1);
      }

      wTH1 *myHisto = it->second;
      TH1 *h = myHisto->histo();

      if (!j) {
	//scale second set of histos to the pad coordinates
	rightmin = h->GetMinimum();
	rightmax = 1.1*h->GetMaximum();
	scale    = gPad->GetUymax()/rightmax;
      }
      TH1 *scaled=(TH1 *)h->Clone(Form("%s_%d",h->GetName(),ipad));

      scaled->Scale(scale);
      scaled->Draw("same");
   
      //draw an axis on the right side
      TGaxis *axis = new TGaxis(gPad->GetUxmax(), gPad->GetUymin(),
				gPad->GetUxmax(), gPad->GetUymax(),
				rightmin,rightmax,505,"+L");
      axis->Draw();
      gPad->Update();
      if (drawlegend && myHisto->GetLegendEntry().size()) {
	if (wleg->drawoption.size()) myHisto->SetDrawOption(wleg->drawoption);
	myHisto->Add2Legend(wleg->leg);
      }
    }

    /***************************************************
     * LOOP OVER GRAPHS DEFINED FOR PAD...
     ***************************************************/
#if 0
    TMultiGraph *mg;
    if (graph_ids.size())
      mg = new TMultiGraph();
#endif
    for( unsigned j = 0; j < wp->graph_ids.size(); j++ ) {
      string& gid = wp->graph_ids[j];
      
      wGraph_t *wg   = findGraph(gid);

      bool firstInPad = !j && !wp->histo_ids.size() && !wp->macro_ids.size();
      if( firstInPad && wg->gr && wg->gr->IsA()==TGraph::Class() )
	wg->drawopt += string("A"); // no histos drawn, need to draw the frame ourselves.

      if( wg && wg->gr ) {
	// "pre-draw" in order to define the plot elements
	wg->gr->Draw(wg->drawopt.c_str());

	if (firstInPad) {
	  // Now we can set the axis attributes and range:
	  wg->gr->GetXaxis()->ImportAttributes(wg->xax);
	  wg->gr->GetYaxis()->ImportAttributes(wg->yax);

	  cout << wg->xax->GetXmin() << " " << wg->xax->GetXmax() << endl;
	  if( wg->xax->GetXmax()>wg->xax->GetXmin() )
	    wg->gr->GetXaxis()->SetLimits(wg->xax->GetXmin(),wg->xax->GetXmax());
	  if( wg->yax->GetXmax()>wg->yax->GetXmin() )
	    wg->gr->GetYaxis()->SetRangeUser(wg->yax->GetXmin(),wg->yax->GetXmax());
	}
	// draw for good
	drawInPad<TGraph>(wp,wg->gr,wg->drawopt.c_str(),firstInPad);

	wp->vp->Update();
	if( wg->fitfn ) 
	  wg->gr->Fit(wg->fitfn);
	if( drawlegend && wg->leglabel.size() )
	  wleg->leg->AddEntry(wg->gr,wg->leglabel.c_str(),wg->legdrawopt.c_str());
      }
      if( wg && wg->gr2d ) {
	drawInPad<TGraph2D>(wp,wg->gr2d,wg->drawopt.c_str(),firstInPad);

	if (firstInPad) {
	  // Now we can set the axis attributes and range:
	  wg->gr2d->GetXaxis()->ImportAttributes(wg->xax);
	  wg->gr2d->GetYaxis()->ImportAttributes(wg->yax);

	  cout << wg->xax->GetXmin() << " " << wg->xax->GetXmax() << endl;
	  if( wg->xax->GetXmax()>wg->xax->GetXmin() )
	    wg->gr2d->GetXaxis()->SetLimits(wg->xax->GetXmin(),wg->xax->GetXmax());
	  if( wg->yax->GetXmax()>wg->yax->GetXmin() )
	    wg->gr2d->GetYaxis()->SetRangeUser(wg->yax->GetXmin(),wg->yax->GetXmax());
	}

	if (wg->contours) {
	  //cout << "setting contours "; wg->contours->Print();
	  wg->gr2d->GetHistogram()->SetContour(wg->contours->GetNoElements(),
					       wg->contours->GetMatrixArray());
	  wg->gr2d->SetLineStyle   (wg->lstyle);
	  wg->gr2d->SetLineColor   (wg->lcolor);
	  wg->gr2d->SetLineWidth   (wg->lwidth);
	}
	wp->vp->Modified();
	wp->vp->Update();
	if( drawlegend && wg->leglabel.size() )
	  wleg->leg->AddEntry(wg->gr2d,wg->leglabel.c_str(),wg->legdrawopt.c_str());
      }
    } // graph loop

    /***************************************************
     * LOOP OVER LINES DEFINED FOR PAD...
     ***************************************************/

    for( unsigned j = 0; j < wp->line_ids.size(); j++ ) {
      string drawopt("L");
      string& lid = wp->line_ids[j];
      map<string,TLine *>::const_iterator it2 = glmap_id2line.find(lid);
      if (it2 == glmap_id2line.end()) {
	cerr << "ERROR: line id " << lid << " never defined in layout" << endl;
	exit (-1);
      }

      TLine *line = it2->second;

      if (!j && !wp->histo_ids.size() && !wp->macro_ids.size())
	drawopt += string("A"); // no histos drawn, need to draw the frame ourselves.

      if (line) {
	drawInPad<TLine>(wp,line,drawopt.c_str());
	//if (drawlegend)
	//wleg->leg->AddEntry(line,lid.c_str(),"L");
      }
    }

    /***************************************************
     * LOOP OVER BOXES DEFINED FOR PAD...
     ***************************************************/

    for (unsigned j = 0; j < wp->box_ids.size(); j++) {
      string drawopt("L");
      string& bid = wp->box_ids[j];
      map<string,TBox *>::const_iterator it2 = glmap_id2box.find(bid);
      if (it2 == glmap_id2box.end()) {
	cerr << "ERROR: box id " << bid << " never defined in layout" << endl;
	exit (-1);
      }

      TBox *box = it2->second;

      if (box) {
	drawInPad<TBox>(wp,box,drawopt.c_str());
      }
    }

    /***************************************************
     * Draw the legend
     ***************************************************/

    if (drawlegend) {
      wleg->leg->Draw("same");
      wp->vp->Update();
    }

    /***************************************************
     * Draw each latex/label object
     ***************************************************/
    
    for (unsigned j=0; j<wp->latex_ids.size(); j++) {
      string& lid = wp->latex_ids[j];
      map<string,TLatex *>::const_iterator it2 = glmap_id2latex.find(lid);
      if (it2 == glmap_id2latex.end()) {
	cerr << "ERROR: latex id " << lid << " never defined in layout" << endl;
	exit (-1);
      }
      if (gl_verbose) cout << "Drawing latex object " << lid << endl;
      TLatex *ltx = it2->second;
      ltx->Draw();
      wp->vp->Update();
    }

    for (unsigned j = 0; j < wp->label_ids.size(); j++) {
      string& lid = wp->label_ids[j];
      map<string,wLabel_t *>::const_iterator it2 = glmap_id2label.find(lid);
      if (it2 == glmap_id2label.end()) {
	cerr << "ERROR: label id " << lid << " never defined in layout" << endl;
	exit (-1);
      }
      if (gl_verbose) cout << "Drawing label object " << lid << endl;
      wLabel_t *wlab = it2->second;
      drawStandardText(wlab->text, wlab->x1ndc, wlab->y1ndc,-1,-1,wlab->textsize);

      wp->vp->Update();
    }
    wc->c1->Update();

  } // pad loop

  //prdFixOverlay();

  if (savePlots2file) {
    wc0 = cs.canvases[0];
    if (!wc0->savenamefmts.size())  // define a default
      wc0->savenamefmts.push_back("%F_%C.png");
    for (size_t i=0; i<cs.canvases.size(); i++) {
      wCanvas_t *wc = cs.canvases[i];
      wc->c1->cd();
      for (size_t j=0; j<wc0->savenamefmts.size(); j++)
	saveCanvas2File(wc,wc0->savenamefmts[j]);
    }
  }
}                                                           // drawPlots
void patBJetVertex_efficiencies()
{
	// define proper canvas style
	setNiceStyle();
	gStyle->SetOptStat(0);

	// open file
	TFile* file = new TFile("analyzePatBJetVertex.root");

	unsigned int j = 0;
	for(const char **algo = algos; *algo; algo++, j++) {
		TLegend *legend[3] = { 0, 0, 0 };

		// draw canvas with efficiencies
		TCanvas *canv;
		canv = new TCanvas(*algo, Form("%s efficiencies", algoNames[j]), 800, 300);
		canv->Divide(3, 1);

		TH1 *total = (TH1*)file->Get(Form("%s/flavours", directory));
		TH1 *effVsCutB = 0;
		unsigned int i = 0;
		for(const char **flavour = flavours; *flavour; flavour++, i++) {
			TH1 *h = (TH1*)file->Get(Form("%s/%s_%s", directory, *algo, *flavour));
			TH1 *discrShape = (TH1*)h->Clone(Form("%s_discrShape", h->GetName()));
			discrShape->Scale(1.0 / discrShape->Integral());
			discrShape->SetMaximum(discrShape->GetMaximum() * 5);
			TH1 *effVsCut = computeEffVsCut(h, total->GetBinContent(4 - i));
			TH1 *effVsBEff = 0;

			if (flavour == flavours)	// b-jets
				effVsCutB = effVsCut;
			else
				effVsBEff = computeEffVsBEff(effVsCut, effVsCutB);

			discrShape->SetTitle("discriminator shape");
			effVsCut->SetTitle("efficiency versus discriminator cut");
			if (effVsBEff)
				effVsBEff->SetTitle("mistag versus b efficiency");

			setHistStyle(discrShape);
			setHistStyle(effVsCut);
			setHistStyle(effVsBEff);

			canv->cd(1);
			gPad->SetLogy(1);
			gPad->SetGridy(1);
			discrShape->SetLineColor(i + 1);
			discrShape->SetMarkerColor(i + 1);
			discrShape->Draw(i > 0 ? "same" : "");
			if (!legend[0])
				legend[0] = new TLegend(0.5, 0.7, 0.78, 0.88);
			legend[0]->AddEntry(discrShape, *flavour);

			canv->cd(2);
			gPad->SetLogy(1);
			gPad->SetGridy(1);
			effVsCut->SetLineColor(i + 1);
			effVsCut->SetMarkerColor(i + 1);
			effVsCut->Draw(i > 0 ? "same" : "");
			if (!legend[1])
				legend[1] = new TLegend(0.3, 0.4, 0.58, 0.58);
			legend[1]->AddEntry(effVsCut, *flavour);

			if (!effVsBEff)
				continue;
			canv->cd(3);
			gPad->SetLogy(1);
			gPad->SetGridx(1);
			gPad->SetGridy(1);
			effVsBEff->SetLineColor(i + 1);
			effVsBEff->SetMarkerColor(i + 1);
			effVsBEff->Draw(i > 1 ? "same" : "");
			if (!legend[2])
				legend[2] = new TLegend(0.12, 0.7, 0.40, 0.88);
			legend[2]->AddEntry(effVsBEff, *flavour);
		}

		canv->cd(1);
		legend[0]->Draw();

		canv->cd(2);
		legend[1]->Draw();

		canv->cd(3);
		legend[2]->Draw();
	}
}
Beispiel #26
0
void plot_efficiencies( TFile* file, Int_t type = 2, TDirectory* BinDir)
{
   // input:   - Input file (result from TMVA),
   //          - type = 1 --> plot efficiency(B) versus eff(S)
   //                 = 2 --> plot rejection (B) versus efficiency (S)

   Bool_t __PLOT_LOGO__  = kTRUE;
   Bool_t __SAVE_IMAGE__ = kTRUE;

   // the coordinates
   Float_t x1 = 0;
   Float_t x2 = 1;
   Float_t y1 = 0;
   Float_t y2 = 0.8;

   // reverse order if "rejection"
   if (type == 2) {
      Float_t z = y1;
      y1 = 1 - y2;
      y2 = 1 - z;    
      //      cout << "--- type==2: plot background rejection versus signal efficiency" << endl;
   }
   else {
      //  cout << "--- type==1: plot background efficiency versus signal efficiency" << endl;
   }
   // create canvas
   TCanvas* c = new TCanvas( "c", "the canvas", 200, 0, 650, 500 );

   // global style settings
   c->SetGrid();
   c->SetTicks();

   // legend
   Float_t x0L = 0.107,     y0H = 0.899;
   Float_t dxL = 0.457-x0L, dyH = 0.22;
   if (type == 2) {
      x0L = 0.15;
      y0H = 1 - y0H + dyH + 0.07;
   }
   TLegend *legend = new TLegend( x0L, y0H-dyH, x0L+dxL, y0H );
   legend->SetTextSize( 0.05 );
   legend->SetHeader( "MVA Method:" );
   legend->SetMargin( 0.4 );

   TString xtit = "Signal efficiency";
   TString ytit = "Background efficiency";  
   if (type == 2) ytit = "Background rejection";
   TString ftit = ytit + " versus " + xtit;

   if (TString(BinDir->GetName()).Contains("multicut")){
      ftit += "  Bin: ";
      ftit += (BinDir->GetTitle());
   }

   // draw empty frame
   if(gROOT->FindObject("frame")!=0) gROOT->FindObject("frame")->Delete();
   TH2F* frame = new TH2F( "frame", ftit, 500, x1, x2, 500, y1, y2 );
   frame->GetXaxis()->SetTitle( xtit );
   frame->GetYaxis()->SetTitle( ytit );
   TMVAGlob::SetFrameStyle( frame, 1.0 );

   frame->Draw();  

   Int_t color = 1;
   Int_t nmva  = 0;
   TKey *key, *hkey;

   TString hNameRef = "effBvsS";
   if (type == 2) hNameRef = "rejBvsS";

   TList hists;
   TList methods;
   UInt_t nm = TMVAGlob::GetListOfMethods( methods );
   //   TIter next(file->GetListOfKeys());
   TIter next(&methods);

   // loop over all methods
   while (key = (TKey*)next()) {
      TDirectory * mDir = (TDirectory*)key->ReadObj();
      TList titles;
      UInt_t ninst = TMVAGlob::GetListOfTitles(mDir,titles);
      TIter nextTitle(&titles);
      TKey *titkey;
      TDirectory *titDir;
      while ((titkey = TMVAGlob::NextKey(nextTitle,"TDirectory"))) {
         titDir = (TDirectory *)titkey->ReadObj();
         TString methodTitle;
         TMVAGlob::GetMethodTitle(methodTitle,titDir);
         TIter nextKey( titDir->GetListOfKeys() );
         while ((hkey = TMVAGlob::NextKey(nextKey,"TH1"))) {
            TH1 *h = (TH1*)hkey->ReadObj();    
            TString hname = h->GetName();
            if (hname.Contains( hNameRef ) && hname.BeginsWith( "MVA_" )) {
               h->SetLineWidth(3);
               h->SetLineColor(color);
               color++; if (color == 5 || color == 10 || color == 11) color++; 
               h->Draw("csame");
               hists.Add(h);
               nmva++;
            }
         }
      }
   }

   while (hists.GetSize()) {
      TListIter hIt(&hists);
      TH1* hist(0);
      Double_t largestInt=-1;
      TH1* histWithLargestInt(0);
      while ((hist = (TH1*)hIt())!=0) {
         Double_t integral = hist->Integral(1,hist->FindBin(0.9999));
         if (integral>largestInt) {
            largestInt = integral;
            histWithLargestInt = hist;
         }
      }
      if (histWithLargestInt == 0) {
         cout << "ERROR - unknown hist \"histWithLargestInt\" --> serious problem in ROOT file" << endl;
         break;
      }
      legend->AddEntry(histWithLargestInt,TString(histWithLargestInt->GetTitle()).ReplaceAll("MVA_",""),"l");
      hists.Remove(histWithLargestInt);
   }   
   
   // rescale legend box size
   // current box size has been tuned for 3 MVAs + 1 title
   if (type == 1) {
      dyH *= (1.0 + Float_t(nmva - 3.0)/4.0);
      legend->SetY1( y0H - dyH );
   }
   else {
      dyH *= (Float_t(nmva - 3.0)/4.0);
      legend->SetY2( y0H + dyH);
   }

   // redraw axes
   frame->Draw("sameaxis");  
   legend->Draw("same");

   // ============================================================

   if (__PLOT_LOGO__) TMVAGlob::plot_logo();

   // ============================================================

   c->Update();

   TString fname = "plots/" + hNameRef;
   if (TString(BinDir->GetName()).Contains("multicut")){
      TString fprepend(BinDir->GetName());
      fprepend.ReplaceAll("multicutMVA_","");
      fname = "plots/" + fprepend + "_" + hNameRef;
   }
   if (__SAVE_IMAGE__) TMVAGlob::imgconv( c, fname );

   return;
}
//void MergeMetHists(const int Nfiles=0, 
//							const std::string filenamebase="",
//							const std::string title="", const std::string name="",
//							const float LoX=-1, const float HiX=-1, const int rebin=1,
//							const std::string printfile="", bool debug=false)
void MergeMetHists(const int Nfiles, 
		const std::string filenamebase,
		const std::string title, const std::string name,
		const float LoX=-1, const float HiX=-1, const int rebin=1,
		const std::string printfile="", const int MetSig=4,
		bool debug=false, const bool logy=false)
{
	assert (Nfiles>0 && "Number of files must be > 0");
	assert (name.length()>0 && "Require hist name!");
	assert (filenamebase.length()>0 && "Require base of the file name!");

	std::cout << "MetSig=" << MetSig << std::endl;
	std::cout << "Searching for obj = " << name <<std::endl;

	std::string data_path, bg_path, def_path;
	std::string ue1_path, ue2_path, ue3_path, ue4_path, ue5_path, ue6_path;
	std::string ue7_path, ue8_path, ue9_path;
	std::string jer1_path, jer2_path, jer3_path, jer4_path, jer5_path;
	std::string jer6_path, jer7_path, jer8_path, jer9_path, jer10_path;
	
	data_path="/Ana/MyJetFilter/Hist/Ana_data/";
	bg_path="/Ana/MyJetFilter/Hist/Ana_bckg/";
	def_path="/Ana/MyJetFilter/Hist/Ana_def/";
	ue1_path="/Ana/MyJetFilter/Hist/Ana_ue1/";
	ue2_path="/Ana/MyJetFilter/Hist/Ana_ue2/";
	ue3_path="/Ana/MyJetFilter/Hist/Ana_ue3/";
	ue4_path="/Ana/MyJetFilter/Hist/Ana_ue4/";
	ue5_path="/Ana/MyJetFilter/Hist/Ana_ue5/";
	ue6_path="/Ana/MyJetFilter/Hist/Ana_ue6/";
	ue7_path="/Ana/MyJetFilter/Hist/Ana_ue7/";
	ue8_path="/Ana/MyJetFilter/Hist/Ana_ue8/";
	ue9_path="/Ana/MyJetFilter/Hist/Ana_ue9/";
	jer1_path="/Ana/MyJetFilter/Hist/Ana_jer1/";
	jer2_path="/Ana/MyJetFilter/Hist/Ana_jer2/";
	jer3_path="/Ana/MyJetFilter/Hist/Ana_jer3/";
	jer4_path="/Ana/MyJetFilter/Hist/Ana_jer4/";
	jer5_path="/Ana/MyJetFilter/Hist/Ana_jer5/";
	jer6_path="/Ana/MyJetFilter/Hist/Ana_jer6/";
	jer7_path="/Ana/MyJetFilter/Hist/Ana_jer7/";
	jer8_path="/Ana/MyJetFilter/Hist/Ana_jer8/";
	jer9_path="/Ana/MyJetFilter/Hist/Ana_jer9/";
	jer10_path="/Ana/MyJetFilter/Hist/Ana_jer10/";


/*	data_path="Ana_data";
	bg_path="Ana_bckg";
	def_path="Ana_def";
	ue1_path="Ana_ue1";
	ue2_path="Ana_ue2";
	ue3_path="Ana_ue3";
	ue4_path="Ana_ue4";
	ue5_path="Ana_ue5";
	ue6_path="Ana_ue6";
	ue7_path="Ana_ue7";
	ue8_path="Ana_ue8";
	ue9_path="Ana_ue9";
	jer1_path="Ana_jer1";
	jer2_path="Ana_jer2";
	jer3_path="Ana_jer3";
	jer4_path="Ana_jer4";
	jer5_path="Ana_jer5";
	jer6_path="Ana_jer6";
	jer7_path="Ana_jer7";
	jer8_path="Ana_jer8";
	jer9_path="Ana_jer9";
	jer10_path="Ana_jer10";
*/


	std::vector<std::string> vPaths;
	vPaths.push_back(data_path);
	vPaths.push_back(bg_path);
	vPaths.push_back(def_path);
	vPaths.push_back(ue1_path);
	vPaths.push_back(ue2_path);
	vPaths.push_back(ue3_path);
	vPaths.push_back(ue4_path);
	vPaths.push_back(ue5_path);
	vPaths.push_back(ue6_path);
	vPaths.push_back(ue7_path);
	vPaths.push_back(ue8_path);
	vPaths.push_back(ue9_path);
	vPaths.push_back(jer1_path);
	vPaths.push_back(jer2_path);
	vPaths.push_back(jer3_path);
	vPaths.push_back(jer4_path);
	vPaths.push_back(jer5_path);
	vPaths.push_back(jer6_path);
	vPaths.push_back(jer7_path);
	vPaths.push_back(jer8_path);
	vPaths.push_back(jer9_path);
	vPaths.push_back(jer10_path);

	TFile *f = 0;
	TH1 *hist_data = 0, *hist_bg = 0;

	int iNHists = vPaths.size();

	std::vector<TH1*> vHist;
	for (int n= 0; n < iNHists; ++n)
	{
		TH1 *temp=0;
		vHist.push_back(temp);
	}

	int NfilesOpened = 0;

	//for (int i=1; i<=1; ++i) 
	for (int i=1; i<=Nfiles; ++i) 
	{
		std::stringstream file;
		file << filenamebase << i;
		//file << "myhisto_PhoJetAna_Pyth_phojet22_1Njet15_test_040208.root";

		f = new TFile (file.str().c_str());
		if (f->IsZombie())
		{
			std::cout << "ERROR::File " << file.str() << " did not open! Exiting." << std::endl;
			exit (1);
		} else {
			NfilesOpened++;
			if (debug)
			{
				std::cout << "File Added::";
				f->Print();
			}
		}

		gROOT->ls();
		
		TFolder *fold = (TFolder*) gDirectory->FindObjectAny("Ana");
		assert(fold != NULL && "folder null");
		TFolder *dir = (TFolder*) fold->FindObjectAny("MyJetFilter");
		assert(dir != NULL && "dir null");
		TFolder *dir2 = (TFolder*) dir->FindObjectAny("Hist");
		assert(dir2 != NULL && "Hist null");

		//TH1 *h = dynamic_cast<TH1*> (dir3->FindObjectAny(name.c_str()));
		//assert (h!=NULL && "hist null");
		//h->Draw();
		//return;


		for (unsigned int iPath = 0; iPath < vPaths.size(); ++iPath)
		{
			//std::cout << "iPath = " << iPath << std::endl;
			TFolder *dir3 = (TFolder*) dir2->FindObjectAny(vPaths.at(iPath).c_str());
			assert(dir3 != NULL && "data null");
			//f->cd();
			//gDirectory->pwd();
			//f->cd(vPaths.at(iPath).c_str());
			//gDirectory->pwd();
			//if (iPath<2) f->ls();
			//TH1 *hTemp = dynamic_cast<TH1*> (gDirectory->FindObjectAny(name.c_str()));
			std::stringstream histpath;
			histpath << vPaths.at(iPath) << name;
			//TFolder *ana = (TFolder*) gDirectory->FindObjectAny("Ana");
			//assert(ana !=NULL && "Ana folder not found");
			
			//std::cout << "histpath = " << histpath.str() << std::endl;
			TH1 *hTemp = dynamic_cast<TH1*> (dir3->FindObjectAny(name.c_str()));
			assert(hTemp != NULL && "object not found!");

			if (hTemp->GetEntries())	// this has to be done to avoid crashes when adding hists which some how have 'sum=nan' instead of 'sum=0' when they do not have any entries.
			{
				if (! vHist.at(iPath))
				{
					std::string name = hTemp->GetName() + std::string ("_Clone");
					vHist.at(iPath) = dynamic_cast<TH1*>(hTemp->Clone (name.c_str()));
					assert(vHist.at(iPath) != NULL && "Data hist cast failed");
					vHist.at(iPath)->SetDirectory(0);
				} else
				{
					vHist.at(iPath)->Add(hTemp);
				}
			}
		}

		delete f;

	}

/*	assert(vHist.size() == vPaths.size());
	for (int k=0; k < vHist.size(); ++k)
	{
		vHist.at(k)->Print();
	}
*/
	DoSystematics(vHist);
	
	hist_data = vHist.at(0);
	hist_bg = vHist.at(1);

/*	std::cout << "NORMALIZING BG TO DATA " << std::endl;
	double data_int = hist_data->Integral();
	double bg_int = hist_bg->Integral();
	hist_bg->Scale(data_int/bg_int);
	std::cout << "SCALE = " << data_int/bg_int << std::endl;
*/

	if (debug) 
	{
		hist_data->Print("all");
		hist_bg->Print("all");
	}

	std::cout << "Total file added = " << NfilesOpened << std::endl;
	gStyle->SetOptStat("");

	if (hist_data->GetEntries()) 	hist_data->Rebin(rebin);
	if (hist_bg->GetEntries()) hist_bg->Rebin(rebin);

	TH1 *hist_err_copy = NULL;
	std::string bgname = hist_bg->GetName() + std::string ("err_copy");
	hist_err_copy = dynamic_cast<TH1*>(hist_bg->Clone (bgname.c_str()));
	hist_err_copy->SetDirectory(0);

	TH1 *hist_data_copy = NULL;
	std::string dataname = hist_data->GetName() + std::string ("data_copy");
	hist_data_copy = dynamic_cast<TH1*>(hist_data->Clone (dataname.c_str()));
	hist_data_copy->SetDirectory(0);



	float x_loLim, x_hiLim;
	if (LoX >0) x_loLim = LoX;
	else x_loLim = hist_data->GetBinLowEdge(1);

	if (HiX >0) x_hiLim = HiX;
	else x_hiLim = max(FindUpLimit(hist_data), FindUpLimit(hist_bg)) + hist_data->GetBinWidth(1) * 2;
	if (debug)
	{
		std::cout << "min, max = " << x_loLim << ", " << x_hiLim << std::endl;
	}

	float y_hiLim = max(FindUpLimit(hist_data,"Y"), FindUpLimit(hist_bg,"Y"));
	if (logy) y_hiLim *= 10;
	else y_hiLim += y_hiLim * 0.1;




	gStyle->SetCanvasColor (10);
	gStyle->SetCanvasBorderSize (0);
	gStyle->SetCanvasBorderMode (0);
	gStyle->SetPadColor (10);
	gStyle->SetFillColor (10);
	gStyle->SetTitleFillColor (10);
	gStyle->SetTitleBorderSize (0);
	gStyle->SetStatColor (10);
	gStyle->SetStatBorderSize (1);
	gStyle->SetCanvasDefW(1200);
	gStyle->SetCanvasDefH(600);
	int labelfont = 10 * 4 + 2;		//10 * font ID + precision (2 = scalable)
	int titlefont = 10 * 4 + 2;		//10 * font ID + precision (2 = scalable)
	gStyle->SetLabelFont(labelfont,"X");
	gStyle->SetLabelFont(labelfont,"Y");
	gStyle->SetTitleFont(titlefont,"X");
	gStyle->SetTitleFont(titlefont,"Y");
	gStyle->SetLabelSize(0.04,"X");
	gStyle->SetLabelSize(0.027,"Y");
	//gStyle->SetLabelOffset(0.9);
	gStyle->SetTitleSize(0.03,"Y");
	gStyle->SetTitleOffset(1.8,"Y");
	//TGaxis::SetMaxDigits(3);



	hist_data->UseCurrentStyle();
	hist_bg->UseCurrentStyle();

	TCanvas *c1= new TCanvas;
	c1->Divide(2,1);
	c1->cd(1);
	if (logy)
	{
		if (hist_data->GetEntries() > 0 && hist_bg->GetEntries() > 0) gPad->SetLogy();
	}
	gPad->SetTickx();
	gPad->SetTicky();
	gPad->SetGridx();
	gPad->SetGridy();

	TPaveText *tp = new TPaveText(0.02,0.92,0.98,0.99,"NDC");
	tp->SetLineColor(10);
	tp->SetTextFont(titlefont);


	std::string tt(hist_data->GetTitle());
//	hist_data->SetTitle("");
//	hist_bg->SetTitle("");
	if (title.length()>0)
	{

		//tt += " - ";
		tt += title;
		//tt = title;
		if (debug)
		{
			std::cout << tt << std::endl;
		}
		tp->AddText(tt.c_str());
	}

	std::stringstream ytitle, xtitle;
	ytitle << "Events / " << setprecision(3) << hist_data->GetXaxis()->GetBinWidth(1) << " GeV";
	if (debug)
	{
		std::cout << hist_data->GetBinWidth(1) <<std::endl;
	}
	if (name == "MetAll") xtitle << "#slash{E}_{T} (for all events) (GeV)";
	else if (name == "Met") xtitle << "#slash{E}_{T} (after cuts) (GeV)";
	else if (name == "MetSig") xtitle << "#slash{E}_{T} Significance (for all events)";
	else if (name == "Njet15") xtitle << "Njets^{E_{T}>15GeV} (After #slash{E}_{T}-Sig cut)";
	else if (name == "Njet20") xtitle << "Njets^{E_{T}>20GeV} (After #slash{E}_{T}-Sig cut)";
	else if (name == "Njet25") xtitle << "Njets^{E_{T}>25GeV} (After #slash{E}_{T}-Sig cut)";
	else if (name == "Njet30") xtitle << "Njets^{E_{T}>30GeV} (After #slash{E}_{T}-Sig cut)";
	else if (name == "Njet35") xtitle << "Njets^{E_{T}>35GeV} (After #slash{E}_{T}-Sig cut)";

	if (debug)
	{
		std::cout << "xtitle=" << xtitle.str() << std::endl;
	}

	if (debug)
	{
		hist_data->Print();
		std::cout << "bin#\tLoEdge\tdata\tdata_err\tbg_cont\tbg_err"<<std::endl;
		for (unsigned bin = 0; bin <= (unsigned) hist_data_copy->GetNbinsX() + 1; ++ bin)
		{
			float val = hist_data->GetBinContent (bin);
			float err = hist_data->GetBinError(bin);
			float val2 = hist_bg->GetBinContent (bin);
			float err2 = hist_bg->GetBinError(bin);
			float loEdge = hist_data->GetBinLowEdge(bin);

			if (val>0 || err>0 || val2>0 || err2>0)
				std::cout << bin << "\t" << loEdge <<"\t" << val << "\t" << err << "\t\t" << val2 << "\t" << err2 << std::endl;
		}
	}

	hist_data->GetXaxis()->SetTitle(xtitle.str().c_str());
	if (name.find("Njet") == std::string::npos) hist_data->GetYaxis()->SetTitle(ytitle.str().c_str());
	hist_data->GetXaxis()->CenterTitle(true);
	hist_data->GetYaxis()->CenterTitle(true);
	hist_bg->GetXaxis()->SetTitle(xtitle.str().c_str());
	if (name.find("Njet") == std::string::npos) hist_bg->GetYaxis()->SetTitle(ytitle.str().c_str());
	hist_bg->GetXaxis()->CenterTitle(true);
	hist_bg->GetYaxis()->CenterTitle(true);

	//temp
	x_loLim = 0; x_hiLim = 200;
	hist_data->GetXaxis()->SetRangeUser(x_loLim, x_hiLim);
	hist_bg->GetXaxis()->SetRangeUser(x_loLim, x_hiLim);

	hist_data->SetMinimum(0.1);
	hist_bg->SetMinimum(0.1);
	hist_data->SetMaximum(y_hiLim);
	hist_bg->SetMaximum(y_hiLim);


	hist_data->SetMarkerStyle(8);
	hist_data->SetMarkerSize(1.0);
	hist_data->SetMarkerColor(kBlue);
	hist_data->SetLineColor(kBlue);
	hist_bg->SetMarkerColor(kRed);
	hist_bg->SetLineColor(kRed);
	hist_bg->SetFillColor(kRed);
	hist_data->SetTitleSize(0.04);
	hist_bg->SetTitleSize(0.04);
	TH1* hist_bg_copy = dynamic_cast<TH1*>(hist_bg->Clone ("hist_bg_BlkLine"));
	hist_bg_copy->SetLineColor(kBlack);
	hist_bg_copy->SetLineWidth(2);
	hist_bg_copy->SetFillColor(0);
	//hist_bg_copy->Draw("L");
	//hist_bg->Draw("sameE2");
//	hist_bg->SetFillColor(10);
//	hist_bg->SetLineColor(10);
	hist_bg->Draw("E2");
	hist_bg_copy->Draw("SAME HIST");
	hist_data->Draw("sameP");
	//tp->Draw();

	TLegend *leg = new TLegend (0.4,0.8,0.90,0.90);
	leg->SetTextFont(42);
	leg->SetTextSize(0.025);
	leg->SetBorderSize (1);
	leg->SetFillColor (10);

	//std::stringstream leg_data, leg_bg;
	//leg_data << "Data (E=" << hist_data->GetEntries() << " M=" << hist_data->GetMean()
	//		<< " R=" << hist_data->GetRMS() << ")";
	//leg_bg << "Bkg (E=" << hist_bg->GetEntries() << " M=" << hist_bg->GetMean()
	//		<< " R=" << hist_bg->GetRMS() << ")";

	//leg->AddEntry(hist_data,leg_data.str().c_str());
	//leg->AddEntry(hist_bg,leg_bg.str().c_str());
	//leg->AddEntry(hist_data,"Data (Measured) (DET Jets) ");
	//leg->AddEntry(hist_bg, "MC Prediction (HAD Jets, Norm to Data)");
	leg->AddEntry(hist_data,"Data (Measured)");
	leg->AddEntry(hist_bg, "MC Prediction");
	leg->Draw();

	// now to make the ratio plots
	for (unsigned bin = 0; bin <= (unsigned) hist_data_copy->GetNbinsX() + 1; ++ bin)
	{
		const float val = hist_err_copy->GetBinContent (bin);
		const float scale = val ? 1. / val : 0;
		hist_data_copy->SetBinContent (bin, (hist_data_copy->GetBinContent (bin) - val) * scale);
		hist_data_copy->SetBinError (bin, hist_data_copy->GetBinError (bin) * scale);
	};
	for (unsigned bin = 0; bin <= (unsigned) hist_err_copy->GetNbinsX() + 1; ++ bin)
	{
		float value = hist_err_copy->GetBinContent (bin);
		float error = hist_err_copy->GetBinError (bin);
		hist_err_copy->SetBinError (bin, value ? error / value : 0);
		hist_err_copy->SetBinContent (bin, 0);
	};


	/*
		TH1 *hist_ratio = NULL;
		std::string myname = hist_data->GetName() + std::string ("_copy");
		hist_ratio = dynamic_cast<TH1*>(hist_data->Clone (myname.c_str()));
		hist_ratio->Divide(hist_bg);
	 */


	hist_data_copy->UseCurrentStyle();
	hist_err_copy->UseCurrentStyle();
	//new TCanvas();
	c1->cd(2);
	gPad->SetTickx();
	gPad->SetTicky();
	gPad->SetGridx();
	gPad->SetGridy();
	hist_data_copy->SetTitle("");
	hist_err_copy->SetTitle("");
	//hist_data_copy->SetTitle(tt.c_str());
	//hist_err_copy->SetTitle(tt.c_str());
	hist_data_copy->GetXaxis()->SetTitle(xtitle.str().c_str());
	hist_err_copy->GetXaxis()->SetTitle(xtitle.str().c_str());
	hist_data_copy->GetXaxis()->SetRangeUser(x_loLim, x_hiLim);
	hist_err_copy->GetXaxis()->SetRangeUser(x_loLim, x_hiLim);
	float fRatioHist_ymax = 1.0;
	float fRatioHist_ymin = -1.0;
	hist_data_copy->SetMinimum(fRatioHist_ymin);
	hist_data_copy->SetMaximum(fRatioHist_ymax);
	hist_err_copy->SetMinimum(fRatioHist_ymin);
	hist_err_copy->SetMaximum(fRatioHist_ymax);
	std::stringstream ratio_ytitle;
	ratio_ytitle << "(Data Measured - MC Prediction) / MC Prediction";
	hist_data_copy->GetYaxis()->SetTitle(ratio_ytitle.str().c_str());
	hist_err_copy->GetYaxis()->SetTitle(ratio_ytitle.str().c_str());
	//hist_data_copy->SetTitle(ratio_ytitle.str().c_str());
	//hist_err_copy->SetTitle(ratio_ytitle.str().c_str());

	hist_data_copy->GetXaxis()->CenterTitle(true);
	hist_data_copy->GetYaxis()->CenterTitle(true);
	hist_err_copy->GetXaxis()->CenterTitle(true);
	hist_err_copy->GetYaxis()->CenterTitle(true);
	//	hist_data->GetYaxis()->SetRangeUser(;
	////	hist_bg->SetMinimum(0.1);


	hist_data_copy->SetLineColor(kBlue);
	hist_data_copy->SetMarkerColor(kBlue);
	hist_data_copy->SetMarkerStyle (8);
	hist_data_copy->SetMarkerSize(1.0);
	hist_err_copy->SetFillColor(kRed);
	hist_err_copy->SetFillStyle(3002);
	hist_data_copy->Draw("P");	
	hist_err_copy->Draw("same E2");	
	//tp->Draw();


	c1->cd();
	if (printfile.length()>0)
	{
		c1->Print(printfile.c_str());
	}

	DebugSystError(hist_data,hist_bg, hist_data_copy, hist_err_copy);
	

}
void loopPlot(){

  gErrorIgnoreLevel=kFatal;//suppresses all info messages
  setTDRStyle();//TDR style
  
  
  //#####################EDIT THE OPTIONS##############################
  /// Boolean flags to steer the histogram making
  bool wantElectrons = false; // Will make histograms for electrons
  bool wantMuons     = true; // Will make histograms for muons
  bool wantSideband  = false; // Will make histograms for sideband region
  bool wantSignal    = true; // Will make histograms for signal region
  bool wantFullRange = false; // Will not check signal or sideband, ie, pick all jet mass range
  int  wantNXJets    = 1; // Will make histograms for 1 or 2 jet topology
  int  isZZchannel   = 1; //plot label for zz (1) or ww (0)
  int  flavour = 0; 
  if(wantElectrons) flavour=11; if(wantMuons) flavour=13;
  
  /// Luminosity value in pb^-1
  //double lumiValue = 19531.85;// for singleEle2012
  //  double lumiValue = 19747; // for doubleMu2012
  //double lumiValue = 19788; // for doubleEle2012
  double lumiValue = 19768.0; 
  /// Should we scale the histograms to data?
  bool scaleToData = false;
  // Should we scale only wjets to make total MC = DATA?
  bool scaleOnlyWJets = false;
  /// Should we plot the Data/Bkg and Data-Bkg/Error ratios?
  bool makeRatio = false;
  /// Should we REDO histograms?
  bool redoHistograms = true;
  /// Should we put the signal MC stacked on top of the background (or just plot the signal alone)?
  bool isSignalStackOnBkg = false;

  /// Path to wherever the files with the trees are. 
  //CA8 (cmgTuple_08032013_CA8)

  std::string pathToTrees="/afs/cern.ch/user/b/bonato/scratch0/PhysAnalysis/EXOVV_2012/analyzer_trees/productionv2i/fullsig/";

  /// Path to wherever you want to put the histograms (figures) in.
  std::string outputDir = "./plots_productionv2i_fullsig_1JLP_MU";
 

  /// Setup names of data files for trees.
 
  
 const int nDATA=4;
 std::string dataLabels[nDATA]={"DoubleMu_Run2012A_22Jan2013",
				"DoubleMuParked_Run2012B_22Jan2013",
				"DoubleMuParked_Run2012C_22Jan2013",
				"DoubleMuParked_Run2012D_22Jan2013"};
  /*
  
  const int nDATA=4;//set to zero if you don't want to plot
  std::string dataLabels[nDATA]={"Photon_Run2012A_22Jan2013",
                                "DoublePhotonHighPt_Run2012B_22Jan2013",
                                "DoublePhotonHighPt_Run2012C_22Jan2013",
                                "DoublePhotonHighPt_Run2012D_22Jan2013"
				};
  */

  /*
  const int nDATA=8;//set to zero if you don't want to plot
  std::string dataLabels[nDATA]={"DoubleMu_Run2012A_22Jan2013",
				"DoubleMuParked_Run2012B_22Jan2013",
				"DoubleMuParked_Run2012C_22Jan2013",
				 "DoubleMuParked_Run2012D_22Jan2013",
				 "Photon_Run2012A_22Jan2013",
                                "DoublePhotonHighPt_Run2012B_22Jan2013",
                                "DoublePhotonHighPt_Run2012C_22Jan2013",
                                "DoublePhotonHighPt_Run2012D_22Jan2013"
				};
  */
  
/* 
  const int nDATA=7;//set to zero if you don't want to plot
  std::string dataLabels[nDATA]={"SingleElectron_Run2012A_13Jul2012_xww",
				 "SingleElectron_Run2012A_recover_xww",
				 "SingleElectron_Run2012B_13Jul2012_xww",
				 "SingleElectron_Run2012C_24Aug2012_xww",
				 "SingleElectron_Run2012C_PromptReco_xww",
				 "SingleElectron_Run2012C_EcalRecove_xww",
				 "SingleElectron_Run2012D_PromptReco_xww"};  


   const int nDATA=7;//set to zero if you don't want to plot
  std::string dataLabels[nDATA]={"SingleMu_Run2012A_13Jul2012_xww",
                 "SingleMu_Run2012A_recover_xww",
                 "SingleMu_Run2012B_13Jul2012_xww",
                 "SingleMu_Run2012C_24Aug2012_xww",
                 "SingleMu_Run2012C_PromptReco_xww",
                 "SingleMu_Run2012C_EcalRecove_xww",
                 "SingleMu_Run2012D_PromptReco_xww"};
*/

/*
  const int nDATA=1;//set to zero if you don't want to plot
  std::string dataLabels[nDATA]={"data_xww"};
*/

/*   
  const int nDATA=0;//set to zero if you don't want to plot
  std::string dataLabels[nDATA]={};
 */

  std::vector<std::string> fData;
  for(int ii=0;ii<nDATA;ii++){
    fData.push_back(pathToTrees+"treeEDBR_"+dataLabels[ii]+".root");
  }

  /// Setup names of MC files for trees.

  const int nMC=6;//set to zero if you don't want to plot
  std::string mcLabels[nMC]={"TTBARpowheg",
			     "WW",
			     "WZ",
			     "ZZ",
			     "DYJetsPt70To100",
			     "DYJetsPt100",
  };
  double kFactorsMC_array[nMC] = {1, 1, 1, 1, 1, 1};
  
  /*
  const int nMC=7;//set to zero if you don't want to plot
  std::string mcLabels[nMC]={"TTBARpowheg",
			     "WW",
			     "WZ",
			     "ZZ",
			     "DYJetsPt50To70",
			     "DYJetsPt70To100",
			     "DYJetsPt100"};
  double kFactorsMC_array[nMC] = {1., 1., 1., 1., 1., 1., 1.};
  */  

  
  /*
  const int nMC=5;//set to zero if you don't want to plot
  std::string mcLabels[nMC]={//"TTBAR_xww",
                               "TTBARpowheg_xww",
			     //"SingleTopBarTWchannel_xww",
			     //"SingleTopTWchannel_xww",
			     //"SingleTopBarSchannel_xww", 
			     //"SingleTopSchannel_xww",
			     //"SingleTopBarTchannel_xww",
			     //"SingleTopTchannel_xww",
				"SingleTop_xww",
			     //"WW_xww",
			     //"WZ_xww",
			     //"ZZ_xww",
				"VV_xww",
			     //"DYJetsPt50To70_xww",
			     //"DYJetsPt70To100_xww",
			     //"DYJetsPt100_xww",
				"DYJets_xww",
			     //"WJetsPt50To70_xww",
			     //"WJetsPt70To100_xww",
			     // "WJetsPt180_xww",
			        "WJetsPt100_xww",
			     };
  */
  //WW, muon channel
  //double kFactorsMC_array[nMC] = {1, 1., 1., 1., 1.3};
  //WW, electron channel

  std::vector<std::string> fMC;
  for(int ii=0;ii<nMC;ii++){
    fMC.push_back(pathToTrees+"treeEDBR_"+mcLabels[ii]+".root");
  }

  std::vector<double> kFactorsMC;
  //std::cout << "The contents of kFactorsMC are:" << std::endl;
  for (int index=0; index<nMC; index++)
    {
      //std::cout << kFactorsMC_array[index] << std::endl;
      kFactorsMC.push_back( kFactorsMC_array[index] );	
    }

  /// Setup names of MC signal files for trees.
  const int nMCSig=1;//set to zero if you don't want to plot
  std::string mcLabelsSig[nMCSig]={"BulkG_ZZ_lljj_c0p2_M1000"
				   //"BulkG_WW_lvjj_c0p2_M1000_xww",				   
                                   //"BulkG_WW_lvjj_c0p2_M2000_xww"				   
                                  };
  double kFactorsSig_array[nMCSig] = {1000.0};


  std::vector<double> kFactorsMCSig;
  for (int index=0; index<nMCSig; index++)
    {
      kFactorsMCSig.push_back( kFactorsSig_array[index] );	
    }
  
  /*
  const int nMCSig=1;//set to zero if you don't want to plot
  std::string mcLabelsSig[nMCSig]={"BulkG_ZZ_lljj_c1p0_M1500"};
  */
  
  std::vector<std::string> fMCSig;
  for(int ii=0;ii<nMCSig;ii++){
    fMCSig.push_back(pathToTrees+"treeEDBR_"+mcLabelsSig[ii]+".root");
  }

  /// Setup names of files for histograms (data and MC)
  std::vector<std::string> fHistosData;
  std::vector<std::string> fHistosMC;
  std::vector<std::string> fHistosMCSig;
 
  char buffer[256];
  printf("All strings set\n");


  /// ----------------------------------------------------------------
  /// This first part is the loop over trees to create histogram files 
  /// ----------------------------------------------------------------

  /// The EDBRHistoMaker, for reference
  ///
  ///EDBRHistoMaker::EDBRHistoMaker(TTree* tree, 
  ///		       bool wantElectrons,
  ///		       bool wantMuons,
  ///		       bool wantSideband,
  ///		       bool wantSignal,
  ///		       int  wantNXJets,
  ///              bool isZZchannel)

  printf("\nStart making histograms\n\n");

  //loop over data files and make histograms individually for each of them
  for(int i=0;i<nDATA;i++){

    std::cout<<"\n-------\nRunning over "<<dataLabels[i].c_str()<<std::endl;
    std::cout<<"The file is " <<fData.at(i)<<std::endl;
    sprintf(buffer,"histos_%s.root",dataLabels[i].c_str());
    fHistosData.push_back(buffer);
    
    if(redoHistograms) {
      TFile *fileData = TFile::Open(fData.at(i).c_str());
      TTree *treeData = (TTree*)fileData->Get("SelectedCandidates");
      EDBRHistoMaker* maker = new EDBRHistoMaker(treeData, 
						 wantElectrons,
						 wantMuons,
						 wantSideband,
						 wantSignal,
						 wantFullRange,
						 wantNXJets,
						 isZZchannel);
      maker->setUnitaryWeights(true);
      maker->Loop(buffer);
      //delete maker; // This class is badly written and deleting it isn't safe!
      fileData->Close();
    }
    
  }//end loop on data files

  printf("Loop over data done\n");
 
  //loop over MC files and make histograms individually for each of them
  for(int i=0;i<nMC;i++){
    std::cout<<"\n-------\nRunning over "<<mcLabels[i].c_str()<<std::endl;
    std::cout<<"The file is " <<fMC.at(i)<<std::endl;    
    sprintf(buffer,"histos_%s.root",mcLabels[i].c_str());
    fHistosMC.push_back(buffer);
    
    if(redoHistograms){
      TFile *fileMC = TFile::Open(fMC.at(i).c_str());
      TTree *treeMC = (TTree*)fileMC->Get("SelectedCandidates");
      EDBRHistoMaker* maker = new EDBRHistoMaker(treeMC, 
						 wantElectrons, 
						 wantMuons, 
						 wantSideband, 
						 wantSignal, 
						 wantFullRange,
						 wantNXJets,
						 isZZchannel);
      maker->setUnitaryWeights(false);
      maker->Loop(buffer);
      //delete maker; // This class is badly written and deleting it isn't safe!
      fileMC->Close();
    }
    
  }//end loop on MC files

  printf("Loop over MC done\n");

  //loop over MC signal files and make histograms individually for each of them
  for(int i=0;i<nMCSig;i++){
    std::cout<<"\n-------\nRunning over "<<mcLabelsSig[i].c_str()<<std::endl;
    std::cout<<"The file is " <<fMCSig.at(i)<<std::endl;    
    sprintf(buffer,"histos_%s.root",mcLabelsSig[i].c_str());
    fHistosMCSig.push_back(buffer);
    
    if(redoHistograms){
      TFile *fileMCSig = TFile::Open(fMCSig.at(i).c_str());
      TTree *treeMCSig = (TTree*)fileMCSig->Get("SelectedCandidates");
      EDBRHistoMaker* maker = new EDBRHistoMaker(treeMCSig, 
						 wantElectrons, 
						 wantMuons, 
						 wantSideband, 
						 wantSignal, 
						 wantFullRange,
						 wantNXJets,
						 isZZchannel);
      maker->setUnitaryWeights(false);
      maker->Loop(buffer);
      //delete maker; // This class is badly written and deleting it isn't safe!
      fileMCSig->Close();
    }
    
  }//end loop on MC files

  printf("Loop over MC signal done\n");
  
  /// ------------------------------------------------------------------
  /// This second part is the loop over histograms to create stack plots
  /// ------------------------------------------------------------------  

  //  EDBRHistoMaker::EDBRHistoMaker(TTree* tree,
  //			 bool wantElectrons,
  //			 bool wantMuons,
  //			 bool wantSideband,
  //			 bool wantSignal,
  //			 int  wantNXJets,
  //			 bool isZZchannel){
    
  printf("\nStart looping over histograms\n\n");
  //make nice plots
  std::vector<std::string> listOfHistos;
  if(nMC>0){
    // Open one of the histogram files just to get the list of histograms
    // produced, then loop over all the histograms inheriting 
    // from TH1 contained in the file.
    sprintf(buffer,"histos_%s.root",mcLabels[0].c_str());
    std::cout<<"Opening "<<buffer<<std::endl;
    TFile* oneFile = TFile::Open(buffer);
    TIter next(oneFile->GetListOfKeys());
    TKey *key;
    
    while ((key = (TKey*)next())) {
      TClass *cl = gROOT->GetClass(key->GetClassName());
      if (!cl->InheritsFrom("TH1")) continue;
      TH1 *hTMP = (TH1*)key->ReadObj();
      std::string hName=hTMP->GetName();
      //  printf("Histogram found: %s\n",hName.c_str());
      if(hName=="h_mj_vs_mzz")continue;//skip 2D histos
      bool isMJJhisto=(hName.find("mJJ")!=std::string::npos);
      bool isMZZhisto=(hName.find("mZZ")!=std::string::npos);
      if( !isMJJhisto && !isMZZhisto)continue;//skip all histos except MJJ and MZZ
      listOfHistos.push_back(hName);
    }//end while loop
    oneFile->Close();
  }//end if fmc size >0

  EDBRHistoPlotter *plotter=new EDBRHistoPlotter("./",
						 fHistosData,
						 fHistosMC,
						 fHistosMCSig,
						 lumiValue,
						 wantNXJets,
						 flavour,
						 isZZchannel,
						 scaleToData,
						 scaleOnlyWJets,
						 makeRatio,
						 isSignalStackOnBkg,
						 kFactorsMC,kFactorsMCSig);
  std::cout<<"Set output dir"<<std::endl;
  plotter->setOutDir(outputDir);
  plotter->setDebug(false);

  //colors are assigned in the same order of mcLabels

  
  //For ZZ
  ////// {"TTBAR","WW","WZ","ZZ","DYJetsPt50To70","DYJetsPt70To100","DYJetsPt100","WJetsPt50To70","WJetsPt70To100","WJetsPt100"};
  std::vector<int> fColorsMC;
  fColorsMC.push_back(kGreen-3);
  //fColorsMC.push_back(kYellow-9);
  //fColorsMC.push_back(kYellow-6);
  //fColorsMC.push_back(kYellow-3);
  //fColorsMC.push_back(kYellow+3);
  //fColorsMC.push_back(kYellow+6);
  //fColorsMC.push_back(kYellow+9);
  fColorsMC.push_back(kMagenta-9);
  fColorsMC.push_back(kMagenta-6);
  fColorsMC.push_back(kMagenta-3);
  //fColorsMC.push_back(kBlue-3);
  fColorsMC.push_back(kBlue-6);
  fColorsMC.push_back(kBlue-9);
  //fColorsMC.push_back(kRed+3);
  //fColorsMC.push_back(kRed);
  //fColorsMC.push_back(kRed-4);
  
  //For WW
  //{ "TTBARpowheg_xww", "SingleTop_xww", "VV_xww", "DYJets_xww", "WJetsPt100_xww"}
  //std::vector<int> fColorsMC;
  //fColorsMC.push_back(kGreen-3);
  //fColorsMC.push_back(kYellow-9);
  //fColorsMC.push_back(kMagenta-9);
  //fColorsMC.push_back(kBlue-3);
  //fColorsMC.push_back(kRed-4);

  ////// {"BulkG_WW_lvjj_c1p0_M600_xww","BulkG_WW_lvjj_c1p0_M1000_xww","BulkG_WW_lvjj_c1p0_M1500_xww"};
  std::vector<int> fColorsMCSig;
  //  fColorsMCSig.push_back(kPink);
  fColorsMCSig.push_back(kOrange+7);
  fColorsMCSig.push_back(kMagenta);
  fColorsMCSig.push_back(kBlue+3);
  
  plotter->setFillColor(fColorsMC);
  plotter->setLineColor(fColorsMCSig);

  int numOfHistos = listOfHistos.size();
  for(int i = 0; i != numOfHistos; ++i) 
    plotter->makeStackPlots(listOfHistos.at(i));      

  printf("Plotting done\n");
    
  delete plotter;

}//end main
//------------------------------------------------------------------------------
THStack* PlotAlignmentValidation::addHists(const char *selection, const TString &residType,
					   bool printModuleIds)
{
  enum ResidType {
    xPrimeRes, yPrimeRes, xPrimeNormRes, yPrimeNormRes, xRes, yRes, xNormRes, /*yResNorm*/
    ResXvsXProfile,  ResXvsYProfile, ResYvsXProfile, ResYvsYProfile
  };
  ResidType rType = xPrimeRes;
  if (residType == "xPrime") rType = xPrimeRes;
  else if (residType == "yPrime") rType = yPrimeRes;
  else if (residType == "xPrimeNorm") rType = xPrimeNormRes;
  else if (residType == "yPrimeNorm") rType = yPrimeNormRes;
  else if (residType == "x") rType = xRes;
  else if (residType == "y") rType = yRes;
  else if (residType == "xNorm") rType = xNormRes;
  // else if (residType == "yNorm") rType = yResNorm;
  else if (residType == "ResXvsXProfile") rType = ResXvsXProfile;
  else if (residType == "ResYvsXProfile") rType = ResYvsXProfile;
  else if (residType == "ResXvsYProfile") rType = ResXvsYProfile;
  else if (residType == "ResYvsYProfile") rType = ResYvsYProfile;
  else {
    std::cout << "PlotAlignmentValidation::addHists: Unknown residual type "
	      << residType << std::endl; 
    return 0;
  }

  cout << "PlotAlignmentValidation::addHists: using selection " << selection << endl;
  THStack * retHistoStack = new THStack();
  double legendY = 0.80;
  TLegend * myLegend = new TLegend(0.17, legendY, 0.85, 0.88);
  setLegendStyle( *myLegend );

  for(std::vector<TkOfflineVariables*>::iterator itSourceFile = sourceList.begin();
      itSourceFile != sourceList.end(); ++itSourceFile) {

    //  TFile *f = (*sourceList.begin())->getFile();
    TFile *f = (*itSourceFile)->getFile();
    //  TTree *tree= (*sourceList.begin())->getTree();
    TTree *tree= (*itSourceFile)->getTree();
    int myLineColor = (*itSourceFile)->getLineColor();
    int myLineStyle = (*itSourceFile)->getLineStyle();
    TString myLegendName = (*itSourceFile)->getName();
    if (!f || !tree) {
      std::cout << "PlotAlignmentValidation::addHists: no tree or no file" << std::endl;
      return 0;
    }

    // Todo: TLegend?
  
    // first loop on tree to find out which entries (i.e. modules) fulfill the selection
    // 'Entry$' gives the entry number in the tree
    Long64_t nSel = tree->Draw("Entry$", selection, "goff");
    if (nSel == -1) return 0; // error in selection
    if (nSel == 0) {
      std::cout << "PlotAlignmentValidation::addHists: no selected module." << std::endl;
      return 0;
    }
    // copy entry numbers that fulfil the selection
    const std::vector<double> selected(tree->GetV1(), tree->GetV1() + nSel);

    TH1 *h = 0;       // becomes result
    UInt_t nEmpty = 0;// selected, but empty hists
    Long64_t nentries =  tree->GetEntriesFast();
    std::vector<double>::const_iterator iterEnt = selected.begin();

    // second loop on tree:
    // for each selected entry get the hist from the file and merge
    TkOffTreeVariables *treeMem = 0; // ROOT will initialise
    tree->SetBranchAddress("TkOffTreeVariables", &treeMem);
    for (Long64_t i = 0; i < nentries; i++){
      if (i < *iterEnt - 0.1             // smaller index (with tolerance): skip
	  || iterEnt == selected.end()) { // at the end: skip 
	continue;
      } else if (TMath::Abs(i - *iterEnt) < 0.11) {
	++iterEnt; // take this entry!
      } else std::cout << "Must not happen: " << i << " " << *iterEnt << std::endl;

      tree->GetEntry(i);
      if (printModuleIds) {
	std::cout << treeMem->moduleId << ": " << treeMem->entries << " entries" << std::endl;
      }
      if (treeMem->entries <= 0) {  // little speed up: skip empty hists
	++nEmpty;
	continue;
      }
      TString hName;
      switch(rType) {
      case xPrimeRes:     hName = treeMem->histNameX.c_str();          break;
      case yPrimeRes:     hName = treeMem->histNameY.c_str();          break;
      case xPrimeNormRes: hName = treeMem->histNameNormX.c_str();      break;
      case yPrimeNormRes: hName = treeMem->histNameNormY.c_str();      break;
      case xRes:          hName = treeMem->histNameLocalX.c_str();     break;
      case yRes:          hName = treeMem->histNameLocalY.c_str();     break;
      case xNormRes:      hName = treeMem->histNameNormLocalX.c_str(); break;
	/*case yResNorm:      hName = treeMem->histNameNormLocalY.c_str(); break;*/
      case ResXvsXProfile: hName = treeMem->profileNameResXvsX.c_str();    break;
      case ResXvsYProfile: hName = treeMem->profileNameResXvsY.c_str();    break;
      case ResYvsXProfile: hName = treeMem->profileNameResYvsX.c_str();    break;
      case ResYvsYProfile: hName = treeMem->profileNameResYvsY.c_str();    break;
      }
      TKey *histKey = f->FindKeyAny(hName);
      TH1 *newHist = (histKey ? static_cast<TH1*>(histKey->ReadObj()) : 0);
      if (!newHist) {
	std::cout << "Hist " << hName << " not found in file, break loop." << std::endl;
	break;
      }
      newHist->SetLineColor(myLineColor);
      newHist->SetLineStyle(myLineStyle);
      if (!h) { // first hist: clone, but rename keeping only first part of name
	TString name(newHist->GetName());
	Ssiz_t pos_ = 0;
	for (UInt_t i2 = 0; i2 < 3; ++i2) pos_ = name.Index("_", pos_+1);
	name = name(0, pos_); // only up to three '_'
	h = static_cast<TH1*>(newHist->Clone("summed_"+name));
	//      TString myTitle = Form("%s: %lld modules", selection, nSel);
	//	h->SetTitle( myTitle );
      } else { // otherwise just add
	h->Add(newHist);
      }
      delete newHist;
    }

    std::cout << "PlotAlignmentValidation::addHists" << "Result is merged from " << nSel-nEmpty
	      << " modules, " << nEmpty << " hists were empty." << std::endl;

    if (nSel-nEmpty == 0) continue;

    myLegend->AddEntry(myLegendName, myLegendName, "L");
    
    retHistoStack->Add(h);
  }
  myLegend->Draw();
  return retHistoStack;
}
//------------------------------------------------------------------------------
void PlotAlignmentValidation::plotOutlierModules(const char *outputFileName, std::string plotVariable,
						 float plotVariable_cut ,int unsigned minHits)
{
 
  Int_t counter=0;
  setNiceStyle();
  
  gStyle->SetOptStat(111111);
  gStyle->SetStatY(0.9);
  //TList treelist=getTreeList();
  
  TCanvas *c1 = new TCanvas("canv", "canv", 800, 500);
  //setCanvasStyle( *c1 );
  outputFile = outputDir +'/'+ outputFileName;   
  c1->Print( (outputFile+'[').Data() ); 
  
  
  c1->Divide(2,1);
  
  TTree *tree= (*sourceList.begin())->getTree();
  TkOffTreeVariables *treeMem = 0; // ROOT will initilise
  tree->SetBranchAddress("TkOffTreeVariables", &treeMem);
  
  
  Long64_t nentries =  tree->GetEntriesFast();
  
  for (Long64_t i = 0; i < nentries; i++){
    
    tree->GetEntry(i);
    float var = 0;
    if (plotVariable == "chi2PerDofX") var =treeMem->chi2PerDofX;
    else if(plotVariable == "chi2PerDofY") var =treeMem->chi2PerDofY;
    else if(plotVariable == "fitMeanX") var =treeMem->fitMeanX;
    else if(plotVariable == "fitMeanY") var =treeMem->fitMeanY;
    else if(plotVariable == "fitSigmaX") var =treeMem->fitSigmaX;
    else if(plotVariable == "fitSigmaY") var =treeMem->fitSigmaY;
    else {
      cout<<"There is no variable "<<plotVariable<<" included in the tree."<<endl;
      break;
    }
//   cout<<"treeMem->entries  "<<treeMem->entries<<endl;  
//  cout<<"var                  "<<var<<endl;
//  cout<<"plotVariable_cut     "<<plotVariable_cut<<endl;
    
    if (var > plotVariable_cut && treeMem->entries > minHits)
      {
	
	TFile *f=(*sourceList.begin())->getFile();//(TFile*)sourcelist->First();
	
	if(f->FindKeyAny(treeMem->histNameX.c_str())!=0){
	  TH1 *h = (TH1*) f->FindKeyAny(treeMem->histNameX.c_str())->ReadObj();//f->FindObjectAny(treeMem->histNameX.c_str());
	  gStyle->SetOptFit(0111);
	  cout<<"hist name "<<h->GetName()<<endl;
	  
	  TString path =(char*)strstr( gDirectory->GetPath(), "TrackerOfflineValidation" );
	  //cout<<"hist path "<<path<<endl;
	  //cout<<"wrote text "<<endl;
	  if(h) cout<<h->GetEntries()<<endl;
	  
	  //modules' location as title
	  c1->cd(0);
	  TPaveText * text=new TPaveText(0,0.95,0.99,0.99);
	  text->AddText(path);
	  text->SetFillColor(0);
	  text->SetShadowColor(0);
	  text->SetBorderSize( 0 );
	  text->Draw();
	  
	  //residual histogram
	  c1->cd(1);
	  TPad *subpad = (TPad*)c1->GetPad(1);
	  subpad->SetPad(0,0,0.5,0.94);
	  h->Draw();
	  
	  //norm. residual histogram
	  h = (TH1*) f->FindObjectAny(treeMem->histNameNormX.c_str());
	  if(h) cout<<h->GetEntries()<<endl;
	  c1->cd(2);
	  TPad *subpad2 = (TPad*)c1->GetPad(2);
	  subpad2->SetPad(0.5,0,0.99,0.94);
	  h->Draw();
	  
	  c1->Print(outputFile);
	  counter++;
	}
	else{
	  cout<<"There are no residual histograms on module level stored!"<<endl;
	  cout<<"Please make sure that moduleLevelHistsTransient = cms.bool(False) in the validation job!"<<endl;
	  break;
	}
      }
    
  }
  c1->Print( (outputFile+"]").Data() );
  if (counter == 0) cout<<"no bad modules found"<<endl;
  
  
  //read the number of entries in the t3
  //TTree* tree=0;
  //tree=(TTree*)treeList->At(0);
  
  
  //c1->Close();
  
}