RooWorkspace* makeInvertedANFit(TTree* tree, float forceSigma=-1, bool constrainMu=false, float forceMu=-1) {
  RooWorkspace *ws = new RooWorkspace("ws","");

  std::vector< TString (*)(TString, RooRealVar&, RooWorkspace&) > bkgPdfList;
  bkgPdfList.push_back(makeSingleExp);
  bkgPdfList.push_back(makeDoubleExp);
#if DEBUG==0
  //bkgPdfList.push_back(makeTripleExp);
  bkgPdfList.push_back(makeModExp);
  bkgPdfList.push_back(makeSinglePow);
  bkgPdfList.push_back(makeDoublePow);
  bkgPdfList.push_back(makePoly2);
  bkgPdfList.push_back(makePoly3);
#endif



  RooRealVar mgg("mgg","m_{#gamma#gamma}",103,160,"GeV");
  mgg.setBins(38);

  mgg.setRange("sideband_low", 103,120);
  mgg.setRange("sideband_high",131,160);
  mgg.setRange("signal",120,131);

  RooRealVar MR("MR","",0,3000,"GeV");
  MR.setBins(60);
  
  RooRealVar Rsq("t1Rsq","",0,1,"GeV");
  Rsq.setBins(20);

  RooRealVar hem1_M("hem1_M","",-1,2000,"GeV");
  hem1_M.setBins(40);

  RooRealVar hem2_M("hem2_M","",-1,2000,"GeV");
  hem2_M.setBins(40);

  RooRealVar ptgg("ptgg","p_{T}^{#gamma#gamma}",0,500,"GeV");
  ptgg.setBins(50);

  RooDataSet data("data","",tree,RooArgSet(mgg,MR,Rsq,hem1_M,hem2_M,ptgg));

  RooDataSet* blind_data = (RooDataSet*)data.reduce("mgg<121 || mgg>130");

  std::vector<TString> tags;
  //fit many different background models
  for(auto func = bkgPdfList.begin(); func != bkgPdfList.end(); func++) {
    TString tag = (*func)("bonly",mgg,*ws);
    tags.push_back(tag);
    ws->pdf("bonly_"+tag+"_ext")->fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
    RooFitResult* bres = ws->pdf("bonly_"+tag+"_ext")->fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
    bres->SetName(tag+"_bonly_fitres");
    ws->import(*bres);

    //make blinded fit
    RooPlot *fmgg_b = mgg.frame();
    blind_data->plotOn(fmgg_b,RooFit::Range("sideband_low,sideband_high"));
    TBox blindBox(121,fmgg_b->GetMinimum()-(fmgg_b->GetMaximum()-fmgg_b->GetMinimum())*0.015,130,fmgg_b->GetMaximum());
    blindBox.SetFillColor(kGray);
    fmgg_b->addObject(&blindBox);
    ws->pdf("bonly_"+tag+"_ext")->plotOn(fmgg_b,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("sideband_low,sideband_high"));
    fmgg_b->SetName(tag+"_blinded_frame");
    ws->import(*fmgg_b);
    delete fmgg_b;
    

    //set all the parameters constant
    RooArgSet* vars = ws->pdf("bonly_"+tag)->getVariables();
    RooFIter iter = vars->fwdIterator();
    RooAbsArg* a;
    while( (a = iter.next()) ){
      if(string(a->GetName()).compare("mgg")==0) continue;
      static_cast<RooRealVar*>(a)->setConstant(kTRUE);
    }

    //make the background portion of the s+b fit
    (*func)("b",mgg,*ws);

    RooRealVar sigma(tag+"_s_sigma","",5,0,100);
    if(forceSigma!=-1) {
      sigma.setVal(forceSigma);
      sigma.setConstant(true);
    }
    RooRealVar mu(tag+"_s_mu","",126,120,132);
    if(forceMu!=-1) {
      mu.setVal(forceMu);
      mu.setConstant(true);
    }
    RooGaussian sig(tag+"_sig_model","",mgg,mu,sigma);
    RooRealVar Nsig(tag+"_sb_Ns","",5,0,100);
    RooRealVar Nbkg(tag+"_sb_Nb","",100,0,100000);
    

    RooRealVar HiggsMass("HiggsMass","",125.1);
    RooRealVar HiggsMassError("HiggsMassError","",0.24);
    RooGaussian HiggsMassConstraint("HiggsMassConstraint","",mu,HiggsMass,HiggsMassError);


    RooAddPdf fitModel(tag+"_sb_model","",RooArgList( *ws->pdf("b_"+tag), sig ),RooArgList(Nbkg,Nsig));

    RooFitResult* sbres;
    RooAbsReal* nll;
    if(constrainMu) {
      fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
      sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
      nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
    } else {
      fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE));
      sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE));
      nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE));
    }
    sbres->SetName(tag+"_sb_fitres");
    ws->import(*sbres);
    ws->import(fitModel);

    RooPlot *fmgg = mgg.frame();
    data.plotOn(fmgg);
    fitModel.plotOn(fmgg);
    ws->pdf("b_"+tag+"_ext")->plotOn(fmgg,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("Full"));
    fmgg->SetName(tag+"_frame");
    ws->import(*fmgg);
    delete fmgg;


    RooMinuit(*nll).migrad();

    RooPlot *fNs = Nsig.frame(0,25);
    fNs->SetName(tag+"_Nsig_pll");
    RooAbsReal *pll = nll->createProfile(Nsig);
    //nll->plotOn(fNs,RooFit::ShiftToZero(),RooFit::LineColor(kRed));
    pll->plotOn(fNs);
    ws->import(*fNs);

    delete fNs;

    RooPlot *fmu = mu.frame(125,132);
    fmu->SetName(tag+"_mu_pll");
    RooAbsReal *pll_mu = nll->createProfile(mu);
    pll_mu->plotOn(fmu);
    ws->import(*fmu);

    delete fmu;

  }

  RooArgSet weights("weights");
  RooArgSet pdfs_bonly("pdfs_bonly");
  RooArgSet pdfs_b("pdfs_b");

  RooRealVar minAIC("minAIC","",1E10);
  //compute AIC stuff
  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooAbsPdf *p_bonly = ws->pdf("bonly_"+*t);
    RooAbsPdf *p_b = ws->pdf("b_"+*t);
    RooFitResult *sb = (RooFitResult*)ws->obj(*t+"_bonly_fitres");
    RooRealVar k(*t+"_b_k","",p_bonly->getParameters(RooArgSet(mgg))->getSize());
    RooRealVar nll(*t+"_b_minNll","",sb->minNll());
    RooRealVar Npts(*t+"_b_N","",blind_data->sumEntries());
    RooFormulaVar AIC(*t+"_b_AIC","2*@0+2*@1+2*@1*(@1+1)/(@2-@1-1)",RooArgSet(nll,k,Npts));
    ws->import(AIC);
    if(AIC.getVal() < minAIC.getVal()) {
      minAIC.setVal(AIC.getVal());
    }
    //aicExpSum+=TMath::Exp(-0.5*AIC.getVal()); //we will need this precomputed  for the next step
    pdfs_bonly.add(*p_bonly);
    pdfs_b.add(*p_b);
  }
  ws->import(minAIC);
  //compute the AIC weight
  float aicExpSum=0;
  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooFormulaVar *AIC = (RooFormulaVar*)ws->obj(*t+"_b_AIC");
    aicExpSum+=TMath::Exp(-0.5*(AIC->getVal()-minAIC.getVal())); //we will need this precomputed  for the next step    
  }
  std::cout << "aicExpSum: " << aicExpSum << std::endl;

  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooFormulaVar *AIC = (RooFormulaVar*)ws->obj(*t+"_b_AIC");
    RooRealVar *AICw = new RooRealVar(*t+"_b_AICWeight","",TMath::Exp(-0.5*(AIC->getVal()-minAIC.getVal()))/aicExpSum);
    if( TMath::IsNaN(AICw->getVal()) ) {AICw->setVal(0);}
    ws->import(*AICw);
    std::cout << *t << ":  " << AIC->getVal()-minAIC.getVal() << "    " << AICw->getVal() << std::endl;
    weights.add(*AICw);
  }
  RooAddPdf bonly_AIC("bonly_AIC","",pdfs_bonly,weights);
  RooAddPdf b_AIC("b_AIC","",pdfs_b,weights);

  //b_AIC.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
  //RooFitResult* bres = b_AIC.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
  //bres->SetName("AIC_b_fitres");
  //ws->import(*bres);

  //make blinded fit
  RooPlot *fmgg_b = mgg.frame(RooFit::Range("sideband_low,sideband_high"));
  blind_data->plotOn(fmgg_b,RooFit::Range("sideband_low,sideband_high"));
  TBox blindBox(121,fmgg_b->GetMinimum()-(fmgg_b->GetMaximum()-fmgg_b->GetMinimum())*0.015,130,fmgg_b->GetMaximum());
  blindBox.SetFillColor(kGray);
  fmgg_b->addObject(&blindBox);
  bonly_AIC.plotOn(fmgg_b,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("sideband_low,sideband_high"));
  fmgg_b->SetName("AIC_blinded_frame");
  ws->import(*fmgg_b);
  delete fmgg_b;
    
