Logo ROOT  
Reference Guide
RooMultiCategory.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 RooMultiCategory.cxx
19\class RooMultiCategory
20\ingroup Roofitcore
21
22RooMultiCategory connects several RooAbsCategory objects into
23a single category. The states of the multi-category consist of all the permutations
24of the input categories.
25RooMultiCategory states are automatically defined and updated whenever an input
26category modifies its list of states.
27
28A RooMultiCategory is not an lvalue, *i.e.* one cannot set its states. Its state simply follows
29as a computation from the states of the input categories. This is because the input categories
30don't need to be lvalues, so their states cannot be set by the MultiCategory. If all input categories
31are lvalues, the RooSuperCategory can be used. It works like RooMultiCategory, but allows for
32setting the states.
33**/
34
35#include "RooMultiCategory.h"
36
37#include "RooFit.h"
38#include "RooStreamParser.h"
39#include "RooArgSet.h"
40#include "RooAbsCategory.h"
41#include "RooMsgService.h"
42
43#include "TString.h"
44
45using namespace std;
46
48
49
50
51////////////////////////////////////////////////////////////////////////////////
52/// Construct a product of the given set of input RooAbsCategories in `inInputCatList`.
53/// The state names of this product category are {S1;S2,S3,...Sn} where Si are the state names
54/// of the input categories.
55
56RooMultiCategory::RooMultiCategory(const char *name, const char *title, const RooArgSet& inputCategories) :
57 RooAbsCategory(name, title), _catSet("input","Input category set",this,kTRUE,kTRUE)
58{
59 // Copy category list
60 for (const auto arg : inputCategories) {
61 if (!dynamic_cast<RooAbsCategory*>(arg)) {
62 coutE(InputArguments) << "RooMultiCategory::RooMultiCategory(" << GetName() << "): input argument " << arg->GetName()
63 << " is not a RooAbsCategory" << endl ;
64 }
65 _catSet.add(*arg) ;
66 }
68}
69
70
71
72////////////////////////////////////////////////////////////////////////////////
73/// Copy constructor
74
76 RooAbsCategory(other,name), _catSet("input",this,other._catSet)
77{
79}
80
81
82
83////////////////////////////////////////////////////////////////////////////////
84/// Destructor
85
87{
88}
89
90
91////////////////////////////////////////////////////////////////////////////////
92/// Compile a string with all the labels of the serving categories,
93/// such as `{1Jet;1Lepton;2Tag}`.
95{
96 // Construct composite label name
97 std::string label;
98 Bool_t first = true;
99 for (const auto arg : _catSet) {
100 auto cat = static_cast<const RooAbsCategory*>(arg);
101
102 label += first ? '{' : ';';
103 label += cat->getCurrentLabel();
104 first = false;
105 }
106 label += '}';
107
108 return label ;
109}
110
111
112#ifndef NDEBUG
113
115namespace {
116/// Check that root-6.22 redesign of category interfaces yields same labels
117std::string computeLabelOldStyle(const RooArgSet& catSet, unsigned int index) {
118 RooMultiCatIter iter(catSet) ;
119 TObjString* obj ;
120 for (unsigned int i=0; (obj=(TObjString*)iter.Next()); ++i) {
121 if (i == index) {
122 return obj->String().Data();
123 }
124 }
125
126 return {};
127}
128}
129#endif
130
131
132////////////////////////////////////////////////////////////////////////////////
133/// Calculate the current value.
134/// This enumerates the states of each serving category, and calculates a unique
135/// state number. The first category occupies the state numbers \f$ 0, \ldots \mathrm{size}_\mathrm{first}-1 \f$,
136/// the second category \f$ (0, \ldots \mathrm{size}_\mathrm{second}-1) * \mathrm{size}_\mathrm{first} \f$ etc.
138{
139 value_type computedStateIndex = 0;
140 value_type multiplier = 1;
141 for (const auto arg : _catSet) {
142 auto cat = static_cast<const RooAbsCategory*>(arg);
143 if (cat->size() == 0) {
144 coutW(InputArguments) << __func__ << " Trying to build a multi-category state based on "
145 "a category with zero states. Fix '" << cat->GetName() << "'." << std::endl;
146 continue;
147 }
148 computedStateIndex += cat->getCurrentOrdinalNumber() * multiplier;
149 multiplier *= cat->size();
150 }
151
152#ifndef NDEBUG
153 assert(hasIndex(computedStateIndex));
154 _currentIndex = computedStateIndex;
155 assert(createLabel() == computeLabelOldStyle(_catSet, computedStateIndex));
156#endif
157
158 return computedStateIndex;
159}
160
161
162
163////////////////////////////////////////////////////////////////////////////////
164/// Print the state of this object to the specified output stream.
165
167{
169
170 if (verbose) {
171 os << indent << "--- RooMultiCategory ---" << endl;
172 os << indent << " Input category list:" << endl ;
173 TString moreIndent(indent) ;
174 moreIndent.Append(" ") ;
175 _catSet.printStream(os,kName|kValue,kStandard,moreIndent.Data()) ;
176 }
177}
178
179
180////////////////////////////////////////////////////////////////////////////////
181/// Write object contents to given stream
182
183void RooMultiCategory::writeToStream(ostream& os, Bool_t compact) const
184{
186}
187
188
189////////////////////////////////////////////////////////////////////////////////
190/// Get current label. If labels haven't been computed, yet, or if the shape is
191/// dirty, a recomputation is triggered.
193 for (const auto& item : stateNames()) {
194 if (item.second == getCurrentIndex())
195 return item.first.c_str();
196 }
197
198 return "";
199}
200
201
202////////////////////////////////////////////////////////////////////////////////
203/// Inspect all the subcategories, and enumerate and name their states.
205 // Propagate up:
207
208 clearTypes();
209
210 unsigned int totalSize = 1;
211 for (const auto arg : _catSet) {
212 auto cat = static_cast<const RooAbsCategory*>(arg);
213 totalSize *= cat->size();
214 }
215
216 for (unsigned int i=0; i < totalSize; ++i) {
217 unsigned int workingIndex = i;
218 std::string catName = "{";
219 for (const auto arg : _catSet) {
220 auto cat = static_cast<const RooAbsCategory*>(arg);
221 unsigned int thisStateOrdinal = workingIndex % cat->size();
222 const auto& thisState = cat->getOrdinal(thisStateOrdinal);
223 catName += thisState.first + ';';
224 workingIndex = (workingIndex - thisStateOrdinal) / cat->size();
225 }
226 catName[catName.size()-1] = '}';
227
228 // It's important that we define the states unchecked, because for checking that name
229 // or index are available, recomputeShape() would be called.
230 defineStateUnchecked(catName, i);
231 }
232 assert(_stateNames.size() == totalSize);
233 assert(_insertionOrder.size() == totalSize);
234
235 // Possible new state numbers will invalidate all cached numbers
237}
#define coutW(a)
Definition: RooMsgService.h:32
#define coutE(a)
Definition: RooMsgService.h:33
int Int_t
Definition: RtypesCore.h:43
bool Bool_t
Definition: RtypesCore.h:61
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassImp(name)
Definition: Rtypes.h:361
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition: TGX11.cxx:109
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition: RooAbsArg.h:492
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition: RooAbsArg.h:487
RooAbsCategory is the base class for objects that represent a discrete value with a finite number of ...
virtual value_type getCurrentIndex() const
Return index number of current state.
value_type _currentIndex
void defineStateUnchecked(const std::string &label, value_type index)
Internal version of defineState() that does not check if type already exists.
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to ostream.
int value_type
The type used to denote a specific category state.
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Print info about this object to the specified stream.
std::size_t size() const
Number of states defined.
bool hasIndex(value_type index) const
Check if a state with index index exists.
std::vector< std::string > _insertionOrder
Map state names to index numbers. Make sure state names are updated in recomputeShape().
std::map< std::string, value_type > _stateNames
Current category state.
const std::map< std::string, value_type > & stateNames() const
Access the map of state names to index numbers.
void clearTypes()
Delete all currently defined states.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
RooMultiCategory connects several RooAbsCategory objects into a single category.
value_type evaluate() const override
Calculate the current value.
const char * getCurrentLabel() const override
Get current label.
std::string createLabel() const
Compile a string with all the labels of the serving categories, such as {1Jet;1Lepton;2Tag}.
virtual ~RooMultiCategory()
Destructor.
RooSetProxy _catSet
void recomputeShape() override
Inspect all the subcategories, and enumerate and name their states.
virtual void writeToStream(std::ostream &os, Bool_t compact) const override
Write object contents to given stream.
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const override
Print the state of this object to the specified output stream.
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Overloaded RooArgSet::add() method inserts 'var' into set and registers 'var' as server to owner with...
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Collectable string class.
Definition: TObjString.h:28
TString & String()
Definition: TObjString.h:48
Basic string class.
Definition: TString.h:131
const char * Data() const
Definition: TString.h:364
TString & Append(const char *cs)
Definition: TString.h:559
@ InputArguments
Definition: RooGlobalFunc.h:68
Definition: first.py:1