Logo ROOT  
Reference Guide
RooRandomizeParamMCSModule.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooRandomizeParamMCSModule.cxx
19\class RooRandomizeParamMCSModule
20\ingroup Roofitcore
21
22RooRandomizeParamMCSModule is an add-on modules to RooMCStudy that
23allows you to randomize input generation parameters. Randomized generation
24parameters can be sampled from a uniform or Gaussian distribution.
25For every randomized parameter, an extra variable is added to
26RooMCStudy::fitParDataSet() named <tt>`<parname>`_gen</tt> that indicates the actual
27value used for generation for each trial.
28You can also choose to randomize the sum of N parameters, rather
29than a single parameter. In that case common multiplicative scale
30factor is applied to each component to bring the sum to the desired
31target value taken from either uniform or Gaussian sampling. This
32latter option is for example useful if you want to change the total
33number of expected events of an extended p.d.f
34**/
35
36
37#include "Riostream.h"
38#include "RooDataSet.h"
39#include "RooRealVar.h"
40#include "RooRandom.h"
41#include "TString.h"
42#include "RooFitResult.h"
43#include "RooAddition.h"
44#include "RooMsgService.h"
46
47using namespace std ;
48
50 ;
51
52
53
54////////////////////////////////////////////////////////////////////////////////
55/// Constructor
56
58 RooAbsMCStudyModule("RooRandomizeParamMCSModule","RooRandomizeParamMCSModule"), _data(0)
59{
60}
61
62
63
64////////////////////////////////////////////////////////////////////////////////
65/// Copy constructor
66
69 _unifParams(other._unifParams),
70 _gausParams(other._gausParams),
71 _data(0)
72{
73}
74
75
76
77////////////////////////////////////////////////////////////////////////////////
78/// Destructor
79
81{
82 if (_data) {
83 delete _data ;
84 }
85}
86
87
88
89////////////////////////////////////////////////////////////////////////////////
90/// Request uniform smearing of param in range [lo,hi] in RooMCStudy
91/// generation cycle
92
94{
95 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
96 // If not attached, this check is repeated at the attachment moment
97 if (genParams()) {
98 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(param.GetName())) ;
99 if (!actualPar) {
100 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << param.GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
101 return ;
102 }
103 }
104
105 _unifParams.push_back(UniParam(&param,lo,hi)) ;
106}
107
108
109
110////////////////////////////////////////////////////////////////////////////////
111/// Request Gaussian smearing of param in with mean 'mean' and width
112/// 'sigma' in RooMCStudy generation cycle
113
115{
116 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
117 // If not attached, this check is repeated at the attachment moment
118 if (genParams()) {
119 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(param.GetName())) ;
120 if (!actualPar) {
121 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << param.GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
122 return ;
123 }
124 }
125
126 _gausParams.push_back(GausParam(&param,mean,sigma)) ;
127}
128
129
130
131
132////////////////////////////////////////////////////////////////////////////////
133/// Request uniform smearing of sum of parameters in paramSet uniform
134/// smearing in range [lo,hi] in RooMCStudy generation cycle. This
135/// option applies a common multiplicative factor to each parameter
136/// in paramSet to make the sum of the parameters add up to the
137/// sampled value in the range [lo,hi]
138
139void RooRandomizeParamMCSModule::sampleSumUniform(const RooArgSet& paramSet, double lo, double hi)
140{
141 // Check that all args are RooRealVars
142 RooArgSet okset ;
143 for(RooAbsArg * arg : paramSet) {
144 // Check that arg is a RooRealVar
145 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
146 if (!rrv) {
147 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumUniform() ERROR: input parameter " << arg->GetName() << " is not a RooRealVar and is ignored" << endl ;
148 continue;
149 }
150 okset.add(*rrv) ;
151 }
152
153 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
154 // If not attached, this check is repeated at the attachment moment
155 RooArgSet okset2 ;
156 if (genParams()) {
157 for(RooAbsArg * arg2 : okset) {
158 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg2->GetName())) ;
159 if (!actualVar) {
160 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumUniform: variable " << arg2->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
161 } else {
162 okset2.add(*actualVar) ;
163 }
164 }
165 } else {
166
167 // If genParams() are not available, skip this check for now
168 okset2.add(okset) ;
169
170 }
171
172
173 _unifParamSets.push_back(UniParamSet(okset2,lo,hi)) ;
174
175}
176
177
178
179
180////////////////////////////////////////////////////////////////////////////////
181/// Request gaussian smearing of sum of parameters in paramSet
182/// uniform smearing with mean 'mean' and width 'sigma' in RooMCStudy
183/// generation cycle. This option applies a common multiplicative
184/// factor to each parameter in paramSet to make the sum of the
185/// parameters add up to the sampled value from the
186/// gaussian(mean,sigma)
187
188void RooRandomizeParamMCSModule::sampleSumGauss(const RooArgSet& paramSet, double mean, double sigma)
189{
190 // Check that all args are RooRealVars
191 RooArgSet okset ;
192 for(RooAbsArg * arg : paramSet) {
193 // Check that arg is a RooRealVar
194 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
195 if (!rrv) {
196 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumGauss() ERROR: input parameter " << arg->GetName() << " is not a RooRealVar and is ignored" << endl ;
197 continue;
198 }
199 okset.add(*rrv) ;
200 }
201
202 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
203 // If not attached, this check is repeated at the attachment moment
204 RooArgSet okset2 ;
205 if (genParams()) {
206 for(RooAbsArg * arg2 : okset) {
207 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg2->GetName())) ;
208 if (!actualVar) {
209 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumUniform: variable " << arg2->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
210 } else {
211 okset2.add(*actualVar) ;
212 }
213 }
214 } else {
215
216 // If genParams() are not available, skip this check for now
217 okset2.add(okset) ;
218
219 }
220
221 _gausParamSets.push_back(GausParamSet(okset,mean,sigma)) ;
222
223}
224
225
226
227
228////////////////////////////////////////////////////////////////////////////////
229/// Initialize module after attachment to RooMCStudy object
230
232{
233 // Loop over all uniform smearing parameters
234 std::list<UniParam>::iterator uiter ;
235 for (uiter= _unifParams.begin() ; uiter!= _unifParams.end() ; ++uiter) {
236
237 // Check that listed variable is actual generator model parameter
238 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(uiter->_param->GetName())) ;
239 if (!actualPar) {
240 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << uiter->_param->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
241 uiter = _unifParams.erase(uiter) ;
242 continue ;
243 }
244 uiter->_param = actualPar ;
245
246 // Add variable to summary dataset to hold generator value
247 TString parName = Form("%s_gen",uiter->_param->GetName()) ;
248 TString parTitle = Form("%s as generated",uiter->_param->GetTitle()) ;
249 RooRealVar* par_gen = new RooRealVar(parName.Data(),parTitle.Data(),0) ;
250 _genParSet.addOwned(*par_gen) ;
251 }
252
253 // Loop over all gaussian smearing parameters
254 std::list<GausParam>::iterator giter ;
255 for (giter= _gausParams.begin() ; giter!= _gausParams.end() ; ++giter) {
256
257 // Check that listed variable is actual generator model parameter
258 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(giter->_param->GetName())) ;
259 if (!actualPar) {
260 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << giter->_param->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
261 giter = _gausParams.erase(giter) ;
262 continue ;
263 }
264 giter->_param = actualPar ;
265
266 // Add variable to summary dataset to hold generator value
267 TString parName = Form("%s_gen",giter->_param->GetName()) ;
268 TString parTitle = Form("%s as generated",giter->_param->GetTitle()) ;
269 RooRealVar* par_gen = new RooRealVar(parName.Data(),parTitle.Data(),0) ;
270 _genParSet.addOwned(*par_gen) ;
271 }
272
273
274 // Loop over all uniform smearing set of parameters
275 std::list<UniParamSet>::iterator usiter ;
276 for (usiter= _unifParamSets.begin() ; usiter!= _unifParamSets.end() ; ++usiter) {
277
278 // Check that all listed variables are actual generator model parameters
279 RooArgSet actualPSet ;
280 for(RooAbsArg * arg : usiter->_pset) {
281 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg->GetName())) ;
282 if (!actualVar) {
283 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << arg->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
284 } else {
285 actualPSet.add(*actualVar) ;
286 }
287 }
288 usiter->_pset.removeAll() ;
289 usiter->_pset.add(actualPSet) ;
290
291 // Add variables to summary dataset to hold generator values
292 for(auto * param : static_range_cast<RooRealVar*>(usiter->_pset)) {
293 TString parName = Form("%s_gen",param->GetName()) ;
294 TString parTitle = Form("%s as generated",param->GetTitle()) ;
295 RooRealVar* par_gen = new RooRealVar(parName.Data(),parTitle.Data(),0) ;
296 _genParSet.addOwned(*par_gen) ;
297 }
298 }
299
300 // Loop over all gaussian smearing set of parameters
301 std::list<GausParamSet>::iterator ugiter ;
302 for (ugiter= _gausParamSets.begin() ; ugiter!= _gausParamSets.end() ; ++ugiter) {
303
304 // Check that all listed variables are actual generator model parameters
305 RooArgSet actualPSet ;
306 for(RooAbsArg * arg : ugiter->_pset) {
307 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg->GetName())) ;
308 if (!actualVar) {
309 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << arg->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
310 } else {
311 actualPSet.add(*actualVar) ;
312 }
313 }
314
315 ugiter->_pset.removeAll() ;
316 ugiter->_pset.add(actualPSet) ;
317
318 // Add variables to summary dataset to hold generator values
319 for(auto * param : static_range_cast<RooRealVar*>(ugiter->_pset)) {
320 TString parName = Form("%s_gen",param->GetName()) ;
321 TString parTitle = Form("%s as generated",param->GetTitle()) ;
322 RooRealVar* par_gen = new RooRealVar(parName.Data(),parTitle.Data(),0) ;
323 _genParSet.addOwned(*par_gen) ;
324 }
325 }
326
327 // Create new dataset to be merged with RooMCStudy::fitParDataSet
328 _data = new RooDataSet("DeltaLLSigData","Additional data for Delta(-log(L)) study",_genParSet) ;
329
330 return true ;
331}
332
333
334
335////////////////////////////////////////////////////////////////////////////////
336/// Initialize module at beginning of RooCMStudy run
337
339{
340 // Clear dataset at beginning of run
341 _data->reset() ;
342 return true ;
343}
344
345
346
347////////////////////////////////////////////////////////////////////////////////
348/// Apply all smearings to generator parameters
349
351{
352 // Apply uniform smearing to all generator parameters for which it is requested
353 std::list<UniParam>::iterator uiter ;
354 for (uiter= _unifParams.begin() ; uiter!= _unifParams.end() ; ++uiter) {
355 double newVal = RooRandom::randomGenerator()->Uniform(uiter->_lo,uiter->_hi) ;
356 oocoutE(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying uniform smearing to generator parameter "
357 << uiter->_param->GetName() << " in range [" << uiter->_lo << "," << uiter->_hi << "], chosen value for this sample is " << newVal << endl ;
358 uiter->_param->setVal(newVal) ;
359
360 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",uiter->_param->GetName()))) ;
361 genpar->setVal(newVal) ;
362 }
363
364 // Apply gaussian smearing to all generator parameters for which it is requested
365 std::list<GausParam>::iterator giter ;
366 for (giter= _gausParams.begin() ; giter!= _gausParams.end() ; ++giter) {
367 double newVal = RooRandom::randomGenerator()->Gaus(giter->_mean,giter->_sigma) ;
368 oocoutI(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying gaussian smearing to generator parameter "
369 << giter->_param->GetName() << " with a mean of " << giter->_mean << " and a width of " << giter->_sigma << ", chosen value for this sample is " << newVal << endl ;
370 giter->_param->setVal(newVal) ;
371
372 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",giter->_param->GetName()))) ;
373 genpar->setVal(newVal) ;
374 }
375
376 // Apply uniform smearing to all sets of generator parameters for which it is requested
377 std::list<UniParamSet>::iterator usiter ;
378 for (usiter= _unifParamSets.begin() ; usiter!= _unifParamSets.end() ; ++usiter) {
379
380 // Calculate new value for sum
381 double newVal = RooRandom::randomGenerator()->Uniform(usiter->_lo,usiter->_hi) ;
382 oocoutI(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying uniform smearing to sum of set of generator parameters "
383 << usiter->_pset
384 << " in range [" << usiter->_lo << "," << usiter->_hi << "], chosen sum value for this sample is " << newVal << endl ;
385
386 // Determine original value of sum and calculate per-component scale factor to obtain new valye for sum
387 RooAddition sumVal("sumVal","sumVal",usiter->_pset) ;
388 double compScaleFactor = newVal/sumVal.getVal() ;
389
390 // Apply multiplicative correction to each term of the sum
391 for(auto * param : static_range_cast<RooRealVar*>(usiter->_pset)) {
392 param->setVal(param->getVal()*compScaleFactor) ;
393 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",param->GetName()))) ;
394 genpar->setVal(param->getVal()) ;
395 }
396 }
397
398 // Apply gaussian smearing to all sets of generator parameters for which it is requested
399 std::list<GausParamSet>::iterator gsiter ;
400 for (gsiter= _gausParamSets.begin() ; gsiter!= _gausParamSets.end() ; ++gsiter) {
401
402 // Calculate new value for sum
403 double newVal = RooRandom::randomGenerator()->Gaus(gsiter->_mean,gsiter->_sigma) ;
404 oocoutI(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying gaussian smearing to sum of set of generator parameters "
405 << gsiter->_pset
406 << " with a mean of " << gsiter->_mean << " and a width of " << gsiter->_sigma
407 << ", chosen value for this sample is " << newVal << endl ;
408
409 // Determine original value of sum and calculate per-component scale factor to obtain new valye for sum
410 RooAddition sumVal("sumVal","sumVal",gsiter->_pset) ;
411 double compScaleFactor = newVal/sumVal.getVal() ;
412
413 // Apply multiplicative correction to each term of the sum
414 for(auto * param : static_range_cast<RooRealVar*>(gsiter->_pset)) {
415 param->setVal(param->getVal()*compScaleFactor) ;
416 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",param->GetName()))) ;
417 genpar->setVal(param->getVal()) ;
418 }
419 }
420
421 // Store generator values for all modified parameters
423
424 return true ;
425}
426
427
428
429////////////////////////////////////////////////////////////////////////////////
430/// Return auxiliary data of this module so that it is merged with
431/// RooMCStudy::fitParDataSet()
432
434{
435 return _data ;
436}
437
438
#define oocoutW(o, a)
Definition: RooMsgService.h:51
#define oocoutE(o, a)
Definition: RooMsgService.h:52
#define oocoutI(o, a)
Definition: RooMsgService.h:49
#define ClassImp(name)
Definition: Rtypes.h:375
#define hi
Definition: THbookFile.cxx:128
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition: TString.cxx:2452
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:71
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
RooAbsArg * find(const char *name) const
Find object with given name in list.
virtual void reset()
Definition: RooAbsData.cxx:381
RooAbsMCStudyModule is a base class for add-on modules to RooMCStudy that can perform additional calc...
RooArgSet * genParams()
Return current value of generator model parameters.
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
RooAddition calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
Definition: RooAddition.h:27
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:56
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:55
void add(const RooArgSet &row, double weight=1.0, double weightError=0.0) override
Add one ore more rows of data.
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition: RooRandom.cxx:51
RooRandomizeParamMCSModule is an add-on modules to RooMCStudy that allows you to randomize input gene...
void sampleSumGauss(const RooArgSet &paramSet, double lo, double hi)
Request gaussian smearing of sum of parameters in paramSet uniform smearing with mean 'mean' and widt...
bool initializeRun(Int_t) override
Initialize module at beginning of RooCMStudy run.
std::list< GausParam > _gausParams
!
void sampleSumUniform(const RooArgSet &paramSet, double lo, double hi)
Request uniform smearing of sum of parameters in paramSet uniform smearing in range [lo,...
std::list< UniParamSet > _unifParamSets
!
void sampleGaussian(RooRealVar &param, double mean, double sigma)
Request Gaussian smearing of param in with mean 'mean' and width 'sigma' in RooMCStudy generation cyc...
bool processBeforeGen(Int_t) override
Apply all smearings to generator parameters.
~RooRandomizeParamMCSModule() override
Destructor.
RooDataSet * finalizeRun() override
Return auxiliary data of this module so that it is merged with RooMCStudy::fitParDataSet()
bool initializeInstance() override
Initialize module after attachment to RooMCStudy object.
void sampleUniform(RooRealVar &param, double lo, double hi)
Request uniform smearing of param in range [lo,hi] in RooMCStudy generation cycle.
std::list< GausParamSet > _gausParamSets
!
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:40
void setVal(double value) override
Set value of variable to 'value'.
Definition: RooRealVar.cxx:254
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
Definition: TRandom.cxx:274
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:672
Basic string class.
Definition: TString.h:136
const char * Data() const
Definition: TString.h:369
const Double_t sigma
@ Generation
Definition: RooGlobalFunc.h:61
@ InputArguments
Definition: RooGlobalFunc.h:62