Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooAbsCategory.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 RooAbsCategory.cxx
19\class RooAbsCategory
20\ingroup Roofitcore
21
22RooAbsCategory is the base class for objects that represent a discrete value with a finite number of states.
23
24Each state is denoted by an integer and a name. Both can be used to retrieve and
25set states, but referring to states by index is more efficient. Conversion between
26index and name can be done using lookupName() or lookupIndex().
27It is possible to iterate through all defined states using begin() and end().
28
29For category classes deriving from RooAbsCategory, states can only be evaluated, *i.e.*, queried.
30Refer to RooAbsCategoryLValue and its derived classes for categories where states can also be set. The
31simplest category class whose states can be set, queried and saved in a dataset, refer to RooCategory.
32
33### Interface change in ROOT-6.22
34Category data were based in the class RooCatType, holding an index state and a category name truncated to 256
35characters. This wastes 64 bytes of storage space per entry, and prevents fast retrieval of category data.
36Since ROOT-6.22, categories are only represented by an integer. RooAbsCategory::lookupName() can be used to
37retrieve the corresponding state name. There is no limit for the length of the state name.
38
39To not break old code, the old RooCatType interfaces are still available. Whenever possible,
40the following replacements should be used:
41- lookupType() \f$ \rightarrow \f$ lookupName() / lookupIndex()
42- typeIterator() \f$ \rightarrow \f$ range-based for loop / begin() / end()
43- isValidIndex(Int_t index) \f$ \rightarrow \f$ hasIndex()
44- isValid(const RooCatType&) \f$ \rightarrow \f$ hasIndex() / hasLabel()
45**/
46
47#include "RooAbsCategory.h"
48
49#include "RooArgSet.h"
50#include "Roo1DTable.h"
51#include "RooCategory.h"
52#include "RooMsgService.h"
53#include "RooVectorDataStore.h"
55#include "TreeReadBuffer.h"
56
57#include "Compression.h"
58#include "TString.h"
59#include "TTree.h"
60#include "TLeaf.h"
61#include "TBranch.h"
62
63#include <functional>
64#include <memory>
65
67
68/// A category state to signify an invalid category. The category name is empty,
69/// the index is the minimal int.
71 static const decltype(RooAbsCategory::_stateNames)::value_type invalid{"", std::numeric_limits<value_type>::min()};
72 return invalid;
73}
74
75
77
78
79////////////////////////////////////////////////////////////////////////////////
80/// Constructor
81
82RooAbsCategory::RooAbsCategory(const char *name, const char *title) :
83 RooAbsArg(name,title), _currentIndex(0)
84{
87}
88
89
90
91////////////////////////////////////////////////////////////////////////////////
92/// Copy constructor, copies the registered category states from the original.
93
95 RooAbsArg(other,name), _currentIndex(other._currentIndex),
96 _stateNames(other._stateNames),
97 _insertionOrder(other._insertionOrder)
98{
100 setShapeDirty() ;
101}
102
103
104
105////////////////////////////////////////////////////////////////////////////////
106/// Destructor
107
109{
110
111}
112
113
114
115////////////////////////////////////////////////////////////////////////////////
116/// Return index number of current state
117
119{
120 if (isValueDirty() || isShapeDirty()) {
122
124 }
125
126 return _currentIndex;
127}
128
129
130
131////////////////////////////////////////////////////////////////////////////////
132/// Return label string of current state.
133
135{
136 const auto index = getCurrentIndex();
137 for (const auto& item : stateNames()) {
138 if (item.second == index)
139 return item.first.c_str();
140 }
141
142 return "";
143}
144
145
146////////////////////////////////////////////////////////////////////////////////
147/// Equality operator with a integer (compares with state index number)
148
150{
151 return (index==getCurrentIndex()) ;
152}
153
154
155
156////////////////////////////////////////////////////////////////////////////////
157/// Equality operator with a string (compares with state label string)
158
159bool RooAbsCategory::operator==(const char* label) const
160{
161 return strcmp(label, getCurrentLabel()) == 0;
162}
163
164
165
166////////////////////////////////////////////////////////////////////////////////
167/// Equality operator with another RooAbsArg. Only functional
168/// is also a RooAbsCategory, will return true if index is the same
169
170bool RooAbsCategory::operator==(const RooAbsArg& other) const
171{
172 const RooAbsCategory* otherCat = dynamic_cast<const RooAbsCategory*>(&other) ;
173 return otherCat ? operator==(otherCat->getCurrentIndex()) : false ;
174}
175
176
177////////////////////////////////////////////////////////////////////////////////
178
179bool RooAbsCategory::isIdentical(const RooAbsArg& other, bool assumeSameType) const
180{
181 if (!assumeSameType) {
182 const RooAbsCategory* otherCat = dynamic_cast<const RooAbsCategory*>(&other) ;
183 return otherCat ? operator==(otherCat->getCurrentIndex()) : false ;
184 } else {
185 return getCurrentIndex() == static_cast<const RooAbsCategory&>(other).getCurrentIndex();
186 }
187}
188
189
190////////////////////////////////////////////////////////////////////////////////
191/// Check if a state with index `index` exists.
193{
194 for (const auto& item : stateNames()) {
195 if (item.second == index)
196 return true;
197 }
198
199 return false;
200}
201
202
203////////////////////////////////////////////////////////////////////////////////
204/// Look up the name corresponding to the given index.
205const std::string& RooAbsCategory::lookupName(value_type index) const {
206 for (const auto& item : stateNames()) {
207 if (item.second == index)
208 return item.first;
209 }
210
211 return invalidCategory().first;
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// Define a new state with given label. The next available
216/// integer is assigned as index value.
217const std::map<std::string, RooAbsCategory::value_type>::value_type& RooAbsCategory::defineState(const std::string& label)
218{
219 return defineState(label, nextAvailableStateIndex());
220}
221
222
223////////////////////////////////////////////////////////////////////////////////
224/// Internal version of defineState() that does not check if type
225/// already exists
227{
228 _stateNames.emplace(label, index);
229 _insertionOrder.push_back(label);
230
231 if (_stateNames.size() == 1)
233
235}
236
237
238
239////////////////////////////////////////////////////////////////////////////////
240/// Define new state with given name and index number.
241
242const std::map<std::string, RooAbsCategory::value_type>::value_type& RooAbsCategory::defineState(const std::string& label, RooAbsCategory::value_type index)
243{
244 auto& theStateNames = stateNames();
245
246 if (hasIndex(index)) {
247 coutE(InputArguments) << "RooAbsCategory::" << __func__ << "(" << GetName() << "): index "
248 << index << " already assigned" << std::endl;
249 return invalidCategory();
250 }
251
252 if (hasLabel(label)) {
253 coutE(InputArguments) << "RooAbsCategory::" << __func__ << "(" << GetName() << "): label "
254 << label << " already assigned or not allowed" << std::endl;
255 return invalidCategory();
256 }
257
258 const auto result = theStateNames.emplace(label, index);
259 _insertionOrder.push_back(label);
260
261 if (theStateNames.size() == 1)
263
265
266 return *(result.first);
267}
268
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Delete all currently defined states
273
275{
276 _stateNames.clear();
277 _insertionOrder.clear();
279 setShapeDirty() ;
280}
281
282
283////////////////////////////////////////////////////////////////////////////////
284/// Find the index number corresponding to the state name.
285/// \see hasLabel() for checking if a given label has been defined.
286/// \return Index of the category or std::numeric_limits<int>::min() on failure.
287RooAbsCategory::value_type RooAbsCategory::lookupIndex(const std::string& stateName) const {
288 const auto item = stateNames().find(stateName);
289 if (item != stateNames().end()) {
290 return item->second;
291 }
292
293 return invalidCategory().second;
294}
295
296////////////////////////////////////////////////////////////////////////////////
297/// Find our type that matches the specified type, or return 0 for no match.
298/// \deprecated RooCatType is not used, any more. This function will create one and let it leak.
299/// Use lookupIndex() (preferred) or lookupName() instead.
300const RooCatType* RooAbsCategory::lookupType(const RooCatType &other, bool printError) const
301{
302 return lookupType(other.getVal(), printError);
303}
304
305
306
307////////////////////////////////////////////////////////////////////////////////
308/// Find our type corresponding to the specified index, or return nullptr for no match.
309/// \deprecated RooCatType is not used, any more. This function will create one and let it leak.
310/// Use lookupIndex() (preferred) or lookupName() instead.
312{
313 for (const auto& item : stateNames())
314 if (item.second == index) {
316 }
317
318 if (printError) {
319 coutE(InputArguments) << ClassName() << "::" << GetName() << ":lookupType: no match for index "
320 << index << std::endl;
321 }
322
323 return nullptr;
324}
325
326
327
328////////////////////////////////////////////////////////////////////////////////
329/// Find our type corresponding to the specified label, or return 0 for no match.
330/// \deprecated RooCatType is not used, any more. This function will create one and let it leak.
331/// Use lookupIndex() (preferred) or lookupName() instead.
332const RooCatType* RooAbsCategory::lookupType(const char* label, bool printError) const
333{
334 for (const auto& type : stateNames()) {
335 if(type.first == label)
336 return retrieveLegacyState(type.second);
337 }
338
339 // Try if label represents integer number
340 char* endptr ;
341 RooAbsCategory::value_type idx=strtol(label,&endptr,10) ;
342 if (endptr==label+strlen(label)) {
343 return lookupType(idx);
344 }
345
346 if (printError) {
347 coutE(InputArguments) << ClassName() << "::" << GetName() << ":lookupType: no match for label "
348 << label << std::endl;
349 }
350 return nullptr;
351}
352
353
354////////////////////////////////////////////////////////////////////////////////
355/// Check if given state is defined for this object
356
358{
359 return hasIndex(value.getVal()) ;
360}
361
362
363
364////////////////////////////////////////////////////////////////////////////////
365/// Create a table matching the shape of this category
366
368{
369 return new Roo1DTable(GetName(),label,*this) ;
370}
371
372
373
374////////////////////////////////////////////////////////////////////////////////
375/// Read object contents from stream (dummy for now)
376
377bool RooAbsCategory::readFromStream(std::istream&, bool, bool)
378{
379 return false ;
380}
381
382
383
384////////////////////////////////////////////////////////////////////////////////
385/// Write object contents to ostream
386
387void RooAbsCategory::writeToStream(std::ostream& os, bool /* compact */) const
388{
389 os << getCurrentLabel() ;
390}
391
392
393
394////////////////////////////////////////////////////////////////////////////////
395/// Print value (label name)
396
397void RooAbsCategory::printValue(std::ostream& os) const
398{
399 os << getCurrentLabel() << "(idx = " << getCurrentIndex() << ")" << std::endl;
400}
401
402
403
404////////////////////////////////////////////////////////////////////////////////
405/// Print info about this object to the specified stream. In addition to the info
406/// from RooAbsArg::printStream() we add:
407///
408/// Shape : label, index, defined types
409
410void RooAbsCategory::printMultiline(std::ostream& os, Int_t contents, bool verbose, TString indent) const
411{
412 RooAbsArg::printMultiline(os,contents,verbose,indent);
413
414 os << indent << "--- RooAbsCategory ---" << std::endl;
415 if (stateNames().empty()) {
416 os << indent << " ** No values defined **" << std::endl;
417 return;
418 }
419 os << indent << " Value = " << getCurrentIndex() << " \"" << getCurrentLabel() << ')' << std::endl;
420 os << indent << " Possible states:" << std::endl;
421 indent.Append(" ");
422 for (const auto& type : stateNames()) {
423 os << indent << type.first << '\t' << type.second << "\n";
424 }
425}
426
427
428
429////////////////////////////////////////////////////////////////////////////////
430/// Attach the category index and label to as branches to the given vector store
431
433{
434 RooVectorDataStore::CatVector* cv = vstore.addCategory(this) ;
436}
437
438
439
440
441////////////////////////////////////////////////////////////////////////////////
442/// Attach the category index and label as branches to the given
443/// TTree. The index field will be attached as integer with name
444/// `<name>_idx`. If a branch `<name>` exists, it attaches to this branch.
446{
447 // First check if there is an integer branch matching the category name
448 std::string cleanName = cleanBranchName().Data();
449 TBranch* branch = tree.GetBranch(cleanName.c_str());
450 if (!branch) {
451 cleanName += "_idx";
452 branch = tree.GetBranch(cleanName.c_str());
453 }
454
455 if (branch) {
456 TLeaf* leaf = static_cast<TLeaf*>(branch->GetListOfLeaves()->At(0));
457
458 // Check that leaf is _not_ an array
459 Int_t dummy ;
460 TLeaf* counterLeaf = leaf->GetLeafCounter(dummy) ;
461 if (counterLeaf) {
462 coutE(Eval) << "RooAbsCategory::attachToTree(" << GetName() << ") ERROR: TTree branch " << GetName()
463 << " is an array and cannot be attached to a RooAbsCategory" << std::endl;
464 return ;
465 }
466
467 const std::string typeName = leaf->GetTypeName();
468
469
470 // For different type names, store a function to attach
471 std::map<std::string, std::function<std::unique_ptr<TreeReadBuffer>()>> typeMap {
472 {"Float_t", [&](){ return createTreeReadBuffer<Float_t >(cleanName, tree); }},
473 {"Double_t", [&](){ return createTreeReadBuffer<Double_t >(cleanName, tree); }},
474 {"UChar_t", [&](){ return createTreeReadBuffer<UChar_t >(cleanName, tree); }},
475 {"Boolt_", [&](){ return createTreeReadBuffer<Bool_t >(cleanName, tree); }},
476 {"Char_t", [&](){ return createTreeReadBuffer<Char_t >(cleanName, tree); }},
477 {"UInt_t", [&](){ return createTreeReadBuffer<UInt_t >(cleanName, tree); }},
478 {"Long64_t", [&](){ return createTreeReadBuffer<Long64_t >(cleanName, tree); }},
479 {"ULong64_t", [&](){ return createTreeReadBuffer<ULong64_t>(cleanName, tree); }},
480 {"Short_t", [&](){ return createTreeReadBuffer<Short_t >(cleanName, tree); }},
481 {"UShort_t", [&](){ return createTreeReadBuffer<UShort_t >(cleanName, tree); }},
482 };
483
484 auto typeDetails = typeMap.find(typeName);
485 if (typeDetails != typeMap.end()) {
486 coutI(DataHandling) << "RooAbsCategory::attachToTree(" << GetName() << ") TTree " << typeName << " branch \"" << cleanName
487 << "\" will be converted to int." << std::endl;
488 _treeReadBuffer = typeDetails->second();
489 } else {
490 _treeReadBuffer = nullptr;
491
492 if (typeName == "Int_t") {
493 tree.SetBranchAddress(cleanName.c_str(), &_currentIndex);
494 }
495 else {
496 coutE(InputArguments) << "RooAbsCategory::attachToTree(" << GetName() << ") data type " << typeName << " is not supported." << std::endl;
497 }
498 }
499 } else {
500 void* ptr = &_currentIndex;
501 tree.Branch(cleanName.c_str(), ptr, (cleanName + "/I").c_str(), bufSize);
502 }
503}
504
505
506
507////////////////////////////////////////////////////////////////////////////////
508/// Fill tree branches associated with current object with current value
509
511{
512 // First determine if branch is taken
513 TBranch* idxBranch = t.GetBranch((std::string(GetName()) + "_idx").c_str()) ;
514 if (!idxBranch) {
515 coutF(DataHandling) << "RooAbsCategory::fillTreeBranch(" << GetName() << ") ERROR: not attached to tree" << std::endl;
516 throw std::runtime_error("RooAbsCategory::fillTreeBranch(): Category is not attached to a tree.");
517 }
518
519 idxBranch->Fill() ;
520}
521
522
523
524////////////////////////////////////////////////////////////////////////////////
525/// (De)activate associate tree branch
526
528{
529 TBranch* branch = t.GetBranch(Form("%s_idx",GetName())) ;
530 if (branch) {
531 t.SetBranchStatus(Form("%s_idx",GetName()),active?1:0) ;
532 }
533}
534
535
536
537////////////////////////////////////////////////////////////////////////////////
538/// Explicitly synchronize RooAbsCategory internal cache
539
541{
543}
544
545
546
547////////////////////////////////////////////////////////////////////////////////
548/// Copy the cached value from given source and raise dirty flag.
549/// It is the callers responsibility to ensure that the sources
550/// cache is clean(valid) before this function is called, e.g. by
551/// calling syncCache() on the source.
552
553void RooAbsCategory::copyCache(const RooAbsArg *source, bool /*valueOnly*/, bool setValDirty)
554{
555 auto other = static_cast<const RooAbsCategory*>(source);
556 assert(dynamic_cast<const RooAbsCategory*>(source));
557
558 _currentIndex = other->_treeReadBuffer ? *other->_treeReadBuffer : other->_currentIndex;
559
560 if (setValDirty) {
562 }
563}
564
565
566////////////////////////////////////////////////////////////////////////////////
567/// Overwrite the value stored in this object's cache.
568/// This can be used to fake a computation that resulted in `value`.
569/// \param[in] value Value to write. The argument is reinterpreted as a category state.
570/// If such a state does not exist, this will create undefined behaviour.
571/// \param[in] notifyClients If true, notify users of this object that its value changed.
572/// This is the default.
573void RooAbsCategory::setCachedValue(double value, bool notifyClients) {
574 _currentIndex = static_cast<value_type>(value);
575
576 if (notifyClients) {
578 _valueDirty = false;
579 }
580}
581
582
583////////////////////////////////////////////////////////////////////////////////
584/// Return name and index of the `n`th defined state. When states are defined using
585/// defineType() or operator[], the order of insertion is tracked, to mimic the behaviour
586/// before modernising the category classes.
587/// When directly manipulating the map with state names using states(), the order of insertion
588/// is not known, so alphabetical ordering as usual for std::map is used. The latter is faster.
589/// \param[in] n Number of state to be retrieved.
590/// \return A pair with name and index.
591const std::map<std::string, RooAbsCategory::value_type>::value_type& RooAbsCategory::getOrdinal(unsigned int n) const {
592 // Retrieve state names, trigger possible recomputation
593 auto& theStateNames = stateNames();
594
595 if (n >= theStateNames.size())
596 return invalidCategory();
597
598 if (theStateNames.size() != _insertionOrder.size())
599 return *std::next(theStateNames.begin(), n);
600
601 const auto item = theStateNames.find(_insertionOrder[n]);
602 if (item != theStateNames.end())
603 return *item;
604
605 return invalidCategory();
606}
607
608
609////////////////////////////////////////////////////////////////////////////////
610/// Return ordinal number of the current state.
612 // Retrieve state names, trigger possible recomputation
613 auto& theStateNames = stateNames();
614
615 // If we don't have the full history of inserted state names, have to go by map ordering:
616 if (theStateNames.size() != _insertionOrder.size()) {
617 const auto currentIndex = getCurrentIndex();
618 for (auto it = theStateNames.begin(); it != theStateNames.end(); ++it) {
619 if (it->second == currentIndex)
620 return std::distance(theStateNames.begin(), it);
621 }
622 }
623
624 // With full insertion history, find index of current label:
625 auto item = std::find(_insertionOrder.begin(), _insertionOrder.end(), getCurrentLabel());
626 assert(item != _insertionOrder.end());
627
628 return item - _insertionOrder.begin();
629}
630
631
632////////////////////////////////////////////////////////////////////////////////
633/// Create a RooCategory fundamental object with our properties.
634
636{
637 // Add and precalculate new category column
638 RooCategory *fund= new RooCategory(newname?newname:GetName(),GetTitle()) ;
639
640 // Copy states
641 for (const auto& type : stateNames()) {
642 fund->defineStateUnchecked(type.first, type.second);
643 }
644
645 return fund;
646}
647
648
649
650////////////////////////////////////////////////////////////////////////////////
651/// Determine if category has 2 or 3 states with index values -1,0,1
652
653bool RooAbsCategory::isSignType(bool mustHaveZero) const
654{
655 const auto& theStateNames = stateNames();
656
657 if (theStateNames.size() > 3 || theStateNames.size() < 2) return false;
658 if (mustHaveZero && theStateNames.size() != 3) return false;
659
660 for (const auto& type : theStateNames) {
661 if (std::abs(type.second)>1)
662 return false;
663 }
664
665 return true;
666}
667
668/// \deprecated Use begin() and end() instead.
669/// \note Using this iterator creates useless RooCatType instances, which will leak
670/// unless deleted by the user.
673}
674
675const RooCatType* RooAbsCategory::defineType(const char* label) {
676 defineState(label);
677 return retrieveLegacyState(stateNames()[label]);
678}
679
680const RooCatType* RooAbsCategory::defineType(const char* label, int index) {
681 defineState(label, index);
683}
684
688}
689
690/// Return the legacy RooCatType corresponding to `index`. If it doesn't exist, create one.
692 auto result = _legacyStates.find(index);
693 if (result == _legacyStates.end()) {
694 result = _legacyStates.emplace(index,
695 std::make_unique<RooCatType>(lookupName(index).c_str(), index)).first;
696 }
697
698 return result->second.get();
699}
700
701
703 const auto& theStateNames = stateNames();
704
705 if (theStateNames.empty())
706 return 0;
707
708 return 1 + std::max_element(theStateNames.begin(), theStateNames.end(),
709 [](auto const& left, auto const& right) { return left.second < right.second; })->second;
710}
#define coutI(a)
#define coutF(a)
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:377
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 Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
Roo1DTable implements a one-dimensional table.
Definition Roo1DTable.h:23
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:74
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition RooAbsArg.h:492
bool isShapeDirty() const
Definition RooAbsArg.h:413
void clearValueDirty() const
Definition RooAbsArg.h:599
bool _valueDirty
Definition RooAbsArg.h:708
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:487
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Implement multi-line detailed printing.
TString cleanBranchName() const
Construct a mangled name from the actual name that is free of any math symbols that might be interpre...
bool isValueDirty() const
Definition RooAbsArg.h:418
A space to attach TBranches.
virtual value_type getCurrentIndex() const
Return index number of current state.
void setCachedValue(double value, bool notifyClients=true) final
Overwrite the value stored in this object's cache.
unsigned int getCurrentOrdinalNumber() const
Return ordinal number of the current state.
bool hasLabel(const std::string &label) const
Check if a state with name label exists.
virtual const char * getCurrentLabel() const
Return label string of current state.
const std::string & lookupName(value_type index) const
Get the name corresponding to the given index.
TIterator * typeIterator() const
bool operator==(value_type index) const
Equality operator with a integer (compares with state index number)
RooCatType * retrieveLegacyState(value_type index) const
Return the legacy RooCatType corresponding to index. If it doesn't exist, create one.
void copyCache(const RooAbsArg *source, bool valueOnly=false, bool setValueDirty=true) override
Copy the cached value from given source and raise dirty flag.
value_type _currentIndex
Current category state.
Roo1DTable * createTable(const char *label) const
Create a table matching the shape of this category.
void defineStateUnchecked(const std::string &label, value_type index)
Internal version of defineState() that does not check if type already exists.
const RooCatType * defineTypeUnchecked(const char *label, value_type index)
void setTreeBranchStatus(TTree &t, bool active) override
(De)activate associate tree branch
const RooCatType * lookupType(value_type index, bool printError=false) const
Find our type corresponding to the specified index, or return nullptr for no match.
void writeToStream(std::ostream &os, bool compact) const override
Write object contents to ostream.
value_type nextAvailableStateIndex() const
bool readFromStream(std::istream &is, bool compact, bool verbose=false) override
Read object contents from stream (dummy for now)
bool isSignType(bool mustHaveZero=false) const
Determine if category has 2 or 3 states with index values -1,0,1.
std::map< std::string, value_type >::const_iterator end() const
Iterator for category state names. Points to pairs of index and name.
virtual const std::map< std::string, RooAbsCategory::value_type >::value_type & defineState(const std::string &label)
Define a new state with given label.
virtual value_type evaluate() const =0
Evaluate the category state and return.
void syncCache(const RooArgSet *set=nullptr) override
Explicitly synchronize RooAbsCategory internal cache.
const std::map< std::string, value_type >::value_type & getOrdinal(unsigned int n) const
Return name and index of the nth defined state.
RooAbsArg * createFundamental(const char *newname=nullptr) const override
Create a RooCategory fundamental object with our properties.
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::map< value_type, std::unique_ptr< RooCatType, std::function< void(RooCatType *)> > > _legacyStates
! Map holding pointers to RooCatType instances. Only for legacy interface. Don't use if possible.
bool isIdentical(const RooAbsArg &other, bool assumeSameType=false) const override
~RooAbsCategory() override
Destructor.
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().
bool isValid() const override
WVE (08/21/01) Probably obsolete now.
const RooCatType * defineType(const char *label)
const std::map< std::string, value_type > & stateNames() const
Access the map of state names to index numbers.
bool hasIndex(value_type index) const
Check if a state with index index exists.
void attachToVStore(RooVectorDataStore &vstore) override
Attach the category index and label to as branches to the given vector store.
static const decltype(_stateNames) ::value_type & invalidCategory()
A category state to signify an invalid category.
value_type lookupIndex(const std::string &stateName) const
Find the index number corresponding to the state name.
std::unique_ptr< TreeReadBuffer > _treeReadBuffer
void attachToTree(TTree &t, Int_t bufSize=32000) override
Attach the category index and label as branches to the given TTree.
void fillTreeBranch(TTree &t) override
Fill tree branches associated with current object with current value.
bool empty() const
If there are no states defined.
void clearTypes()
Delete all currently defined states.
void printValue(std::ostream &os) const override
Print value (label name)
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooCatType is an auxilary class for RooAbsCategory and defines a a single category state.
Int_t getVal() const
RooCategory is an object to represent discrete states.
Definition RooCategory.h:28
void setBuffer(RooAbsCategory::value_type *newBuf)
RooVectorDataStore uses std::vectors to store data columns.
CatVector * addCategory(RooAbsCategory *cat)
A TTree is a list of TBranches.
Definition TBranch.h:89
TObjArray * GetListOfLeaves()
Definition TBranch.h:243
Int_t Fill()
Definition TBranch.h:201
Iterator abstract base class.
Definition TIterator.h:30
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
virtual const char * GetTypeName() const
Definition TLeaf.h:139
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf (if any) or store the number of elements that the leaf c...
Definition TLeaf.cxx:249
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:380
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5285
virtual void SetBranchStatus(const char *bname, Bool_t status=1, UInt_t *found=nullptr)
Set branch status to Process or DoNotProcess.
Definition TTree.cxx:8520
const Int_t n
Definition legend1.C:16
Definition tree.py:1