예제 #1
0
void ProcEvent(Int_t event, Int_t px, Int_t py, TObject *sel)
{
   //  print event type and current cursor position


   TCanvas *c = (TCanvas *) gTQSender;
   TPad *pad = (TPad *) c->GetSelectedPad();
   
    if(!pad) return;
    gROOT->SetEditHistograms(kFALSE);
    //printf("event=%d, px=%d, py=%d\n", event, px, py);
    //Float_t x = pad->AbsPixeltoX(px);
    //Float_t y = pad->AbsPixeltoY(py);
    //x = pad->PadtoX(x);
    //y = pad->PadtoY(y);
    //printf("x=%.3g, y=%.3g\n",x,y);
   if(event==kButton1Double){ 
     pad->Pop();
     //printf("%s %d\n",pad->GetName(),pad->GetNumber());
     pad->cd();
     TCanvas *c_blow;
     TIter next(pad->GetListOfPrimitives());
     if((TCanvas*)gROOT->GetListOfCanvases()->FindObject("c_blow")){
       c_blow=(TCanvas*)gROOT->GetListOfCanvases()->FindObject("c_blow");
       c_blow->Clear();
       //printf("show %d\n",c_blow->GetUniqueID());
       //c_blow->GetCanvasImp()->Show();
       //c_blow->RaiseWindow();
       //c_blow->GetCanvasImp()->RaiseWindow();
       //c_blow->Flush();
       //gVirtualX->RaiseWindow(c_blow->GetUniqueID());
       //c_blow->Show();

     }
     else{
 //      c_blow = new TCanvas("c_blow","blowup",750,0,743,525);
       c_blow = new TCanvas("c_blow","blowup",100,50,600,600);
       c_blow->SetFillColor(10); //white
       //c_blow->ToggleEventStatus();
       //c_blow->SetCrosshair();
       c_blow->Draw();
     }
     c_blow->cd();

     gROOT->SetSelectedPad((TPad*)c_blow);
     TPad *clone =(TPad*)pad->Clone();
     clone->SetPad(0,0,1,1);
     clone->Draw();
     clone->Modified();
     clone->Update();
     c_blow->Show();
  }
}
void tnail(){
  TPad *sel = (TPad*)gPad->GetSelectedPad();
  int px = gPad->GetEventX();
  int py = gPad->GetEventY();
  if (sel && sel != c  && sel != ct) {
    ct->cd();
    TPad *newpad = (TPad*)sel->Clone();
    ct->GetListOfPrimitives()->Add(newpad);
    newpad->SetPad(0,0,1,1);
    selold_tnail = newpad;
    ct->Update();
    ct->cd();
  }
}
예제 #3
0
/** 
 * Draw the Poisson estimate of the occupancy in a given ring.
 * 
 * @param p            List 
 * @param d            Detector
 * @param r            Ring
 * 
 * @return The occupancy (in percent)
 *
 * @deprecated Use QATrender instead
 * @ingroup pwglf_forward_scripts_qa
 */
