HistoToWorkspaceFactoryFast.cxx

Go to the documentation of this file.
00001 // @(#)root/roostats:$Id:  cranmer $
00002 // Author: Kyle Cranmer, Akira Shibata
00003 /*************************************************************************
00004  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
00005  * All rights reserved.                                                  *
00006  *                                                                       *
00007  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00008  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00009  *************************************************************************/
00010 
00011 //_________________________________________________
00012 /*
00013 BEGIN_HTML
00014 <p>
00015 </p>
00016 END_HTML
00017 */
00018 //
00019 
00020 
00021 #ifndef __CINT__
00022 #include "RooGlobalFunc.h"
00023 #endif
00024 
00025 // Roofit/Roostat include
00026 #include "RooDataSet.h"
00027 #include "RooRealVar.h"
00028 #include "RooConstVar.h"
00029 #include "RooAddition.h"
00030 #include "RooProduct.h"
00031 #include "RooProdPdf.h"
00032 #include "RooAddPdf.h"
00033 #include "RooGaussian.h"
00034 #include "RooExponential.h"
00035 #include "RooRandom.h"
00036 #include "RooCategory.h"
00037 #include "RooSimultaneous.h"
00038 #include "RooMultiVarGaussian.h"
00039 #include "RooNumIntConfig.h"
00040 #include "RooMinuit.h"
00041 #include "RooNLLVar.h"
00042 #include "RooProfileLL.h"
00043 #include "RooFitResult.h"
00044 #include "RooDataHist.h"
00045 #include "RooHistFunc.h"
00046 #include "RooHistPdf.h"
00047 #include "RooRealSumPdf.h"
00048 #include "RooProduct.h"
00049 #include "RooWorkspace.h"
00050 #include "RooCustomizer.h"
00051 #include "RooPlot.h"
00052 #include "RooMsgService.h"
00053 #include "RooStats/RooStatsUtils.h"
00054 #include "RooStats/ModelConfig.h"
00055 #include "RooStats/HistFactory/PiecewiseInterpolation.h"
00056 
00057 #include "TH2F.h"
00058 #include "TH3F.h"
00059 #include "TFile.h"
00060 #include "TCanvas.h"
00061 #include "TH1F.h"
00062 #include "TLine.h"
00063 #include "TTree.h"
00064 #include "TMarker.h"
00065 #include "TStopwatch.h"
00066 #include "TROOT.h"
00067 #include "TStyle.h"
00068 #include "TVectorD.h"
00069 #include "TMatrixDSym.h"
00070 
00071 // specific to this package
00072 //#include "RooStats/HistFactory/Helper.h"
00073 #include "Helper.h"
00074 #include "RooStats/HistFactory/LinInterpVar.h"
00075 #include "RooStats/HistFactory/HistoToWorkspaceFactoryFast.h"
00076 
00077 #define VERBOSE
00078 
00079 #define alpha_Low "-5"
00080 #define alpha_High "5"
00081 #define NoHistConst_Low "0"
00082 #define NoHistConst_High "2000"
00083 
00084 // use this order for safety on library loading
00085 using namespace RooFit ;
00086 using namespace RooStats ;
00087 using namespace std ;
00088 //using namespace RooMsgService ;
00089 
00090 ClassImp(RooStats::HistFactory::HistoToWorkspaceFactoryFast)
00091 
00092 namespace RooStats{
00093 namespace HistFactory{
00094 
00095   HistoToWorkspaceFactoryFast::HistoToWorkspaceFactoryFast(){}
00096   HistoToWorkspaceFactoryFast::~HistoToWorkspaceFactoryFast(){
00097     fclose(pFile);
00098   }
00099 
00100   HistoToWorkspaceFactoryFast::HistoToWorkspaceFactoryFast(string filePrefix, string row, vector<string> syst, double nomL, double lumiE, int low, int high, TFile* f):
00101       fFileNamePrefix(filePrefix),
00102       fRowTitle(row),
00103       fSystToFix(syst),
00104       fNomLumi(nomL),
00105       fLumiError(lumiE),
00106       fLowBin(low),
00107       fHighBin(high),
00108       fOut_f(f) {
00109 
00110     //    fResultsPrefixStr<<"results" << "_" << fNomLumi<< "_" << fLumiError<< "_" << fLowBin<< "_" << fHighBin;
00111     fResultsPrefixStr<< "_" << fRowTitle;
00112     while(fRowTitle.find("\\ ")!=string::npos){
00113       int pos=fRowTitle.find("\\ ");
00114       fRowTitle.replace(pos, 1, "");
00115     }
00116     pFile = fopen ((filePrefix+"_results.table").c_str(),"a"); 
00117     //RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
00118 
00119   }
00120 
00121   string HistoToWorkspaceFactoryFast::FilePrefixStr(string prefix){
00122 
00123     stringstream ss;
00124     ss << prefix << "_" << fNomLumi<< "_" << fLumiError<< "_" << fLowBin<< "_" << fHighBin<< "_"<<fRowTitle;
00125 
00126     return ss.str();
00127   }
00128 
00129   void HistoToWorkspaceFactoryFast::ProcessExpectedHisto(TH1F* hist,RooWorkspace* proto, string prefix, string
00130                                                          productPrefix, string systTerm, double /*low*/ , double
00131                                                          /*high*/, int /*lowBin*/, int /*highBin*/ ){
00132     if(hist)
00133       cout << "processing hist " << hist->GetName() << endl;
00134     else
00135       cout << "hist is empty" << endl;
00136 
00137 
00138     if(!proto->var(fObsName.c_str())){
00139       proto->factory(Form("%s[%f,%f]",fObsName.c_str(),hist->GetXaxis()->GetXmin(),hist->GetXaxis()->GetXmax()));
00140       proto->var(fObsName.c_str())->setBins(hist->GetNbinsX());
00141     }
00142     RooDataHist* histDHist = new RooDataHist((prefix+"nominalDHist").c_str(),"",*proto->var(fObsName.c_str()),hist);
00143     RooHistFunc* histFunc = new RooHistFunc((prefix+"_nominal").c_str(),"",*proto->var(fObsName.c_str()),*histDHist,0) ;
00144     proto->import(*histFunc);
00145 
00146     // now create the product of the overall efficiency times the sigma(params) for this estimate
00147     proto->factory(("prod:"+productPrefix+"("+prefix+"_nominal,"+systTerm+")").c_str() );    
00148     //    proto->Print();
00149   }
00150 
00151   void HistoToWorkspaceFactoryFast::AddMultiVarGaussConstraint(RooWorkspace* proto, string prefix,int lowBin, int highBin, vector<string>& likelihoodTermNames){
00152     // these are the nominal predictions: eg. the mean of some space of variations
00153     // later fill these in a loop over histogram bins
00154     TVectorD mean(highBin-lowBin);
00155     cout << "a" << endl;
00156     for(Int_t i=lowBin; i<highBin; ++i){
00157       std::stringstream str;
00158       str<<"_"<<i;
00159       RooRealVar* temp = proto->var((prefix+str.str()).c_str());
00160       mean(i) = temp->getVal();
00161     }
00162 
00163     TMatrixDSym Cov(highBin-lowBin);
00164     for(int i=lowBin; i<highBin; ++i){
00165       for(int j=0; j<highBin-lowBin; ++j){
00166         if(i==j) 
00167     Cov(i,j) = sqrt(mean(i));
00168         else
00169     Cov(i,j) = 0;
00170       }
00171     }
00172     // can't make MultiVarGaussian with factory yet, do it by hand
00173     RooArgList floating( *(proto->set(prefix.c_str() ) ) );
00174     RooMultiVarGaussian constraint((prefix+"Constraint").c_str(),"",
00175              floating, mean, Cov);
00176              
00177     proto->import(constraint);
00178 
00179     likelihoodTermNames.push_back(constraint.GetName());
00180 
00181   }
00182 
00183 
00184   void HistoToWorkspaceFactoryFast::LinInterpWithConstraint(RooWorkspace* proto, TH1F* nominal, vector<TH1F*> lowHist, vector<TH1F*> highHist, 
00185              vector<string> sourceName, string prefix, string productPrefix, string systTerm, 
00186                                                             int /*lowBin*/, int /*highBin */, vector<string>& likelihoodTermNames){
00187     // these are the nominal predictions: eg. the mean of some space of variations
00188     // later fill these in a loop over histogram bins
00189 
00190 
00191     if(!proto->var(fObsName.c_str())){
00192       proto->factory(Form("%s[%f,%f]",fObsName.c_str(),nominal->GetXaxis()->GetXmin(),nominal->GetXaxis()->GetXmax()));
00193       proto->var(fObsName.c_str())->setBins(nominal->GetNbinsX());
00194     }
00195     RooDataHist* nominalDHist = new RooDataHist((prefix+"nominalDHist").c_str(),"",*proto->var(fObsName.c_str()),nominal);
00196     RooHistFunc* nominalFunc = new RooHistFunc((prefix+"nominal").c_str(),"",*proto->var(fObsName.c_str()),*nominalDHist,0) ;
00197 
00198     // make list of abstract parameters that interpolate in space of variations
00199     RooArgList params( ("alpha_Hist") );
00200     // range is set using defined macro (see top of the page)
00201     string range=string("[")+alpha_Low+","+alpha_High+"]";
00202     for(unsigned int j=0; j<lowHist.size(); ++j){
00203       std::stringstream str;
00204       str<<"_"<<j;
00205 
00206       RooRealVar* temp = (RooRealVar*) proto->var(("alpha_"+sourceName.at(j)).c_str());
00207       if(!temp){
00208         temp = (RooRealVar*) proto->factory(("alpha_"+sourceName.at(j)+range).c_str());
00209 
00210         // now add a constraint term for these parameters
00211         string command=("Gaussian::alpha_"+sourceName.at(j)+"Constraint(alpha_"+sourceName.at(j)+",nom_"+sourceName.at(j)+"[0.,-10,10],1.)");
00212         cout << command << endl;
00213         likelihoodTermNames.push_back(  proto->factory( command.c_str() )->GetName() );
00214         proto->var(("nom_"+sourceName.at(j)).c_str())->setConstant();
00215         const_cast<RooArgSet*>(proto->set("globalObservables"))->add(*proto->var(("nom_"+sourceName.at(j)).c_str()));
00216 
00217       } 
00218 
00219       params.add(* temp );
00220 
00221     }
00222 
00223     // now make function that linearly interpolates expectation between variations
00224     // get low/high variations to interpolate between
00225     vector<double> low, high;
00226     RooArgSet lowSet, highSet;
00227     for(unsigned int j=0; j<lowHist.size(); ++j){
00228       std::stringstream str;
00229       str<<"_"<<j;
00230       lowHist.at(j);
00231       highHist.at(j);
00232       RooDataHist* lowDHist = new RooDataHist((prefix+str.str()+"lowDHist").c_str(),"",*proto->var(fObsName.c_str()),lowHist.at(j));
00233       RooDataHist* highDHist = new RooDataHist((prefix+str.str()+"lowDHist").c_str(),"",*proto->var(fObsName.c_str()),highHist.at(j));
00234       RooHistFunc* lowFunc = new RooHistFunc((prefix+str.str()+"low").c_str(),"",*proto->var(fObsName.c_str()),*lowDHist,0) ;
00235       RooHistFunc* highFunc = new RooHistFunc((prefix+str.str()+"high").c_str(),"",*proto->var(fObsName.c_str()),*highDHist,0) ;
00236       lowSet.add(*lowFunc);
00237       highSet.add(*highFunc);
00238     }
00239     
00240     // this is sigma(params), a piece-wise linear interpolation
00241     //    LinInterpVar interp( (prefix+str.str()).c_str(), "", params, nominal->GetBinContent(i+1), low, high);
00242     PiecewiseInterpolation interp(prefix.c_str(),"",*nominalFunc,lowSet,highSet,params);
00243     interp.setPositiveDefinite();
00244     
00245     //    cout << "check: " << interp.getVal() << endl;
00246     proto->import(interp); // individual params have already been imported in first loop of this function
00247     
00248     // now create the product of the overall efficiency times the sigma(params) for this estimate
00249     proto->factory(("prod:"+productPrefix+"("+prefix+","+systTerm+")").c_str() );    
00250     //    proto->Print();
00251 
00252   }
00253 
00254   string HistoToWorkspaceFactoryFast::AddNormFactor(RooWorkspace * proto, string & channel, string & sigmaEpsilon, EstimateSummary & es, bool doRatio){
00255     string overallNorm_times_sigmaEpsilon ;
00256     string prodNames;
00257     vector<EstimateSummary::NormFactor> norm=es.normFactor;
00258     if(norm.size()){
00259       for(vector<EstimateSummary::NormFactor>::iterator itr=norm.begin(); itr!=norm.end(); ++itr){
00260         cout << "making normFactor: " << itr->name << endl;
00261         // remove "doRatio" and name can be changed when ws gets imported to the combined model.
00262         std::stringstream range;
00263         range<<"["<<itr->val<<","<<itr->low<<","<<itr->high<<"]";
00264         RooRealVar* var = 0;
00265 
00266         string varname;
00267         if(!prodNames.empty()) prodNames+=",";
00268         if(doRatio) {
00269           varname=itr->name+"_"+channel;
00270         }
00271         else {
00272           varname=itr->name;
00273         }
00274         var = (RooRealVar*) proto->factory((varname+range.str()).c_str());
00275         prodNames+=varname;
00276       }
00277       overallNorm_times_sigmaEpsilon = es.name+"_"+channel+"_overallNorm_x_sigma_epsilon";
00278       proto->factory(("prod::"+overallNorm_times_sigmaEpsilon+"("+prodNames+","+sigmaEpsilon+")").c_str());
00279     }
00280 
00281     if(!overallNorm_times_sigmaEpsilon.empty())
00282       return overallNorm_times_sigmaEpsilon;
00283     else
00284       return sigmaEpsilon;
00285   }        
00286 
00287 
00288   void HistoToWorkspaceFactoryFast::AddEfficiencyTerms(RooWorkspace* proto, string prefix, string interpName,
00289         map<string,pair<double,double> > systMap, 
00290         vector<string>& likelihoodTermNames, vector<string>& totSystTermNames){
00291     // add variables for all the relative overall uncertainties we expect
00292     
00293     // range is set using defined macro (see top of the page)
00294     string range=string("[0,")+alpha_Low+","+alpha_High+"]";
00295     //string range="[0,-1,1]";
00296     totSystTermNames.push_back(prefix);
00297     //bool first=true;
00298     RooArgSet params(prefix.c_str());
00299     vector<double> lowVec, highVec;
00300     for(map<string,pair<double,double> >::iterator it=systMap.begin(); it!=systMap.end(); ++it){
00301       // add efficiency term
00302       RooRealVar* temp = (RooRealVar*) proto->var((prefix+ it->first).c_str());
00303       if(!temp){
00304         temp = (RooRealVar*) proto->factory((prefix+ it->first +range).c_str());
00305 
00306         string command=("Gaussian::"+prefix+it->first+"Constraint("+prefix+it->first+",nom_"+prefix+it->first+"[0.,-10,10],1.)");
00307         cout << command << endl;
00308         likelihoodTermNames.push_back(  proto->factory( command.c_str() )->GetName() );
00309         proto->var(("nom_"+prefix+it->first).c_str())->setConstant();
00310         const_cast<RooArgSet*>(proto->set("globalObservables"))->add(*proto->var(("nom_"+prefix+it->first).c_str()));
00311         
00312       } 
00313       params.add(*temp);
00314 
00315       // add constraint in terms of bifrucated gauss with low/high as sigmas
00316       std::stringstream lowhigh;
00317       double low = it->second.first; 
00318       double high = it->second.second;
00319       lowVec.push_back(low);
00320       highVec.push_back(high);
00321       
00322     }
00323     if(systMap.size()>0){
00324       // this is epsilon(alpha_j), a piece-wise linear interpolation
00325       LinInterpVar interp( (interpName).c_str(), "", params, 1., lowVec, highVec);
00326       proto->import(interp); // params have already been imported in first loop of this function
00327     } else{
00328       // some strange behavior if params,lowVec,highVec are empty.  
00329       //cout << "WARNING: No OverallSyst terms" << endl;
00330       RooConstVar interp( (interpName).c_str(), "", 1.);
00331       proto->import(interp); // params have already been imported in first loop of this function
00332     }
00333     
00334   }
00335 
00336 
00337   void  HistoToWorkspaceFactoryFast::MakeTotalExpected(RooWorkspace* proto, string totName, string /**/, string /**/, 
00338                                                        int /*lowBin*/, int /*highBin */, vector<string>& syst_x_expectedPrefixNames, 
00339                                                        vector<string>& normByNames){
00340 
00341     // for ith bin calculate totN_i =  lumi * sum_j expected_j * syst_j 
00342     string command;
00343     string coeffList="";
00344     string shapeList="";
00345     string prepend="";
00346 
00347     /*
00348     double binWidth = proto->var(fObsName.c_str())->numBins()/(proto->var(fObsName.c_str())->getMax()- proto->var(fObsName.c_str())->getMin());
00349     command=string(Form("binWidth_%s[%f]",fObsName.c_str(),binWidth));
00350     cout << "bin width command \n" << command <<endl;
00351     proto->factory(command.c_str());
00352     proto->var(Form("binWidth_%s",fObsName.c_str()))->setConstant();
00353     string binWidthName = Form("binWidth_%s",fObsName.c_str());
00354     */
00355     vector<string>::iterator it=syst_x_expectedPrefixNames.begin();
00356     for(unsigned int j=0; j<syst_x_expectedPrefixNames.size();++j){
00357       std::stringstream str;
00358       str<<"_"<<j;
00359       // repatative, but we need one coeff for each term in the sum
00360       // maybe can be avoided if we don't use bin width as coefficient
00361       double binWidth = proto->var(fObsName.c_str())->numBins()/(proto->var(fObsName.c_str())->getMax()- proto->var(fObsName.c_str())->getMin());
00362       command=string(Form("binWidth_%s_%d[%f]",fObsName.c_str(),j,binWidth));     
00363       proto->factory(command.c_str());
00364       proto->var(Form("binWidth_%s_%d",fObsName.c_str(),j))->setConstant();
00365       coeffList+=prepend+"binWidth_"+fObsName+str.str();
00366       command="prod::L_x_"+syst_x_expectedPrefixNames.at(j)+"("+normByNames.at(j)+","+syst_x_expectedPrefixNames.at(j)+")";
00367       proto->factory(command.c_str());
00368       shapeList+=prepend+"L_x_"+syst_x_expectedPrefixNames.at(j);
00369       prepend=",";
00370     }    
00371     proto->defineSet("coefList",coeffList.c_str());
00372     proto->defineSet("shapeList",shapeList.c_str());
00373     //    command = "RooRealSumPdf::"+totName+"(shapeList,coefList,1)";
00374     //    proto->factory(command.c_str());
00375     RooRealSumPdf tot(totName.c_str(),totName.c_str(),*proto->set("shapeList"),*proto->set("coefList"),kTRUE);
00376     proto->import(tot);
00377     //    proto->Print();
00378     
00379   }
00380 
00381   void HistoToWorkspaceFactoryFast::AddPoissonTerms(RooWorkspace* proto, string prefix, string obsPrefix, string expPrefix, int lowBin, int highBin, 
00382            vector<string>& likelihoodTermNames){
00383     /////////////////////////////////
00384     // Relate observables to expected for each bin
00385     // later modify variable named expPrefix_i to be product of terms
00386     RooArgSet Pois(prefix.c_str());
00387     for(Int_t i=lowBin; i<highBin; ++i){
00388       std::stringstream str;
00389       str<<"_"<<i;
00390       //string command("Poisson::"+prefix+str.str()+"("+obsPrefix+str.str()+","+expPrefix+str.str()+")");
00391       string command("Poisson::"+prefix+str.str()+"("+obsPrefix+str.str()+","+expPrefix+str.str()+",1)");//for no rounding
00392       RooAbsArg* temp = (proto->factory( command.c_str() ) );
00393 
00394       // output
00395       cout << "Poisson Term " << command << endl;
00396       ((RooAbsPdf*) temp)->setEvalErrorLoggingMode(RooAbsReal::PrintErrors);
00397       //cout << temp << endl;
00398 
00399       likelihoodTermNames.push_back( temp->GetName() );
00400       Pois.add(* temp );
00401     }  
00402     proto->defineSet(prefix.c_str(),Pois); // add argset to workspace
00403   }
00404 
00405    void HistoToWorkspaceFactoryFast::SetObsToExpected(RooWorkspace* proto, string obsPrefix, string expPrefix, int lowBin, int highBin){ 
00406     /////////////////////////////////
00407     // set observed to expected
00408      TTree* tree = new TTree();
00409      Double_t* obsForTree = new Double_t[highBin-lowBin];
00410      RooArgList obsList("obsList");
00411 
00412      for(Int_t i=lowBin; i<highBin; ++i){
00413        std::stringstream str;
00414        str<<"_"<<i;
00415        RooRealVar* obs = (RooRealVar*) proto->var((obsPrefix+str.str()).c_str());
00416        cout << "expected number of events called: " << expPrefix << endl;
00417        RooAbsReal* exp = proto->function((expPrefix+str.str()).c_str());
00418        if(obs && exp){
00419          
00420          //proto->Print();
00421          obs->setVal(  exp->getVal() );
00422          cout << "setting obs"+str.str()+" to expected = " << exp->getVal() << " check: " << obs->getVal() << endl;
00423          
00424          // add entry to array and attach to tree
00425          obsForTree[i] = exp->getVal();
00426          tree->Branch((obsPrefix+str.str()).c_str(), obsForTree+i ,(obsPrefix+str.str()+"/D").c_str());
00427          obsList.add(*obs);
00428        }else{
00429          cout << "problem retrieving obs or exp " << obsPrefix+str.str() << obs << " " << expPrefix+str.str() << exp << endl;
00430        }
00431      }  
00432      tree->Fill();
00433      RooDataSet* data = new RooDataSet("expData","", tree, obsList); // one experiment
00434 
00435      proto->import(*data);
00436 
00437   }
00438 
00439   void HistoToWorkspaceFactoryFast::Customize(RooWorkspace* proto, const char* pdfNameChar, map<string,string> renameMap) {
00440     cout << "in customizations" << endl;
00441     string pdfName(pdfNameChar);
00442     map<string,string>::iterator it;
00443     string edit="EDIT::customized("+pdfName+",";
00444     string preceed="";
00445     for(it=renameMap.begin(); it!=renameMap.end(); ++it) {
00446       cout << it->first + "=" + it->second << endl;
00447       edit+=preceed + it->first + "=" + it->second;
00448       preceed=",";
00449     }
00450     edit+=")";
00451     cout << edit<< endl;
00452     proto->factory( edit.c_str() );
00453   }
00454 
00455   //_____________________________________________________________
00456   void HistoToWorkspaceFactoryFast::EditSyst(RooWorkspace* proto, const char* pdfNameChar, map<string,double> gammaSyst, map<string,double> uniformSyst,map<string,double> logNormSyst) {
00457     //    cout << "in edit, gammamap.size = " << gammaSyst.size() << ", unimap.size = " << uniformSyst.size() << endl;
00458     string pdfName(pdfNameChar);
00459 
00460     ModelConfig * combined_config = (ModelConfig *) proto->obj("ModelConfig");
00461     //    const RooArgSet * constrainedParams=combined_config->GetNuisanceParameters();
00462     //    RooArgSet temp(*constrainedParams);
00463     string edit="EDIT::newSimPdf("+pdfName+",";
00464     string editList;
00465     string lastPdf=pdfName;
00466     string preceed="";
00467     unsigned int numReplacements = 0;
00468     unsigned int nskipped = 0;
00469     map<string,double>::iterator it;
00470 
00471     // add gamma terms and their constraints
00472     for(it=gammaSyst.begin(); it!=gammaSyst.end(); ++it) {
00473       //cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
00474       if(! proto->var(("alpha_"+it->first).c_str())){
00475         //cout << "systematic not there" << endl;
00476         nskipped++; 
00477         continue;
00478       }
00479       numReplacements++;      
00480 
00481       double relativeUncertainty = it->second;
00482       double scale = 1/sqrt((1+1/pow(relativeUncertainty,2)));
00483       
00484       // this is the Gamma PDF and in a form that doesn't have roundoff problems like the Poisson does
00485       proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
00486       proto->factory(Form("y_%s[%f]",it->first.c_str(),1./pow(relativeUncertainty,2))) ;
00487       proto->factory(Form("theta_%s[%f]",it->first.c_str(),pow(relativeUncertainty,2))) ;
00488       proto->factory(Form("Gamma::beta_%sConstraint(beta_%s,sum::k_%s(y_%s,one[1]),theta_%s,zero[0])",
00489                           it->first.c_str(),
00490                           it->first.c_str(),
00491                           it->first.c_str(),
00492                           it->first.c_str(),
00493                           it->first.c_str())) ;
00494 
00495       /*
00496       // this has some problems because N in poisson is rounded to nearest integer     
00497       proto->factory(Form("Poisson::beta_%sConstraint(y_%s[%f],prod::taub_%s(taus_%s[%f],beta_%s[1,0,5]))",
00498                           it->first.c_str(),
00499                           it->first.c_str(),
00500                           1./pow(relativeUncertainty,2),
00501                           it->first.c_str(),
00502                             it->first.c_str(),
00503                           1./pow(relativeUncertainty,2),
00504                           it->first.c_str()
00505                           ) ) ;
00506       */
00507       //        combined->factory(Form("expr::alphaOfBeta('(beta-1)/%f',beta)",scale));
00508       //        combined->factory(Form("expr::alphaOfBeta_%s('(beta_%s-1)/%f',beta_%s)",it->first.c_str(),it->first.c_str(),scale,it->first.c_str()));
00509       proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1./scale,1./scale));
00510         
00511       // set beta const status to be same as alpha
00512       if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant())
00513         proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
00514       else
00515         proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
00516       // set alpha const status to true
00517       //      proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
00518 
00519       // replace alphas with alphaOfBeta and replace constraints
00520       //cout <<         "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
00521       editList+=preceed + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
00522       preceed=",";
00523       //      cout <<         "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
00524       editList+=preceed + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
00525 
00526       /*
00527       if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
00528       cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
00529       else
00530         cout << "NOT THERE" << endl;
00531       */
00532 
00533       // EDIT seems to die if the list of edits is too long.  So chunck them up.
00534       if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
00535         edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
00536         lastPdf+="_"; // append an underscore for the edit
00537         editList=""; // reset edit list
00538         preceed="";
00539         cout << "Going to issue this edit command\n" << edit<< endl;
00540         proto->factory( edit.c_str() );
00541         RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
00542         if(!newOne)
00543           cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
00544         
00545       }
00546     }
00547 
00548     // add uniform terms and their constraints
00549     for(it=uniformSyst.begin(); it!=uniformSyst.end(); ++it) {
00550       cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
00551       if(! proto->var(("alpha_"+it->first).c_str())){
00552         cout << "systematic not there" << endl;
00553         nskipped++; 
00554         continue;
00555       }
00556       numReplacements++;      
00557 
00558       // this is the Uniform PDF
00559       proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
00560       proto->factory(Form("Uniform::beta_%sConstraint(beta_%s)",it->first.c_str(),it->first.c_str()));
00561       proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{-1,1})",it->first.c_str(),it->first.c_str()));
00562       
00563       // set beta const status to be same as alpha
00564       if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant())
00565         proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
00566       else
00567         proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
00568       // set alpha const status to true
00569       //      proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
00570 
00571       // replace alphas with alphaOfBeta and replace constraints
00572       cout <<         "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
00573       editList+=preceed + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
00574       preceed=",";
00575       cout <<         "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
00576       editList+=preceed + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
00577 
00578       if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
00579         cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
00580       else
00581         cout << "NOT THERE" << endl;
00582 
00583       // EDIT seems to die if the list of edits is too long.  So chunck them up.
00584       if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
00585         edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
00586         lastPdf+="_"; // append an underscore for the edit
00587         editList=""; // reset edit list
00588         preceed="";
00589         cout << edit<< endl;
00590         proto->factory( edit.c_str() );
00591         RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
00592         if(!newOne)
00593           cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
00594         
00595       }
00596     }
00597 
00598     /////////////////////////////////////////
00599     ////////////////////////////////////
00600 
00601 
00602     // add lognormal terms and their constraints
00603     for(it=logNormSyst.begin(); it!=logNormSyst.end(); ++it) {
00604       cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
00605       if(! proto->var(("alpha_"+it->first).c_str())){
00606         cout << "systematic not there" << endl;
00607         nskipped++; 
00608         continue;
00609       }
00610       numReplacements++;      
00611 
00612       double relativeUncertainty = it->second;
00613       double kappa = 1+relativeUncertainty;
00614       // when transforming beta -> alpha, need alpha=1 to be +1sigma value.
00615       // the P(beta>kappa*\hat(beta)) = 16%
00616       // and \hat(beta) is 1, thus
00617       double scale = relativeUncertainty;
00618       //double scale = kappa; 
00619 
00620       // this is the LogNormal
00621       proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
00622       proto->factory(Form("kappa_%s[%f]",it->first.c_str(),kappa));
00623       proto->factory(Form("Lognormal::beta_%sConstraint(beta_%s,one[1],kappa_%s)",
00624                           it->first.c_str(),
00625                           it->first.c_str(),
00626                           it->first.c_str())) ;
00627       proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1./scale,1./scale));
00628       //      proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1.,1./scale));
00629       
00630       // set beta const status to be same as alpha
00631       if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant())
00632         proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
00633       else
00634         proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
00635       // set alpha const status to true
00636       //      proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
00637 
00638       // replace alphas with alphaOfBeta and replace constraints
00639       cout <<         "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
00640       editList+=preceed + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
00641       preceed=",";
00642       cout <<         "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
00643       editList+=preceed + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
00644 
00645       if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
00646         cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
00647       else
00648         cout << "NOT THERE" << endl;
00649 
00650       // EDIT seems to die if the list of edits is too long.  So chunck them up.
00651       if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
00652         edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
00653         lastPdf+="_"; // append an underscore for the edit
00654         editList=""; // reset edit list
00655         preceed="";
00656         cout << edit<< endl;
00657         proto->factory( edit.c_str() );
00658         RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
00659         if(!newOne)
00660           cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
00661         
00662       }
00663     }
00664 
00665     /////////////////////////////////////////
00666     ////////////////////////////////////
00667 
00668     // commit last bunch of edits
00669     edit="EDIT::newSimPdf("+lastPdf+","+editList+")";
00670     cout << edit<< endl;
00671     proto->factory( edit.c_str() );
00672     //    proto->writeToFile(("results/model_"+fRowTitle+"_edited.root").c_str());
00673     RooAbsPdf* newOne = proto->pdf("newSimPdf");
00674     if(newOne){
00675       // newOne->graphVizTree(("results/"+pdfName+"_"+fRowTitle+"newSimPdf.dot").c_str());
00676       combined_config->SetPdf(*newOne);
00677     }
00678     else{
00679       cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
00680     }
00681   }
00682 
00683   void HistoToWorkspaceFactoryFast::PrintCovarianceMatrix(RooFitResult* result, RooArgSet* params, string filename){
00684     //    FILE * pFile;
00685     pFile = fopen ((filename).c_str(),"w"); 
00686 
00687 
00688     TIter iti = params->createIterator();
00689     TIter itj = params->createIterator();
00690     RooRealVar *myargi, *myargj; 
00691     fprintf(pFile," ") ;
00692     while ((myargi = (RooRealVar *)iti.Next())) { 
00693       if(myargi->isConstant()) continue;
00694       fprintf(pFile," & %s",  myargi->GetName());
00695     }
00696     fprintf(pFile,"\\\\ \\hline \n" );
00697     iti.Reset();
00698     while ((myargi = (RooRealVar *)iti.Next())) { 
00699       if(myargi->isConstant()) continue;
00700       fprintf(pFile,"%s", myargi->GetName());
00701       itj.Reset();
00702       while ((myargj = (RooRealVar *)itj.Next())) { 
00703         if(myargj->isConstant()) continue;
00704         cout << myargi->GetName() << "," << myargj->GetName();
00705         fprintf(pFile, " & %.2f", result->correlation(*myargi, *myargj));
00706       }
00707       cout << endl;
00708       fprintf(pFile, " \\\\\n");
00709     }
00710     fclose(pFile);
00711     
00712   }
00713 
00714 
00715   ///////////////////////////////////////////////
00716   RooWorkspace* HistoToWorkspaceFactoryFast::MakeSingleChannelModel(vector<EstimateSummary> summary, vector<string> systToFix, bool doRatio)
00717   {
00718     
00719     // to time the macro
00720     TStopwatch t;
00721     t.Start();
00722     string channel=summary[0].channel;
00723     //    fObsName.c_str()=Form("%s_%s",summary.at(0).nominal->GetXaxis()->GetName()],summary[0].channel.c_str()); // set name ov observable
00724     fObsName= "obs_"+summary[0].channel; // set name ov observable
00725     cout << "\n\n-------------------\nStarting to process " << channel << " channel with obs " << fObsName << endl;
00726 
00727     //
00728     // our main workspace that we are using to construct the model
00729     //
00730     RooWorkspace* proto = new RooWorkspace(summary[0].channel.c_str(),(summary[0].channel+" workspace").c_str());
00731     ModelConfig * proto_config = new ModelConfig("ModelConfig", proto);
00732     proto_config->SetWorkspace(*proto);
00733 
00734     RooArgSet likelihoodTerms("likelihoodTerms");
00735     vector<string> likelihoodTermNames, totSystTermNames,syst_x_expectedPrefixNames, normalizationNames;
00736 
00737     string prefix, range;
00738 
00739 
00740     /////////////////////////////
00741     // shared parameters
00742     // this is ratio of lumi to nominal lumi.  We will include relative uncertainty in model
00743     std::stringstream lumiStr;
00744     // lumi range
00745     lumiStr<<"["<<fNomLumi<<",0,"<<10.*fNomLumi<<"]";
00746     proto->factory(("Lumi"+lumiStr.str()).c_str());
00747     cout << "lumi str = " << lumiStr.str() << endl;
00748     
00749     std::stringstream lumiErrorStr;
00750     lumiErrorStr << "nominalLumi["<<fNomLumi << ",0,"<<fNomLumi+10*fLumiError<<"]," << fLumiError ;
00751     proto->factory(("Gaussian::lumiConstraint(Lumi,"+lumiErrorStr.str()+")").c_str());
00752     proto->var("nominalLumi")->setConstant();
00753     proto->defineSet("globalObservables","nominalLumi");
00754     likelihoodTermNames.push_back("lumiConstraint");
00755     cout << "lumi Error str = " << lumiErrorStr.str() << endl;
00756     
00757     //proto->factory((string("SigXsecOverSM[1.,0.5,1..8]").c_str()));
00758     ///////////////////////////////////
00759     // loop through estimates, add expectation, floating bin predictions, 
00760     // and terms that constrain floating to expectation via uncertainties
00761     vector<EstimateSummary>::iterator it = summary.begin();
00762     for(; it!=summary.end(); ++it){
00763       if(it->name=="Data") continue;
00764 
00765       string overallSystName = it->name+"_"+it->channel+"_epsilon"; 
00766       string systSourcePrefix = "alpha_";
00767       AddEfficiencyTerms(proto,systSourcePrefix, overallSystName,
00768              it->overallSyst, 
00769              likelihoodTermNames, totSystTermNames);    
00770 
00771       overallSystName=AddNormFactor(proto, channel, overallSystName, *it, doRatio); 
00772 
00773       // get histogram
00774       TH1F* nominal = it->nominal;
00775       if(it->lowHists.size() == 0){
00776         cout << it->name+"_"+it->channel+" has no variation histograms " <<endl;
00777         string expPrefix=it->name+"_"+it->channel;//+"_expN";
00778         string syst_x_expectedPrefix=it->name+"_"+it->channel+"_overallSyst_x_Exp";
00779         ProcessExpectedHisto(nominal,proto,expPrefix,syst_x_expectedPrefix,overallSystName,atoi(NoHistConst_Low),atoi(NoHistConst_High),fLowBin,fHighBin);
00780         syst_x_expectedPrefixNames.push_back(syst_x_expectedPrefix);
00781       } else if(it->lowHists.size() != it->highHists.size()){
00782         cout << "problem in "+it->name+"_"+it->channel 
00783        << " number of low & high variation histograms don't match" << endl;
00784         return 0;
00785       } else {
00786         string constraintPrefix = it->name+"_"+it->channel+"_Hist_alpha"; // name of source for variation
00787         string syst_x_expectedPrefix = it->name+"_"+it->channel+"_overallSyst_x_HistSyst";
00788         LinInterpWithConstraint(proto, nominal, it->lowHists, it->highHists, it->systSourceForHist,
00789               constraintPrefix, syst_x_expectedPrefix, overallSystName, 
00790               fLowBin, fHighBin, likelihoodTermNames);
00791         syst_x_expectedPrefixNames.push_back(syst_x_expectedPrefix);
00792       }
00793 
00794       //    AddMultiVarGaussConstraint(proto, "exp"+it->first+"N", fLowBin, fHighBin, likelihoodTermNames);
00795 
00796       if(it->normName=="")
00797         normalizationNames.push_back( "Lumi" );
00798       else
00799         normalizationNames.push_back( it->normName);
00800     }
00801     //    proto->Print();
00802 
00803     ///////////////////////////////////
00804     // for ith bin calculate totN_i =  lumi * sum_j expected_j * syst_j 
00805     MakeTotalExpected(proto,channel+"_model",channel,"Lumi",fLowBin,fHighBin, 
00806           syst_x_expectedPrefixNames, normalizationNames);
00807 
00808     likelihoodTermNames.push_back(channel+"_model");
00809 
00810     /////////////////////////////////
00811     // Relate observables to expected for each bin
00812     //    AddPoissonTerms(proto, "Pois_"+channel, "obsN", channel+"_totN", fLowBin, fHighBin, likelihoodTermNames);
00813 
00814     /*
00815     /////////////////////////////////
00816     // if no data histogram provided, make asimov data
00817     if(summary.at(0).name!="Data"){
00818       SetObsToExpected(proto, "obsN",channel+"_totN", fLowBin, fHighBin);
00819       cout << " using asimov data" << endl;
00820     }  else{
00821       SetObsToExpected(proto, "obsN","obsN", fLowBin, fHighBin);
00822       cout << " using input data histogram" << endl;
00823     }
00824     */
00825 
00826     //////////////////////////////////////
00827     // fix specified parameters
00828     for(unsigned int i=0; i<systToFix.size(); ++i){
00829       RooRealVar* temp = proto->var((systToFix.at(i)).c_str());
00830       if(temp) temp->setConstant();
00831       else cout << "could not find variable " << systToFix.at(i) << " could not set it to constant" << endl;
00832     }
00833 
00834     //////////////////////////////////////
00835     // final proto model
00836     for(unsigned int i=0; i<likelihoodTermNames.size(); ++i){
00837       //    cout << likelihoodTermNames[i] << endl;
00838       likelihoodTerms.add(* (proto->arg(likelihoodTermNames[i].c_str())) );
00839     }
00840     //  likelihoodTerms.Print();
00841 
00842     proto->defineSet("likelihoodTerms",likelihoodTerms);
00843     //  proto->Print();
00844 
00845     cout <<"-----------------------------------------"<<endl;
00846     cout <<"import model into workspace" << endl;
00847     RooProdPdf* model = new RooProdPdf(("model_"+channel).c_str(),
00848                "product of Poissons accross bins for a single channel",
00849                likelihoodTerms);
00850     proto->import(*model,RecycleConflictNodes());
00851 
00852     proto_config->SetPdf(*model);
00853     proto_config->SetObservables(*proto->var(fObsName.c_str()));
00854     proto_config->SetGlobalObservables(*proto->set("globalObservables"));
00855     //    proto->writeToFile(("results/model_"+channel+".root").c_str());
00856     // fill out nuisance parameters in model config
00857     //    proto_config->GuessObsAndNuisance(*proto->data("asimovData"));
00858     proto->import(*proto_config,proto_config->GetName());
00859     proto->importClassCode();
00860 
00861     ///////////////////////////
00862     // make data sets
00863       // THis works and is natural, but the memory size of the simultaneous dataset grows exponentially with channels
00864     //    RooAbsData* data = model->generateBinned(*proto->var(fObsName.c_str()),ExpectedData());
00865     //    const char* weightName = Form("%s_w",fObsName.c_str());
00866     const char* weightName="weightVar";
00867     proto->factory(Form("%s[0,-1e10,1e10]",weightName));
00868     proto->defineSet("obsAndWeight",Form("%s,%s",weightName,fObsName.c_str()));
00869     RooAbsData* data = model->generateBinned(*proto->var(fObsName.c_str()),ExpectedData());
00870     RooDataSet* asimovDataUnbinned = new RooDataSet("asimovData","",*proto->set("obsAndWeight"),weightName);
00871     for(int i=0; i<data->numEntries(); ++i){
00872       data->get(i)->Print("v");
00873       cout <<  data->weight() <<endl;
00874       asimovDataUnbinned->add(*data->get(i), data->weight() );
00875     }    
00876     //    proto->import(*data,Rename("asimovData"));
00877     proto->import(*asimovDataUnbinned);
00878 
00879     if (summary.at(0).name=="Data") {
00880       // THis works and is natural, but the memory size of the simultaneous dataset grows exponentially with channels
00881       //      RooDataHist* obsData = new RooDataHist("obsData","",*proto->var(fObsName.c_str()),summary.at(0).nominal);
00882       //      proto->import(*obsData);
00883 
00884       RooDataSet* obsDataUnbinned = new RooDataSet("obsData","",*proto->set("obsAndWeight"),weightName);
00885       for(int i=1; i<=summary.at(0).nominal->GetNbinsX(); ++i){
00886         proto->var(fObsName.c_str())->setVal( summary.at(0).nominal->GetBinCenter(i) );
00887         //      proto->var(weightName)->setVal( summary.at(0).nominal->GetBinContent(i) );
00888         //      proto->set("obsAndWeight")->Print("v");
00889         obsDataUnbinned->add(*  proto->set("obsAndWeight"), summary.at(0).nominal->GetBinContent(i));
00890       }    
00891       proto->import(*obsDataUnbinned);
00892     }
00893 
00894 
00895     /////////////////////////////
00896     // Make observables, set values to observed data if data is specified,
00897     // otherwise use expected "Asimov" data
00898     /*
00899     if (summary.at(0).name=="Data") {
00900       ProcessExpectedHisto(summary.at(0).nominal,proto,"obsN","","",0,100000,fLowBin,fHighBin);
00901     } else {
00902       cout << "Will use expected (\"Asimov\") data set" << endl;
00903       ProcessExpectedHisto(NULL,proto,"obsN","","",0,100000,fLowBin,fHighBin);
00904     }
00905     */
00906 
00907 
00908     proto->Print();
00909     return proto;
00910   }
00911 
00912   RooWorkspace* HistoToWorkspaceFactoryFast::MakeCombinedModel(vector<string> ch_names, vector<RooWorkspace*> chs)
00913   {
00914 
00915     //
00916     /// These things were used for debugging. Maybe useful in the future
00917     //
00918 
00919     map<string, RooAbsPdf*> pdfMap;
00920     vector<RooAbsPdf*> models;
00921     stringstream ss;
00922 
00923     RooArgList obsList;
00924     for(unsigned int i = 0; i< ch_names.size(); ++i){
00925       ModelConfig * config = (ModelConfig *) chs[i]->obj("ModelConfig");
00926       obsList.add(*config->GetObservables());
00927     }
00928     cout <<"full list of observables:"<<endl;
00929     obsList.Print();
00930 
00931     RooArgSet globalObs;
00932     for(unsigned int i = 0; i< ch_names.size(); ++i){
00933       string channel_name=ch_names[i];
00934 
00935       if (ss.str().empty()) ss << channel_name ;
00936       else ss << ',' << channel_name ;
00937       RooWorkspace * ch=chs[i];
00938       
00939       RooAbsPdf* model = ch->pdf(("model_"+channel_name).c_str());
00940       if(!model) cout <<"failed to find model for channel"<<endl;
00941       //      cout << "int = " << model->createIntegral(*obsN)->getVal() << endl;;
00942       models.push_back(model);
00943       globalObs.add(*ch->set("globalObservables"));
00944 
00945       //      constrainedParams->add( * ch->set("constrainedParams") );
00946       pdfMap[channel_name]=model;
00947     }
00948     //constrainedParams->Print();
00949 
00950     cout << "\n\n------------------\n Entering combination" << endl;
00951     RooWorkspace* combined = new RooWorkspace("combined");
00952     //    RooWorkspace* combined = chs[0];
00953     
00954 
00955     RooCategory* channelCat = (RooCategory*) combined->factory(("channelCat["+ss.str()+"]").c_str());
00956     RooSimultaneous * simPdf= new RooSimultaneous("simPdf","",pdfMap, *channelCat);
00957     ModelConfig * combined_config = new ModelConfig("ModelConfig", combined);
00958     combined_config->SetWorkspace(*combined);
00959     //    combined_config->SetNuisanceParameters(*constrainedParams);
00960 
00961     combined->import(globalObs);
00962     combined->defineSet("globalObservables",globalObs);
00963     combined_config->SetGlobalObservables(*combined->set("globalObservables"));
00964     
00965 
00966     ////////////////////////////////////////////
00967     // Make toy simultaneous dataset
00968     cout <<"-----------------------------------------"<<endl;
00969     cout << "create toy data for " << ss.str() << endl;
00970     
00971 
00972     // see tutorials/roofit/rf401_importttreethx.C
00973     /*
00974     RooDataHist * simData=new RooDataHist("simData","master dataset", *obsN, 
00975             Index(*channelCat), Import(ch_names[0].c_str(),*((RooDataHist*)chs[0]->data("asimovData"))));
00976     for(unsigned int i = 1; i< ch_names.size(); ++i){
00977       RooDataHist * simData_ch=new RooDataHist("simData","master dataset", *obsN, 
00978               Index(*channelCat), Import(ch_names[i].c_str(),*((RooDataHist*)chs[i]->data("asimovData"))));
00979       //      simData->append(*simData_ch);
00980       simData->add(*simData_ch);
00981     }
00982     */
00983 
00984 
00985     
00986     /*
00987       map<string,RooDataSet*> dsmap;
00988       // previously using datahists (but this had problems.
00989       // For example, when there were 4 channels with 70 bins, the dataset wanted 70^4 bins
00990     map<string,RooDataHist*> dsmap;
00991     for(unsigned int i = 0; i< ch_names.size(); ++i){
00992       dsmap[ch_names[i]] = (RooDataHist*)chs[i]->data("asimovData");
00993     }
00994     RooDataHist * simData=new RooDataHist("asimovData","", obsList, *channelCat, dsmap);
00995 
00996     if(chs[0]->data("obsData")){
00997       for(unsigned int i = 0; i< ch_names.size(); ++i){
00998         dsmap[ch_names[i]] = (RooDataHist*)chs[i]->data("obsData");
00999       }
01000       RooDataHist * obsData=new RooDataHist("obsData","", obsList, *channelCat, dsmap);
01001 
01002       //      for(int i=0; i<obsData->numEntries(); ++i)
01003       //        obsData->get(i)->Print("v");
01004       
01005       combined->import(*obsData);
01006     }
01007     */
01008 
01009     /*
01010     // same as above.  Why no map option for RooDataSet?
01011     if(chs[0]->data("obsData")){
01012       for(unsigned int i = 0; i< ch_names.size(); ++i){
01013         dsmap[ch_names[i]] = (RooDataSet*)chs[i]->data("obsData");
01014       }
01015       RooDataSet * obsData=new RooDataSet("obsData","", obsList, *channelCat, dsmap);
01016 
01017       //      for(int i=0; i<obsData->numEntries(); ++i)
01018       //        obsData->get(i)->Print("v");
01019       
01020       combined->import(*obsData);
01021     }
01022     */
01023 
01024     // now with weighted datasets
01025     // First Asimov
01026     RooDataSet * simData=NULL;
01027     combined->factory("weightVar[0,-1e10,1e10]");
01028     obsList.add(*combined->var("weightVar"));
01029     for(unsigned int i = 0; i< ch_names.size(); ++i){
01030       cout << "merging data for channel " << ch_names[i].c_str() << endl;
01031       RooDataSet * tempData=new RooDataSet(ch_names[i].c_str(),"", obsList, Index(*channelCat),
01032                                            WeightVar("weightVar"),
01033                                           Import(ch_names[i].c_str(),*(RooDataSet*)chs[i]->data("asimovData")));
01034       if(simData){
01035         simData->append(*tempData);
01036       delete tempData;
01037       }else{
01038         simData = tempData;
01039       }
01040     }
01041     
01042     combined->import(*simData,Rename("asimovData"));
01043 
01044     // now obs
01045     if(chs[0]->data("obsData")){
01046       simData=NULL;
01047       for(unsigned int i = 0; i< ch_names.size(); ++i){
01048         cout << "merging data for channel " << ch_names[i].c_str() << endl;
01049         RooDataSet * tempData=new RooDataSet(ch_names[i].c_str(),"", obsList, Index(*channelCat),
01050                                              WeightVar("weightVar"),
01051                                              Import(ch_names[i].c_str(),*(RooDataSet*)chs[i]->data("obsData")));
01052         if(simData){
01053           simData->append(*tempData);
01054           delete tempData;
01055         }else{
01056           simData = tempData;
01057         }
01058       }
01059       
01060       combined->import(*simData,Rename("obsData"));
01061     }
01062     
01063 
01064 
01065     //    obsList.Print();
01066     //    combined->import(obsList);
01067     //    combined->Print();
01068     obsList.add(*channelCat);
01069     combined->defineSet("observables",obsList);
01070     combined_config->SetObservables(*combined->set("observables"));
01071 
01072 
01073     combined->Print();
01074 
01075     cout << "\n\n----------------\n Importing combined model" << endl;
01076     combined->import(*simPdf,RecycleConflictNodes());
01077     //combined->import(*simPdf, RenameVariable("SigXsecOverSM","SigXsecOverSM_comb"));
01078     cout << "check pointer " << simPdf << endl;
01079     //    cout << "check val " << simPdf->getVal() << endl;
01080 
01081     for(unsigned int i=0; i<fSystToFix.size(); ++i){
01082       // make sure they are fixed
01083       RooRealVar* temp = combined->var((fSystToFix.at(i)).c_str());
01084       if(temp) {
01085         temp->setConstant();
01086         cout <<"setting " << fSystToFix.at(i) << " constant" << endl;
01087       } else 
01088         cout << "could not find variable " << fSystToFix.at(i) << " could not set it to constant" << endl;
01089     }
01090 
01091     ///
01092     /// writing out the model in graphViz
01093     /// 
01094     //    RooAbsPdf* customized=combined->pdf("simPdf"); 
01095     //combined_config->SetPdf(*customized);
01096     combined_config->SetPdf(*simPdf);
01097     //    combined_config->GuessObsAndNuisance(*simData);
01098     //    customized->graphVizTree(("results/"+fResultsPrefixStr.str()+"_simul.dot").c_str());
01099     combined->import(*combined_config,combined_config->GetName());
01100     combined->importClassCode();
01101     //    combined->writeToFile("results/model_combined.root");
01102 
01103     return combined;
01104   }
01105 
01106   ///////////////////////////////////////////////
01107    void HistoToWorkspaceFactoryFast::FitModel(RooWorkspace * combined, string channel, string /*model_name*/, string data_name, bool /*doParamInspect*/)
01108   {
01109     cout << "In Fit Model"<<endl;
01110     ModelConfig * combined_config = (ModelConfig *) combined->obj("ModelConfig");
01111     if(!combined_config){
01112       cout << "no model config " << "ModelConfig" << " exiting" << endl;
01113       return;
01114     }
01115     //    RooDataSet * simData = (RooDataSet *) combined->obj(data_name.c_str());
01116     RooAbsData* simData = combined->data(data_name.c_str());
01117     if(!simData){
01118       cout << "no data " << data_name << " exiting" << endl;
01119       return;
01120     }
01121     //    const RooArgSet * constrainedParams=combined_config->GetNuisanceParameters();
01122     const RooArgSet * POIs=combined_config->GetParametersOfInterest();
01123     if(!POIs){
01124       cout << "no poi " << data_name << " exiting" << endl;
01125       return;
01126     }
01127 
01128     /*
01129           RooRealVar* poi = (RooRealVar*) combined->var("SigXsecOverSM");
01130           RooArgSet * params= new RooArgSet;
01131           params->add(*poi);
01132           combined_config->SetParameters(*params);
01133 
01134           RooAbsData* expData = combined->data("expData");
01135           RooArgSet* temp =  (RooArgSet*) combined->set("obsN")->Clone("temp");
01136           temp->add(*poi);
01137           RooAbsPdf* model=combined_config->GetPdf();
01138           RooArgSet* constrainedParams = model->getParameters(temp);
01139           combined->defineSet("constrainedParams", *constrainedParams);
01140     */
01141 
01142     //RooAbsPdf* model=combined->pdf(model_name.c_str()); 
01143     RooAbsPdf* model=combined_config->GetPdf();
01144     //    RooArgSet* allParams = model->getParameters(*simData);
01145 
01146     ///////////////////////////////////////
01147     //Do combined fit
01148     //RooMsgService::instance().setGlobalKillBelow(RooMsgService::INFO) ;
01149     cout << "\n\n---------------" << endl;
01150     cout << "---------------- Doing "<< channel << " Fit" << endl;
01151     cout << "---------------\n\n" << endl;
01152     //    RooFitResult* result = model->fitTo(*simData, Minos(kTRUE), Save(kTRUE), PrintLevel(1));
01153     model->fitTo(*simData, Minos(kTRUE), PrintLevel(1));
01154     //    PrintCovarianceMatrix(result, allParams, "results/"+FilePrefixStr(channel)+"_corrMatrix.table" );
01155 
01156     //
01157     // assuming there is only on poi
01158     // 
01159     RooRealVar* poi = 0; // (RooRealVar*) POIs->first();
01160     // for results tables
01161     TIterator* params_itr=POIs->createIterator();
01162     TObject* params_obj=0;
01163     while((params_obj=params_itr->Next())){
01164       poi = (RooRealVar*) params_obj;
01165       cout << "printing results for " << poi->GetName() << " at " << poi->getVal()<< " high " << poi->getErrorLo() << " low " << poi->getErrorHi()<<endl;
01166     }
01167     fprintf(pFile, " %.4f / %.4f  ", poi->getErrorLo(), poi->getErrorHi());
01168 
01169     RooAbsReal* nll = model->createNLL(*simData);
01170     RooAbsReal* profile = nll->createProfile(*poi);
01171     RooPlot* frame = poi->frame();
01172     FormatFrameForLikelihood(frame);
01173     TCanvas* c1 = new TCanvas( channel.c_str(), "",800,600);
01174     nll->plotOn(frame, ShiftToZero(), LineColor(kRed), LineStyle(kDashed));
01175     profile->plotOn(frame);
01176     frame->SetMinimum(0);
01177     frame->SetMaximum(2.);
01178     frame->Draw();
01179     //    c1->SaveAs( ("results/"+FilePrefixStr(channel)+"_profileLR.eps").c_str() );
01180     c1->SaveAs( (fFileNamePrefix+"_"+channel+"_"+fRowTitle+"_profileLR.eps").c_str() );
01181 
01182     fOut_f->mkdir(channel.c_str())->mkdir("Summary")->cd();
01183 
01184     // an example of calculating profile for a nuisance parameter not poi
01185     /*
01186     RooRealVar* alpha_isrfsr = (RooRealVar*) combined->var("alpha_isrfsr");
01187     RooAbsReal* profile_isrfsr = nll->createProfile(*alpha_isrfsr);
01188     poi->setVal(0.55);
01189     poi->setConstant();
01190 
01191     RooPlot* frame_isrfsr = alpha_isrfsr->frame();
01192     profile_isrfsr->plotOn(frame_isrfsr, Precision(0.1));
01193     TCanvas c_isrfsr = new TCanvas( "combined", "",800,600);
01194     FormatFrameForLikelihood(frame_isrfsr, "alpha_{isrfsr}");
01195     frame_isrfsr->Draw();
01196     fOut_f->cd("Summary");
01197     c1->Write((FilePrefixStr(channel).str()+"_profileLR_alpha_isrfsr").c_str() );
01198     delete frame; delete c1;
01199     poi->setConstant(kFALSE);
01200     */
01201 
01202     RooCurve* curve=frame->getCurve();
01203     Int_t curve_N=curve->GetN();
01204     Double_t* curve_x=curve->GetX();
01205     delete frame; delete c1;
01206 
01207     //
01208     // Verbose output from MINUIT
01209     //
01210     /*
01211     RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
01212     profile->getVal();
01213     RooMinuit* minuit = ((RooProfileLL*) profile)->minuit();
01214     minuit->setPrintLevel(5) ; // Print MINUIT messages
01215     minuit->setVerbose(5) ; // Print RooMinuit messages with parameter 
01216                                 // changes (corresponds to the Verbose() option of fitTo()
01217     */
01218   
01219     Double_t * x_arr = new Double_t[curve_N];
01220     Double_t * y_arr_nll = new Double_t[curve_N];
01221 //     Double_t y_arr_prof_nll[curve_N];
01222 //     Double_t y_arr_prof[curve_N];
01223 
01224     for(int i=0; i<curve_N; i++){
01225       double f=curve_x[i];
01226       poi->setVal(f);
01227       x_arr[i]=f;
01228       y_arr_nll[i]=nll->getVal();
01229     }
01230     TGraph * g = new TGraph(curve_N, x_arr, y_arr_nll);
01231     g->SetName((FilePrefixStr(channel)+"_nll").c_str());
01232     g->Write(); 
01233     delete g;
01234     delete [] x_arr;
01235     delete [] y_arr_nll;
01236 
01237     /** find out what's inside the workspace **/
01238     //combined->Print();
01239 
01240   }
01241 
01242 
01243 void HistoToWorkspaceFactoryFast::FormatFrameForLikelihood(RooPlot* frame, string /*XTitle*/, string YTitle){
01244 
01245       gStyle->SetCanvasBorderMode(0);
01246       gStyle->SetPadBorderMode(0);
01247       gStyle->SetPadColor(0);
01248       gStyle->SetCanvasColor(255);
01249       gStyle->SetTitleFillColor(255);
01250       gStyle->SetFrameFillColor(0);  
01251       gStyle->SetStatColor(255);
01252       
01253       RooAbsRealLValue* var = frame->getPlotVar();
01254       double xmin = var->getMin();
01255       double xmax = var->getMax();
01256       
01257       frame->SetTitle("");
01258       //      frame->GetXaxis()->SetTitle(XTitle.c_str());
01259       frame->GetXaxis()->SetTitle(var->GetTitle());
01260       frame->GetYaxis()->SetTitle(YTitle.c_str());
01261       frame->SetMaximum(2.);
01262       frame->SetMinimum(0.);
01263       TLine * line = new TLine(xmin,.5,xmax,.5);
01264       line->SetLineColor(kGreen);
01265       TLine * line90 = new TLine(xmin,2.71/2.,xmax,2.71/2.);
01266       line90->SetLineColor(kGreen);
01267       TLine * line95 = new TLine(xmin,3.84/2.,xmax,3.84/2.);
01268       line95->SetLineColor(kGreen);
01269       frame->addObject(line);
01270       frame->addObject(line90);
01271       frame->addObject(line95);
01272   }
01273 
01274   TDirectory * HistoToWorkspaceFactoryFast::Makedirs( TDirectory * file, vector<string> names ){
01275     if(! file) return file;
01276     string path="";
01277     TDirectory* ptr=0;
01278     for(vector<string>::iterator itr=names.begin(); itr != names.end(); ++itr){
01279       if( ! path.empty() ) path+="/";
01280       path+=(*itr);
01281       ptr=file->GetDirectory(path.c_str());
01282       if( ! ptr ) ptr=file->mkdir((*itr).c_str());
01283       file=file->GetDirectory(path.c_str());
01284     }
01285     return ptr;
01286   }
01287   TDirectory * HistoToWorkspaceFactoryFast::Mkdir( TDirectory * file, string name ){
01288     if(! file) return file;
01289     TDirectory* ptr=0;
01290     ptr=file->GetDirectory(name.c_str());
01291     if( ! ptr )  ptr=file->mkdir(name.c_str());
01292     return ptr;
01293   }
01294 
01295 }
01296 }
01297 

Generated on Tue Jul 5 14:52:33 2011 for ROOT_528-00b_version by  doxygen 1.5.1