Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
22Connects 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 std::endl, std::ostream;
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,true,true)
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/// Compile a string with all the labels of the serving categories,
82/// such as `{1Jet;1Lepton;2Tag}`.
84{
85 // Construct composite label name
86 std::string label;
87 bool first = true;
88 for (const auto arg : _catSet) {
89 auto cat = static_cast<const RooAbsCategory*>(arg);
90
91 label += first ? '{' : ';';
92 label += cat->getCurrentLabel();
93 first = false;
94 }
95 label += '}';
96
97 return label ;
98}
99
100
101////////////////////////////////////////////////////////////////////////////////
102/// Calculate the current value.
103/// This enumerates the states of each serving category, and calculates a unique
104/// state number. The first category occupies the state numbers \f$ 0, \ldots \mathrm{size}_\mathrm{first}-1 \f$,
105/// the second category \f$ (0, \ldots \mathrm{size}_\mathrm{second}-1) * \mathrm{size}_\mathrm{first} \f$ etc.
107{
108 value_type computedStateIndex = 0;
109 value_type multiplier = 1;
110 for (const auto arg : _catSet) {
111 auto cat = static_cast<const RooAbsCategory*>(arg);
112 if (cat->empty()) {
113 coutW(InputArguments) << __func__ << " Trying to build a multi-category state based on "
114 "a category with zero states. Fix '" << cat->GetName() << "'." << std::endl;
115 continue;
116 }
117 computedStateIndex += cat->getCurrentOrdinalNumber() * multiplier;
118 multiplier *= cat->size();
119 }
120
121 return computedStateIndex;
122}
123
124
125
126////////////////////////////////////////////////////////////////////////////////
127/// Print the state of this object to the specified output stream.
128
129void RooMultiCategory::printMultiline(ostream& os, Int_t content, bool verbose, TString indent) const
130{
131 RooAbsCategory::printMultiline(os,content,verbose,indent) ;
132
133 if (verbose) {
134 os << indent << "--- RooMultiCategory ---" << endl;
135 os << indent << " Input category list:" << endl ;
136 TString moreIndent(indent) ;
137 moreIndent.Append(" ") ;
138 _catSet.printStream(os,kName|kValue,kStandard,moreIndent.Data()) ;
139 }
140}
141
142
143////////////////////////////////////////////////////////////////////////////////
144/// Write object contents to given stream
145
146void RooMultiCategory::writeToStream(ostream& os, bool compact) const
147{
149}
150
151
152////////////////////////////////////////////////////////////////////////////////
153/// Get current label. If labels haven't been computed, yet, or if the shape is
154/// dirty, a recomputation is triggered.
156 for (const auto& item : stateNames()) {
157 if (item.second == getCurrentIndex())
158 return item.first.c_str();
159 }
160
161 return "";
162}
163
164
165////////////////////////////////////////////////////////////////////////////////
166/// Inspect all the subcategories, and enumerate and name their states.
168 // Propagate up:
170
171 clearTypes();
172
173 unsigned int totalSize = 1;
174 for (const auto arg : _catSet) {
175 auto cat = static_cast<const RooAbsCategory*>(arg);
176 totalSize *= cat->size();
177 }
178
179 for (unsigned int i=0; i < totalSize; ++i) {
180 unsigned int workingIndex = i;
181 std::string catName = "{";
182 for (const auto arg : _catSet) {
183 auto cat = static_cast<const RooAbsCategory*>(arg);
184 unsigned int thisStateOrdinal = workingIndex % cat->size();
185 const auto& thisState = cat->getOrdinal(thisStateOrdinal);
186 catName += thisState.first + ';';
187 workingIndex = (workingIndex - thisStateOrdinal) / cat->size();
188 }
189 catName[catName.size()-1] = '}';
190
191 // It's important that we define the states unchecked, because for checking that name
192 // or index are available, recomputeShape() would be called.
193 defineStateUnchecked(catName, i);
194 }
195 assert(_stateNames.size() == totalSize);
196 assert(_insertionOrder.size() == totalSize);
197
198 // Possible new state numbers will invalidate all cached numbers
200}
#define coutW(a)
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:382
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition TGX11.cxx:110
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition RooAbsArg.h:436
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:431
A space to attach TBranches.
virtual value_type getCurrentIndex() const
Return index number of current state.
void defineStateUnchecked(const std::string &label, value_type index)
Internal version of defineState() that does not check if type already exists.
void writeToStream(std::ostream &os, bool compact) const override
Write object contents to ostream.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print info about this object to the specified stream.
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:24
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...
Connects several RooAbsCategory objects into a single category.
value_type evaluate() const override
Calculate the current value.
void printMultiline(std::ostream &os, Int_t content, bool verbose=false, TString indent="") const override
Print the state of this object to the specified output stream.
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 writeToStream(std::ostream &os, bool compact) const override
Write object contents to given stream.
void recomputeShape() override
Inspect all the subcategories, and enumerate and name their states.
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
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:376
TString & Append(const char *cs)
Definition TString.h:572