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