Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
ModelConfig.cxx
Go to the documentation of this file.
1 // @(#)root/roostats:$Id$
2 // Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke, Sven Kreiss
3 /*************************************************************************
4  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 /** \class RooStats::ModelConfig
12  \ingroup Roostats
13 
14 ModelConfig is a simple class that holds configuration information specifying how a model
15 should be used in the context of various RooStats tools. A single model can be used
16 in different ways, and this class should carry all that is needed to specify how it should be used.
17 ModelConfig requires a workspace to be set.
18 
19 A ModelConfig holds sets of parameters of the likelihood function that have different interpretations:
20 - **Parameter of interest** Parameters that are measured (*i.e.* fitted).
21 - **Nuisance parameters** Parameters that are fitted, but their post-fit value is not interesting. Often,
22 they might be constrained because external knowledge about them exists, *e.g.* from external measurements.
23 - **Constraint parameters** No direct use in RooFit/RooStats. Can be used by the user for bookkeeping.
24 - **Observables** Parameters that have been measured externally, *i.e.* they exist in a dataset. These are not fitted,
25 but read during fitting from the entries of a dataset.
26 - **Conditional observables** Observables that are not integrated when the normalisation of the PDF is calculated.
27 See *e.g.* `rf306_condpereventerrors` in the RooFit tutorials.
28 - **Global observables** Observables that to the fit look like "constant" values, *i.e.* they are not being
29 fitted and they are not loaded from a dataset, but some knowledge exists that allows to set them to a
30 specific value. Examples:
31 -- A signal efficiency measured in a Monte Carlo study.
32 -- When constraining a parameter \f$ b \f$, the target value (\f$ b_0 \f$) that this parameter is constrained to:
33 \f[
34  \mathrm{Constraint}_b = \mathrm{Gauss}(b_0 \, | \, b, 0.2)
35 \f]
36 */
37 
38 #include "RooStats/ModelConfig.h"
39 
40 #include "TROOT.h"
41 
42 #include "RooMsgService.h"
43 
44 #include "RooStats/RooStatsUtils.h"
45 
46 #include <sstream>
47 
48 
49 ClassImp(RooStats::ModelConfig);
50 
51 using namespace std;
52 
53 namespace RooStats {
54 
55 ////////////////////////////////////////////////////////////////////////////////
56 /// Makes sensible guesses of observables, parameters of interest
57 /// and nuisance parameters if one or multiple have been set by the creator of this ModelConfig.
58 ///
59 /// Defaults:
60 /// - Observables: determined from data,
61 /// - Global observables: explicit obs - obs from data - constant observables
62 /// - Parameters of interest: empty,
63 /// - Nuisance parameters: all parameters except parameters of interest
64 ///
65 /// We use NULL to mean not set, so we don't want to fill
66 /// with empty RooArgSets.
67 
68 void ModelConfig::GuessObsAndNuisance(const RooAbsData& data) {
69 
70  // observables
71  if (!GetObservables()) {
72  const RooArgSet * obs = GetPdf()->getObservables(data);
73  SetObservables(*obs);
74  delete obs;
75  }
76  // global observables
77  if (!GetGlobalObservables()) {
78  RooArgSet co(*GetObservables());
79  const RooArgSet * obs = GetPdf()->getObservables(data);
80  co.remove(*obs);
81  RemoveConstantParameters(&co);
82  if(co.getSize()>0)
83  SetGlobalObservables(co);
84 
85  // TODO BUG This does not work as observables with the same name are already in the workspace.
86  /*
87  RooArgSet o(*GetObservables());
88  o.remove(co);
89  SetObservables(o);
90  */
91  delete obs;
92  }
93 
94  // parameters
95  // if (!GetParametersOfInterest()) {
96  // SetParametersOfInterest(RooArgSet());
97  // }
98  if (!GetNuisanceParameters()) {
99  const RooArgSet * params = GetPdf()->getParameters(data);
100  RooArgSet p(*params);
101  p.remove(*GetParametersOfInterest());
102  RemoveConstantParameters(&p);
103  if(p.getSize()>0)
104  SetNuisanceParameters(p);
105  delete params;
106  }
107 
108  // print Modelconfig as an info message
109 
110  std::ostream& oldstream = RooPrintable::defaultPrintStream(&ccoutI(InputArguments));
111  Print();
112  RooPrintable::defaultPrintStream(&oldstream);
113 }
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 /// print contents of Model on the default print stream
117 /// It can be changed using RooPrintable
118 
119 void ModelConfig::Print(Option_t*) const {
120  ostream& os = RooPrintable::defaultPrintStream();
121 
122  os << endl << "=== Using the following for " << GetName() << " ===" << endl;
123 
124 
125  // args
126  if(GetObservables()){
127  os << "Observables: ";
128  GetObservables()->Print("");
129  }
130  if(GetParametersOfInterest()) {
131  os << "Parameters of Interest: ";
132  GetParametersOfInterest()->Print("");
133  }
134  if(GetNuisanceParameters()){
135  os << "Nuisance Parameters: ";
136  GetNuisanceParameters()->Print("");
137  }
138  if(GetGlobalObservables()){
139  os << "Global Observables: ";
140  GetGlobalObservables()->Print("");
141  }
142  if(GetConstraintParameters()){
143  os << "Constraint Parameters: ";
144  GetConstraintParameters()->Print("");
145  }
146  if(GetConditionalObservables()){
147  os << "Conditional Observables: ";
148  GetConditionalObservables()->Print("");
149  }
150  if(GetProtoData()){
151  os << "Proto Data: ";
152  GetProtoData()->Print("");
153  }
154 
155  // pdfs
156  if(GetPdf()) {
157  os << "PDF: ";
158  GetPdf()->Print("");
159  }
160  if(GetPriorPdf()) {
161  os << "Prior PDF: ";
162  GetPriorPdf()->Print("");
163  }
164 
165  // snapshot
166  const RooArgSet * snapshot = GetSnapshot();
167  if(snapshot) {
168  os << "Snapshot: " << endl;
169  snapshot->Print("v");
170  delete snapshot;
171  }
172 
173  os << endl;
174 }
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 /// If a workspace already exists in this ModelConfig, RooWorkspace::merge(ws) will be called
178 /// on the existing workspace.
179 
180 void ModelConfig::SetWS(RooWorkspace & ws) {
181  if( !fRefWS.GetObject() ) {
182  fRefWS = &ws;
183  fWSName = ws.GetName();
184  }
185  else{
186  RooFit::MsgLevel level = RooMsgService::instance().globalKillBelow();
187  RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
188  GetWS()->merge(ws);
189  RooMsgService::instance().setGlobalKillBelow(level) ;
190  }
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// get from TRef
195 
196 RooWorkspace * ModelConfig::GetWS() const {
197  RooWorkspace *ws = dynamic_cast<RooWorkspace *>(fRefWS.GetObject() );
198  if(!ws) {
199  coutE(ObjectHandling) << "workspace not set" << endl;
200  return NULL;
201  }
202  return ws;
203 }
204 
205 ////////////////////////////////////////////////////////////////////////////////
206 /// save snapshot in the workspace
207 /// and use values passed with the set
208 
209 void ModelConfig::SetSnapshot(const RooArgSet& set) {
210  if ( !GetWS() ) return;
211 
212  fSnapshotName = GetName();
213  if (fSnapshotName.size() > 0) fSnapshotName += "_";
214  fSnapshotName += set.GetName();
215  if (fSnapshotName.size() > 0) fSnapshotName += "_";
216  fSnapshotName += "snapshot";
217  GetWS()->saveSnapshot(fSnapshotName.c_str(), set, true); // import also the given parameter values
218  DefineSetInWS(fSnapshotName.c_str(), set);
219 }
220 
221 ////////////////////////////////////////////////////////////////////////////////
222 /// Load the snapshot from ws and return the corresponding set with the snapshot values.
223 /// User must delete returned RooArgSet.
224 
225 const RooArgSet * ModelConfig::GetSnapshot() const{
226  if ( !GetWS() ) return 0;
227  if (!fSnapshotName.length()) return 0;
228  // calling loadSnapshot will also copy the current parameter values in the workspaces
229  // since we do not want to change the model parameters - we restore the previous ones
230  if (! GetWS()->set(fSnapshotName.c_str() ) )return 0;
231  RooArgSet snapshotVars(*GetWS()->set(fSnapshotName.c_str() ) );
232  if (snapshotVars.getSize() == 0) return 0;
233  // make my snapshot which will contain a copy of the snapshot variables
234  RooArgSet tempSnapshot;
235  snapshotVars.snapshot(tempSnapshot);
236  // load snapshot value from the workspace
237  if (!(GetWS()->loadSnapshot(fSnapshotName.c_str())) ) return 0;
238  // by doing this snapshotVars will have the snapshot values - make the snapshot to return
239  const RooArgSet * modelSnapshot = dynamic_cast<const RooArgSet*>( snapshotVars.snapshot());
240  // restore now the variables of snapshot in ws to their original values
241  // need to const cast since assign is not const (but in reality in just assign values and does not change the set)
242  // and anyway the set is const
243  snapshotVars.assignFast(tempSnapshot);
244  return modelSnapshot;
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 /// load the snapshot from ws if it exists
249 
250 void ModelConfig::LoadSnapshot() const{
251  if ( !GetWS() ) return;
252  GetWS()->loadSnapshot(fSnapshotName.c_str());
253 }
254 
255 ////////////////////////////////////////////////////////////////////////////////
256 /// helper functions to avoid code duplication
257 
258 void ModelConfig::DefineSetInWS(const char* name, const RooArgSet& set) {
259  if ( !GetWS() ) return;
260 
261  const RooArgSet * prevSet = GetWS()->set(name);
262  if ( prevSet ) {
263  //be careful not to remove passed set in case it is the same updated
264  if (prevSet != &set)
265  GetWS()->removeSet(name);
266  }
267 
268  // suppress warning when we re-define a previously defined set (when set == prevSet )
269  // and set is not removed in that case
270  RooFit::MsgLevel level = RooMsgService::instance().globalKillBelow();
271  RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
272 
273 
274  GetWS()->defineSet(name, set,true);
275 
276  RooMsgService::instance().setGlobalKillBelow(level) ;
277 
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// internal function to import Pdf in WS
282 
283 void ModelConfig::ImportPdfInWS(const RooAbsPdf & pdf) {
284  if ( !GetWS() ) return;
285 
286  if (! GetWS()->pdf( pdf.GetName() ) ){
287  RooFit::MsgLevel level = RooMsgService::instance().globalKillBelow();
288  RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
289  GetWS()->import(pdf, RooFit::RecycleConflictNodes());
290  RooMsgService::instance().setGlobalKillBelow(level) ;
291  }
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 /// internal function to import data in WS
296 
297 void ModelConfig::ImportDataInWS(RooAbsData & data) {
298  if ( !GetWS() ) return;
299 
300  if (! GetWS()->data( data.GetName() ) ){
301  RooFit::MsgLevel level = RooMsgService::instance().globalKillBelow();
302  RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
303  GetWS()->import(data);
304  RooMsgService::instance().setGlobalKillBelow(level) ;
305  }
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 
310 Bool_t ModelConfig::SetHasOnlyParameters(const RooArgSet& set, const char* errorMsgPrefix) {
311 
312  RooArgSet nonparams ;
313  RooFIter iter = set.fwdIterator() ;
314  RooAbsArg* arg ;
315  while ((arg=iter.next())) {
316  if (!arg->isFundamental()) {
317  nonparams.add(*arg) ;
318  }
319  }
320 
321  if (errorMsgPrefix && nonparams.getSize()>0) {
322  cout << errorMsgPrefix << " ERROR: specified set contains non-parameters: " << nonparams << endl ;
323  }
324  return (nonparams.getSize()==0) ;
325  }
326 
327 } // end namespace RooStats