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,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
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 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////////////////////////////////////////////////////////////////////////////////
112/// Calculate the current value.
113/// This enumerates the states of each serving category, and calculates a unique
114/// state number. The first category occupies the state numbers \f$ 0, \ldots \mathrm{size}_\mathrm{first}-1 \f$,
115/// the second category \f$ (0, \ldots \mathrm{size}_\mathrm{second}-1) * \mathrm{size}_\mathrm{first} \f$ etc.
117{
118 value_type computedStateIndex = 0;
119 value_type multiplier = 1;
120 for (const auto arg : _catSet) {
121 auto cat = static_cast<const RooAbsCategory*>(arg);
122 if (cat->empty()) {
123 coutW(InputArguments) << __func__ << " Trying to build a multi-category state based on "
124 "a category with zero states. Fix '" << cat->GetName() << "'." << std::endl;
125 continue;
126 }
127 computedStateIndex += cat->getCurrentOrdinalNumber() * multiplier;
128 multiplier *= cat->size();
129 }
130
131 return computedStateIndex;
132}
133
134
135
136////////////////////////////////////////////////////////////////////////////////
137/// Print the state of this object to the specified output stream.
138
139void RooMultiCategory::printMultiline(ostream& os, Int_t content, bool verbose, TString indent) const
140{
142
143 if (verbose) {
144 os << indent << "--- RooMultiCategory ---" << endl;
145 os << indent << " Input category list:" << endl ;
146 TString moreIndent(indent) ;
147 moreIndent.Append(" ") ;
148 _catSet.printStream(os,kName|kValue,kStandard,moreIndent.Data()) ;
149 }
150}
151
152
153////////////////////////////////////////////////////////////////////////////////
154/// Write object contents to given stream
155
156void RooMultiCategory::writeToStream(ostream& os, bool compact) const
157{
159}
160
161
162////////////////////////////////////////////////////////////////////////////////
163/// Get current label. If labels haven't been computed, yet, or if the shape is
164/// dirty, a recomputation is triggered.
166 for (const auto& item : stateNames()) {
167 if (item.second == getCurrentIndex())
168 return item.first.c_str();
169 }
170
171 return "";
172}
173
174
175////////////////////////////////////////////////////////////////////////////////
176/// Inspect all the subcategories, and enumerate and name their states.
178 // Propagate up:
180
181 clearTypes();
182
183 unsigned int totalSize = 1;
184 for (const auto arg : _catSet) {
185 auto cat = static_cast<const RooAbsCategory*>(arg);
186 totalSize *= cat->size();
187 }
188
189 for (unsigned int i=0; i < totalSize; ++i) {
190 unsigned int workingIndex = i;
191 std::string catName = "{";
192 for (const auto arg : _catSet) {
193 auto cat = static_cast<const RooAbsCategory*>(arg);
194 unsigned int thisStateOrdinal = workingIndex % cat->size();
195 const auto& thisState = cat->getOrdinal(thisStateOrdinal);
196 catName += thisState.first + ';';
197 workingIndex = (workingIndex - thisStateOrdinal) / cat->size();
198 }
199 catName[catName.size()-1] = '}';
200
201 // It's important that we define the states unchecked, because for checking that name
202 // or index are available, recomputeShape() would be called.
203 defineStateUnchecked(catName, i);
204 }
205 assert(_stateNames.size() == totalSize);
206 assert(_insertionOrder.size() == totalSize);
207
208 // Possible new state numbers will invalidate all cached numbers
210}
#define coutW(a)
Definition: RooMsgService.h:36
#define coutE(a)
Definition: RooMsgService.h:37
#define ClassImp(name)
Definition: Rtypes.h:375
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:495
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition: RooAbsArg.h:490
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:56
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.
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.
~RooMultiCategory() override
Destructor.
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:136
const char * Data() const
Definition: TString.h:369
TString & Append(const char *cs)
Definition: TString.h:564
@ InputArguments
Definition: RooGlobalFunc.h:62
Definition: first.py:1