void ws_profile_interval1( const char* wsfile = "ws-test1.root", const char* parName = "mu_susy_sig", double alpha = 0.10, double mu_susy_sig_val = 0., double xmax = -1. ) {




       TFile* wstf = new TFile( wsfile ) ;

       RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") );
       ws->Print() ;






 ////  ModelConfig* modelConfig = (ModelConfig*) ws->obj( "SbModel" ) ;

 ////  printf("\n\n\n  ===== SbModel ====================\n\n") ;
 ////  modelConfig->Print() ;







       RooDataSet* rds = (RooDataSet*) ws->obj( "ra2b_observed_rds" ) ;
       printf("\n\n\n  ===== RooDataSet ====================\n\n") ;

       rds->Print() ;
       rds->printMultiline(cout, 1, kTRUE, "") ;









       printf("\n\n\n  ===== Grabbing %s rrv ====================\n\n", parName ) ;
       RooRealVar* rrv_par = ws->var( parName ) ;
       if ( rrv_par == 0x0 ) {
          printf("\n\n\n *** can't find %s in workspace.  Quitting.\n\n\n", parName ) ; return ;
       } else {
          printf(" current value is : %8.3f\n", rrv_par->getVal() ) ; cout << flush ;
       }
       if ( xmax > 0 ) { rrv_par->setMax( xmax ) ; }

       printf("\n\n\n  ===== Grabbing mu_susy_sig rrv ====================\n\n") ;
       RooRealVar* rrv_mu_susy_sig = ws->var("mu_susy_sig") ;
       if ( rrv_mu_susy_sig == 0x0 ) {
          printf("\n\n\n *** can't find mu_susy_sig in workspace.  Quitting.\n\n\n") ; return ;
       }
       if ( strcmp( parName, "mu_susy_sig" ) != 0 ) {
          if ( mu_susy_sig_val >= 0. ) {
             printf(" current value is : %8.3f\n", rrv_mu_susy_sig->getVal() ) ; cout << flush ;
             printf(" fixing to %8.2f.\n", mu_susy_sig_val ) ;
             rrv_mu_susy_sig->setVal( mu_susy_sig_val ) ;
             rrv_mu_susy_sig->setConstant(kTRUE) ;
          } else {
             printf(" current value is : %8.3f\n", rrv_mu_susy_sig->getVal() ) ; cout << flush ;
             printf(" allowing mu_susy_sig to float.\n") ;
             rrv_mu_susy_sig->setConstant(kFALSE) ;
          }
       } else {
          printf("\n\n profile plot parameter is mu_susy_sig.\n") ;
          rrv_mu_susy_sig->setConstant(kFALSE) ;
       }

       printf("\n\n\n  ===== Grabbing likelihood pdf ====================\n\n") ;
       RooAbsPdf* likelihood = ws->pdf("likelihood") ;
       if ( likelihood == 0x0 ) {
          printf("\n\n\n *** can't find likelihood pdf in workspace.  Quitting.\n\n\n") ; return ;
       } else {
          printf("\n\n likelihood pdf: \n\n") ;
          likelihood->Print() ;
       }












       printf("\n\n\n  ===== Doing a fit ====================\n\n") ;

       likelihood->fitTo( *rds ) ;

       double mlValue = rrv_par->getVal() ;
       printf("  Maximum likelihood value of %s : %8.3f +/- %8.3f\n",
            parName, rrv_par->getVal(), rrv_par->getError() ) ;






       printf("\n\n ========== Creating ProfileLikelihoodCalculator\n\n" ) ; cout << flush ;

    // ProfileLikelihoodCalculator plc( *rds, *modelConfig ) ;
       ProfileLikelihoodCalculator plc( *rds, *likelihood, RooArgSet( *rrv_par ) ) ;

       plc.SetTestSize( alpha ) ;
       ConfInterval* plinterval = plc.GetInterval() ;
       double low  = ((LikelihoodInterval*) plinterval)->LowerLimit(*rrv_par) ;
       double high = ((LikelihoodInterval*) plinterval)->UpperLimit(*rrv_par) ;

       printf("\n\n  Limits: %8.3f,  %8.3f\n\n", low, high ) ;








       printf("\n\n ========= Making profile likelihood plot\n\n") ; cout << flush ;

       LikelihoodIntervalPlot* profPlot = new LikelihoodIntervalPlot((LikelihoodInterval*)plinterval) ;

       TCanvas* cplplot = new TCanvas("cplplot","cplplot", 500, 400) ;
       profPlot->Draw() ;
       gPad->SetGridy(1) ;
       char plotname[10000] ;
       sprintf( plotname, "plplot-%s.png", parName ) ;
       cplplot->SaveAs( plotname ) ;



       if ( alpha > 0.3 ) {
          printf("\n\n\n 1 standard-deviation errors for %s : %8.2f   + %8.2f  - %8.2f\n\n\n",
              parName, mlValue, high-mlValue, mlValue-low ) ;
       }



   }