Double_t
DrawRingOccupancy(TList* p, UShort_t d, Char_t r)
{
  if (!p) return 0;

  TList* ring = static_cast<TList*>(p->FindObject(Form("FMD%d%c",d,r)));
  if (!ring) { 
    Error("DrawOccupancy", "List FMD%d%c not found in %s",d,r,p->GetName());
    return 0;
  }
  
  TH1* corr = static_cast<TH1*>(ring->FindObject("occupancy"));
  if (!corr) { 
    Error("DrawRingOccupancy", "Histogram occupancy not found in FMD%d%c",
	  d, r);
    return 0;
  }
  corr->Rebin(4);

  TPad* pad = static_cast<TPad*>(gPad);
  pad->SetGridy();
  pad->SetGridx();
  pad->SetLogy();
  pad->SetFillColor(0);
    pad->SetRightMargin(0.01);
#if 0
  if (d == 3) { 
    pad->SetPad(pad->GetXlowNDC(), pad->GetYlowNDC(), .99, 
		 pad->GetYlowNDC()+pad->GetHNDC());
    pad->SetRightMargin(0.15);
  }
#endif

  corr->Draw("hist");

  TLatex* ltx = new TLatex(.95, .95, Form("FMD%d%c", d, r));
  ltx->SetNDC();
  ltx->SetTextAlign(33);
  ltx->SetTextSize(.08);
  ltx->Draw();

  return corr->GetMean();
}
예제 #4
0
//------------------------------------------------------------------------------
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();
  
}
예제 #5
0
void RooFitMacro()
{	
    gROOT->Reset();
    gSystem->Load("libRooFit");
    gROOT->LoadMacro("RooCMSShape.cc+");

    //gStyle->SetOptStat(111111);
    //gROOT->ProcessLine(".x ~/rootlogon.C");

    TFile f("TagAndProbeResults_Marco.root");


    TH1F * Z_mass = new TH1F("Z","Z" , 200, 0, 200);
    //TH1D *results = new TH1D("results", "results", 200, 0, 200);
    //results->Sumw2();

    // We need to include NJetCut because there is depedence w.r.t. jet multiplicity
    Z_mass = (TH1F*)f.Get("Zmass_Inclusive_NoElectronVeto_Numerator;1");
    //Z_mass = (TH1F*)f.Get("Zmass_Inclusive_NoElectronVeto_Denominator;1");

    //float bincontent = Z_mass->GetBinContent(60);
    //cout << "60.bin content  : " << bincontent << endl;

    double hmin = 60;
    double hmax = 120;
    double r  = .25;
    double sl = 1. / ( 1. - r );

    // Declare observable x
    RooRealVar x("x","x",hmin,hmax) ;
    RooDataHist dh("dh","dh",x,Import(*Z_mass)) ;
    //  Breit-Wigner Lineshape 
    //  Parameters for Breit-Wigner Distribution
    RooRealVar  M("M_{Z^{0}}", "Z0 Resonance  Mass", 91.18, 85.0, 95.0, "GeV/c^{2}");
    RooRealVar  gamma("#Gamma", "#Gamma", 2.4952, 2.0, 3.0, "GeV/c^{2}");
    M.setConstant();
    //gamma.setConstant();
    RooBreitWigner bw("bw", "A Breit-Wigner Distribution", x, M, gamma);
    //  Mass resolution model - Crystal Ball Lineshape
    //  Parameters for Crystal Ball Lineshape 
    RooRealVar  M_CB("#Delta m_{0}", "Bias", -2.0, -10.0, 10.0, "GeV/c^{2}");
    RooRealVar  sigma("#sigma_{CB}", "Width", 1.6, 0.1, 15.0, "GeV/c^{2}");
    //	RooRealVar  sigma("#sigma_{CB}", "Width", 2.5, 0.1, 15.0, "GeV/c^{2}");
    RooRealVar  alpha("#alpha", "Cut", 1.5, 0.1, 15.0);
    RooRealVar  n("n", "Power", 1.8, 0.5, 5.0);
    RooCBShape  cb("resCBF", "A  Crystal Ball Lineshape", x, M_CB, sigma, alpha, n);
    // background p.d.f
    RooRealVar cms_alpha("alpha", "alpha", 60, 50, 70);
    RooRealVar cms_beta("beta", "beta", 0.01, 0.001, 0.05);
    RooRealVar cms_gamma("gamma", "gamma", 0.05, 0.005, 0.5);
    RooRealVar peak("peak", "peak", 60, 50, 70);
    RooCMSShape bag("bag", "RooCMSShape", x, cms_alpha, cms_beta, cms_gamma, peak);
    RooRealVar  frac("frac", "f", 0.01, 0, 1.0);
    RooFFTConvPdf signal("signal", "Convolution", x, bw, cb);

    RooRealVar signal_yield("signal_yield", "signal_yield", 100, 0, Z_mass->Integral());
    RooRealVar bag_yield("bag_yield", "bag_yield", 0, 0, Z_mass->Integral());

    RooArgList shapes;
    RooArgList yields;

    shapes.add(signal);  
    shapes.add(bag);


    yields.add(signal_yield);  
    yields.add(bag_yield);

    RooRealVar fsig("fsig", "fsig", 0, 0, 1.);
    //RooAddPdf model("model","model",shapes,yields);

    // model = fsig x signal + (1-fsig) x bag
    RooAddPdf model("model","model",shapes,fsig,kTRUE);

    // Signal p.d.f.
    //RooFFTConvPdf sum("sum", "Convolution", x, bw, cb);
    //RooAddPdf sum("sum","sum",bw,cb,frac);
    //RooAddPdf model("model","model",RooArgList(sum, bag),frac);
    //RooFFTConvPdf model("model","model",x,sum,bag);
    //RooFitResult* filters = sum.fitTo(dh,Range(0,200),"qr");
    //filters->Print("v");


    //RooFitResult* filters = model.fitTo(dh,Range(0,200),"qr");
    RooFitResult* filters = model.fitTo(dh, RooFit::Minimizer("Minuit", "migradimproved"), RooFit::NumCPU(4), RooFit::Save(true), RooFit::Extended(false), RooFit::PrintLevel(-1));
    //RooFitResult* filters = model.fitTo(dh, RooFit::Extended(true), RooFit::PrintLevel(-1));
    //RooFitResult* filters = model.fitTo(dh, "mhe");
    //RooFitResult* filters = cb.fitTo(dh,Range(0,200),"qr");
    //RooFitResult* filters = bw.fitTo(dh,Range(0,100),"qr");
    //RooFitResult* filters = bag.fitTo(dh,"qr");


    TCanvas* canvas = new TCanvas("ZmassHisto","ZmassHisto",0, 0, 1000,700) ;
    canvas->cd() ; //gPad->SetLeftMargin(0.15);
    //gPad->SetLogy();
    RooPlot* frame = x.frame(Title("e #gamma invariant mass fit")) ;
    dh.plotOn(frame,MarkerSize(0.5),Name("data_hist"));  //this will show histogram data points on canvas

    dh.statOn(frame,Layout(0.15,0.37,0.85),What("N")) ;


    //dh.statOn(frame);  //this will display hist stat on canvas

    //sum.plotOn(frame,LineColor(4));//this will show fit overlay on canvas
    //sum.paramOn(frame); //this will display the fit parameters on canvas

    //bag.plotOn(frame,LineColor(2));//this will show fit overlay on canvas 
    //bag.paramOn(frame); //this will display the fit parameters on canvas

    model.plotOn(frame,Components(bag),LineColor(2));//this will show fit overlay on canvas 
    model.plotOn(frame,Components(signal),LineColor(3));//this will show fit overlay on canvas 
    model.plotOn(frame,LineColor(kBlue),Name("main_curve"));//this will show fit overlay on canvas 

    //	model.paramOn(frame); //this will display the fit parameters on canvas
    model.paramOn(frame, Layout(0.6, 0.95, 0.92)); //this will display the fit parameters on canvas
    //model.paramOn(frame, Layout(0.6, 0.99, 0.75));
    //	model.plotOn(frame,LineColor(4));//this will show fit overlay on canvas 
    //	model.paramOn(frame); //this will display the fit parameters on canvas

    RooHist* histogram = frame->getHist("data_hist");
    RooCurve* curve = frame->getCurve("main_curve");
    TH1D* hresidual  = residualHist(histogram,curve);
    hresidual->Sumw2();
    canvas->Divide( 1, 2, .1, .1 );
    TPad* padHisto = (TPad*) canvas->cd(1);
    TPad* padResid = (TPad*) canvas->cd(2);
    double small = 0.1;
    padHisto->SetPad( 0., r , 1., 1. );
    padHisto->SetBottomMargin( small );
    padResid->SetPad( 0., 0., 1., r  );
    padResid->SetBottomMargin( 0.3  );
    padResid->SetTopMargin   ( small );
    padHisto->cd();


    //float fitvalue = frame.GetX()[60];
    //Double_t nX = x.getVal();
    //cout << "nX  : " << nX << endl;
    //results->SetBinContent(results->GetXaxis()->FindBin(60), nX);
    //float fitvalue = results->GetBinContent(59);
    //cout << "59.5daki fit value  : " << fitvalue << endl;

    //cb.plotOn(frame,LineColor(2));//this will show fit overlay on canvas 
    //cb.paramOn(frame); //this will display the fit parameters on canvas

    //bw.plotOn(frame,LineColor(4));//this will show fit overlay on canvas 
    //bw.paramOn(frame); //this will display the fit parameters on canvas


    //gPad->SetLogy();
    cout << "chisquare : " << frame->chiSquare() << endl ;

    //cout << "Total Number of events: " << Z_mass->Integral() << endl;
    //cout << "Number of signal events: " << fsig.getVal() *  Z_mass->Integral() << endl;
    //cout << "Number of background events: " << (1 - fsig.getVal()) * Z_mass->Integral() << endl;

    //Draw all frames on a canvas

    //TPaveLabel *label1 = new TPaveLabel(1,500,15,700,"Chisquare:");
    frame->GetXaxis()->SetTitle("Invariant mass w/ NoElectronVeto photon (in GeV/c^{2})");  
    //frame->GetXaxis()->SetTitle("Invariant mass w/ TIGHT photon (in GeV/c^{2})");  
    //frame->GetXaxis()->SetTitleOffset(1.2);
    frame->Draw();
    //float binsize = Z_mass->GetBinWidth(1);
    //char Bsize[50]; 
    //sprintf(Bsize,"Events per %2.2f",binsize);
    //frame->GetYaxis()->SetTitle(Bsize);  
    //frame->GetYaxis()->SetTitleOffset(1.2);
    //results->Sumw2();
    padResid->cd();
    hresidual->Draw();
    Lines( hresidual );
    hresidual->Draw( "SAME" );

    //frame->Draw();
    //results->Draw();

    //canvas->Update();
    //title->Draw("same");
    //hresidual->Draw();

    canvas->SaveAs("pdf_TagAndProbe/ResidualNumerator_binned_negligible_errorfit.pdf");
    //canvas->SaveAs("pdf_TagAndProbe/ResidualDenominator_binned_negligible_errorfit.pdf");


}
예제 #6
0
// Make main selection plots
// n-1, control type plots and plots after all cuts
void makePlot(const TString & histoName, TFile * outputFile, TString anaType,
    const TString & xTitle,  const double & xMin, const double & xMax,
    const double & yMin = 0., const double & yMax = 0., bool logY=false,
    const float lumi = 0, const bool plotData=false, bool drawRatioPlot=false )
{
  std::cout << "----> Making plots for : " << histoName.Data() << std::endl;
  std::cout << "Plotting data ? " << plotData << std::endl;
  TH1::SetDefaultSumw2();
  gStyle->SetOptStat(0);
  gStyle->SetOptTitle(0);

  // Keep track of integrals of background & data
  double totalBkgMCIntegral = 0;
  //  double totalDataIntegral = 0;

  //
  // DATA
  //

  TH1F * histoData=0;

  if (plotData) {

    TFile * inputFile= new TFile ("CombinedFiles/Data_combined_"+anaType+".root", "READ");
    histoData = (TH1F*)inputFile->Get(histoName);
    //    totalDataIntegral = histoData->Integral();

    histoData->SetStats(0);
    histoData->SetMarkerStyle(21);
    histoData->SetMarkerSize(1);
  }

  //
  // SIGNAL MC
  //


  // Not good at the moment - just taking one or two examples to plot and hard coded the names of the files here
  TFile * signalInputFile1= new TFile (signal1+anaType+".root", "READ");
  TH1F * histoSignal1 = (TH1F*)signalInputFile1->Get(histoName);
  histoSignal1->SetStats(0);
  histoSignal1->Scale(lumi);

  TFile * signalInputFile2= new TFile (signal2+anaType+".root", "READ");
  TH1F * histoSignal2 = (TH1F*)signalInputFile2->Get(histoName);
  histoSignal2->SetStats(0);
  histoSignal2->Scale(lumi);

  int minIntegral=0;
  int maxIntegral=histoSignal1->GetNbinsX();

//  if ( histoName=="nMinus1_isolationLeptonH_removedLifetimeCuts" || histoName=="nMinus1_relIsolationLeptonH_removedLifetimeCuts" ) {
//    //    std::cout << find90Cut( histoSignal1 ) << std::endl;
//    //    std::cout << find90Cut( histoSignal2 ) << std::endl;
//
//    minIntegral=histoSignal1->FindBin( find90Cut(histoSignal1) );
//
//    // Check integral below specific cut
//    if ( histoName=="nMinus1_relIsolationLeptonH_removedLifetimeCuts" ) {
//      std::cout << "Signal 1" << std::endl;
//      std::cout << "Efficiency with rel iso cut at 0.1 : " << histoSignal1->Integral( 1, histoSignal1->FindBin(0.1) ) / histoSignal1->Integral() << std::endl;
//      std::cout << "Efficiency with rel iso cut at 0.05 : " << histoSignal1->Integral( 1, histoSignal1->FindBin(0.05) ) / histoSignal1->Integral() << std::endl;
//      std::cout << "Signal 2" << std::endl;
//      std::cout << "Efficiency with rel iso cut at 0.1 : " << histoSignal2->Integral( 1, histoSignal2->FindBin(0.1) ) / histoSignal2->Integral() << std::endl;
//      std::cout << "Efficiency with rel iso cut at 0.05 : " << histoSignal2->Integral( 1, histoSignal2->FindBin(0.05) ) / histoSignal2->Integral() << std::endl;
//    }
//  }

  TFile * signalInputFile3= new TFile (signal3+anaType+".root", "READ");
  TH1F * histoSignal3 = (TH1F*)signalInputFile3->Get(histoName);
  histoSignal3->SetStats(0);
  histoSignal3->Scale(lumi);

  //
  // BACKGROUND MC
  //

  THStack stack("Background MC","");
  setPlotTitle(stack, lumi);

  // Add all different background MC to this stack
  TLegend *legend= new TLegend(0.5,0.6,0.85,0.85);

  totalBkgMCIntegral = addBackgroundHistos(anaType, histoName, stack, legend, lumi, minIntegral, maxIntegral);


//  if ( histoName=="nMinus1_isolationLeptonH_removedLifetimeCuts" || histoName=="nMinus1_relIsolationLeptonH_removedLifetimeCuts" ) {
//    std::cout << "Integral of background between " << minIntegral << " and " << maxIntegral << " : " << totalBkgMCIntegral << std::endl;
//  }

  // Output histograms to file
  outputFile->cd();

  // Setup canvas
  TCanvas canvas(histoName);
  canvas.cd();
  // Draw one or two pads
  TPad * up = new TPad("u","u",0.01,0.25,0.99,0.99);
  up->SetNumber(1);
  up->Draw();
  TPad * dp = new TPad("d","d",0.01,0.01,0.99,0.25);

  if ( drawRatioPlot ) {
    dp->SetNumber(2);
    dp->UseCurrentStyle();
    dp->Draw();
  }
  else {
    up->SetPad(0.01,0.01,0.99,0.99);
    up->Draw();
  }

  if ( logY ) up->SetLogy();
  canvas.Draw();
  canvas.cd(1);
  up->cd();
  canvas.SetFillColor(kWhite);
  canvas.SetBorderMode(0);


  // Draw background MC
  // There may be zero entries, which will mess up drawing options
  // Not a good fix at the moment
  bool axesExist=false;
  if (totalBkgMCIntegral>0) {
    axesExist=true;

    stack.Draw("HISTE");

    stack.GetXaxis()->SetRangeUser(xMin, xMax);
    stack.SetMaximum(yMax);
    stack.SetMinimum(yMin);
    stack.GetXaxis()->SetTitle(xTitle);
    stack.GetYaxis()->SetTitle("Entries");
  }

  std::cout << "Drawing signal histos" << std::endl;
  // Draw signal MC
  histoSignal1->SetLineStyle(2);
  histoSignal1->SetLineColor(kMagenta+2);
  histoSignal1->SetLineWidth(2);
  if(axesExist) histoSignal1->Draw("same,HIST");
  else histoSignal1->Draw("HIST");

  histoSignal2->SetLineStyle(2);
  histoSignal2->SetLineColor(kGreen+2);
  histoSignal2->SetLineWidth(2);
  if(axesExist) histoSignal2->Draw("same,HIST");
  else histoSignal2->Draw("HIST");

  //  histoSignal3->SetLineStyle(2);
  //  histoSignal3->SetLineColor(4);
  //  histoSignal3->SetLineWidth(2);
  //  histoSignal3->Draw("same,HIST");

  // Draw data
  if ( plotData ) {
    if (axesExist) histoData->Draw("same,P,E,X0");
    else histoData->Draw("P,E,X0");
  }

  // Draw legend
  legend->SetBorderSize(0);
  legend->SetFillStyle(0);
  if ( plotData ) legend->AddEntry(histoData,"data","p");
  legend->AddEntry(histoSignal1,"m_{H}=1000 GeV/c^{2} m_{X}=350 GeV/c^{2}","l");
  legend->AddEntry(histoSignal2,"m_{H}=400 GeV/c^{2} m_{X}=50 GeV/c^{2}","l");
  //  legend->AddEntry(histoSignal3,"m_{squark}=350 GeV/c^{2} m_{#Chi}=148 GeV/c^{2}","l");

  legend->Draw();

  canvas.Update();

  // Draw mc/data ratio
  if ( drawRatioPlot ) {
    dp->cd();
    TH1F ratioHist( drawMCDataRatio( ((TH1*)stack.GetStack()->Last()), histoData ) );

    // Check content of ratioHist
    ratioHist.GetXaxis()->SetRangeUser(xMin, xMax);
    ratioHist.SetMarkerStyle(20);
    ratioHist.GetYaxis()->SetNdivisions(5,0,0);
    ratioHist.GetYaxis()->SetTickLength(0.01);
    dp->SetGridy();
    ratioHist.Draw("P");
    canvas.Update();
    canvas.Write();
  }
  else canvas.Write();

  // Draw systematic errors for reco PV plot
  // FIXME For some reason, old canvas can't handle this!
  if ( histoName=="nRecoPV" ) {
    TGraphAsymmErrors gr( makePUPlot( stack, anaType, lumi ) );

    // Move back to output file (as other files have been opened and closed in makePUPlot
    outputFile->cd();

    gr.SetFillColor(1);
    gr.SetFillStyle(3001);
    gr.Draw("2P0");
    canvas.Update();

    // Test
    TCanvas can("puSystematic");
    can.cd();
//    can.SetLogy();
    can.Draw();
    gr.SetTitle("TGraphAsymmErrors Example");

    stack.Draw("HISTE");
    gr.Draw("2P0");
    histoData->Draw("P,E,X0SAME");
    legend->Draw();

    can.Update();
    can.Write();
  }
}