void ZeeGammaMassFitSystematicStudy(string workspaceFile, const Int_t seed = 1234, 
                                    Int_t Option = 0, Int_t NToys = 1) {


  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================    
  TRandom3 *randomnumber = new TRandom3(seed);
//   RooRealVar m("m","mass",60,130);

  RooCategory sample("sample","");
  sample.defineType("Pass",1);
  sample.defineType("Fail",2);

  //--------------------------------------------------------------------------------------------------------------
  //Load Workspace
  //==============================================================================================================    
  TFile *f = new TFile (workspaceFile.c_str(), "READ");
  RooWorkspace *w = (RooWorkspace*)f->Get("MassFitWorkspace");

  //--------------------------------------------------------------------------------------------------------------
  //Setup output tree
  //==============================================================================================================    
  TFile *outputfile = new TFile (Form("EffToyResults_Option%d_Seed%d.root",Option, seed), "RECREATE");
  float varEff = 0;
  float varEffErrL = 0;
  float varEffErrH = 0;
  TTree *outTree = new TTree("eff","eff");
  outTree->Branch("eff",&varEff, "eff/F");
  outTree->Branch("efferrl",&varEffErrL, "efferrl/F");
  outTree->Branch("efferrh",&varEffErrH, "efferrh/F");
  
  //--------------------------------------------------------------------------------------------------------------
  //Load Model
  //==============================================================================================================    
  RooSimultaneous *totalPdf = (RooSimultaneous*)w->pdf("totalPdf");
  RooRealVar *m_default = (RooRealVar*)w->var("m");
  m_default->setRange("signalRange",85, 95);
  
  //get default models
  RooAddPdf *modelPass_default = (RooAddPdf*)w->pdf("modelPass");
  RooAddPdf *modelFail_default = (RooAddPdf*)w->pdf("modelFail");

  //get variables
  RooRealVar *Nsig = (RooRealVar*)w->var("Nsig");
  RooRealVar *eff = (RooRealVar*)w->var("eff");
  RooRealVar *NbkgFail = (RooRealVar*)w->var("NbkgFail");

  RooFormulaVar NsigPass("NsigPass","eff*Nsig",RooArgList(*eff,*Nsig));	 
  RooFormulaVar NsigFail("NsigFail","(1.0-eff)*Nsig",RooArgList(*eff,*Nsig));

  //get number of expected events
  Double_t npass = 100;
  Double_t nfail = 169;

  //*************************************************************************************
  //make alternative model
  //*************************************************************************************
  RooRealVar *tFail_default = (RooRealVar*)w->var("tFail");
  RooRealVar *fracFail_default = (RooRealVar*)w->var("fracFail");
 

  RooRealVar *meanFail_default = (RooRealVar*)w->var("meanFail");
  RooRealVar *sigmaFail_default = (RooRealVar*)w->var("sigmaFail");
  RooHistPdf *bkgFailTemplate_default = (RooHistPdf*)w->pdf("bkgHistPdfFail");
  RooFFTConvPdf *sigFail_default = (RooFFTConvPdf*)w->pdf("signalFail");
  RooFFTConvPdf *bkgFail_default = (RooFFTConvPdf*)w->pdf("bkgConvPdfFail");
  RooExtendPdf *esignalFail_default = (RooExtendPdf *)w->pdf("esignalFail");
  RooExtendPdf *ebackgroundFail_default = (RooExtendPdf *)w->pdf("ebackgroundFail");
  RooExponential *bkgexpFail_default = (RooExponential*)w->pdf("bkgexpFail");
  RooAddPdf *backgroundFail_default = (RooAddPdf*)w->pdf("backgroundFail");
  RooGaussian *bkggausFail_default = (RooGaussian*)w->pdf("bkggausFail");

  //shifted mean
  RooRealVar *meanFail_shifted = new RooRealVar("meanFail_shifted","meanFail_shifted", 0, -5, 5);
  meanFail_shifted->setVal(meanFail_default->getVal());
  if (Option == 1) meanFail_shifted->setVal(meanFail_default->getVal()-1.0);
  else if (Option == 2) meanFail_shifted->setVal(meanFail_default->getVal()+1.0);  
  else if (Option == 11) meanFail_shifted->setVal(meanFail_default->getVal()-2.0);
  else if (Option == 12) meanFail_shifted->setVal(meanFail_default->getVal()+2.0);  

  RooRealVar *sigmaFail_shifted = new RooRealVar("sigmaFail_shifted","sigmaFail_shifted", 0, -5, 5);
  sigmaFail_shifted->setVal(sigmaFail_default->getVal());
  if (Option == 3) sigmaFail_shifted->setVal(sigmaFail_default->getVal()*1.2);
  else if (Option == 4) sigmaFail_shifted->setVal(sigmaFail_default->getVal()*0.8);

  CMCBkgTemplateConvGaussianPlusExp *bkgFailModel = new CMCBkgTemplateConvGaussianPlusExp(*m_default,bkgFailTemplate_default,false,meanFail_shifted,sigmaFail_shifted, "shifted");
  bkgFailModel->t->setVal(tFail_default->getVal());
  bkgFailModel->frac->setVal(fracFail_default->getVal());

  cout << "mean : " << meanFail_default->getVal() << " - " << meanFail_shifted->getVal() << endl;
  cout << "sigma : " << sigmaFail_default->getVal() << " - " << sigmaFail_shifted->getVal() << endl;
  cout << "t: " << tFail_default->getVal() << " - " << bkgFailModel->t->getVal() << endl;
  cout << "frac: " << fracFail_default->getVal() << " - " << bkgFailModel->frac->getVal() << endl;
  
  cout << "eff: " << eff->getVal() << " : " << NsigPass.getVal() << " / " << (NsigPass.getVal() + NsigFail.getVal()) << endl;
  cout << "NbkgFail: " << NbkgFail->getVal() << endl;


  //make alternative fail model
  RooAddPdf *modelFail=0;
  RooExtendPdf *esignalFail=0, *ebackgroundFail=0;
  ebackgroundFail = new RooExtendPdf("ebackgroundFail_shifted","ebackgroundFail_shifted",*(bkgFailModel->model),*NbkgFail,"signalRange");
  modelFail       = new RooAddPdf("modelFail","Model for FAIL sample", RooArgList(*esignalFail_default,*ebackgroundFail));



  cout << "*************************************\n";
  ebackgroundFail->Print();
  cout << "*************************************\n";
  ebackgroundFail_default->Print();
  cout << "*************************************\n";
  modelFail->Print();
  cout << "*************************************\n";
  modelFail_default->Print();
  cout << "*************************************\n";

  TCanvas *cv = new TCanvas("cv","cv",800,600);

  RooPlot *mframeFail_default = m_default->frame(Bins(Int_t(130-60)/2));
  modelFail_default->plotOn(mframeFail_default);
  modelFail_default->plotOn(mframeFail_default,Components("ebackgroundFail"),LineStyle(kDashed),LineColor(kRed));
  modelFail_default->plotOn(mframeFail_default,Components("bkgexpFail"),LineStyle(kDashed),LineColor(kGreen+2));
  mframeFail_default->GetYaxis()->SetTitle("");
  mframeFail_default->GetYaxis()->SetTitleOffset(1.2);
  mframeFail_default->GetXaxis()->SetTitle("m_{ee#gamma} [GeV/c^{2}]");
  mframeFail_default->GetXaxis()->SetTitleOffset(1.05);
  mframeFail_default->SetTitle("");
  mframeFail_default->Draw();

  cv->SaveAs("DefaultModel.gif");

  RooPlot *mframeFail = m_default->frame(Bins(Int_t(130-60)/2));
  modelFail->plotOn(mframeFail);
  modelFail->plotOn(mframeFail,Components("ebackgroundFail_shifted"),LineStyle(kDashed),LineColor(kRed));
  modelFail->plotOn(mframeFail,Components("bkgexpFail_shifted"),LineStyle(kDashed),LineColor(kGreen+2));
  mframeFail->GetYaxis()->SetTitle("");
  mframeFail->GetYaxis()->SetTitleOffset(1.2);
  mframeFail->GetXaxis()->SetTitle("m_{ee#gamma} [GeV/c^{2}]");
  mframeFail->GetXaxis()->SetTitleOffset(1.05);
  mframeFail->SetTitle("");
  mframeFail->Draw();
  cv->SaveAs(Form("ShiftedModel_%d.gif",Option));


  //*************************************************************************************
  //Do Toys
  //*************************************************************************************
  for(uint t=0; t < NToys; ++t) {

    RooDataSet *pseudoData_pass    = modelPass_default->generate(*m_default, randomnumber->Poisson(npass));
    RooDataSet *pseudoData_fail  = 0;
    pseudoData_fail    = modelFail->generate(*m_default, randomnumber->Poisson(nfail));
    RooDataSet *pseudoDataCombined = new RooDataSet("pseudoDataCombined","pseudoDataCombined",RooArgList(*m_default),
                                                    RooFit::Index(sample),
                                                    RooFit::Import("Pass",*pseudoData_pass),
                                                    RooFit::Import("Fail",*pseudoData_fail));

    pseudoDataCombined->write(Form("toy%d.txt",t));

    RooFitResult *fitResult=0;
    fitResult = totalPdf->fitTo(*pseudoDataCombined,
                                RooFit::Extended(),
                                RooFit::Strategy(2),
                                //RooFit::Minos(RooArgSet(eff)),
                                RooFit::Save());

    cout << "\n\n";
    cout << "Eff Fit: " << eff->getVal() << " -" << fabs(eff->getErrorLo()) << " +" << eff->getErrorHi() << endl;

    //Fill Tree
    varEff = eff->getVal();
    varEffErrL = fabs(eff->getErrorLo());
    varEffErrH = eff->getErrorHi();
    outTree->Fill();


//   //*************************************************************************************
//   //Plot Toys
//   //*************************************************************************************
//   TCanvas *cv = new TCanvas("cv","cv",800,600);
//   char pname[50];
//   char binlabelx[100];
//   char binlabely[100];
//   char yield[50];
//   char effstr[100];
//   char nsigstr[100];
//   char nbkgstr[100];
//   char chi2str[100];

//   //
//   // Plot passing probes
//   //

//   RooPlot *mframeFail_default = m.frame(Bins(Int_t(130-60)/2));
//   modelFail_default->plotOn(mframeFail_default);
//   modelFail_default->plotOn(mframeFail_default,Components("ebackgroundFail"),LineStyle(kDashed),LineColor(kRed));
//   modelFail_default->plotOn(mframeFail_default,Components("bkgexpFail"),LineStyle(kDashed),LineColor(kGreen+2));
//   mframeFail_default->Draw();
//   cv->SaveAs("DefaultModel.gif");





//   RooPlot *mframeFail = m.frame(Bins(Int_t(130-60)/2));
//   modelFail->plotOn(mframeFail);
//   modelFail->plotOn(mframeFail,Components("ebackgroundFail_shifted"),LineStyle(kDashed),LineColor(kRed));
//   modelFail->plotOn(mframeFail,Components("bkgexpFail_shifted"),LineStyle(kDashed),LineColor(kGreen+2));

//   sprintf(yield,"%u Events",(Int_t)passTree->GetEntries());
//   sprintf(nsigstr,"N_{sig} = %.1f #pm %.1f",NsigPass.getVal(),NsigPass.getPropagatedError(*fitResult));
//     plotPass.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);    
//   plotPass.AddTextBox(effstr,0.70,0.85,0.94,0.90,0,kBlack,-1);
//     plotPass.AddTextBox(0.70,0.73,0.94,0.83,0,kBlack,-1,1,nsigstr);//,chi2str);

//   mframeFail->Draw();
//   cv->SaveAs(Form("ShiftedModel_%d.gif",Option));


 
//   //
//   // Plot failing probes
//   //
//   sprintf(pname,"fail%s_%i",name.Data(),ibin);
//   sprintf(yield,"%u Events",(Int_t)failTree->GetEntries());
//   sprintf(nsigstr,"N_{sig} = %.1f #pm %.1f",NsigFail.getVal(),NsigFail.getPropagatedError(*fitResult));
//   sprintf(nbkgstr,"N_{bkg} = %.1f #pm %.1f",NbkgFail.getVal(),NbkgFail.getPropagatedError(*fitResult));
//   sprintf(chi2str,"#chi^{2}/DOF = %.3f",mframePass->chiSquare(nflfail));
//   CPlot plotFail(pname,mframeFail,"Failing probes","tag-probe mass [GeV/c^{2}]","Events / 2.0 GeV/c^{2}");
//   plotFail.AddTextBox(binlabelx,0.21,0.85,0.51,0.90,0,kBlack,-1);
//   if((name.CompareTo("etapt")==0) || (name.CompareTo("etaphi")==0)) {
//     plotFail.AddTextBox(binlabely,0.21,0.80,0.51,0.85,0,kBlack,-1);    
//     plotFail.AddTextBox(yield,0.21,0.76,0.51,0.80,0,kBlack,-1);    
//   } else {
//     plotFail.AddTextBox(yield,0.21,0.81,0.51,0.85,0,kBlack,-1);
//   }
//   plotFail.AddTextBox(effstr,0.70,0.85,0.94,0.90,0,kBlack,-1);  
//   plotFail.AddTextBox(0.70,0.68,0.94,0.83,0,kBlack,-1,2,nsigstr,nbkgstr);//,chi2str);
//   plotFail.Draw(cfail,kTRUE,format);  




  } //for loop over all toys
  



  //*************************************************************************************
  //Save To File
  //*************************************************************************************
  outputfile->WriteTObject(outTree, outTree->GetName(), "WriteDelete");

}
Example #2
0
void doPseudoFits(const TString infilename,      // input file
                  const TString binname,         // name
                  const TString binfile,         // file with bin info
                  const Int_t   sigModPass,      // signal extraction method for PASS sample
                  const Int_t   bkgModPass,      // background model for PASS sample
                  const Int_t   sigModFail,      // signal extraction method for FAIL sample
                  const Int_t   bkgModFail,      // background model for FAIL sample
                  const TString outputDir,       // output directory
                  const Int_t   charge,          // 0 (no charge requirement), -1, +1
                  const TString mcfilename="")   // ROOT file containing MC events to generate templates from
{
    gBenchmark->Start("plotEff");


    //--------------------------------------------------------------------------------------------------------------
    // Settings
    //==============================================================================================================

    // signal extraction mass region
    const Double_t massLo    = 60;
    const Double_t massHi    = 120;

    // fit mass region
    const Double_t fitMassLo = massLo;
    const Double_t fitMassHi = massHi;

    gSystem->mkdir(outputDir,kTRUE);

    //
    // parse pseudodata file
    //
    TH1D* histPass = new TH1D("histPass","",Int_t(fitMassHi-fitMassLo)/BIN_SIZE_PASS,fitMassLo,fitMassHi);
    TH1D* histFail = new TH1D("histFail","",Int_t(fitMassHi-fitMassLo)/BIN_SIZE_FAIL,fitMassLo,fitMassHi);

    TString readInFile = infilename+"/"+binname;

    cout << readInFile << endl;

    ifstream ifs;
    ifs.open(readInFile.Data());
    string line;
    while(getline(ifs,line)) {
        if(line[0]=='#') continue;
        if(line[0]=='%') continue;

        Double_t mass;
        Int_t state;
        stringstream ss(line);
        ss >> mass >> state;

        if (state == 1) histPass->Fill(mass);
        else if (state == 2) histFail->Fill(mass);
    }
    ifs.close();

    cout << "histPass has " << histPass->GetEntries() << endl;
    cout << "histFail has " << histFail->GetEntries() << endl;
    cout << "total we have " << histPass->GetEntries()+histFail->GetEntries() << endl;

    //
    // get binning info
    //
    TFile *f = new TFile(binfile);
    TTree *intree = (TTree*)f->Get("Bin");
    BinInfo bin;
    intree->SetBranchAddress("Bin",&bin);
    intree->GetEntry(0);

    cout << "we should have " << bin.nEvents << endl;

    cout << bin.ptLo << " " << bin.ptHi << " " << bin.etaLo << " " << bin.etaHi << " " << bin.phiLo << " " << bin.phiHi << " " << bin.npvLo << " " << bin.npvHi << " " << bin.absEta << endl;

    //
    // Generate histogram templates from MC if necessary
    //
    if(sigModPass==2 || sigModFail==2) {
        generateHistTemplates(mcfilename, bin.ptLo, bin.ptHi, bin.etaLo, bin.etaHi, bin.phiLo, bin.phiHi, bin.npvLo, bin.npvHi, bin.absEta, 0, bin.iBin);
    }

    RooRealVar m("m","mass",fitMassLo,fitMassHi);
    m.setBins(10000);

    Int_t nflpass=0, nflfail=0;

    TFile *histfile = 0;
    if(sigModPass==2 || sigModFail==2) {
        histfile = new TFile("histTemplates.root");
        assert(histfile);
    }


    RooCategory sample("sample","");
    sample.defineType("Pass",1);
    sample.defineType("Fail",2);

    RooAbsData *dataPass=0;
    RooAbsData *dataFail=0;
    RooAbsData *dataCombined=0;

    dataPass = new RooDataHist("dataPass","dataPass",RooArgSet(m),histPass);
    dataFail = new RooDataHist("dataFail","dataFail",RooArgSet(m),histFail);

    dataCombined = new RooDataHist("dataCombined","dataCombined",RooArgList(m),
                                   RooFit::Index(sample),
                                   RooFit::Import("Pass",*((RooDataHist*)dataPass)),
                                   RooFit::Import("Fail",*((RooDataHist*)dataFail)));

    // Define signal and background models
    CSignalModel     *sigPass = 0;
    CBackgroundModel *bkgPass = 0;
    CSignalModel     *sigFail = 0;
    CBackgroundModel *bkgFail = 0;

    char hname[50];
    sprintf(hname,"pass_%i",bin.iBin);
    TH1D *h = (TH1D*)histfile->Get(hname);
    assert(h);
    sigPass = new CMCTemplateConvGaussian(m,h,kTRUE);
    //((CMCTemplateConvGaussian*)sigPass)->mean->setVal(-0.1);
    //((CMCTemplateConvGaussian*)sigPass)->sigma->setVal(0.015);
    //((CMCTemplateConvGaussian*)sigPass)->sigma->setMax(0.2);
    nflpass += 2;
    if (bkgModPass == 1) {
        bkgPass = new CExponential(m,kTRUE);
        nflpass += 1;
    }
    else if (bkgModPass == 2) {
        bkgPass = new CErfExpo(m,kTRUE);
        nflfail += 3;
        //((CErfExpo*)bkgPass)->alfa->setVal(64.);
        //((CErfExpo*)bkgPass)->alfa->setMax(80.);
        //((CErfExpo*)bkgPass)->beta->setVal(1.0);
        //((CErfExpo*)bkgPass)->beta->setMax(3.0);
        //((CErfExpo*)bkgPass)->gamma->setVal(1.0);
        //((CErfExpo*)bkgPass)->gamma->setMax(3.0);
    }
    else {
        cout << "trying to use bkg model that's not implemented!!" << endl;
    }
    char hname2[50];
    sprintf(hname2,"fail_%i",bin.iBin);
    TH1D *h2 = (TH1D*)histfile->Get(hname2);
    assert(h2);
    sigFail = new CMCTemplateConvGaussian(m,h2,kFALSE);
    //((CMCTemplateConvGaussian*)sigFail)->mean->setVal(-0.28);
    //((CMCTemplateConvGaussian*)sigFail)->sigma->setVal(0.2);
    //((CMCTemplateConvGaussian*)sigFail)->sigma->setMax(2.0);
    nflfail += 2;

    if (bkgModFail == 1) {
        bkgFail = new CExponential(m,kFALSE);
        nflfail += 1;
    }
    else if (bkgModFail == 2) {
        bkgFail = new CErfExpo(m,kFALSE);
        nflfail += 3;
        //((CErfExpo*)bkgFail)->alfa->setVal(60.);
        //((CErfExpo*)bkgFail)->alfa->setMax(80.);
        //((CErfExpo*)bkgFail)->beta->setVal(0.07);
        //((CErfExpo*)bkgFail)->beta->setMax(0.5);
        //((CErfExpo*)bkgFail)->gamma->setVal(0.02);
        //((CErfExpo*)bkgFail)->gamma->setMax(1.0);
    }
    else {
        cout << "trying to use bkg model that's not implemented!!" << endl;
    }

    // Define free parameters
    Double_t NsigMax     = histPass->Integral()+histFail->Integral();
    cout << "NsigMax " << NsigMax << endl;
    Double_t NbkgFailMax = histFail->Integral();
    cout << "NbkgFailMax " << NbkgFailMax << endl;
    Double_t NbkgPassMax = histPass->Integral();
    RooRealVar Nsig("Nsig","Signal Yield",0.80*NsigMax,0,NsigMax);
    RooRealVar eff("eff","Efficiency",0.9,0,1.0);
    //cout << "got here" << endl;
    RooRealVar NbkgPass("NbkgPass","Background count in PASS sample",10,0,NbkgPassMax);
    //cout << "chicken" << endl;
    RooRealVar NbkgFail("NbkgFail","Background count in FAIL sample",10,0.01,NbkgFailMax);
    //cout << "frog" << endl;

    RooFormulaVar NsigPass("NsigPass","eff*Nsig",RooArgList(eff,Nsig));
    RooFormulaVar NsigFail("NsigFail","(1.0-eff)*Nsig",RooArgList(eff,Nsig));
    RooAddPdf *modelPass=0, *modelFail=0;
    RooExtendPdf *esignalPass=0, *ebackgroundPass=0, *esignalFail=0, *ebackgroundFail=0;

    if(massLo!=fitMassLo || massHi!=fitMassHi) {
        m.setRange("signalRange",massLo,massHi);

        esignalPass     = new RooExtendPdf("esignalPass","esignalPass",*(sigPass->model),NsigPass,"signalRange");
        ebackgroundPass = new RooExtendPdf("ebackgroundPass","ebackgroundPass",(bkgModPass>0) ? *(bkgPass->model) : *(sigPass->model),NbkgPass,"signalRange");
        modelPass       = new RooAddPdf("modelPass","Model for PASS sample",(bkgModPass>0) ? RooArgList(*esignalPass,*ebackgroundPass) : RooArgList(*esignalPass));

        esignalFail     = new RooExtendPdf("esignalFail","esignalFail",*(sigFail->model),NsigFail,"signalRange");
        ebackgroundFail = new RooExtendPdf("ebackgroundFail","ebackgroundFail",*(bkgFail->model),NbkgFail,"signalRange");
        modelFail       = new RooAddPdf("modelFail","Model for FAIL sample", (bkgModFail>0) ? RooArgList(*esignalFail,*ebackgroundFail) : RooArgList(*esignalFail));

    } else {
        modelPass = new RooAddPdf("modelPass","Model for PASS sample",
                                  RooArgList(*(sigPass->model),*(bkgPass->model)),
                                  RooArgList(NsigPass,NbkgPass));

        modelFail = new RooAddPdf("modelFail","Model for FAIL sample",
                                  RooArgList(*(sigFail->model),*(bkgFail->model)),
                                  RooArgList(NsigFail,NbkgFail));
    }
    cout << "whale?" << endl;
    RooSimultaneous totalPdf("totalPdf","totalPdf",sample);
    totalPdf.addPdf(*modelPass,"Pass");
    totalPdf.addPdf(*modelFail,"Fail");

    RooFitResult *fitResult=0;
    fitResult = totalPdf.fitTo(*dataCombined,
                               RooFit::Extended(),
                               RooFit::Strategy(1),
                               //RooFit::Minos(RooArgSet(eff)),
                               RooFit::Save());

    // Refit w/o MINOS if MINOS errors are strange...
    if((fabs(eff.getErrorLo())<5e-5) || (eff.getErrorHi()<5e-5))
        fitResult = totalPdf.fitTo(*dataCombined, RooFit::Extended(), RooFit::Strategy(1), RooFit::Save());

    cout << eff.getVal() << " " << fabs(eff.getErrorLo()) << " " << eff.getErrorHi() << endl;
    /*
    RooPlot *mframePass = m.frame(Bins(Int_t(fitMassHi-fitMassLo)/BIN_SIZE_PASS));
    dataPass->plotOn(mframePass,MarkerStyle(kFullCircle),MarkerSize(0.8),DrawOption("ZP"));
    modelPass->plotOn(mframePass);
    modelPass->plotOn(mframePass,Components("backgroundPass"),LineStyle(kDashed),LineColor(kRed));

    RooPlot *mframeFail = m.frame(Bins(Int_t(fitMassHi-fitMassLo)/BIN_SIZE_FAIL));
    dataFail->plotOn(mframeFail,MarkerStyle(kFullCircle),MarkerSize(0.8),DrawOption("ZP"));
    modelFail->plotOn(mframeFail);
    modelFail->plotOn(mframeFail,Components("backgroundFail"),LineStyle(kDashed),LineColor(kRed));

    TCanvas *cpass = MakeCanvas("cpass","cpass",720,540);
    cpass->SetWindowPosition(cpass->GetWindowTopX()+cpass->GetBorderSize()+800,0);
    TCanvas *cfail = MakeCanvas("cfail","cfail",720,540);
    cfail->SetWindowPosition(cfail->GetWindowTopX()+cfail->GetBorderSize()+800,cpass->GetWindowTopX()+cfail->GetBorderSize()+540);

    char ylabel[50];

    //
    // Plot passing probes
    //
    sprintf(ylabel,"Events / %.1f GeV/c^{2}",(Double_t)BIN_SIZE_PASS);
    CPlot plotPass("pass",mframePass,"Passing probes","tag-probe mass [GeV/c^{2}]",ylabel);
    plotPass.Draw(cpass,kTRUE,"png");

    //
    // Plot failing probes
    //
    sprintf(ylabel,"Events / %.1f GeV/c^{2}",(Double_t)BIN_SIZE_FAIL);
    CPlot plotFail("fail",mframeFail,"Failing probes","tag-probe mass [GeV/c^{2}]",ylabel);
    plotFail.Draw(cfail,kTRUE,"png");
    */
    //
    // Write fit results
    //

    TObjString* temp=(TObjString*)readInFile.Tokenize("/.")->At(4);

    ofstream txtfile;
    char txtfname[100];
    sprintf(txtfname,"%s/%s.output",outputDir.Data(),temp->GetString().Data());
    txtfile.open(txtfname);
    assert(txtfile.is_open());
    fitResult->printStream(txtfile,RooPrintable::kValue,RooPrintable::kVerbose);
    txtfile.close();

}