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 
22 RooMultiCategory connects several RooAbsCategory objects into
23 a single category. The states of the multi-category consist of all the permutations
24 of the input categories.
25 RooMultiCategory states are automatically defined and updated whenever an input
26 category modifies its list of states.
27 
28 A RooMultiCategory is not an lvalue, *i.e.* one cannot set its states. Its state simply follows
29 as a computation from the states of the input categories. This is because the input categories
30 don't need to be lvalues, so their states cannot be set by the MultiCategory. If all input categories
31 are lvalues, the RooSuperCategory can be used. It works like RooMultiCategory, but allows for
32 setting 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 
45 using 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 
56 RooMultiCategory::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  }
67  setShapeDirty();
68 }
69 
70 
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Copy constructor
74 
76  RooAbsCategory(other,name), _catSet("input",this,other._catSet)
77 {
78  setShapeDirty();
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}`.
94 std::string RooMultiCategory::createLabel() const
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 
115 namespace {
116 /// Check that root-6.22 redesign of category interfaces yields same labels
117 std::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 
183 void RooMultiCategory::writeToStream(ostream& os, Bool_t compact) const
184 {
185  RooAbsCategory::writeToStream(os,compact) ;
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:
206  setShapeDirty();
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
236  setValueDirty();
237 }
RooStreamParser.h
RooMultiCategory::recomputeShape
void recomputeShape() override
Inspect all the subcategories, and enumerate and name their states.
Definition: RooMultiCategory.cxx:204
RooSetProxy::add
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...
Definition: RooSetProxy.cxx:165
first
Definition: first.py:1
RooMultiCategory::_catSet
RooSetProxy _catSet
Definition: RooMultiCategory.h:53
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
RooMsgService.h
RooMultiCategory::~RooMultiCategory
virtual ~RooMultiCategory()
Destructor.
Definition: RooMultiCategory.cxx:86
RooAbsCategory::defineStateUnchecked
void defineStateUnchecked(const std::string &label, value_type index)
Internal version of defineState() that does not check if type already exists.
Definition: RooAbsCategory.cxx:217
RooAbsCategory::getCurrentIndex
virtual value_type getCurrentIndex() const
Return index number of current state.
Definition: RooAbsCategory.cxx:110
RooFit.h
RooMultiCatIter
Definition: RooMultiCatIter.h:29
RooFit::InputArguments
@ InputArguments
Definition: RooGlobalFunc.h:68
RooAbsCategory::writeToStream
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to ostream.
Definition: RooAbsCategory.cxx:378
RooArgSet.h
TString::Data
const char * Data() const
Definition: TString.h:369
RooPrintable::kStandard
@ kStandard
Definition: RooPrintable.h:34
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
coutE
#define coutE(a)
Definition: RooMsgService.h:33
coutW
#define coutW(a)
Definition: RooMsgService.h:32
indent
static void indent(ostringstream &buf, int indent_level)
Definition: TClingCallFunc.cxx:87
TString
Definition: TString.h:136
TString.h
RooMultiCategory::RooMultiCategory
RooMultiCategory()
Definition: RooMultiCategory.h:31
bool
TObjString::String
TString & String()
Definition: TObjString.h:54
RooMultiCategory::getCurrentLabel
const char * getCurrentLabel() const override
Get current label.
Definition: RooMultiCategory.cxx:192
RooAbsCategory
Definition: RooAbsCategory.h:38
TObjString
Definition: TObjString.h:28
RooAbsCategory::hasIndex
bool hasIndex(value_type index) const
Check if a state with index index exists.
Definition: RooAbsCategory.cxx:183
RooPrintable::kName
@ kName
Definition: RooPrintable.h:33
RooMultiCategory
Definition: RooMultiCategory.h:28
RooMultiCategory.h
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
RooAbsCategory::_stateNames
std::map< std::string, value_type > _stateNames
Current category state.
Definition: RooAbsCategory.h:222
RooMultiCategory::writeToStream
virtual void writeToStream(std::ostream &os, Bool_t compact) const override
Write object contents to given stream.
Definition: RooMultiCategory.cxx:183
RooMultiCategory::createLabel
std::string createLabel() const
Compile a string with all the labels of the serving categories, such as {1Jet;1Lepton;2Tag}.
Definition: RooMultiCategory.cxx:94
RooAbsCategory::_currentIndex
value_type _currentIndex
Definition: RooAbsCategory.h:221
RooPrintable::kValue
@ kValue
Definition: RooPrintable.h:33
RooMultiCategory::printMultiline
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.
Definition: RooMultiCategory.cxx:166
RooAbsCategory::printMultiline
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.
Definition: RooAbsCategory.cxx:401
RooAbsCategory::_insertionOrder
std::vector< std::string > _insertionOrder
Map state names to index numbers. Make sure state names are updated in recomputeShape().
Definition: RooAbsCategory.h:223
RooAbsCategory.h
RooAbsArg::setShapeDirty
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition: RooAbsArg.h:510
RooMultiCategory::evaluate
value_type evaluate() const override
Calculate the current value.
Definition: RooMultiCategory.cxx:137
name
char name[80]
Definition: TGX11.cxx:110
RooAbsCategory::stateNames
const std::map< std::string, value_type > & stateNames() const
Access the map of state names to index numbers.
Definition: RooAbsCategory.h:164
RooPrintable::printStream
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,...
Definition: RooPrintable.cxx:75
genreflex::verbose
bool verbose
Definition: rootcling_impl.cxx:133
RooAbsArg::setValueDirty
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition: RooAbsArg.h:505
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:53
RooMultiCatIter.h
RooAbsCategory::clearTypes
void clearTypes()
Delete all currently defined states.
Definition: RooAbsCategory.cxx:265
RooArgSet
Definition: RooArgSet.h:28
int