#if 1

  RooRealVar sigma("AIC_s_sigma","",5,0,100);
  if(forceSigma!=-1) {
    sigma.setVal(forceSigma);
    sigma.setConstant(true);
  }
  RooRealVar mu("AIC_s_mu","",126,120,132);
  if(forceMu!=-1) {
    mu.setVal(forceMu);
    mu.setConstant(true);
  }
  RooGaussian sig("AIC_sig_model","",mgg,mu,sigma);
  RooRealVar Nsig("AIC_sb_Ns","",5,0,100);
  RooRealVar Nbkg("AIC_sb_Nb","",100,0,100000);
  
  
  RooRealVar HiggsMass("HiggsMass","",125.1);
  RooRealVar HiggsMassError("HiggsMassError","",0.24);
  RooGaussian HiggsMassConstraint("HiggsMassConstraint","",mu,HiggsMass,HiggsMassError);
  
  
  RooAddPdf fitModel("AIC_sb_model","",RooArgList( b_AIC, sig ),RooArgList(Nbkg,Nsig));

  RooFitResult* sbres;
  RooAbsReal *nll;

  if(constrainMu) {
    fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
    sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
    nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
  } else {
    fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE));
    sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE));
    nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE));
  }

  assert(nll!=0);
  
  sbres->SetName("AIC_sb_fitres");
  ws->import(*sbres);
  ws->import(fitModel);
  
  RooPlot *fmgg = mgg.frame();
  data.plotOn(fmgg);
  fitModel.plotOn(fmgg);
  ws->pdf("b_AIC")->plotOn(fmgg,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("Full"));
  fmgg->SetName("AIC_frame");
  ws->import(*fmgg);
  delete fmgg;

  RooMinuit(*nll).migrad();
  
  RooPlot *fNs = Nsig.frame(0,25);
  fNs->SetName("AIC_Nsig_pll");
  RooAbsReal *pll = nll->createProfile(Nsig);
  //nll->plotOn(fNs,RooFit::ShiftToZero(),RooFit::LineColor(kRed));
  pll->plotOn(fNs);
  ws->import(*fNs);
  delete fNs;


  RooPlot *fmu = mu.frame(125,132);
  fmu->SetName("AIC_mu_pll");
  RooAbsReal *pll_mu = nll->createProfile(mu);
  pll_mu->plotOn(fmu);
  ws->import(*fmu);

  delete fmu;

  std::cout << "min AIC: " << minAIC.getVal() << std::endl;
  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooFormulaVar *AIC = (RooFormulaVar*)ws->obj(*t+"_b_AIC");
    RooRealVar *AICw = ws->var(*t+"_b_AICWeight");
    RooRealVar* k = ws->var(*t+"_b_k");
    printf("%s & %0.0f & %0.2f & %0.2f \\\\\n",t->Data(),k->getVal(),AIC->getVal()-minAIC.getVal(),AICw->getVal());
    //std::cout << k->getVal() << " " << AIC->getVal()-minAIC.getVal() << " " << AICw->getVal() << std::endl;
  }
#endif
  return ws;
}
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();

}