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 "RooStreamParser.h"
38#include "RooArgSet.h"
39#include "RooAbsCategory.h"
40#include "RooMsgService.h"
41
42#include "TString.h"
43
44using namespace std;
45
47
48
49
50////////////////////////////////////////////////////////////////////////////////
51/// Construct a product of the given set of input RooAbsCategories in `inInputCatList`.
52/// The state names of this product category are {S1;S2,S3,...Sn} where Si are the state names
53/// of the input categories.
54
55RooMultiCategory::RooMultiCategory(const char *name, const char *title, const RooArgSet& inputCategories) :
56 RooAbsCategory(name, title), _catSet("input","Input category set",this,kTRUE,kTRUE)
57{
58 // Copy category list
59 for (const auto arg : inputCategories) {
60 if (!dynamic_cast<RooAbsCategory*>(arg)) {
61 coutE(InputArguments) << "RooMultiCategory::RooMultiCategory(" << GetName() << "): input argument " << arg->GetName()
62 << " is not a RooAbsCategory" << endl ;
63 }
64 _catSet.add(*arg) ;
65 }
67}
68
69
70
71////////////////////////////////////////////////////////////////////////////////
72/// Copy constructor
73
75 RooAbsCategory(other,name), _catSet("input",this,other._catSet)
76{
78}
79
80
81
82////////////////////////////////////////////////////////////////////////////////
83/// Destructor
84
86{
87}
88
89
90////////////////////////////////////////////////////////////////////////////////
91/// Compile a string with all the labels of the serving categories,
92/// such as `{1Jet;1Lepton;2Tag}`.
94{
95 // Construct composite label name
96 std::string label;
97 Bool_t first = true;
98 for (const auto arg : _catSet) {
99 auto cat = static_cast<const RooAbsCategory*>(arg);
100
101 label += first ? '{' : ';';
102 label += cat->getCurrentLabel();
103 first = false;
104 }
105 label += '}';
106
107 return label ;
108}
109
110
111#ifndef NDEBUG
112
114namespace {
115/// Check that root-6.22 redesign of category interfaces yields same labels
116std::string computeLabelOldStyle(const RooArgSet& catSet, unsigned int index) {
117 RooMultiCatIter iter(catSet) ;
118 TObjString* obj ;
119 for (unsigned int i=0; (obj=(TObjString*)iter.Next()); ++i) {
120 if (i == index) {
121 return obj->String().Data();
122 }
123 }
124
125 return {};
126}
127}
128#endif
129
130
131////////////////////////////////////////////////////////////////////////////////
132/// Calculate the current value.
133/// This enumerates the states of each serving category, and calculates a unique
134/// state number. The first category occupies the state numbers \f$ 0, \ldots \mathrm{size}_\mathrm{first}-1 \f$,
135/// the second category \f$ (0, \ldots \mathrm{size}_\mathrm{second}-1) * \mathrm{size}_\mathrm{first} \f$ etc.
137{
138 value_type computedStateIndex = 0;
139 value_type multiplier = 1;
140 for (const auto arg : _catSet) {
141 auto cat = static_cast<const RooAbsCategory*>(arg);
142 if (cat->size() == 0) {
143 coutW(InputArguments) << __func__ << " Trying to build a multi-category state based on "
144 "a category with zero states. Fix '" << cat->GetName() << "'." << std::endl;
145 continue;
146 }
147 computedStateIndex += cat->getCurrentOrdinalNumber() * multiplier;
148 multiplier *= cat->size();
149 }
150
151#ifndef NDEBUG
152 assert(hasIndex(computedStateIndex));
153 _currentIndex = computedStateIndex;
154 assert(createLabel() == computeLabelOldStyle(_catSet, computedStateIndex));
155#endif
156
157 return computedStateIndex;
158}
159
160
161
162////////////////////////////////////////////////////////////////////////////////
163/// Print the state of this object to the specified output stream.
164
166{
168
169 if (verbose) {
170 os << indent << "--- RooMultiCategory ---" << endl;
171 os << indent << " Input category list:" << endl ;
172 TString moreIndent(indent) ;
173 moreIndent.Append(" ") ;
174 _catSet.printStream(os,kName|kValue,kStandard,moreIndent.Data()) ;
175 }
176}
177
178
179////////////////////////////////////////////////////////////////////////////////
180/// Write object contents to given stream
181
182void RooMultiCategory::writeToStream(ostream& os, Bool_t compact) const
183{
185}
186
187
188////////////////////////////////////////////////////////////////////////////////
189/// Get current label. If labels haven't been computed, yet, or if the shape is
190/// dirty, a recomputation is triggered.
192 for (const auto& item : stateNames()) {
193 if (item.second == getCurrentIndex())
194 return item.first.c_str();
195 }
196
197 return "";
198}
199
200
201////////////////////////////////////////////////////////////////////////////////
202/// Inspect all the subcategories, and enumerate and name their states.
204 // Propagate up:
206
207 clearTypes();
208
209 unsigned int totalSize = 1;
210 for (const auto arg : _catSet) {
211 auto cat = static_cast<const RooAbsCategory*>(arg);
212 totalSize *= cat->size();
213 }
214
215 for (unsigned int i=0; i < totalSize; ++i) {
216 unsigned int workingIndex = i;
217 std::string catName = "{";
218 for (const auto arg : _catSet) {
219 auto cat = static_cast<const RooAbsCategory*>(arg);
220 unsigned int thisStateOrdinal = workingIndex % cat->size();
221 const auto& thisState = cat->getOrdinal(thisStateOrdinal);
222 catName += thisState.first + ';';
223 workingIndex = (workingIndex - thisStateOrdinal) / cat->size();
224 }
225 catName[catName.size()-1] = '}';
226
227 // It's important that we define the states unchecked, because for checking that name
228 // or index are available, recomputeShape() would be called.
229 defineStateUnchecked(catName, i);
230 }
231 assert(_stateNames.size() == totalSize);
232 assert(_insertionOrder.size() == totalSize);
233
234 // Possible new state numbers will invalidate all cached numbers
236}
#define coutW(a)
Definition: RooMsgService.h:32
#define coutE(a)
Definition: RooMsgService.h:33
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
char name[80]
Definition: TGX11.cxx:110
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition: RooAbsArg.h:519
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition: RooAbsArg.h:514
A space to attach TBranches.
virtual value_type getCurrentIndex() const
Return index number of current state.
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const override
Print info about this object to the specified stream.
void writeToStream(std::ostream &os, Bool_t compact) const override
Write object contents to ostream.
value_type _currentIndex
Current category state.
void defineStateUnchecked(const std::string &label, value_type index)
Internal version of defineState() that does not check if type already exists.
bool hasIndex(value_type index) const
Check if a state with index index exists.
std::vector< std::string > _insertionOrder
Keeps track in which order state numbers have been inserted. Make sure this is updated in recomputeSh...
std::map< std::string, value_type > _stateNames
Map state names to index numbers. Make sure state names are updated in recomputeShape().
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:57
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
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}.
RooSetProxy _catSet
Set of input category.
void recomputeShape() override
Inspect all the subcategories, and enumerate and name their states.
~RooMultiCategory() override
Destructor.
void writeToStream(std::ostream &os, Bool_t compact) const override
Write object contents to given stream.
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,...
const char * GetName() const override
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:136
const char * Data() const
Definition: TString.h:369
TString & Append(const char *cs)
Definition: TString.h:564
@ InputArguments
Definition: RooGlobalFunc.h:64
Definition: first.py:1