Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
22Add-on module 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/// Constructor
54
56 RooAbsMCStudyModule("RooRandomizeParamMCSModule","RooRandomizeParamMCSModule"), _data(nullptr)
57{
58}
59
60
61
62////////////////////////////////////////////////////////////////////////////////
63/// Copy constructor
64
67 _unifParams(other._unifParams),
68 _gausParams(other._gausParams),
69 _data(nullptr)
70{
71}
72
73
74
75////////////////////////////////////////////////////////////////////////////////
76/// Destructor
77
79{
80 if (_data) {
81 delete _data ;
82 }
83}
84
85
86
87////////////////////////////////////////////////////////////////////////////////
88/// Request uniform smearing of param in range [lo,hi] in RooMCStudy
89/// generation cycle
90
92{
93 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
94 // If not attached, this check is repeated at the attachment moment
95 if (genParams()) {
96 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(param.GetName())) ;
97 if (!actualPar) {
98 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << param.GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
99 return ;
100 }
101 }
102
103 _unifParams.push_back(UniParam(&param,lo,hi)) ;
104}
105
106
107
108////////////////////////////////////////////////////////////////////////////////
109/// Request Gaussian smearing of param in with mean 'mean' and width
110/// 'sigma' in RooMCStudy generation cycle
111
113{
114 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
115 // If not attached, this check is repeated at the attachment moment
116 if (genParams()) {
117 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(param.GetName())) ;
118 if (!actualPar) {
119 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << param.GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
120 return ;
121 }
122 }
123
124 _gausParams.push_back(GausParam(&param,mean,sigma)) ;
125}
126
127
128
129
130////////////////////////////////////////////////////////////////////////////////
131/// Request uniform smearing of sum of parameters in paramSet uniform
132/// smearing in range [lo,hi] in RooMCStudy generation cycle. This
133/// option applies a common multiplicative factor to each parameter
134/// in paramSet to make the sum of the parameters add up to the
135/// sampled value in the range [lo,hi]
136
137void RooRandomizeParamMCSModule::sampleSumUniform(const RooArgSet& paramSet, double lo, double hi)
138{
139 // Check that all args are RooRealVars
140 RooArgSet okset ;
141 for(RooAbsArg * arg : paramSet) {
142 // Check that arg is a RooRealVar
143 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
144 if (!rrv) {
145 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumUniform() ERROR: input parameter " << arg->GetName() << " is not a RooRealVar and is ignored" << endl ;
146 continue;
147 }
148 okset.add(*rrv) ;
149 }
150
151 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
152 // If not attached, this check is repeated at the attachment moment
153 RooArgSet okset2 ;
154 if (genParams()) {
155 for(RooAbsArg * arg2 : okset) {
156 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg2->GetName())) ;
157 if (!actualVar) {
158 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumUniform: variable " << arg2->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
159 } else {
160 okset2.add(*actualVar) ;
161 }
162 }
163 } else {
164
165 // If genParams() are not available, skip this check for now
166 okset2.add(okset) ;
167
168 }
169
170
171 _unifParamSets.push_back(UniParamSet(okset2,lo,hi)) ;
172
173}
174
175
176
177
178////////////////////////////////////////////////////////////////////////////////
179/// Request gaussian smearing of sum of parameters in paramSet
180/// uniform smearing with mean 'mean' and width 'sigma' in RooMCStudy
181/// generation cycle. This option applies a common multiplicative
182/// factor to each parameter in paramSet to make the sum of the
183/// parameters add up to the sampled value from the
184/// gaussian(mean,sigma)
185
186void RooRandomizeParamMCSModule::sampleSumGauss(const RooArgSet& paramSet, double mean, double sigma)
187{
188 // Check that all args are RooRealVars
189 RooArgSet okset ;
190 for(RooAbsArg * arg : paramSet) {
191 // Check that arg is a RooRealVar
192 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
193 if (!rrv) {
194 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumGauss() ERROR: input parameter " << arg->GetName() << " is not a RooRealVar and is ignored" << endl ;
195 continue;
196 }
197 okset.add(*rrv) ;
198 }
199
200 // If we're already attached to a RooMCStudy, check that given param is actual generator model parameter
201 // If not attached, this check is repeated at the attachment moment
202 RooArgSet okset2 ;
203 if (genParams()) {
204 for(RooAbsArg * arg2 : okset) {
205 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg2->GetName())) ;
206 if (!actualVar) {
207 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::sampleSumUniform: variable " << arg2->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
208 } else {
209 okset2.add(*actualVar) ;
210 }
211 }
212 } else {
213
214 // If genParams() are not available, skip this check for now
215 okset2.add(okset) ;
216
217 }
218
219 _gausParamSets.push_back(GausParamSet(okset,mean,sigma)) ;
220
221}
222
223
224
225
226////////////////////////////////////////////////////////////////////////////////
227/// Initialize module after attachment to RooMCStudy object
228
230{
231 // Loop over all uniform smearing parameters
232 std::list<UniParam>::iterator uiter ;
233 for (uiter= _unifParams.begin() ; uiter!= _unifParams.end() ; ++uiter) {
234
235 // Check that listed variable is actual generator model parameter
236 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(uiter->_param->GetName())) ;
237 if (!actualPar) {
238 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << uiter->_param->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
239 uiter = _unifParams.erase(uiter) ;
240 continue ;
241 }
242 uiter->_param = actualPar ;
243
244 // Add variable to summary dataset to hold generator value
245 std::string parName = std::string(uiter->_param->GetName()) + "_gen";
246 std::string parTitle = std::string(uiter->_param->GetTitle()) + " as generated";
247 _genParSet.addOwned(std::make_unique<RooRealVar>(parName.c_str(),parTitle.c_str(),0));
248 }
249
250 // Loop over all gaussian smearing parameters
251 std::list<GausParam>::iterator giter ;
252 for (giter= _gausParams.begin() ; giter!= _gausParams.end() ; ++giter) {
253
254 // Check that listed variable is actual generator model parameter
255 RooRealVar* actualPar = static_cast<RooRealVar*>(genParams()->find(giter->_param->GetName())) ;
256 if (!actualPar) {
257 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << giter->_param->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
258 giter = _gausParams.erase(giter) ;
259 continue ;
260 }
261 giter->_param = actualPar ;
262
263 // Add variable to summary dataset to hold generator value
264 std::string parName = std::string(giter->_param->GetName()) + "_gen";
265 std::string parTitle = std::string(giter->_param->GetTitle()) + " as generated";
266 _genParSet.addOwned(std::make_unique<RooRealVar>(parName.c_str(),parTitle.c_str(),0));
267 }
268
269
270 // Loop over all uniform smearing set of parameters
271 std::list<UniParamSet>::iterator usiter ;
272 for (usiter= _unifParamSets.begin() ; usiter!= _unifParamSets.end() ; ++usiter) {
273
274 // Check that all listed variables are actual generator model parameters
275 RooArgSet actualPSet ;
276 for(RooAbsArg * arg : usiter->_pset) {
277 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg->GetName())) ;
278 if (!actualVar) {
279 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << arg->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
280 } else {
281 actualPSet.add(*actualVar) ;
282 }
283 }
284 usiter->_pset.removeAll() ;
285 usiter->_pset.add(actualPSet) ;
286
287 // Add variables to summary dataset to hold generator values
288 for(auto * param : static_range_cast<RooRealVar*>(usiter->_pset)) {
289 std::string parName = std::string(param->GetName()) + "_gen";
290 std::string parTitle = std::string(param->GetTitle()) + " as generated";
291 _genParSet.addOwned(std::make_unique<RooRealVar>(parName.c_str(),parTitle.c_str(),0));
292 }
293 }
294
295 // Loop over all gaussian smearing set of parameters
296 std::list<GausParamSet>::iterator ugiter ;
297 for (ugiter= _gausParamSets.begin() ; ugiter!= _gausParamSets.end() ; ++ugiter) {
298
299 // Check that all listed variables are actual generator model parameters
300 RooArgSet actualPSet ;
301 for(RooAbsArg * arg : ugiter->_pset) {
302 RooRealVar* actualVar= static_cast<RooRealVar*>(genParams()->find(arg->GetName())) ;
303 if (!actualVar) {
304 oocoutW(nullptr,InputArguments) << "RooRandomizeParamMCSModule::initializeInstance: variable " << arg->GetName() << " is not a parameter of RooMCStudy model and is ignored!" << endl ;
305 } else {
306 actualPSet.add(*actualVar) ;
307 }
308 }
309
310 ugiter->_pset.removeAll() ;
311 ugiter->_pset.add(actualPSet) ;
312
313 // Add variables to summary dataset to hold generator values
314 for(auto * param : static_range_cast<RooRealVar*>(ugiter->_pset)) {
315 std::string parName = std::string(param->GetName()) + "_gen";
316 std::string parTitle = std::string(param->GetTitle()) + " as generated";
317 _genParSet.addOwned(std::make_unique<RooRealVar>(parName.c_str(),parTitle.c_str(),0));
318 }
319 }
320
321 // Create new dataset to be merged with RooMCStudy::fitParDataSet
322 _data = new RooDataSet("DeltaLLSigData","Additional data for Delta(-log(L)) study",_genParSet) ;
323
324 return true ;
325}
326
327
328
329////////////////////////////////////////////////////////////////////////////////
330/// Initialize module at beginning of RooCMStudy run
331
333{
334 // Clear dataset at beginning of run
335 _data->reset() ;
336 return true ;
337}
338
339
340
341////////////////////////////////////////////////////////////////////////////////
342/// Apply all smearings to generator parameters
343
345{
346 // Apply uniform smearing to all generator parameters for which it is requested
347 std::list<UniParam>::iterator uiter ;
348 for (uiter= _unifParams.begin() ; uiter!= _unifParams.end() ; ++uiter) {
349 double newVal = RooRandom::randomGenerator()->Uniform(uiter->_lo,uiter->_hi) ;
350 oocoutE(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying uniform smearing to generator parameter "
351 << uiter->_param->GetName() << " in range [" << uiter->_lo << "," << uiter->_hi << "], chosen value for this sample is " << newVal << endl ;
352 uiter->_param->setVal(newVal) ;
353
354 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",uiter->_param->GetName()))) ;
355 genpar->setVal(newVal) ;
356 }
357
358 // Apply gaussian smearing to all generator parameters for which it is requested
359 std::list<GausParam>::iterator giter ;
360 for (giter= _gausParams.begin() ; giter!= _gausParams.end() ; ++giter) {
361 double newVal = RooRandom::randomGenerator()->Gaus(giter->_mean,giter->_sigma) ;
362 oocoutI(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying gaussian smearing to generator parameter "
363 << giter->_param->GetName() << " with a mean of " << giter->_mean << " and a width of " << giter->_sigma << ", chosen value for this sample is " << newVal << endl ;
364 giter->_param->setVal(newVal) ;
365
366 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",giter->_param->GetName()))) ;
367 genpar->setVal(newVal) ;
368 }
369
370 // Apply uniform smearing to all sets of generator parameters for which it is requested
371 std::list<UniParamSet>::iterator usiter ;
372 for (usiter= _unifParamSets.begin() ; usiter!= _unifParamSets.end() ; ++usiter) {
373
374 // Calculate new value for sum
375 double newVal = RooRandom::randomGenerator()->Uniform(usiter->_lo,usiter->_hi) ;
376 oocoutI(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying uniform smearing to sum of set of generator parameters "
377 << usiter->_pset
378 << " in range [" << usiter->_lo << "," << usiter->_hi << "], chosen sum value for this sample is " << newVal << endl ;
379
380 // Determine original value of sum and calculate per-component scale factor to obtain new value for sum
381 RooAddition sumVal("sumVal","sumVal",usiter->_pset) ;
382 double compScaleFactor = newVal/sumVal.getVal() ;
383
384 // Apply multiplicative correction to each term of the sum
385 for(auto * param : static_range_cast<RooRealVar*>(usiter->_pset)) {
386 param->setVal(param->getVal()*compScaleFactor) ;
387 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",param->GetName()))) ;
388 genpar->setVal(param->getVal()) ;
389 }
390 }
391
392 // Apply gaussian smearing to all sets of generator parameters for which it is requested
393 std::list<GausParamSet>::iterator gsiter ;
394 for (gsiter= _gausParamSets.begin() ; gsiter!= _gausParamSets.end() ; ++gsiter) {
395
396 // Calculate new value for sum
397 double newVal = RooRandom::randomGenerator()->Gaus(gsiter->_mean,gsiter->_sigma) ;
398 oocoutI(nullptr,Generation) << "RooRandomizeParamMCSModule::processBeforeGen: applying gaussian smearing to sum of set of generator parameters "
399 << gsiter->_pset
400 << " with a mean of " << gsiter->_mean << " and a width of " << gsiter->_sigma
401 << ", chosen value for this sample is " << newVal << endl ;
402
403 // Determine original value of sum and calculate per-component scale factor to obtain new value for sum
404 RooAddition sumVal("sumVal","sumVal",gsiter->_pset) ;
405 double compScaleFactor = newVal/sumVal.getVal() ;
406
407 // Apply multiplicative correction to each term of the sum
408 for(auto * param : static_range_cast<RooRealVar*>(gsiter->_pset)) {
409 param->setVal(param->getVal()*compScaleFactor) ;
410 RooRealVar* genpar = static_cast<RooRealVar*>(_genParSet.find(Form("%s_gen",param->GetName()))) ;
411 genpar->setVal(param->getVal()) ;
412 }
413 }
414
415 // Store generator values for all modified parameters
417
418 return true ;
419}
420
421
422
423////////////////////////////////////////////////////////////////////////////////
424/// Return auxiliary data of this module so that it is merged with
425/// RooMCStudy::fitParDataSet()
426
428{
429 return _data ;
430}
431
432
#define oocoutW(o, a)
#define oocoutE(o, a)
#define oocoutI(o, a)
#define ClassImp(name)
Definition Rtypes.h:377
#define hi
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:79
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()
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:103
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:55
RooDataSet is a container class to hold unbinned data.
Definition RooDataSet.h:57
void add(const RooArgSet &row, double weight, double weightError)
Add one ore more rows of data.
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition RooRandom.cxx:51
Add-on module to RooMCStudy that allows you to randomize input generation parameters.
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.
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:37
void setVal(double value) override
Set value of variable to 'value'.
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
const Double_t sigma