//#include <typeinfo.h>
void addFlatNuisances(std::string fi){
  gSystem->Load("libHiggsAnalysisCombinedLimit.so");
  TFile *fin = TFile::Open(fi.c_str());
  RooWorkspace *wspace = (RooWorkspace*)fin->Get("w_hmumu");

  wspace->Print("");

  RooStats::ModelConfig *mc = (RooStats::ModelConfig*)wspace->genobj("ModelConfig");
  RooArgSet *nuis = (RooArgSet*) mc->GetNuisanceParameters();
  std::cout << "Before...." << std::endl;
  nuis->Print();
  
  RooRealVar *mgg = (RooRealVar*)wspace->var("mmm");
  // Get all of the "flat" nuisances to be added to the nusiances:
  RooArgSet pdfs = (RooArgSet) wspace->allVars();
  RooAbsReal *pdf;
  TIterator *it_pdf = pdfs.createIterator();
  

  while ( (pdf=(RooAbsReal*)it_pdf->Next()) ){
  	  if (!(std::string(pdf->GetName()).find("zmod") != std::string::npos )) {
  	   if (!(std::string(pdf->GetName()).find("__norm") != std::string::npos )) {
	   	continue;
	   }
	  }
	  pdf->Print();
	  RooArgSet* pdfpars = (RooArgSet*)pdf->getParameters(RooArgSet(*mgg));
	  pdfpars->Print();

	  std::string newname_pdf = (std::string("unconst_")+std::string(pdf->GetName()));
	  wspace->import(*pdf,RooFit::RenameVariable(pdf->GetName(),newname_pdf.c_str()));
	  pdf->SetName(newname_pdf.c_str());
	  nuis->add(*pdf);
  }
 
  wspace->var("MH")->setVal(125.0);
  std::cout << "After..." << std::endl;
  nuis->Print();
  mc->SetNuisanceParameters(*nuis);
  //RooWorkspace *wspace_new = wspace->Clone();
  //mc->SetWorkspace(*wspace_new);
  //wspace_new->import(*mc,true);

  TFile *finew = new TFile((std::string(fin->GetName())+std::string("_unconst.root")).c_str(),"RECREATE");
  //wspace_new->SetName("w");
  finew->WriteTObject(wspace);
  finew->Close();
}
Esempio n. 2
0
void rf105_funcbinding()
{

   // B i n d   T M a t h : : E r f   C   f u n c t i o n
   // ---------------------------------------------------

   // Bind one-dimensional TMath::Erf function as RooAbsReal function
   RooRealVar x("x","x",-3,3) ;
   RooAbsReal* errorFunc = bindFunction("erf",TMath::Erf,x) ;

   // Print erf definition
   errorFunc->Print() ;

   // Plot erf on frame 
   RooPlot* frame1 = x.frame(Title("TMath::Erf bound as RooFit function")) ;
   errorFunc->plotOn(frame1) ;


   // B i n d   R O O T : : M a t h : : b e t a _ p d f   C   f u n c t i o n
   // -----------------------------------------------------------------------

   // Bind pdf ROOT::Math::Beta with three variables as RooAbsPdf function
   RooRealVar x2("x2","x2",0,0.999) ;
   RooRealVar a("a","a",5,0,10) ;
   RooRealVar b("b","b",2,0,10) ;
   RooAbsPdf* beta = bindPdf("beta",ROOT::Math::beta_pdf,x2,a,b) ;

   // Perf beta definition
   beta->Print() ;

   // Generate some events and fit
   RooDataSet* data = beta->generate(x2,10000) ;
   beta->fitTo(*data) ;

   // Plot data and pdf on frame
   RooPlot* frame2 = x2.frame(Title("ROOT::Math::Beta bound as RooFit pdf")) ;
   data->plotOn(frame2) ;
   beta->plotOn(frame2) ;



   // B i n d   R O O T   T F 1   a s   R o o F i t   f u n c t i o n
   // ---------------------------------------------------------------

   // Create a ROOT TF1 function
   TF1 *fa1 = new TF1("fa1","sin(x)/x",0,10);

   // Create an observable 
   RooRealVar x3("x3","x3",0.01,20) ;

   // Create binding of TF1 object to above observable
   RooAbsReal* rfa1 = bindFunction(fa1,x3) ;

   // Print rfa1 definition
   rfa1->Print() ;

   // Make plot frame in observable, plot TF1 binding function
   RooPlot* frame3 = x3.frame(Title("TF1 bound as RooFit function")) ;
   rfa1->plotOn(frame3) ;



   TCanvas* c = new TCanvas("rf105_funcbinding","rf105_funcbinding",1200,400) ;
   c->Divide(3) ;
   c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame1->GetYaxis()->SetTitleOffset(1.6) ; frame1->Draw() ;
   c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.6) ; frame2->Draw() ;
   c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.6) ; frame3->Draw() ;

}
Esempio n. 3
0
void rf506_msgservice()
{
  // C r e a t e   p d f 
  // --------------------

  // Construct gauss(x,m,s)
  RooRealVar x("x","x",-10,10) ;
  RooRealVar m("m","m",0,-10,10) ;
  RooRealVar s("s","s",1,-10,10) ;
  RooGaussian gauss("g","g",x,m,s) ;

  // Construct poly(x,p0)
  RooRealVar p0("p0","p0",0.01,0.,1.) ;
  RooPolynomial poly("p","p",x,p0) ;		 

  // Construct model = f*gauss(x) + (1-f)*poly(x)
  RooRealVar f("f","f",0.5,0.,1.) ;
  RooAddPdf model("model","model",RooArgSet(gauss,poly),f) ;

  RooDataSet* data = model.generate(x,10) ;



  // P r i n t   c o n f i g u r a t i o n   o f   m e s s a g e   s e r v i c e
  // ---------------------------------------------------------------------------

  // Print streams configuration
  RooMsgService::instance().Print() ;
  cout << endl ;



  // A d d i n g   I n t e g r a t i o n   t o p i c   t o   e x i s t i n g   I N F O   s t r e a m
  // -----------------------------------------------------------------------------------------------

  // Print streams configuration
  RooMsgService::instance().Print() ;
  cout << endl ;

  // Add Integration topic to existing INFO stream
  RooMsgService::instance().getStream(1).addTopic(Integration) ;

  // Construct integral over gauss to demonstrate new message stream
  RooAbsReal* igauss = gauss.createIntegral(x) ;
  igauss->Print() ;

  // Print streams configuration in verbose, which also shows inactive streams
  cout << endl ;
  RooMsgService::instance().Print() ;
  cout << endl ;

  // Remove stream
  RooMsgService::instance().getStream(1).removeTopic(Integration) ;



  // E x a m p l e s   o f   p d f   v a l u e   t r a c i n g   s t r e a m
  // -----------------------------------------------------------------------
  
  // Show DEBUG level message on function tracing, trace RooGaussian only
  RooMsgService::instance().addStream(DEBUG,Topic(Tracing),ClassName("RooGaussian")) ;

  // Perform a fit to generate some tracing messages
  model.fitTo(*data,Verbose(kTRUE)) ;

  // Reset message service to default stream configuration
  RooMsgService::instance().reset() ;



  // Show DEBUG level message on function tracing on all objects, redirect output to file
  RooMsgService::instance().addStream(DEBUG,Topic(Tracing),OutputFile("rf506_debug.log")) ;

  // Perform a fit to generate some tracing messages
  model.fitTo(*data,Verbose(kTRUE)) ;

  // Reset message service to default stream configuration
  RooMsgService::instance().reset() ;



  // E x a m p l e   o f   a n o t h e r   d e b u g g i n g   s t r e a m
  // ---------------------------------------------------------------------

  // Show DEBUG level messages on client/server link state management
  RooMsgService::instance().addStream(DEBUG,Topic(LinkStateMgmt)) ;
  RooMsgService::instance().Print("v") ;

  // Clone composite pdf g to trigger some link state management activity
  RooAbsArg* gprime = gauss.cloneTree() ;
  gprime->Print() ;

  // Reset message service to default stream configuration
  RooMsgService::instance().reset() ;



}
int main() {
// Construct gauss(x,m,s)
  RooRealVar x("x","x",-10,10) ;
  RooRealVar m("m","m",0,-10,10) ;
  RooRealVar s("s","s",1,-10,10) ;
  RooGaussian gauss("g","g",x,m,s) ;

  // Construct poly(x,p0)
  RooRealVar p0("p0","p0",0.01,0.,1.) ;
  RooPolynomial poly("p","p",x,p0) ;		 

  // Construct model = f*gauss(x) + (1-f)*poly(x)
  RooRealVar f("f","f",0.5,0.,1.) ;
  RooAddPdf model("model","model",RooArgSet(gauss,poly),f) ;

  RooDataSet* data = model.generate(x,10);
  
// P r i n t   c o n f i g u r a t i o n   o f   m e s s a g e   s e r v i c e
  // ---------------------------------------------------------------------------

  // Print streams configuration
  RooMsgService::instance().Print() ;
  cout << endl ;



  // A d d i n g   I n t e g r a t i o n   t o p i c   t o   e x i s t i n g   I N F O   s t r e a m
  // -----------------------------------------------------------------------------------------------

  // Print streams configuration
  RooMsgService::instance().Print() ;
  cout << endl ;

  // Add Integration topic to existing INFO stream
  RooMsgService::instance().getStream(1).addTopic(Integration) ;

  // Construct integral over gauss to demonstrate new message stream
  RooAbsReal* igauss = gauss.createIntegral(x) ;
  igauss->Print() ;

  // Print streams configuration in verbose, which also shows inactive streams
  cout << endl ;
  RooMsgService::instance().Print() ;
  cout << endl ;

  // Remove stream
  RooMsgService::instance().getStream(1).removeTopic(Integration) ;



  // E x a m p l e s   o f   p d f   v a l u e   t r a c i n g   s t r e a m
  // -----------------------------------------------------------------------
  
  // Show DEBUG level message on function tracing, trace RooGaussian only
  RooMsgService::instance().addStream(DEBUG,Topic(Tracing),ClassName("RooGaussian")) ;

  // Perform a fit to generate some tracing messages
  model.fitTo(*data,Verbose(kTRUE)) ;
  
  TH1 *histo = model.createHistogram("histo");
  
  
  return 0;
}
   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() ;

   }