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
46
47
48
49////////////////////////////////////////////////////////////////////////////////
50/// Construct a product of the given set of input RooAbsCategories in `inInputCatList`.
51/// The state names of this product category are {S1;S2,S3,...Sn} where Si are the state names
52/// of the input categories.
53
54RooMultiCategory::RooMultiCategory(const char *name, const char *title, const RooArgSet& inputCategories) :
55 RooAbsCategory(name, title), _catSet("input","Input category set",this,true,true)
56{
57 // Copy category list
58 for (const auto arg : inputCategories) {
59 if (!dynamic_cast<RooAbsCategory*>(arg)) {
60 coutE(InputArguments) << "RooMultiCategory::RooMultiCategory(" << GetName() << "): input argument " << arg->GetName()
61 << " is not a RooAbsCategory" << std::endl ;
62 }
63 _catSet.add(*arg) ;
64 }
66}
67
68
69
70////////////////////////////////////////////////////////////////////////////////
71/// Copy constructor
72
74 RooAbsCategory(other,name), _catSet("input",this,other._catSet)
75{
77}
78
79////////////////////////////////////////////////////////////////////////////////
80/// Compile a string with all the labels of the serving categories,
81/// such as `{1Jet;1Lepton;2Tag}`.
83{
84 // Construct composite label name
85 std::string label;
86 bool first = true;
87 for (const auto arg : _catSet) {
88 auto cat = static_cast<const RooAbsCategory*>(arg);
89
90 label += first ? '{' : ';';
91 label += cat->getCurrentLabel();
92 first = false;
93 }
94 label += '}';
95
96 return label ;
97}
98
99
100////////////////////////////////////////////////////////////////////////////////
101/// Calculate the current value.
102/// This enumerates the states of each serving category, and calculates a unique
103/// state number. The first category occupies the state numbers \f$ 0, \ldots \mathrm{size}_\mathrm{first}-1 \f$,
104/// the second category \f$ (0, \ldots \mathrm{size}_\mathrm{second}-1) * \mathrm{size}_\mathrm{first} \f$ etc.
106{
109 for (const auto arg : _catSet) {
110 auto cat = static_cast<const RooAbsCategory*>(arg);
111 if (cat->empty()) {
112 coutW(InputArguments) << __func__ << " Trying to build a multi-category state based on "
113 "a category with zero states. Fix '" << cat->GetName() << "'." << std::endl;
114 continue;
115 }
116 computedStateIndex += cat->getCurrentOrdinalNumber() * multiplier;
117 multiplier *= cat->size();
118 }
119
120 return computedStateIndex;
121}
122
123
124
125////////////////////////////////////////////////////////////////////////////////
126/// Print the state of this object to the specified output stream.
127
128void RooMultiCategory::printMultiline(ostream& os, Int_t content, bool verbose, TString indent) const
129{
131
132 if (verbose) {
133 os << indent << "--- RooMultiCategory ---" << std::endl;
134 os << indent << " Input category list:" << std::endl ;
136 moreIndent.Append(" ") ;
138 }
139}
140
141
142////////////////////////////////////////////////////////////////////////////////
143/// Write object contents to given stream
144
145void RooMultiCategory::writeToStream(ostream& os, bool compact) const
146{
148}
149
150
151////////////////////////////////////////////////////////////////////////////////
152/// Get current label. If labels haven't been computed, yet, or if the shape is
153/// dirty, a recomputation is triggered.
155 for (const auto& item : stateNames()) {
156 if (item.second == getCurrentIndex())
157 return item.first.c_str();
158 }
159
160 return "";
161}
162
163
164////////////////////////////////////////////////////////////////////////////////
165/// Inspect all the subcategories, and enumerate and name their states.
167 // Propagate up:
169
170 clearTypes();
171
172 unsigned int totalSize = 1;
173 for (const auto arg : _catSet) {
174 auto cat = static_cast<const RooAbsCategory*>(arg);
175 totalSize *= cat->size();
176 }
177
178 for (unsigned int i=0; i < totalSize; ++i) {
179 unsigned int workingIndex = i;
180 std::string catName = "{";
181 for (const auto arg : _catSet) {
182 auto cat = static_cast<const RooAbsCategory*>(arg);
183 unsigned int thisStateOrdinal = workingIndex % cat->size();
184 const auto& thisState = cat->getOrdinal(thisStateOrdinal);
185 catName += thisState.first + ';';
186 workingIndex = (workingIndex - thisStateOrdinal) / cat->size();
187 }
188 catName[catName.size()-1] = '}';
189
190 // It's important that we define the states unchecked, because for checking that name
191 // or index are available, recomputeShape() would be called.
193 }
194 assert(_stateNames.size() == totalSize);
196
197 // Possible new state numbers will invalidate all cached numbers
199}
#define coutW(a)
#define coutE(a)
static void indent(ostringstream &buf, int indent_level)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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:49
Basic string class.
Definition TString.h:139