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