Exemple #2
0
    void ztonunu1() {

    // RooMsgService::instance().addStream(DEBUG,Topic(Tracing),ClassName("RooPoisson"),OutputFile("debug.log")) ;

       float acc_mm_mean( 0.98 ) ; float acc_mm_err(  0.02 ) ;
       float acc_ee_mean( 0.98 ) ; float acc_ee_err(  0.02 ) ;
       float eff_mm_mean( 0.77 ) ; float eff_mm_err(  0.08 ) ;
       float eff_ee_mean( 0.76 ) ; float eff_ee_err(  0.08 ) ;


       RooRealVar* rv_Nsbee  = new RooRealVar( "Nsbee"  ,"Nsbee"  , 0., 100. ) ;
       RooRealVar* rv_Nsbmm  = new RooRealVar( "Nsbmm"  ,"Nsbmm"  , 0., 100. ) ;
       RooRealVar* rv_Nsigee = new RooRealVar( "Nsigee" ,"Nsigee" , 0., 100. ) ;
       RooRealVar* rv_Nsigmm = new RooRealVar( "Nsigmm" ,"Nsigmm" , 0., 100. ) ;

       rv_Nsbee->setVal( 5 ) ;
       rv_Nsbmm->setVal( 3 ) ;

       rv_Nsigee->setVal( 4 ) ;
       rv_Nsigmm->setVal( 3 ) ;


       RooRealVar* rv_mu_Znnsb  = new RooRealVar( "mu_Znnsb"  , "mu_Znnsb"  , 0., 100. ) ;
       RooRealVar* rv_mu_Znnsig = new RooRealVar( "mu_Znnsig" , "mu_Znnsig" , 0., 100. ) ;


       rv_mu_Znnsb->setVal( 37 ) ; // starting value
       rv_mu_Znnsig->setVal( 17. ) ; // starting value

       RooRealVar* rv_bfRatio = new RooRealVar( "bfRatio", "bfRatio", 0., 10. ) ;

       rv_bfRatio->setVal( 5.95 ) ;
       rv_bfRatio->setConstant( kTRUE ) ;

       RooRealVar* rv_acc_mm = new RooRealVar( "acc_mm", "acc_mm", 0.001, 1.000 ) ;
       RooRealVar* rv_acc_ee = new RooRealVar( "acc_ee", "acc_ee", 0.001, 1.000 ) ;

       RooRealVar* rv_eff_mm = new RooRealVar( "eff_mm", "eff_mm", 0.001, 1.000 ) ;
       RooRealVar* rv_eff_ee = new RooRealVar( "eff_ee", "eff_ee", 0.001, 1.000 ) ;

       rv_acc_mm->setVal( acc_mm_mean ) ;
       rv_acc_ee->setVal( acc_ee_mean ) ;
       rv_eff_mm->setVal( eff_mm_mean ) ;
       rv_eff_ee->setVal( eff_ee_mean ) ;

       RooRealVar* rv_lumi_ratio = new RooRealVar( "lumi_ratio", "lumi_ratio", 0., 10. ) ;

       rv_lumi_ratio -> setVal( 686./869. ) ;
       rv_lumi_ratio -> setConstant( kTRUE) ;



       RooFormulaVar* rv_mu_Zeesb = new RooFormulaVar( "mu_Zeesb",
                       "mu_Znnsb * ( acc_ee * eff_ee / (bfRatio*lumi_ratio) )",
                       RooArgSet( *rv_mu_Znnsb, *rv_acc_ee, *rv_eff_ee, *rv_bfRatio, *rv_lumi_ratio ) ) ;

       RooFormulaVar* rv_mu_Zmmsb = new RooFormulaVar( "mu_Zmmsb",
                       "mu_Znnsb * ( acc_mm * eff_mm / (bfRatio*lumi_ratio) )",
                       RooArgSet( *rv_mu_Znnsb, *rv_acc_mm, *rv_eff_mm, *rv_bfRatio, *rv_lumi_ratio ) ) ;

       RooFormulaVar* rv_mu_Zeesig = new RooFormulaVar( "mu_Zeesig",
                       "mu_Znnsig * ( acc_ee * eff_ee / (bfRatio*lumi_ratio) )",
                       RooArgSet( *rv_mu_Znnsig, *rv_acc_ee, *rv_eff_ee, *rv_bfRatio, *rv_lumi_ratio ) ) ;

       RooFormulaVar* rv_mu_Zmmsig = new RooFormulaVar( "mu_Zmmsig",
                       "mu_Znnsig * ( acc_mm * eff_mm / (bfRatio*lumi_ratio) )",
                       RooArgSet( *rv_mu_Znnsig, *rv_acc_mm, *rv_eff_mm, *rv_bfRatio, *rv_lumi_ratio ) ) ;



       RooFormulaVar* rv_n_sbee  = new RooFormulaVar( "n_sbee"  , "mu_Zeesb"  , RooArgSet( *rv_mu_Zeesb  ) ) ;
       RooFormulaVar* rv_n_sbmm  = new RooFormulaVar( "n_sbmm"  , "mu_Zmmsb"  , RooArgSet( *rv_mu_Zmmsb  ) ) ;
       RooFormulaVar* rv_n_sigee = new RooFormulaVar( "n_sigee" , "mu_Zeesig" , RooArgSet( *rv_mu_Zeesig ) ) ;
       RooFormulaVar* rv_n_sigmm = new RooFormulaVar( "n_sigmm" , "mu_Zmmsig" , RooArgSet( *rv_mu_Zmmsig ) ) ;



       RooGaussian* pdf_acc_mm = new RooGaussian( "pdf_acc_mm", "Gaussian pdf for Z to mumu acceptance",
                       *rv_acc_mm, RooConst( acc_mm_mean ), RooConst( acc_mm_err ) ) ;


       RooGaussian* pdf_acc_ee = new RooGaussian( "pdf_acc_ee", "Gaussian pdf for Z to ee acceptance",
                       *rv_acc_ee, RooConst( acc_ee_mean ), RooConst( acc_ee_err ) ) ;




       RooGaussian* pdf_eff_mm = new RooGaussian( "pdf_eff_mm", "Gaussian pdf for Z to mumu efficiency",
                       *rv_eff_mm, RooConst( eff_mm_mean ), RooConst( eff_mm_err ) ) ;



       RooGaussian* pdf_eff_ee = new RooGaussian( "pdf_eff_ee", "Gaussian pdf for Z to ee efficiency",
                       *rv_eff_ee, RooConst( eff_ee_mean ), RooConst( eff_ee_err ) ) ;



       RooPoisson* pdf_Nsbee   = new RooPoisson( "pdf_Nsbee"  , "Nsb , Z to ee Poisson PDF", *rv_Nsbee  , *rv_n_sbee  ) ;
       RooPoisson* pdf_Nsbmm   = new RooPoisson( "pdf_Nsbmm"  , "Nsb , Z to mm Poisson PDF", *rv_Nsbmm  , *rv_n_sbmm  ) ;
       RooPoisson* pdf_Nsigee  = new RooPoisson( "pdf_Nsigee" , "Nsig, Z to ee Poisson PDF", *rv_Nsigee , *rv_n_sigee ) ;
       RooPoisson* pdf_Nsigmm  = new RooPoisson( "pdf_Nsigmm" , "Nsig, Z to mm Poisson PDF", *rv_Nsigmm , *rv_n_sigmm ) ;

       RooArgSet pdflist ;
       pdflist.add( *pdf_acc_mm ) ;
       pdflist.add( *pdf_acc_ee ) ;
       pdflist.add( *pdf_eff_mm ) ;
       pdflist.add( *pdf_eff_ee ) ;
       pdflist.add( *pdf_Nsbee  ) ;
       pdflist.add( *pdf_Nsbmm  ) ;
       pdflist.add( *pdf_Nsigee  ) ;
       pdflist.add( *pdf_Nsigmm  ) ;

       RooProdPdf* znnLikelihood = new RooProdPdf( "znnLikelihood", "Z to nunu likelihood", pdflist ) ;


       RooArgSet observedParametersList ;
       observedParametersList.add( *rv_Nsbee ) ;
       observedParametersList.add( *rv_Nsbmm ) ;
       observedParametersList.add( *rv_Nsigee ) ;
       observedParametersList.add( *rv_Nsigmm ) ;

       RooDataSet* dsObserved = new RooDataSet( "ztonn_rds", "Z to nunu dataset", observedParametersList ) ;
       dsObserved->add( observedParametersList ) ;
       //// RooDataSet* dsObserved = znnLikelihood->generate( observedParametersList, 1) ;

       RooWorkspace* znnWorkspace = new RooWorkspace("ztonn_ws") ;
       znnWorkspace->import( *znnLikelihood ) ;
       znnWorkspace->import( *dsObserved ) ;

       znnWorkspace->Print() ;

       dsObserved->printMultiline(cout, 1, kTRUE, "") ;
       RooFitResult* fitResult = znnLikelihood->fitTo( *dsObserved, Verbose(true), Save(true) ) ;

       printf("\n\n----- Constant parameters:\n") ;
       RooArgList constPars = fitResult->constPars() ;
       for ( int pi=0; pi<constPars.getSize(); pi++ ) {
          constPars[pi].Print() ;
       } // pi.

       printf("\n\n----- Floating parameters:\n") ;
       RooArgList floatPars = fitResult->floatParsFinal() ;
       for ( int pi=0; pi<floatPars.getSize(); pi++ ) {
          floatPars[pi].Print() ;
       } // pi.
       printf("\n\n") ;



       ProfileLikelihoodCalculator plc_znn_sb(  *dsObserved, *znnLikelihood, RooArgSet( *rv_mu_Znnsb ) ) ;
       ProfileLikelihoodCalculator plc_znn_sig( *dsObserved, *znnLikelihood, RooArgSet( *rv_mu_Znnsig ) ) ;

       plc_znn_sb.SetTestSize(0.32) ;
       plc_znn_sig.SetTestSize(0.32) ;

       ConfInterval* sb_znn_interval = plc_znn_sb.GetInterval() ;
       float sbZnnLow  = ((LikelihoodInterval*) sb_znn_interval)->LowerLimit(*rv_mu_Znnsb) ;
       float sbZnnHigh = ((LikelihoodInterval*) sb_znn_interval)->UpperLimit(*rv_mu_Znnsb) ;
       printf("\n\n znn SB interval %6.1f to %6.1f\n", sbZnnLow, sbZnnHigh ) ;

       ConfInterval* sig_znn_interval = plc_znn_sig.GetInterval() ;
       float sigZnnLow  = ((LikelihoodInterval*) sig_znn_interval)->LowerLimit(*rv_mu_Znnsig) ;
       float sigZnnHigh = ((LikelihoodInterval*) sig_znn_interval)->UpperLimit(*rv_mu_Znnsig) ;
       printf("\n\n znn SIG interval %6.1f to %6.1f\n", sigZnnLow, sigZnnHigh ) ;



       TCanvas* c_prof_sb = new TCanvas("c_prof_sb","SB Z to nunu profile") ;
       LikelihoodIntervalPlot plot_znn_sb((LikelihoodInterval*)sb_znn_interval) ;
       plot_znn_sb.Draw() ;
       c_prof_sb->SaveAs("znn_sb_profile.png") ;

       TCanvas* c_prof_sig = new TCanvas("c_prof_sig","sig Z to nunu profile") ;
       LikelihoodIntervalPlot plot_znn_sig((LikelihoodInterval*)sig_znn_interval) ;
       plot_znn_sig.Draw() ;
       c_prof_sig->SaveAs("znn_sig_profile.png") ;


    }
   void constrained_scan( const char* wsfile = "outputfiles/ws.root",
                          const char* new_poi_name="mu_bg_4b_msig_met1",
                          double constraintWidth=1.5,
                          int npoiPoints = 20,
                          double poiMinVal = 0.,
                          double poiMaxVal = 10.0,
                          double ymax = 9.,
                          int verbLevel=1  ) {

      TString outputdir("outputfiles") ;

      gStyle->SetOptStat(0) ;

      TFile* wstf = new TFile( wsfile ) ;
      RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") );
      ws->Print() ;

      RooDataSet* rds = (RooDataSet*) ws->obj( "hbb_observed_rds" ) ;
      cout << "\n\n\n  ===== RooDataSet ====================\n\n" << endl ;
      rds->Print() ;
      rds->printMultiline(cout, 1, kTRUE, "") ;

      RooRealVar* rv_sig_strength = ws->var("sig_strength") ;
      if ( rv_sig_strength == 0x0 ) { printf("\n\n *** can't find sig_strength in workspace.\n\n" ) ; return ; }

      RooAbsPdf* likelihood = ws->pdf("likelihood") ;
      if ( likelihood == 0x0 ) { printf("\n\n *** can't find likelihood in workspace.\n\n" ) ; return ; }
      printf("\n\n Likelihood:\n") ;
      likelihood -> Print() ;



      /////rv_sig_strength -> setConstant( kFALSE ) ;
      rv_sig_strength -> setVal(0.) ;
      rv_sig_strength -> setConstant( kTRUE ) ;

      likelihood->fitTo( *rds, Save(false), PrintLevel(0), Hesse(true), Strategy(1) ) ;
      //RooFitResult* fitResult = likelihood->fitTo( *rds, Save(true), PrintLevel(0), Hesse(true), Strategy(1) ) ;
      //double minNllSusyFloat = fitResult->minNll() ;
      //double susy_ss_atMinNll = rv_sig_strength -> getVal() ;

      RooMsgService::instance().getStream(1).removeTopic(Minimization) ;
      RooMsgService::instance().getStream(1).removeTopic(Fitting) ;



     //-- Construct the new POI parameter.
      RooAbsReal* new_poi_rar(0x0) ;

      new_poi_rar = ws->var( new_poi_name ) ;
      if ( new_poi_rar == 0x0 ) {
         printf("\n\n New POI %s is not a variable.  Trying function.\n\n", new_poi_name ) ;
         new_poi_rar = ws->function( new_poi_name ) ;
         if ( new_poi_rar == 0x0 ) {
            printf("\n\n New POI %s is not a function.  I quit.\n\n", new_poi_name ) ;
            return ;
         } else {
            printf("\n Found it.\n\n") ;
         }
      } else {
         printf("\n\n     New POI %s is a variable with current value %.1f.\n\n", new_poi_name, new_poi_rar->getVal() ) ;
      }

       double startPoiVal = new_poi_rar->getVal() ;


       RooAbsReal* nll = likelihood -> createNLL( *rds, Verbose(true) ) ;

       RooRealVar* rrv_poiValue = new RooRealVar( "poiValue", "poiValue", 0., -10000., 10000. ) ;

       RooRealVar* rrv_constraintWidth = new RooRealVar("constraintWidth","constraintWidth", 0.1, 0.1, 1000. ) ;
       rrv_constraintWidth -> setVal( constraintWidth ) ;
       rrv_constraintWidth -> setConstant(kTRUE) ;


       RooMinuit* rminuit( 0x0 ) ;


       RooMinuit* rminuit_uc = new RooMinuit( *nll  ) ;

       rminuit_uc->setPrintLevel(verbLevel-1) ;
       rminuit_uc->setNoWarn() ;

       rminuit_uc->migrad() ;
       rminuit_uc->hesse() ;

       RooFitResult* rfr_uc = rminuit_uc->fit("mr") ;

       double floatParInitVal[10000] ;
       char   floatParName[10000][100] ;
       int nFloatParInitVal(0) ;
       RooArgList ral_floats = rfr_uc->floatParsFinal() ;
       TIterator* floatParIter = ral_floats.createIterator() ;
       {
          RooRealVar* par ;
          while ( (par = (RooRealVar*) floatParIter->Next()) ) {
             sprintf( floatParName[nFloatParInitVal], "%s", par->GetName() ) ;
             floatParInitVal[nFloatParInitVal] = par->getVal() ;
             nFloatParInitVal++ ;
          }
       }


       printf("\n\n Unbiased best value for new POI %s is : %7.1f\n\n", new_poi_rar->GetName(), new_poi_rar->getVal() ) ;
       double best_poi_val = new_poi_rar->getVal() ;

       char minuit_formula[10000] ;
       sprintf( minuit_formula, "%s+%s*(%s-%s)*(%s-%s)",
         nll->GetName(),
         rrv_constraintWidth->GetName(),
         new_poi_rar->GetName(), rrv_poiValue->GetName(),
         new_poi_rar->GetName(), rrv_poiValue->GetName()
          ) ;

       printf("\n\n Creating new minuit variable with formula: %s\n\n", minuit_formula ) ;
       RooFormulaVar* new_minuit_var = new RooFormulaVar("new_minuit_var", minuit_formula,
           RooArgList( *nll,
                       *rrv_constraintWidth,
                       *new_poi_rar, *rrv_poiValue,
                       *new_poi_rar, *rrv_poiValue
                       ) ) ;

       printf("\n\n Current value is %.2f\n\n",
            new_minuit_var->getVal() ) ;

       rminuit = new RooMinuit( *new_minuit_var ) ;


       RooAbsReal* plot_var = nll ;

       printf("\n\n Current value is %.2f\n\n",
            plot_var->getVal() ) ;


       rminuit->setPrintLevel(verbLevel-1) ;
       if ( verbLevel <=0 ) { rminuit->setNoWarn() ; }


       if ( poiMinVal < 0. && poiMaxVal < 0. ) {

          printf("\n\n Automatic determination of scan range.\n\n") ;

          if ( startPoiVal <= 0. ) {
             printf("\n\n *** POI starting value zero or negative %g.  Quit.\n\n\n", startPoiVal ) ;
             return ;
          }

          poiMinVal = startPoiVal - 3.5 * sqrt(startPoiVal) ;
          poiMaxVal = startPoiVal + 6.0 * sqrt(startPoiVal) ;

          if ( poiMinVal < 0. ) { poiMinVal = 0. ; }

          printf("    Start val = %g.   Scan range:   %g  to  %g\n\n", startPoiVal, poiMinVal, poiMaxVal ) ;


       }



    //----------------------------------------------------------------------------------------------


       double poiVals_scanDown[1000] ;
       double nllVals_scanDown[1000] ;

       //-- Do scan down from best value.

       printf("\n\n +++++ Starting scan down from best value.\n\n") ;

       double minNllVal(1.e9) ;

       for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) {

          ////double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*(npoiPoints-1)) ;
          double poiValue = best_poi_val - poivi*(best_poi_val-poiMinVal)/(1.*(npoiPoints/2-1)) ;

          rrv_poiValue -> setVal( poiValue ) ;
          rrv_poiValue -> setConstant( kTRUE ) ;


       //+++++++++++++++++++++++++++++++++++

          rminuit->migrad() ;
          rminuit->hesse() ;
          RooFitResult* rfr = rminuit->save() ;

       //+++++++++++++++++++++++++++++++++++


          if ( verbLevel > 0 ) { rfr->Print("v") ; }


          float fit_minuit_var_val = rfr->minNll() ;

          printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI :    %.5f   %.5f   %.5f   %.5f\n",
                poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ;
          cout << flush ;



          poiVals_scanDown[poivi] = new_poi_rar->getVal() ;
          nllVals_scanDown[poivi] = plot_var->getVal() ;

          if ( nllVals_scanDown[poivi] < minNllVal ) { minNllVal = nllVals_scanDown[poivi] ; }

          delete rfr ;


       } // poivi


       printf("\n\n +++++ Resetting floats to best fit values.\n\n") ;

       for ( int pi=0; pi<nFloatParInitVal; pi++ ) {
          RooRealVar* par = ws->var( floatParName[pi] ) ;
          par->setVal( floatParInitVal[pi] ) ;
       } // pi.

       printf("\n\n +++++ Starting scan up from best value.\n\n") ;

      //-- Now do scan up.

       double poiVals_scanUp[1000] ;
       double nllVals_scanUp[1000] ;

       for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) {

          double poiValue = best_poi_val + poivi*(poiMaxVal-best_poi_val)/(1.*(npoiPoints/2-1)) ;

          rrv_poiValue -> setVal( poiValue ) ;
          rrv_poiValue -> setConstant( kTRUE ) ;


       //+++++++++++++++++++++++++++++++++++

          rminuit->migrad() ;
          rminuit->hesse() ;
          RooFitResult* rfr = rminuit->save() ;

       //+++++++++++++++++++++++++++++++++++


          if ( verbLevel > 0 ) { rfr->Print("v") ; }


          float fit_minuit_var_val = rfr->minNll() ;

          printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI :    %.5f   %.5f   %.5f   %.5f\n",
                poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ;
          cout << flush ;

          poiVals_scanUp[poivi] = new_poi_rar->getVal() ;
          nllVals_scanUp[poivi] = plot_var->getVal() ;

          if ( nllVals_scanUp[poivi] < minNllVal ) { minNllVal = nllVals_scanUp[poivi] ; }

          delete rfr ;


       } // poivi





       double poiVals[1000] ;
       double nllVals[1000] ;

       int pointCount(0) ;
       for ( int pi=0; pi<npoiPoints/2; pi++ ) {
          poiVals[pi] = poiVals_scanDown[(npoiPoints/2-1)-pi] ;
          nllVals[pi] = nllVals_scanDown[(npoiPoints/2-1)-pi] ;
          pointCount++ ;
       }
       for ( int pi=1; pi<npoiPoints/2; pi++ ) {
          poiVals[pointCount] = poiVals_scanUp[pi] ;
          nllVals[pointCount] = nllVals_scanUp[pi] ;
          pointCount++ ;
       }
       npoiPoints = pointCount ;

       printf("\n\n --- TGraph arrays:\n") ;
       for ( int i=0; i<npoiPoints; i++ ) {
          printf("  %2d : poi = %6.1f, nll = %g\n", i, poiVals[i], nllVals[i] ) ;
       }
       printf("\n\n") ;

       double nllDiffVals[1000] ;

       double poiAtMinlnL(-1.) ;
       double poiAtMinusDelta2(-1.) ;
       double poiAtPlusDelta2(-1.) ;
       for ( int poivi=0; poivi < npoiPoints ; poivi++ ) {
          nllDiffVals[poivi] = 2.*(nllVals[poivi] - minNllVal) ;
          double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*npoiPoints) ;
          if ( nllDiffVals[poivi] < 0.01 ) { poiAtMinlnL = poiValue ; }
          if ( poiAtMinusDelta2 < 0. && nllDiffVals[poivi] < 2.5 ) { poiAtMinusDelta2 = poiValue ; }
          if ( poiAtMinlnL > 0. && poiAtPlusDelta2 < 0. && nllDiffVals[poivi] > 2.0 ) { poiAtPlusDelta2 = poiValue ; }
       } // poivi

       printf("\n\n Estimates for poi at delta ln L = -2, 0, +2:  %g ,   %g ,   %g\n\n", poiAtMinusDelta2, poiAtMinlnL, poiAtPlusDelta2 ) ;




      //--- Main canvas

       TCanvas* cscan = (TCanvas*) gDirectory->FindObject("cscan") ;
       if ( cscan == 0x0 ) {
          printf("\n Creating canvas.\n\n") ;
          cscan = new TCanvas("cscan","Delta nll") ;
       }


       char gname[1000] ;

       TGraph* graph = new TGraph( npoiPoints, poiVals, nllDiffVals ) ;
       sprintf( gname, "scan_%s", new_poi_name ) ;
       graph->SetName( gname ) ;

       double poiBest(-1.) ;
       double poiMinus1stdv(-1.) ;
       double poiPlus1stdv(-1.) ;
       double poiMinus2stdv(-1.) ;
       double poiPlus2stdv(-1.) ;
       double twoDeltalnLMin(1e9) ;

       int nscan(1000) ;
       for ( int xi=0; xi<nscan; xi++ ) {

          double x = poiVals[0] + xi*(poiVals[npoiPoints-1]-poiVals[0])/(nscan-1) ;

          double twoDeltalnL = graph -> Eval( x, 0, "S" ) ;

          if ( poiMinus1stdv < 0. && twoDeltalnL < 1.0 ) { poiMinus1stdv = x ; printf(" set m1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}
          if ( poiMinus2stdv < 0. && twoDeltalnL < 4.0 ) { poiMinus2stdv = x ; printf(" set m2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}
          if ( twoDeltalnL < twoDeltalnLMin ) { poiBest = x ; twoDeltalnLMin = twoDeltalnL ; }
          if ( twoDeltalnLMin < 0.3 && poiPlus1stdv < 0. && twoDeltalnL > 1.0 ) { poiPlus1stdv = x ; printf(" set p1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}
          if ( twoDeltalnLMin < 0.3 && poiPlus2stdv < 0. && twoDeltalnL > 4.0 ) { poiPlus2stdv = x ; printf(" set p2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}

          if ( xi%100 == 0 ) { printf( " %4d : poi=%6.2f,  2DeltalnL = %6.2f\n", xi, x, twoDeltalnL ) ; }

       }
       printf("\n\n POI estimate :  %g  +%g  -%g    [%g,%g],   two sigma errors: +%g  -%g   [%g,%g]\n\n",
               poiBest,
               (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), poiMinus1stdv, poiPlus1stdv,
               (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv), poiMinus2stdv, poiPlus2stdv
               ) ;

       printf(" %s val,pm1sig,pm2sig: %7.2f  %7.2f  %7.2f  %7.2f  %7.2f\n",
          new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv) ) ;

       char htitle[1000] ;
       sprintf(htitle, "%s profile likelihood scan: -2ln(L/Lm)", new_poi_name ) ;
       TH1F* hscan = new TH1F("hscan", htitle, 10, poiMinVal, poiMaxVal ) ;
       hscan->SetMinimum(0.) ;
       hscan->SetMaximum(ymax) ;


       hscan->DrawCopy() ;
       graph->SetLineColor(4) ;
       graph->SetLineWidth(3) ;
       graph->Draw("CP") ;
       gPad->SetGridx(1) ;
       gPad->SetGridy(1) ;
       cscan->Update() ;

       TLine* line = new TLine() ;
       line->SetLineColor(2) ;
       line->DrawLine(poiMinVal, 1., poiPlus1stdv, 1.) ;
       line->DrawLine(poiMinus1stdv,0., poiMinus1stdv, 1.) ;
       line->DrawLine(poiPlus1stdv ,0., poiPlus1stdv , 1.) ;

       TText* text = new TText() ;
       text->SetTextSize(0.04) ;
       char tstring[1000] ;

       sprintf( tstring, "%s = %.1f +%.1f -%.1f", new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv) ) ;
       text -> DrawTextNDC( 0.15, 0.85, tstring ) ;

       sprintf( tstring, "68%% interval [%.1f,  %.1f]", poiMinus1stdv, poiPlus1stdv ) ;
       text -> DrawTextNDC( 0.15, 0.78, tstring ) ;


       char hname[1000] ;
       sprintf( hname, "hscanout_%s", new_poi_name ) ;
       TH1F* hsout = new TH1F( hname,"scan results",4,0.,4.) ;
       double obsVal(-1.) ;
       hsout->SetBinContent(1, obsVal ) ;
       hsout->SetBinContent(2, poiPlus1stdv ) ;
       hsout->SetBinContent(3, poiBest ) ;
       hsout->SetBinContent(4, poiMinus1stdv ) ;
       TAxis* xaxis = hsout->GetXaxis() ;
       xaxis->SetBinLabel(1,"Observed val.") ;
       xaxis->SetBinLabel(2,"Model+1sd") ;
       xaxis->SetBinLabel(3,"Model") ;
       xaxis->SetBinLabel(4,"Model-1sd") ;

       char outrootfile[10000] ;
       sprintf( outrootfile, "%s/scan-ff-%s.root", outputdir.Data(), new_poi_name ) ;

       char outpdffile[10000] ;
       sprintf( outpdffile, "%s/scan-ff-%s.pdf", outputdir.Data(), new_poi_name ) ;

       cscan->Update() ; cscan->Draw() ;

       printf("\n Saving %s\n", outpdffile ) ;
       cscan->SaveAs( outpdffile ) ;



     //--- save in root file

       printf("\n Saving %s\n", outrootfile ) ;
       TFile fout(outrootfile,"recreate") ;
       graph->Write() ;
       hsout->Write() ;
       fout.Close() ;

       delete ws ;
       wstf->Close() ;




   } // constrained_scan.
   void ws_constrained_profile3D( const char* wsfile = "rootfiles/ws-data-unblind.root",
                                   const char* new_poi_name = "n_M234_H4_3b",
                                   int npoiPoints = 20,
                                   double poiMinVal = 0.,
                                   double poiMaxVal = 20.,
                                   double constraintWidth = 1.5,
                                   double ymax = 10.,
                                   int verbLevel=0 ) {


     gStyle->SetOptStat(0) ;

     //--- make output directory.

     char command[10000] ;
     sprintf( command, "basename %s", wsfile ) ;
     TString wsfilenopath = gSystem->GetFromPipe( command ) ;
     wsfilenopath.ReplaceAll(".root","") ;
     char outputdirstr[1000] ;
     sprintf( outputdirstr, "outputfiles/scans-%s", wsfilenopath.Data() ) ;
     TString outputdir( outputdirstr ) ;


     printf("\n\n Creating output directory: %s\n\n", outputdir.Data() ) ;
     sprintf(command, "mkdir -p %s", outputdir.Data() ) ;
     gSystem->Exec( command ) ;


     //--- Tell RooFit to shut up about anything less important than an ERROR.
      RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;



       if ( verbLevel > 0 ) { printf("\n\n Verbose level : %d\n\n", verbLevel) ; }


       TFile* wstf = new TFile( wsfile ) ;

       RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") );

       if ( verbLevel > 0 ) { ws->Print() ; }






       RooDataSet* rds = (RooDataSet*) ws->obj( "ra2b_observed_rds" ) ;

       if ( verbLevel > 0 ) {
          printf("\n\n\n  ===== RooDataSet ====================\n\n") ;
          rds->Print() ;
          rds->printMultiline(cout, 1, kTRUE, "") ;
       }





       ModelConfig* modelConfig = (ModelConfig*) ws->obj( "SbModel" ) ;
       RooAbsPdf* likelihood = modelConfig->GetPdf() ;

       RooRealVar* rrv_mu_susy_all0lep = ws->var("mu_susy_all0lep") ;
       if ( rrv_mu_susy_all0lep == 0x0 ) {
          printf("\n\n\n *** can't find mu_susy_all0lep in workspace.  Quitting.\n\n\n") ;
          return ;
       }





       //-- do BG only.
       rrv_mu_susy_all0lep->setVal(0.) ;
       rrv_mu_susy_all0lep->setConstant( kTRUE ) ;










       //-- do a prefit.

       printf("\n\n\n ====== Pre fit with unmodified nll var.\n\n") ;

       RooFitResult* dataFitResultSusyFixed = likelihood->fitTo(*rds, Save(true),Hesse(false),Minos(false),Strategy(1),PrintLevel(verbLevel));
       int dataSusyFixedFitCovQual = dataFitResultSusyFixed->covQual() ;
       if ( dataSusyFixedFitCovQual < 2 ) { printf("\n\n\n *** Failed fit!  Cov qual %d.  Quitting.\n\n", dataSusyFixedFitCovQual ) ; return ; }
       double dataFitSusyFixedNll = dataFitResultSusyFixed->minNll() ;

       if ( verbLevel > 0 ) {
          dataFitResultSusyFixed->Print("v") ;
       }

       printf("\n\n Nll value, from fit result : %.3f\n\n", dataFitSusyFixedNll ) ;

       delete dataFitResultSusyFixed ;






       //-- Construct the new POI parameter.
       RooAbsReal* new_poi_rar(0x0) ;

       new_poi_rar = ws->var( new_poi_name ) ;
       if ( new_poi_rar == 0x0 ) {
          printf("\n\n New POI %s is not a variable.  Trying function.\n\n", new_poi_name ) ;
          new_poi_rar = ws->function( new_poi_name ) ;
          if ( new_poi_rar == 0x0 ) {
             printf("\n\n New POI %s is not a function.  I quit.\n\n", new_poi_name ) ;
             return ;
          }
       } else {
          printf("\n\n     New POI %s is a variable with current value %.1f.\n\n", new_poi_name, new_poi_rar->getVal() ) ;
       }








       if ( npoiPoints <=0 ) {
          printf("\n\n Quitting now.\n\n" ) ;
          return ;
       }


       double startPoiVal = new_poi_rar->getVal() ;



      //--- The RooNLLVar is NOT equivalent to what minuit uses.
  //   RooNLLVar* nll = new RooNLLVar("nll","nll", *likelihood, *rds ) ;
  //   printf("\n\n Nll value, from construction : %.3f\n\n", nll->getVal() ) ;

      //--- output of createNLL IS what minuit uses, so use that.
       RooAbsReal* nll = likelihood -> createNLL( *rds, Verbose(true) ) ;

       RooRealVar* rrv_poiValue = new RooRealVar( "poiValue", "poiValue", 0., -10000., 10000. ) ;
   /// rrv_poiValue->setVal( poiMinVal ) ;
   /// rrv_poiValue->setConstant(kTRUE) ;

       RooRealVar* rrv_constraintWidth = new RooRealVar("constraintWidth","constraintWidth", 0.1, 0.1, 1000. ) ;
       rrv_constraintWidth -> setVal( constraintWidth ) ;
       rrv_constraintWidth -> setConstant(kTRUE) ;




       if ( verbLevel > 0 ) {
          printf("\n\n ======= debug likelihood print\n\n") ;
          likelihood->Print("v") ;
          printf("\n\n ======= debug nll print\n\n") ;
          nll->Print("v") ;
       }






    //----------------------------------------------------------------------------------------------

       RooMinuit* rminuit( 0x0 ) ;


       RooMinuit* rminuit_uc = new RooMinuit( *nll  ) ;

       rminuit_uc->setPrintLevel(verbLevel-1) ;
       rminuit_uc->setNoWarn() ;

       rminuit_uc->migrad() ;
       rminuit_uc->hesse() ;

       RooFitResult* rfr_uc = rminuit_uc->fit("mr") ;

       double floatParInitVal[10000] ;
       char   floatParName[10000][100] ;
       int nFloatParInitVal(0) ;
       RooArgList ral_floats = rfr_uc->floatParsFinal() ;
       TIterator* floatParIter = ral_floats.createIterator() ;
       {
          RooRealVar* par ;
          while ( (par = (RooRealVar*) floatParIter->Next()) ) {
             sprintf( floatParName[nFloatParInitVal], "%s", par->GetName() ) ;
             floatParInitVal[nFloatParInitVal] = par->getVal() ;
             nFloatParInitVal++ ;
          }
       }



     //-------

       printf("\n\n Unbiased best value for new POI %s is : %7.1f\n\n", new_poi_rar->GetName(), new_poi_rar->getVal() ) ;
       double best_poi_val = new_poi_rar->getVal() ;

       char minuit_formula[10000] ;
       sprintf( minuit_formula, "%s+%s*(%s-%s)*(%s-%s)",
         nll->GetName(),
         rrv_constraintWidth->GetName(),
         new_poi_rar->GetName(), rrv_poiValue->GetName(),
         new_poi_rar->GetName(), rrv_poiValue->GetName()
          ) ;

       printf("\n\n Creating new minuit variable with formula: %s\n\n", minuit_formula ) ;
       RooFormulaVar* new_minuit_var = new RooFormulaVar("new_minuit_var", minuit_formula,
           RooArgList( *nll,
                       *rrv_constraintWidth,
                       *new_poi_rar, *rrv_poiValue,
                       *new_poi_rar, *rrv_poiValue
                       ) ) ;

       printf("\n\n Current value is %.2f\n\n",
            new_minuit_var->getVal() ) ;

       rminuit = new RooMinuit( *new_minuit_var ) ;


       RooAbsReal* plot_var = nll ;

       printf("\n\n Current value is %.2f\n\n",
            plot_var->getVal() ) ;




       rminuit->setPrintLevel(verbLevel-1) ;
       if ( verbLevel <=0 ) { rminuit->setNoWarn() ; }

    //----------------------------------------------------------------------------------------------

       //-- If POI range is -1 to -1, automatically determine the range using the set value.

       if ( poiMinVal < 0. && poiMaxVal < 0. ) {

          printf("\n\n Automatic determination of scan range.\n\n") ;

          if ( startPoiVal <= 0. ) {
             printf("\n\n *** POI starting value zero or negative %g.  Quit.\n\n\n", startPoiVal ) ;
             return ;
          }

          poiMinVal = startPoiVal - 3.5 * sqrt(startPoiVal) ;
          poiMaxVal = startPoiVal + 6.0 * sqrt(startPoiVal) ;

          if ( poiMinVal < 0. ) { poiMinVal = 0. ; }

          printf("    Start val = %g.   Scan range:   %g  to  %g\n\n", startPoiVal, poiMinVal, poiMaxVal ) ;


       }



    //----------------------------------------------------------------------------------------------


       double poiVals_scanDown[1000] ;
       double nllVals_scanDown[1000] ;

       //-- Do scan down from best value.

       printf("\n\n +++++ Starting scan down from best value.\n\n") ;

       double minNllVal(1.e9) ;

       for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) {

          ////double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*(npoiPoints-1)) ;
          double poiValue = best_poi_val - poivi*(best_poi_val-poiMinVal)/(1.*(npoiPoints/2-1)) ;

          rrv_poiValue -> setVal( poiValue ) ;
          rrv_poiValue -> setConstant( kTRUE ) ;


       //+++++++++++++++++++++++++++++++++++

          rminuit->migrad() ;
          rminuit->hesse() ;
          RooFitResult* rfr = rminuit->save() ;

       //+++++++++++++++++++++++++++++++++++


          if ( verbLevel > 0 ) { rfr->Print("v") ; }


          float fit_minuit_var_val = rfr->minNll() ;

          printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI :    %.5f   %.5f   %.5f   %.5f\n",
                poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ;
          cout << flush ;



          poiVals_scanDown[poivi] = new_poi_rar->getVal() ;
          nllVals_scanDown[poivi] = plot_var->getVal() ;

          if ( nllVals_scanDown[poivi] < minNllVal ) { minNllVal = nllVals_scanDown[poivi] ; }

          delete rfr ;


       } // poivi


       printf("\n\n +++++ Resetting floats to best fit values.\n\n") ;

       for ( int pi=0; pi<nFloatParInitVal; pi++ ) {
          RooRealVar* par = ws->var( floatParName[pi] ) ;
          par->setVal( floatParInitVal[pi] ) ;
       } // pi.

       printf("\n\n +++++ Starting scan up from best value.\n\n") ;

      //-- Now do scan up.

       double poiVals_scanUp[1000] ;
       double nllVals_scanUp[1000] ;

       for ( int poivi=0; poivi < npoiPoints/2 ; poivi++ ) {

          double poiValue = best_poi_val + poivi*(poiMaxVal-best_poi_val)/(1.*(npoiPoints/2-1)) ;

          rrv_poiValue -> setVal( poiValue ) ;
          rrv_poiValue -> setConstant( kTRUE ) ;


       //+++++++++++++++++++++++++++++++++++

          rminuit->migrad() ;
          rminuit->hesse() ;
          RooFitResult* rfr = rminuit->save() ;

       //+++++++++++++++++++++++++++++++++++


          if ( verbLevel > 0 ) { rfr->Print("v") ; }


          float fit_minuit_var_val = rfr->minNll() ;

          printf(" %02d : poi constraint = %.2f : allvars : MinuitVar, createNLL, PV, POI :    %.5f   %.5f   %.5f   %.5f\n",
                poivi, rrv_poiValue->getVal(), fit_minuit_var_val, nll->getVal(), plot_var->getVal(), new_poi_rar->getVal() ) ;
          cout << flush ;

          poiVals_scanUp[poivi] = new_poi_rar->getVal() ;
          nllVals_scanUp[poivi] = plot_var->getVal() ;

          if ( nllVals_scanUp[poivi] < minNllVal ) { minNllVal = nllVals_scanUp[poivi] ; }

          delete rfr ;


       } // poivi





       double poiVals[1000] ;
       double nllVals[1000] ;

       int pointCount(0) ;
       for ( int pi=0; pi<npoiPoints/2; pi++ ) {
          poiVals[pi] = poiVals_scanDown[(npoiPoints/2-1)-pi] ;
          nllVals[pi] = nllVals_scanDown[(npoiPoints/2-1)-pi] ;
          pointCount++ ;
       }
       for ( int pi=1; pi<npoiPoints/2; pi++ ) {
          poiVals[pointCount] = poiVals_scanUp[pi] ;
          nllVals[pointCount] = nllVals_scanUp[pi] ;
          pointCount++ ;
       }
       npoiPoints = pointCount ;

       printf("\n\n --- TGraph arrays:\n") ;
       for ( int i=0; i<npoiPoints; i++ ) {
          printf("  %2d : poi = %6.1f, nll = %g\n", i, poiVals[i], nllVals[i] ) ;
       }
       printf("\n\n") ;

       double nllDiffVals[1000] ;

       double poiAtMinlnL(-1.) ;
       double poiAtMinusDelta2(-1.) ;
       double poiAtPlusDelta2(-1.) ;
       for ( int poivi=0; poivi < npoiPoints ; poivi++ ) {
          nllDiffVals[poivi] = 2.*(nllVals[poivi] - minNllVal) ;
          double poiValue = poiMinVal + poivi*(poiMaxVal-poiMinVal)/(1.*npoiPoints) ;
          if ( nllDiffVals[poivi] < 0.01 ) { poiAtMinlnL = poiValue ; }
          if ( poiAtMinusDelta2 < 0. && nllDiffVals[poivi] < 2.5 ) { poiAtMinusDelta2 = poiValue ; }
          if ( poiAtMinlnL > 0. && poiAtPlusDelta2 < 0. && nllDiffVals[poivi] > 2.0 ) { poiAtPlusDelta2 = poiValue ; }
       } // poivi

       printf("\n\n Estimates for poi at delta ln L = -2, 0, +2:  %g ,   %g ,   %g\n\n", poiAtMinusDelta2, poiAtMinlnL, poiAtPlusDelta2 ) ;




      //--- Main canvas

       TCanvas* cscan = (TCanvas*) gDirectory->FindObject("cscan") ;
       if ( cscan == 0x0 ) {
          printf("\n Creating canvas.\n\n") ;
          cscan = new TCanvas("cscan","Delta nll") ;
       }


       char gname[1000] ;

       TGraph* graph = new TGraph( npoiPoints, poiVals, nllDiffVals ) ;
       sprintf( gname, "scan_%s", new_poi_name ) ;
       graph->SetName( gname ) ;

       double poiBest(-1.) ;
       double poiMinus1stdv(-1.) ;
       double poiPlus1stdv(-1.) ;
       double poiMinus2stdv(-1.) ;
       double poiPlus2stdv(-1.) ;
       double twoDeltalnLMin(1e9) ;

       int nscan(1000) ;
       for ( int xi=0; xi<nscan; xi++ ) {

          double x = poiVals[0] + xi*(poiVals[npoiPoints-1]-poiVals[0])/(nscan-1) ;

          double twoDeltalnL = graph -> Eval( x, 0, "S" ) ;

          if ( poiMinus1stdv < 0. && twoDeltalnL < 1.0 ) { poiMinus1stdv = x ; printf(" set m1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}
          if ( poiMinus2stdv < 0. && twoDeltalnL < 4.0 ) { poiMinus2stdv = x ; printf(" set m2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}
          if ( twoDeltalnL < twoDeltalnLMin ) { poiBest = x ; twoDeltalnLMin = twoDeltalnL ; }
          if ( twoDeltalnLMin < 0.3 && poiPlus1stdv < 0. && twoDeltalnL > 1.0 ) { poiPlus1stdv = x ; printf(" set p1 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}
          if ( twoDeltalnLMin < 0.3 && poiPlus2stdv < 0. && twoDeltalnL > 4.0 ) { poiPlus2stdv = x ; printf(" set p2 : %d, x=%g, 2dnll=%g\n", xi, x, twoDeltalnL) ;}

          if ( xi%100 == 0 ) { printf( " %4d : poi=%6.2f,  2DeltalnL = %6.2f\n", xi, x, twoDeltalnL ) ; }

       }
       printf("\n\n POI estimate :  %g  +%g  -%g    [%g,%g],   two sigma errors: +%g  -%g   [%g,%g]\n\n",
               poiBest,
               (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), poiMinus1stdv, poiPlus1stdv,
               (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv), poiMinus2stdv, poiPlus2stdv
               ) ;

       printf(" %s val,pm1sig,pm2sig: %7.2f  %7.2f  %7.2f  %7.2f  %7.2f\n",
          new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv), (poiPlus2stdv-poiBest), (poiBest-poiMinus2stdv) ) ;

       char htitle[1000] ;
       sprintf(htitle, "%s profile likelihood scan: -2ln(L/Lm)", new_poi_name ) ;
       TH1F* hscan = new TH1F("hscan", htitle, 10, poiMinVal, poiMaxVal ) ;
       hscan->SetMinimum(0.) ;
       hscan->SetMaximum(ymax) ;


       hscan->DrawCopy() ;
       graph->SetLineColor(4) ;
       graph->SetLineWidth(3) ;
       graph->Draw("CP") ;
       gPad->SetGridx(1) ;
       gPad->SetGridy(1) ;
       cscan->Update() ;

       TLine* line = new TLine() ;
       line->SetLineColor(2) ;
       line->DrawLine(poiMinVal, 1., poiPlus1stdv, 1.) ;
       line->DrawLine(poiMinus1stdv,0., poiMinus1stdv, 1.) ;
       line->DrawLine(poiPlus1stdv ,0., poiPlus1stdv , 1.) ;

       TText* text = new TText() ;
       text->SetTextSize(0.04) ;
       char tstring[1000] ;

       sprintf( tstring, "%s = %.1f +%.1f -%.1f", new_poi_name, poiBest, (poiPlus1stdv-poiBest), (poiBest-poiMinus1stdv) ) ;
       text -> DrawTextNDC( 0.15, 0.85, tstring ) ;

       sprintf( tstring, "68%% interval [%.1f,  %.1f]", poiMinus1stdv, poiPlus1stdv ) ;
       text -> DrawTextNDC( 0.15, 0.78, tstring ) ;


       char hname[1000] ;
       sprintf( hname, "hscanout_%s", new_poi_name ) ;
       TH1F* hsout = new TH1F( hname,"scan results",4,0.,4.) ;
       double obsVal(-1.) ;
       hsout->SetBinContent(1, obsVal ) ;
       hsout->SetBinContent(2, poiPlus1stdv ) ;
       hsout->SetBinContent(3, poiBest ) ;
       hsout->SetBinContent(4, poiMinus1stdv ) ;
       TAxis* xaxis = hsout->GetXaxis() ;
       xaxis->SetBinLabel(1,"Observed val.") ;
       xaxis->SetBinLabel(2,"Model+1sd") ;
       xaxis->SetBinLabel(3,"Model") ;
       xaxis->SetBinLabel(4,"Model-1sd") ;

       char outrootfile[10000] ;
       sprintf( outrootfile, "%s/scan-ff-%s.root", outputdir.Data(), new_poi_name ) ;

       char outpdffile[10000] ;
       sprintf( outpdffile, "%s/scan-ff-%s.pdf", outputdir.Data(), new_poi_name ) ;

       cscan->Update() ; cscan->Draw() ;

       printf("\n Saving %s\n", outpdffile ) ;
       cscan->SaveAs( outpdffile ) ;



     //--- save in root file

       printf("\n Saving %s\n", outrootfile ) ;
       TFile fout(outrootfile,"recreate") ;
       graph->Write() ;
       hsout->Write() ;
       fout.Close() ;

       delete ws ;
       wstf->Close() ;

   }
Exemple #5
0
   void fitqual_plots( const char* wsfile = "outputfiles/ws.root", const char* plottitle="" ) {

      TText* tt_title = new TText() ;
      tt_title -> SetTextAlign(33) ;

      gStyle -> SetOptStat(0) ;
      gStyle -> SetLabelSize( 0.06, "y" ) ;
      gStyle -> SetLabelSize( 0.08, "x" ) ;
      gStyle -> SetLabelOffset( 0.010, "y" ) ;
      gStyle -> SetLabelOffset( 0.010, "x" ) ;
      gStyle -> SetTitleSize( 0.07, "y" ) ;
      gStyle -> SetTitleSize( 0.05, "x" ) ;
      gStyle -> SetTitleOffset( 1.50, "x" ) ;
      gStyle -> SetTitleH( 0.07 ) ;
      gStyle -> SetPadLeftMargin( 0.15 ) ;
      gStyle -> SetPadBottomMargin( 0.15 ) ;
      gStyle -> SetTitleX( 0.10 ) ;

      gDirectory->Delete("h*") ;

      TFile* wstf = new TFile( wsfile ) ;

      RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") );
      ws->Print() ;

      int bins_of_met = TMath::Nint( ws->var("bins_of_met")->getVal()  ) ;
      printf("\n\n Bins of MET : %d\n\n", bins_of_met ) ;

      int bins_of_nb = TMath::Nint( ws->var("bins_of_nb")->getVal()  ) ;
      printf("\n\n Bins of nb : %d\n\n", bins_of_nb ) ;

      int nb_lookup[10] ;
      if ( bins_of_nb == 2 ) {
         nb_lookup[0] = 2 ;
         nb_lookup[1] = 4 ;
      } else if ( bins_of_nb == 3 ) {
         nb_lookup[0] = 2 ;
         nb_lookup[1] = 3 ;
         nb_lookup[2] = 4 ;
      }

      TCanvas* cfq1 = (TCanvas*) gDirectory->FindObject("cfq1") ;
      if ( cfq1 == 0x0 ) {
         if ( bins_of_nb == 3 ) {
            cfq1 = new TCanvas("cfq1","hbb fit", 700, 1000 ) ;
         } else if ( bins_of_nb == 2 ) {
            cfq1 = new TCanvas("cfq1","hbb fit", 700, 750 ) ;
         } else {
            return ;
         }
      }

      RooRealVar* rv_sig_strength = ws->var("sig_strength") ;
      if ( rv_sig_strength == 0x0 ) { printf("\n\n *** can't find sig_strength in workspace.\n\n" ) ; return ; }

      ModelConfig* modelConfig = (ModelConfig*) ws->obj( "SbModel" ) ;

      RooDataSet* rds = (RooDataSet*) ws->obj( "hbb_observed_rds" ) ;

      rds->Print() ;
      rds->printMultiline(cout, 1, kTRUE, "") ;

      RooAbsPdf* likelihood = modelConfig->GetPdf() ;

      ///RooFitResult* fitResult = likelihood->fitTo( *rds, Save(true), PrintLevel(0) ) ;
      RooFitResult* fitResult = likelihood->fitTo( *rds, Save(true), PrintLevel(3) ) ;
      fitResult->Print() ;


      char hname[1000] ;
      char htitle[1000] ;
      char pname[1000] ;




     //-- unpack observables.

      int obs_N_msig[10][50] ; // first index is n btags, second is met bin.
      int obs_N_msb[10][50]  ; // first index is n btags, second is met bin.

      const RooArgSet* dsras = rds->get() ;
      TIterator* obsIter = dsras->createIterator() ;
      while ( RooRealVar* obs = (RooRealVar*) obsIter->Next() ) {
         for ( int nbi=0; nbi<bins_of_nb; nbi++ ) {
            for ( int mbi=0; mbi<bins_of_met; mbi++ ) {
               sprintf( pname, "N_%db_msig_met%d", nb_lookup[nbi], mbi+1 ) ;
               if ( strcmp( obs->GetName(), pname ) == 0 ) { obs_N_msig[nbi][mbi] = TMath::Nint( obs -> getVal() ) ; }
               sprintf( pname, "N_%db_msb_met%d", nb_lookup[nbi], mbi+1 ) ;
               if ( strcmp( obs->GetName(), pname ) == 0 ) { obs_N_msb[nbi][mbi] = TMath::Nint( obs -> getVal() ) ; }
            } // mbi.
         } // nbi.
      } // obs iterator.


      printf("\n\n") ;
      for ( int nbi=0; nbi<bins_of_nb; nbi++ ) {
         printf(" nb=%d :  ", nb_lookup[nbi] ) ;
         for ( int mbi=0; mbi<bins_of_met; mbi++ ) {
            printf("  sig=%3d, sb=%3d  |", obs_N_msig[nbi][mbi], obs_N_msb[nbi][mbi] ) ;
         } // mbi.
         printf("\n") ;
      } // nbi.
      printf("\n\n") ;




      int pad(1) ;

      cfq1->Clear() ;
      cfq1->Divide( 2, bins_of_nb+1 ) ;

      for ( int nbi=0; nbi<bins_of_nb; nbi++ ) {


         sprintf( hname, "h_bg_%db_msig_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sig, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_bg_msig = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;
         hist_bg_msig -> SetFillColor( kBlue-9 ) ;
         labelBins( hist_bg_msig ) ;

         sprintf( hname, "h_bg_%db_msb_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sb, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_bg_msb = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;
         hist_bg_msb -> SetFillColor( kBlue-9 ) ;
         labelBins( hist_bg_msb ) ;

         sprintf( hname, "h_sig_%db_msig_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sig, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_sig_msig = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;
         hist_sig_msig -> SetFillColor( kMagenta+2 ) ;
         labelBins( hist_sig_msig ) ;

         sprintf( hname, "h_sig_%db_msb_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sb, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_sig_msb = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;
         hist_sig_msb -> SetFillColor( kMagenta+2 ) ;
         labelBins( hist_sig_msb ) ;

         sprintf( hname, "h_all_%db_msig_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sig, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_all_msig = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;

         sprintf( hname, "h_all_%db_msb_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sb, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_all_msb = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;

         sprintf( hname, "h_data_%db_msig_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sig, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_data_msig = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;
         hist_data_msig -> SetLineWidth(2) ;
         hist_data_msig -> SetMarkerStyle(20) ;
         labelBins( hist_data_msig ) ;

         sprintf( hname, "h_data_%db_msb_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sb, %db, MET", nb_lookup[nbi] ) ;
         TH1F* hist_data_msb = new TH1F( hname, htitle, bins_of_met, 0.5, bins_of_met+0.5 ) ;
         hist_data_msb -> SetLineWidth(2) ;
         hist_data_msb -> SetMarkerStyle(20) ;
         labelBins( hist_data_msb ) ;

         for ( int mbi=0; mbi<bins_of_met; mbi++ ) {



            sprintf( pname, "mu_bg_%db_msig_met%d", nb_lookup[nbi], mbi+1 ) ;
            RooAbsReal* mu_bg_msig = ws->function( pname ) ;
            if ( mu_bg_msig == 0x0 ) { printf("\n\n *** ws missing %s\n\n", pname ) ; return ; }
            hist_bg_msig -> SetBinContent( mbi+1, mu_bg_msig->getVal() ) ;

            sprintf( pname, "mu_sig_%db_msig_met%d", nb_lookup[nbi], mbi+1 ) ;
            RooAbsReal* mu_sig_msig = ws->function( pname ) ;
            if ( mu_sig_msig == 0x0 ) { printf("\n\n *** ws missing %s\n\n", pname ) ; return ; }
            hist_sig_msig -> SetBinContent( mbi+1, mu_sig_msig->getVal() ) ;

            hist_all_msig -> SetBinContent( mbi+1, mu_bg_msig->getVal() + mu_sig_msig->getVal() ) ;

            hist_data_msig -> SetBinContent( mbi+1, obs_N_msig[nbi][mbi] ) ;



            sprintf( pname, "mu_bg_%db_msb_met%d", nb_lookup[nbi], mbi+1 ) ;
            RooAbsReal* mu_bg_msb = ws->function( pname ) ;
            if ( mu_bg_msb == 0x0 ) { printf("\n\n *** ws missing %s\n\n", pname ) ; return ; }
            hist_bg_msb -> SetBinContent( mbi+1, mu_bg_msb->getVal() ) ;

            sprintf( pname, "mu_sig_%db_msb_met%d", nb_lookup[nbi], mbi+1 ) ;
            RooAbsReal* mu_sig_msb = ws->function( pname ) ;
            if ( mu_sig_msb == 0x0 ) { printf("\n\n *** ws missing %s\n\n", pname ) ; return ; }
            hist_sig_msb -> SetBinContent( mbi+1, mu_sig_msb->getVal() ) ;

            hist_all_msb -> SetBinContent( mbi+1, mu_bg_msb->getVal() + mu_sig_msb->getVal() ) ;

            hist_data_msb -> SetBinContent( mbi+1, obs_N_msb[nbi][mbi] ) ;



         } // mbi.

         cfq1->cd( pad ) ;

         sprintf( hname, "h_stack_%db_msig_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sig, %db, MET", nb_lookup[nbi] ) ;
         THStack* hstack_msig = new THStack( hname, htitle ) ;
         hstack_msig -> Add( hist_bg_msig ) ;
         hstack_msig -> Add( hist_sig_msig ) ;

         hist_data_msig -> Draw("e") ;
         hstack_msig -> Draw("same") ;
         hist_data_msig -> Draw("same e") ;
         hist_data_msig -> Draw("same axis") ;

         tt_title -> DrawTextNDC( 0.85, 0.85, plottitle ) ;

         pad++ ;



         cfq1->cd( pad ) ;

         sprintf( hname, "h_stack_%db_msb_met", nb_lookup[nbi] ) ;
         sprintf( htitle, "mass sig, %db, MET", nb_lookup[nbi] ) ;
         THStack* hstack_msb = new THStack( hname, htitle ) ;
         hstack_msb -> Add( hist_bg_msb ) ;
         hstack_msb -> Add( hist_sig_msb ) ;

         hist_data_msb -> Draw("e") ;
         hstack_msb -> Draw("same") ;
         hist_data_msb -> Draw("same e") ;
         hist_data_msb -> Draw("same axis") ;

         tt_title -> DrawTextNDC( 0.85, 0.85, plottitle ) ;

         pad++ ;



      } // nbi.




      TH1F* hist_R_msigmsb = new TH1F( "h_R_msigmsb", "R msig/msb vs met bin", bins_of_met, 0.5, 0.5+bins_of_met ) ;
      hist_R_msigmsb -> SetLineWidth(2) ;
      hist_R_msigmsb -> SetMarkerStyle(20) ;
      hist_R_msigmsb -> SetYTitle("R msig/msb") ;
      labelBins( hist_R_msigmsb ) ;


      for ( int mbi=0; mbi<bins_of_met; mbi++ ) {
         sprintf( pname, "R_msigmsb_met%d", mbi+1 ) ;
         RooRealVar* rrv_R = ws->var( pname ) ;
         if ( rrv_R == 0x0 ) { printf("\n\n *** Can't find %s in ws.\n\n", pname ) ; return ; }
         hist_R_msigmsb -> SetBinContent( mbi+1, rrv_R -> getVal() ) ;
         hist_R_msigmsb -> SetBinError( mbi+1, rrv_R -> getError() ) ;
      } // mbi.

      cfq1->cd( pad ) ;

      gPad->SetGridy(1) ;

      hist_R_msigmsb -> SetMaximum(0.35) ;
      hist_R_msigmsb -> Draw("e") ;

      tt_title -> DrawTextNDC( 0.85, 0.85, plottitle ) ;

      pad++ ;



      cfq1->cd( pad ) ;

      scan_sigstrength( wsfile ) ;

      tt_title -> DrawTextNDC( 0.85, 0.25, plottitle ) ;



      TString pdffile( wsfile ) ;
      pdffile.ReplaceAll("ws-","fitqual-") ;
      pdffile.ReplaceAll("root","pdf") ;


      cfq1->SaveAs( pdffile ) ;



      TString histfile( wsfile ) ;
      histfile.ReplaceAll("ws-","fitqual-") ;

      saveHist( histfile, "h*" ) ;



   } // fitqual_plots
float ComputeTestStat(TString wsfile, double mu_susy_sig_val) {

  gROOT->Reset();

  TFile* wstf = new TFile( wsfile ) ;

  RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") );
  ws->Print() ;
  
  ModelConfig* modelConfig = (ModelConfig*) ws->obj( "SbModel" ) ;
  
  modelConfig->Print() ;

  RooDataSet* rds = (RooDataSet*) ws->obj( "ra2b_observed_rds" ) ;
  
  rds->Print() ;
  rds->printMultiline(cout, 1, kTRUE, "") ;
  
  RooAbsPdf* likelihood = modelConfig->GetPdf() ;
  
  RooRealVar* rrv_mu_susy_sig = ws->var("mu_susy_all0lep") ;
  if ( rrv_mu_susy_sig == 0x0 ) {
    printf("\n\n\n *** can't find mu_susy_all0lep in workspace.  Quitting.\n\n\n") ;
    return ;
  } else {
    printf(" current value is : %8.3f\n", rrv_mu_susy_sig->getVal() ) ; cout << flush ;
    rrv_mu_susy_sig->setConstant(kFALSE) ;
  }

  /*
  // check the impact of varying the qcd normalization:

  RooRealVar *rrv_qcd_0lepLDP_ratioH1 = ws->var("qcd_0lepLDP_ratio_H1");
  RooRealVar *rrv_qcd_0lepLDP_ratioH2 = ws->var("qcd_0lepLDP_ratio_H2");
  RooRealVar *rrv_qcd_0lepLDP_ratioH3 = ws->var("qcd_0lepLDP_ratio_H3");
  
  rrv_qcd_0lepLDP_ratioH1->setVal(0.3);
  rrv_qcd_0lepLDP_ratioH2->setVal(0.3);
  rrv_qcd_0lepLDP_ratioH3->setVal(0.3);
  
  rrv_qcd_0lepLDP_ratioH1->setConstant(kTRUE);
  rrv_qcd_0lepLDP_ratioH2->setConstant(kTRUE);
  rrv_qcd_0lepLDP_ratioH3->setConstant(kTRUE);
  */
  
  printf("\n\n\n  ===== Doing a fit with SUSY component floating ====================\n\n") ;

  RooFitResult* fitResult = likelihood->fitTo( *rds, Save(true), PrintLevel(0) ) ;
  double logLikelihoodSusyFloat = fitResult->minNll() ;
  
  double logLikelihoodSusyFixed(0.) ;
  double testStatVal(-1.) ;
  if ( mu_susy_sig_val >= 0. ) {
    printf("\n\n\n  ===== Doing a fit with SUSY fixed ====================\n\n") ;
    printf(" fixing mu_susy_sig to %8.2f.\n", mu_susy_sig_val ) ;
    rrv_mu_susy_sig->setVal( mu_susy_sig_val ) ;
    rrv_mu_susy_sig->setConstant(kTRUE) ;
    
    fitResult = likelihood->fitTo( *rds, Save(true), PrintLevel(0) ) ;
    logLikelihoodSusyFixed = fitResult->minNll() ;
    testStatVal = 2.*(logLikelihoodSusyFixed - logLikelihoodSusyFloat) ;
    printf("\n\n\n ======= test statistic : -2 * ln (L_fixed / ln L_max) = %8.3f\n\n\n", testStatVal ) ;
  }


  return testStatVal ;

}
   void ws_cls_hybrid1_ag( const char* wsfile = "output-files/expected-ws-lm9-2BL.root", bool isBgonlyStudy=false, double poiVal = 150.0, int nToys=100, bool makeTtree=true, int verbLevel=0 ) {



       TTree* toytt(0x0) ;
       TFile* ttfile(0x0) ;

       int    tt_gen_Nsig ;
       int    tt_gen_Nsb ;
       int    tt_gen_Nsig_sl ;
       int    tt_gen_Nsb_sl ;
       int    tt_gen_Nsig_ldp ;
       int    tt_gen_Nsb_ldp ;
       int    tt_gen_Nsig_ee ;
       int    tt_gen_Nsb_ee ;
       int    tt_gen_Nsig_mm ;
       int    tt_gen_Nsb_mm ;

       double tt_testStat ;
       double tt_dataTestStat ;
       double tt_hypo_mu_susy_sig ;
       char ttname[1000] ;
       char tttitle[1000] ;

       if ( makeTtree ) {

          ttfile = gDirectory->GetFile() ;
          if ( ttfile == 0x0 ) { printf("\n\n\n *** asked for a ttree but no open file???\n\n") ; return ; }


          if ( isBgonlyStudy ) {
             sprintf( ttname, "toytt_%.0f_bgo", poiVal ) ;
             sprintf( tttitle, "Toy study for background only, mu_susy_sig = %.0f", poiVal ) ;
          } else {
             sprintf( ttname, "toytt_%.0f_spb", poiVal ) ;
             sprintf( tttitle, "Toy study for signal+background, mu_susy_sig = %.0f", poiVal ) ;
          }

          printf("\n\n Creating TTree : %s : %s\n\n", ttname, tttitle ) ;

          gDirectory->pwd() ;
          gDirectory->ls() ;

          toytt = new TTree( ttname, tttitle ) ;

          gDirectory->ls() ;

          toytt -> Branch(  "gen_Nsig"         ,       &tt_gen_Nsig         ,      "gen_Nsig/I"         ) ;
          toytt -> Branch(  "gen_Nsb"          ,       &tt_gen_Nsb          ,      "gen_Nsb/I"          ) ;
          toytt -> Branch(  "gen_Nsig_sl"      ,       &tt_gen_Nsig_sl      ,      "gen_Nsig_sl/I"      ) ;
          toytt -> Branch(  "gen_Nsb_sl"       ,       &tt_gen_Nsb_sl       ,      "gen_Nsb_sl/I"       ) ;
          toytt -> Branch(  "gen_Nsig_ldp"     ,       &tt_gen_Nsig_ldp     ,      "gen_Nsig_ldp/I"     ) ;
          toytt -> Branch(  "gen_Nsb_ldp"      ,       &tt_gen_Nsb_ldp      ,      "gen_Nsb_ldp/I"      ) ;
          toytt -> Branch(  "gen_Nsig_ee"      ,       &tt_gen_Nsig_ee      ,      "gen_Nsig_ee/I"      ) ;
          toytt -> Branch(  "gen_Nsb_ee"       ,       &tt_gen_Nsb_ee       ,      "gen_Nsb_ee/I"       ) ;
          toytt -> Branch(  "gen_Nsig_mm"      ,       &tt_gen_Nsig_mm      ,      "gen_Nsig_mm/I"      ) ;
          toytt -> Branch(  "gen_Nsb_mm"       ,       &tt_gen_Nsb_mm       ,      "gen_Nsb_mm/I"       ) ;

          toytt -> Branch(  "testStat"         ,       &tt_testStat         ,      "testStat/D"         ) ;
          toytt -> Branch(  "dataTestStat"     ,       &tt_dataTestStat     ,      "dataTestStat/D"     ) ;
          toytt -> Branch(  "hypo_mu_susy_sig" ,       &tt_hypo_mu_susy_sig ,      "hypo_mu_susy_sig/D" ) ;

       }


     //--- Tell RooFit to shut up about anything less important than an ERROR.
      RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;


       random_ng = new TRandom2(12345) ;

   /// char sel[100] ;
   /// if ( strstr( wsfile, "1BL" ) != 0 ) {
   ///    sprintf( sel, "1BL" ) ;
   /// } else if ( strstr( wsfile, "2BL" ) != 0 ) {
   ///    sprintf( sel, "2BL" ) ;
   /// } else if ( strstr( wsfile, "3B" ) != 0 ) {
   ///    sprintf( sel, "3B" ) ;
   /// } else if ( strstr( wsfile, "1BT" ) != 0 ) {
   ///    sprintf( sel, "1BT" ) ;
   /// } else if ( strstr( wsfile, "2BT" ) != 0 ) {
   ///    sprintf( sel, "2BT" ) ;
   /// } else {
   ///    printf("\n\n\n *** can't figure out which selection this is.  I quit.\n\n" ) ;
   ///    return ;
   /// }
   /// printf("\n\n selection is %s\n\n", sel ) ;




       TFile* wstf = new TFile( wsfile ) ;

       RooWorkspace* ws = dynamic_cast<RooWorkspace*>( wstf->Get("ws") );

       ws->Print() ;






       RooDataSet* rds = (RooDataSet*) ws->obj( "ra2b_observed_rds" ) ;
       printf("\n\n\n  ===== RooDataSet ====================\n\n") ;

       rds->Print() ;
       rds->printMultiline(cout, 1, kTRUE, "") ;





       ModelConfig* modelConfig = (ModelConfig*) ws->obj( "SbModel" ) ;
       RooAbsPdf* likelihood = modelConfig->GetPdf() ;

       const RooArgSet* nuisanceParameters = modelConfig->GetNuisanceParameters() ;

       RooRealVar* rrv_mu_susy_sig = ws->var("mu_susy_sig") ;
       if ( rrv_mu_susy_sig == 0x0 ) {
          printf("\n\n\n *** can't find mu_susy_sig in workspace.  Quitting.\n\n\n") ;
          return ;
       }






 ////  printf("\n\n\n  ===== Doing a fit ====================\n\n") ;

 ////  RooFitResult* preFitResult = likelihood->fitTo( *rds, Save(true) ) ;
 ////  const RooArgList preFitFloatVals = preFitResult->floatParsFinal() ;
 ////  {
 ////    TIterator* parIter = preFitFloatVals.createIterator() ;
 ////    while ( RooRealVar* par = (RooRealVar*) parIter->Next() ) {
 ////       printf(" %20s : %8.2f\n", par->GetName(), par->getVal() ) ;
 ////    }
 ////  }







       //--- Get pointers to the model predictions of the observables.

       rfv_n_sig       = ws->function("n_sig") ;
       rfv_n_sb        = ws->function("n_sb") ;
       rfv_n_sig_sl    = ws->function("n_sig_sl") ;
       rfv_n_sb_sl     = ws->function("n_sb_sl") ;
       rfv_n_sig_ldp   = ws->function("n_sig_ldp") ;
       rfv_n_sb_ldp    = ws->function("n_sb_ldp") ;
       rfv_n_sig_ee    = ws->function("n_sig_ee") ;
       rfv_n_sb_ee     = ws->function("n_sb_ee") ;
       rfv_n_sig_mm    = ws->function("n_sig_mm") ;
       rfv_n_sb_mm     = ws->function("n_sb_mm") ;

       if ( rfv_n_sig         == 0x0 ) { printf("\n\n\n *** can't find n_sig       in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sb          == 0x0 ) { printf("\n\n\n *** can't find n_sb        in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sig_sl      == 0x0 ) { printf("\n\n\n *** can't find n_sig_sl    in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sb_sl       == 0x0 ) { printf("\n\n\n *** can't find n_sb_sl     in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sig_ldp     == 0x0 ) { printf("\n\n\n *** can't find n_sig_ldp   in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sb_ldp      == 0x0 ) { printf("\n\n\n *** can't find n_sb_ldp    in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sig_ee      == 0x0 ) { printf("\n\n\n *** can't find n_sig_ee    in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sb_ee       == 0x0 ) { printf("\n\n\n *** can't find n_sb_ee     in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sig_mm      == 0x0 ) { printf("\n\n\n *** can't find n_sig_mm    in workspace.  Quitting.\n\n\n") ; return ; }
       if ( rfv_n_sb_mm       == 0x0 ) { printf("\n\n\n *** can't find n_sb_mm     in workspace.  Quitting.\n\n\n") ; return ; }







       //--- Get pointers to the observables.

       const RooArgSet* dsras = rds->get() ;
       TIterator* obsIter = dsras->createIterator() ;
       while ( RooRealVar* obs = (RooRealVar*) obsIter->Next() ) {
          if ( strcmp( obs->GetName(), "Nsig"     ) == 0 ) { rrv_Nsig      = obs ; }
          if ( strcmp( obs->GetName(), "Nsb"      ) == 0 ) { rrv_Nsb       = obs ; }
          if ( strcmp( obs->GetName(), "Nsig_sl"  ) == 0 ) { rrv_Nsig_sl   = obs ; }
          if ( strcmp( obs->GetName(), "Nsb_sl"   ) == 0 ) { rrv_Nsb_sl    = obs ; }
          if ( strcmp( obs->GetName(), "Nsig_ldp" ) == 0 ) { rrv_Nsig_ldp  = obs ; }
          if ( strcmp( obs->GetName(), "Nsb_ldp"  ) == 0 ) { rrv_Nsb_ldp   = obs ; }
          if ( strcmp( obs->GetName(), "Nsig_ee"  ) == 0 ) { rrv_Nsig_ee   = obs ; }
          if ( strcmp( obs->GetName(), "Nsb_ee"   ) == 0 ) { rrv_Nsb_ee    = obs ; }
          if ( strcmp( obs->GetName(), "Nsig_mm"  ) == 0 ) { rrv_Nsig_mm   = obs ; }
          if ( strcmp( obs->GetName(), "Nsb_mm"   ) == 0 ) { rrv_Nsb_mm    = obs ; }
       }

       if ( rrv_Nsig       == 0x0 ) { printf("\n\n\n *** can't find Nsig       in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsb        == 0x0 ) { printf("\n\n\n *** can't find Nsb        in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsig_sl    == 0x0 ) { printf("\n\n\n *** can't find Nsig_sl    in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsb_sl     == 0x0 ) { printf("\n\n\n *** can't find Nsb_sl     in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsig_ldp   == 0x0 ) { printf("\n\n\n *** can't find Nsig_ldp   in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsb_ldp    == 0x0 ) { printf("\n\n\n *** can't find Nsb_ldp    in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsig_ee    == 0x0 ) { printf("\n\n\n *** can't find Nsig_ee    in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsb_ee     == 0x0 ) { printf("\n\n\n *** can't find Nsb_ee     in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsig_mm    == 0x0 ) { printf("\n\n\n *** can't find Nsig_mm    in dataset.  Quitting.\n\n\n") ; return ; }
       if ( rrv_Nsb_mm     == 0x0 ) { printf("\n\n\n *** can't find Nsb_mm     in dataset.  Quitting.\n\n\n") ; return ; }






       printf("\n\n\n === Model values for observables\n\n") ;

       printObservables() ;



      //--- save the actual values of the observables.

       saveObservables() ;











       //--- evaluate the test stat on the data: fit with susy floating.

       rrv_mu_susy_sig->setVal( poiVal ) ;
       rrv_mu_susy_sig->setConstant( kTRUE ) ;

       printf("\n\n\n ====== Fitting the data with susy fixed.\n\n") ;

       RooFitResult* dataFitResultSusyFixed = likelihood->fitTo(*rds, Save(true));
       int dataSusyFixedFitCovQual = dataFitResultSusyFixed->covQual() ;
       if ( dataSusyFixedFitCovQual != 3 ) { printf("\n\n\n *** Failed fit!  Cov qual %d.  Quitting.\n\n", dataSusyFixedFitCovQual ) ; return ; }
       double dataFitSusyFixedNll = dataFitResultSusyFixed->minNll() ;


       rrv_mu_susy_sig->setVal( 0.0 ) ;
       rrv_mu_susy_sig->setConstant( kFALSE ) ;

       printf("\n\n\n ====== Fitting the data with susy floating.\n\n") ;

       RooFitResult* dataFitResultSusyFloat = likelihood->fitTo(*rds, Save(true));
       int dataSusyFloatFitCovQual = dataFitResultSusyFloat->covQual() ;
       if ( dataSusyFloatFitCovQual != 3 ) { printf("\n\n\n *** Failed fit!  Cov qual %d.  Quitting.\n\n", dataSusyFloatFitCovQual ) ; return ; }
       double dataFitSusyFloatNll = dataFitResultSusyFloat->minNll() ;

       double dataTestStat = 2.*( dataFitSusyFixedNll - dataFitSusyFloatNll) ;

       printf("\n\n\n Data value of test stat : %8.2f\n", dataTestStat ) ;












       printf("\n\n\n === Nuisance parameters\n\n") ;

       {
          int npi(0) ;
          TIterator* npIter = nuisanceParameters->createIterator() ;
          while ( RooRealVar* np_rrv = (RooRealVar*) npIter->Next() ) {

             np_initial_val[npi] = np_rrv->getVal() ; //--- I am assuming that the order of the NPs in the iterator does not change.

             TString npname( np_rrv->GetName() ) ;
             npname.ReplaceAll("_prim","") ;
             RooAbsReal* np_rfv = ws->function( npname ) ;

             TString pdfname( np_rrv->GetName() ) ;
             pdfname.ReplaceAll("_prim","") ;
             pdfname.Prepend("pdf_") ;
             RooAbsPdf* np_pdf = ws->pdf( pdfname ) ;
             if ( np_pdf == 0x0 ) { printf("\n\n *** Can't find nuisance parameter pdf with name %s.\n\n", pdfname.Data() ) ; }

             if ( np_rfv != 0x0 ) {
                printf(" %20s : %8.2f , %20s, %8.2f\n", np_rrv->GetName(), np_rrv->getVal(), np_rfv->GetName(), np_rfv->getVal() ) ;
             } else {
                printf(" %20s : %8.2f\n", np_rrv->GetName(), np_rrv->getVal() ) ;
             }

             npi++ ;
          } // np_rrv iterator.

          np_count = npi ;

       }







       tt_dataTestStat = dataTestStat ;
       tt_hypo_mu_susy_sig = poiVal ;














       printf("\n\n\n === Doing the toys\n\n") ;

       int nToyOK(0) ;
       int nToyWorseThanData(0) ;

       for ( int ti=0; ti<nToys; ti++ ) {

          printf("\n\n\n ======= Toy %4d\n\n\n", ti ) ;





          //--- 1) pick values for the nuisance parameters from the PDFs and fix them.

          {
             TIterator* npIter = nuisanceParameters->createIterator() ;
             while ( RooRealVar* np_rrv = (RooRealVar*) npIter->Next() ) {

                TString pdfname( np_rrv->GetName() ) ;
                pdfname.ReplaceAll("_prim","") ;
                pdfname.Prepend("pdf_") ;
                RooAbsPdf* np_pdf = ws->pdf( pdfname ) ;
                if ( np_pdf == 0x0 ) { printf("\n\n *** Can't find nuisance parameter pdf with name %s.\n\n", pdfname.Data() ) ; return ; }

                RooDataSet* nprds = np_pdf->generate( RooArgSet(*np_rrv) ,1) ;
                const RooArgSet* npdsras = nprds->get() ;
                TIterator* valIter = npdsras->createIterator() ;
                RooRealVar* val = (RooRealVar*) valIter->Next() ;

                //--- reset the value of the nuisance parameter and fix it for the toy model definition fit.
                np_rrv->setVal( val->getVal() ) ;
                np_rrv->setConstant( kTRUE ) ;


                TString npname( np_rrv->GetName() ) ;
                npname.ReplaceAll("_prim","") ;
                RooAbsReal* np_rfv = ws->function( npname ) ;

                if ( verbLevel > 0 ) {
                   if ( np_rfv != 0x0 ) {
                      printf(" %20s : %8.2f , %15s, %8.3f\n", val->GetName(), val->getVal(), np_rfv->GetName(), np_rfv->getVal() ) ;
                   } else if ( strstr( npname.Data(), "eff_sf" ) != 0 ) {
                      np_rfv = ws->function( "eff_sf_sig" ) ;
                      RooAbsReal* np_rfv2 = ws->function( "eff_sf_sb" ) ;
                      printf(" %20s : %8.2f , %15s, %8.3f , %15s, %8.3f\n", val->GetName(), val->getVal(), np_rfv->GetName(), np_rfv->getVal(), np_rfv2->GetName(), np_rfv2->getVal() ) ;
                   } else if ( strstr( npname.Data(), "sf_ll" ) != 0 ) {
                      np_rfv = ws->function( "sf_ee" ) ;
                      RooAbsReal* np_rfv2 = ws->function( "sf_mm" ) ;
                      printf(" %20s : %8.2f , %15s, %8.3f , %15s, %8.3f\n", val->GetName(), val->getVal(), np_rfv->GetName(), np_rfv->getVal(), np_rfv2->GetName(), np_rfv2->getVal() ) ;
                   } else {
                      printf(" %20s : %8.2f\n", val->GetName(), val->getVal() ) ;
                   }
                }

                delete nprds ;

             } // np_rrv iterator
          }






          //--- 2) Fit the dataset with these values for the nuisance parameters.

          if ( isBgonlyStudy ) {
            //-- fit with susy yield fixed to zero.
             rrv_mu_susy_sig -> setVal( 0. ) ;
             if ( verbLevel > 0 ) { printf("\n Setting mu_susy_sig to zero.\n\n") ; }
          } else {
            //-- fit with susy yield fixed to predicted value.
             rrv_mu_susy_sig -> setVal( poiVal ) ;
             if ( verbLevel > 0 ) { printf("\n Setting mu_susy_sig to %8.1f.\n\n", poiVal) ; }
          }
          rrv_mu_susy_sig->setConstant( kTRUE ) ;

          if ( verbLevel > 0 ) {
             printf("\n\n") ;
             printf("  Fitting with these values for the observables to define the model for toy generation.\n") ;
             rds->printMultiline(cout, 1, kTRUE, "") ;
             printf("\n\n") ;
          }

          RooFitResult* toyModelDefinitionFitResult(0x0) ;
          if ( verbLevel < 2 ) {
             toyModelDefinitionFitResult = likelihood->fitTo(*rds, Save(true), PrintLevel(-1));
          } else {
             toyModelDefinitionFitResult = likelihood->fitTo(*rds, Save(true));
          }

          int toyModelDefFitCovQual = toyModelDefinitionFitResult->covQual() ;
          if ( verbLevel > 0 ) { printf("\n fit covariance matrix quality: %d\n\n", toyModelDefFitCovQual ) ; }
          if ( toyModelDefFitCovQual != 3 ) {
             printf("\n\n\n *** Bad toy model definition fit.  Cov qual %d.  Aborting this toy.\n\n\n", toyModelDefFitCovQual ) ;
             continue ;
          }

          delete toyModelDefinitionFitResult ;

          if ( verbLevel > 0 ) {
             printf("\n\n\n === Model values for observables.  These will be used to generate the toy dataset.\n\n") ;
             printObservables() ;
          }









          //--- 3) Generate a new set of observables based on this model.

          generateObservables() ;

          printf("\n\n\n   Generated dataset\n") ;
          rds->Print() ;
          rds->printMultiline(cout, 1, kTRUE, "") ;

          //--- Apparently, I need to make a new RooDataSet...  Resetting the
          //    values in the old one doesn't stick.  If you do likelihood->fitTo(*rds), it
          //    uses the original values, not the reset ones, in the fit.

          RooArgSet toyFitobservedParametersList ;
          toyFitobservedParametersList.add( *rrv_Nsig        ) ;
          toyFitobservedParametersList.add( *rrv_Nsb         ) ;
          toyFitobservedParametersList.add( *rrv_Nsig_sl     ) ;
          toyFitobservedParametersList.add( *rrv_Nsb_sl      ) ;
          toyFitobservedParametersList.add( *rrv_Nsig_ldp    ) ;
          toyFitobservedParametersList.add( *rrv_Nsb_ldp     ) ;
          toyFitobservedParametersList.add( *rrv_Nsig_ee     ) ;
          toyFitobservedParametersList.add( *rrv_Nsb_ee      ) ;
          toyFitobservedParametersList.add( *rrv_Nsig_mm     ) ;
          toyFitobservedParametersList.add( *rrv_Nsb_mm      ) ;


          RooDataSet* toyFitdsObserved = new RooDataSet("toyfit_ra2b_observed_rds", "RA2b toy observed data values",
                                         toyFitobservedParametersList ) ;
          toyFitdsObserved->add( toyFitobservedParametersList ) ;





          //--- 4) Reset and free the nuisance parameters.

          {
             if ( verbLevel > 0 ) { printf("\n\n") ; }
             int npi(0) ;
             TIterator* npIter = nuisanceParameters->createIterator() ;
             while ( RooRealVar* np_rrv = (RooRealVar*) npIter->Next() ) {
                np_rrv -> setVal( np_initial_val[npi] ) ; // assuming that the order in the iterator does not change.
                np_rrv -> setConstant( kFALSE ) ;
                npi++ ;
                if ( verbLevel > 0 ) { printf("    reset %20s to %8.2f and freed it.\n", np_rrv->GetName() , np_rrv->getVal() ) ; }
             } // np_rrv iterator.
             if ( verbLevel > 0 ) { printf("\n\n") ; }
          }





          //--- 5a) Evaluate the test statistic: Fit with susy yield floating to get the absolute maximum log likelihood.

          if ( verbLevel > 0 ) { printf("\n\n  Evaluating the test statistic for this toy.  Fitting with susy floating.\n\n") ; }

          rrv_mu_susy_sig->setVal( 0.0 ) ;
          rrv_mu_susy_sig->setConstant( kFALSE ) ;

          if ( verbLevel > 0 ) {
             printf("\n toy dataset\n\n") ;
             toyFitdsObserved->printMultiline(cout, 1, kTRUE, "") ;
          }

     /////---- nfg.  Need to create a new dataset  ----------
     /////RooFitResult* maxLikelihoodFitResult = likelihood->fitTo(*rds, Save(true), PrintLevel(-1));
     /////RooFitResult* maxLikelihoodFitResult = likelihood->fitTo(*rds, Save(true));
     /////--------------

          RooFitResult* maxLikelihoodFitResult(0x0) ;
          if ( verbLevel < 2 ) {
             maxLikelihoodFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true), PrintLevel(-1));
          } else {
             maxLikelihoodFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true));
          }

          if ( verbLevel > 0 ) { printObservables() ; }

          int mlFitCovQual = maxLikelihoodFitResult->covQual() ;
          if ( verbLevel > 0 ) { printf("\n fit covariance matrix quality: %d , -log likelihood %f\n\n", mlFitCovQual, maxLikelihoodFitResult->minNll() ) ; }
          if ( mlFitCovQual != 3 ) {
             printf("\n\n\n *** Bad maximum likelihood fit (susy floating).  Cov qual %d.  Aborting this toy.\n\n\n", mlFitCovQual ) ;
             continue ;
          }
          double maxL_susyFloat = maxLikelihoodFitResult->minNll() ;
          double maxL_mu_susy_sig = rrv_mu_susy_sig->getVal() ;

          delete maxLikelihoodFitResult ;






          //--- 5b) Evaluate the test statistic: Fit with susy yield fixed to hypothesis value.
          //        This is only necessary if the maximum likelihood fit value of the susy yield
          //        is less than the hypothesis value (to get a one-sided limit).


          double testStat(0.0) ;
          double maxL_susyFixed(0.0) ;

          if ( maxL_mu_susy_sig < poiVal ) {

             if ( verbLevel > 0 ) { printf("\n\n  Evaluating the test statistic for this toy.  Fitting with susy fixed to %8.2f.\n\n", poiVal ) ; }

             rrv_mu_susy_sig->setVal( poiVal ) ;
             rrv_mu_susy_sig->setConstant( kTRUE ) ;

             if ( verbLevel > 0 ) {
                printf("\n toy dataset\n\n") ;
                rds->printMultiline(cout, 1, kTRUE, "") ;
             }

         ////--------- nfg.  need to make a new dataset  ---------------
         ////RooFitResult* susyFixedFitResult = likelihood->fitTo(*rds, Save(true), PrintLevel(-1));
         ////RooFitResult* susyFixedFitResult = likelihood->fitTo(*rds, Save(true));
         ////-----------------------------

             RooFitResult* susyFixedFitResult(0x0) ;
             if ( verbLevel < 2 ) {
                susyFixedFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true), PrintLevel(-1));
             } else {
                susyFixedFitResult = likelihood->fitTo(*toyFitdsObserved, Save(true));
             }

             if ( verbLevel > 0 ) { printObservables() ; }

             int susyFixedFitCovQual = susyFixedFitResult->covQual() ;
             if ( verbLevel > 0 ) { printf("\n fit covariance matrix quality: %d , -log likelihood %f\n\n", susyFixedFitCovQual, susyFixedFitResult->minNll()  ) ; }
             if ( susyFixedFitCovQual != 3 ) {
                printf("\n\n\n *** Bad maximum likelihood fit (susy fixed).  Cov qual %d.  Aborting this toy.\n\n\n", susyFixedFitCovQual ) ;
                continue ;
             }
             maxL_susyFixed = susyFixedFitResult->minNll() ;
             testStat = 2. * (maxL_susyFixed - maxL_susyFloat) ;


             delete susyFixedFitResult ;


          } else {

             if ( verbLevel > 0 ) { printf("\n\n  Floating value of susy yield greater than hypo value (%8.2f > %8.2f).  Setting test stat to zero.\n\n", maxL_mu_susy_sig, poiVal ) ; }

             testStat = 0.0 ;

          }

          printf("   --- test stat for toy %4d : %8.2f\n", ti, testStat ) ;





          nToyOK++ ;

          if ( testStat > dataTestStat ) { nToyWorseThanData++ ; }


          if ( makeTtree ) {

             tt_testStat = testStat ;

             tt_gen_Nsig     = rrv_Nsig->getVal() ;
             tt_gen_Nsb      = rrv_Nsb->getVal() ;
             tt_gen_Nsig_sl  = rrv_Nsig_sl->getVal() ;
             tt_gen_Nsb_sl   = rrv_Nsb_sl->getVal() ;
             tt_gen_Nsig_ldp = rrv_Nsig_ldp->getVal() ;
             tt_gen_Nsb_ldp  = rrv_Nsb_ldp->getVal() ;
             tt_gen_Nsig_ee  = rrv_Nsig_ee->getVal() ;
             tt_gen_Nsb_ee   = rrv_Nsb_ee->getVal() ;
             tt_gen_Nsig_mm  = rrv_Nsig_mm->getVal() ;
             tt_gen_Nsb_mm   = rrv_Nsb_mm->getVal() ;

             toytt->Fill() ;

          }





          //--- *) reset things for the next toy.

          resetObservables() ;

          delete toyFitdsObserved ;




       } // ti.

       wstf->Close() ;

       printf("\n\n\n") ;

       if ( nToyOK == 0 ) { printf("\n\n\n *** All toys bad !?!?!\n\n\n") ; return ; }

       double pValue = (1.0*nToyWorseThanData) / (1.0*nToyOK) ;

       if ( isBgonlyStudy ) {
          printf("\n\n\n p-value result, BG-only , poi=%3.0f : %4d / %4d = %6.3f\n\n\n\n", poiVal, nToyWorseThanData, nToyOK, pValue ) ;
       } else {
          printf("\n\n\n p-value result, S-plus-B, poi=%3.0f : %4d / %4d = %6.3f\n\n\n\n", poiVal, nToyWorseThanData, nToyOK, pValue ) ;
       }


       if ( makeTtree ) {
          printf("\n\n Writing TTree : %s : %s\n\n", ttname, tttitle ) ;
          ttfile->cd() ;
          toytt->Write() ;
       }


   } // ws_cls_hybrid1