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- isValid(const RooCatType&) \f$ \rightarrow \f$ hasIndex() / hasLabel()
44**/
45
46#include "RooAbsCategory.h"
47
48#include "RooFit.h"
49#include "RooArgSet.h"
50#include "Roo1DTable.h"
51#include "RooCategory.h"
52#include "RooMsgService.h"
53#include "RooVectorDataStore.h"
55
56#include "Compression.h"
57#include "TString.h"
58#include "TTree.h"
59#include "TLeaf.h"
60#include "TBranch.h"
61
62#include <memory>
63
64using namespace std;
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////////////////////////////////////////////////////////////////////////////////
76/// Constructor
77
78RooAbsCategory::RooAbsCategory(const char *name, const char *title) :
79 RooAbsArg(name,title), _currentIndex(0)
80{
83}
84
85
86
87////////////////////////////////////////////////////////////////////////////////
88/// Copy constructor, copies the registered category states from the original.
89
91 RooAbsArg(other,name), _currentIndex(other._currentIndex),
92 _stateNames(other._stateNames),
93 _insertionOrder(other._insertionOrder),
94 _treeVar(other._treeVar)
95{
98}
99
100
101
102////////////////////////////////////////////////////////////////////////////////
103/// Destructor
104
106{
107
108}
109
110
111
112////////////////////////////////////////////////////////////////////////////////
113/// Return index number of current state
114
116{
117 if (isValueDirty() || isShapeDirty()) {
119
121 }
122
123 return _currentIndex;
124}
125
126
127
128////////////////////////////////////////////////////////////////////////////////
129/// Return label string of current state.
130
132{
133 const auto index = getCurrentIndex();
134 for (const auto& item : stateNames()) {
135 if (item.second == index)
136 return item.first.c_str();
137 }
138
139 return "";
140}
141
142
143////////////////////////////////////////////////////////////////////////////////
144/// Equality operator with a integer (compares with state index number)
145
147{
148 return (index==getCurrentIndex()) ;
149}
150
151
152
153////////////////////////////////////////////////////////////////////////////////
154/// Equality operator with a string (compares with state label string)
155
156Bool_t RooAbsCategory::operator==(const char* label) const
157{
158 return strcmp(label, getCurrentLabel()) == 0;
159}
160
161
162
163////////////////////////////////////////////////////////////////////////////////
164/// Equality operator with another RooAbsArg. Only functional
165/// is also a RooAbsCategory, will return true if index is the same
166
168{
169 const RooAbsCategory* otherCat = dynamic_cast<const RooAbsCategory*>(&other) ;
170 return otherCat ? operator==(otherCat->getCurrentIndex()) : kFALSE ;
171}
172
173
174////////////////////////////////////////////////////////////////////////////////
175
176Bool_t RooAbsCategory::isIdentical(const RooAbsArg& other, Bool_t assumeSameType) const
177{
178 if (!assumeSameType) {
179 const RooAbsCategory* otherCat = dynamic_cast<const RooAbsCategory*>(&other) ;
180 return otherCat ? operator==(otherCat->getCurrentIndex()) : kFALSE ;
181 } else {
182 return getCurrentIndex() == static_cast<const RooAbsCategory&>(other).getCurrentIndex();
183 }
184}
185
186
187////////////////////////////////////////////////////////////////////////////////
188/// Check if a state with index `index` exists.
190{
191 for (const auto& item : stateNames()) {
192 if (item.second == index)
193 return true;
194 }
195
196 return false;
197}
198
199
200////////////////////////////////////////////////////////////////////////////////
201/// Look up the name corresponding to the given index.
202const std::string& RooAbsCategory::lookupName(value_type index) const {
203 for (const auto& item : stateNames()) {
204 if (item.second == index)
205 return item.first;
206 }
207
208 return invalidCategory().first;
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Define a new state with given label. The next available
213/// integer is assigned as index value.
214const std::map<std::string, RooAbsCategory::value_type>::value_type& RooAbsCategory::defineState(const std::string& label)
215{
216 return defineState(label, nextAvailableStateIndex());
217}
218
219
220////////////////////////////////////////////////////////////////////////////////
221/// Internal version of defineState() that does not check if type
222/// already exists
224{
225 _stateNames.emplace(label, index);
226 _insertionOrder.push_back(label);
227
228 if (_stateNames.size() == 1)
229 _currentIndex = index;
230
232}
233
234
235
236////////////////////////////////////////////////////////////////////////////////
237/// Define new state with given name and index number.
238
239const std::map<std::string, RooAbsCategory::value_type>::value_type& RooAbsCategory::defineState(const std::string& label, RooAbsCategory::value_type index)
240{
241 auto& theStateNames = stateNames();
242
243 if (hasIndex(index)) {
244 coutE(InputArguments) << "RooAbsCategory::" << __func__ << "(" << GetName() << "): index "
245 << index << " already assigned" << endl ;
246 return invalidCategory();
247 }
248
249 if (hasLabel(label)) {
250 coutE(InputArguments) << "RooAbsCategory::" << __func__ << "(" << GetName() << "): label "
251 << label << " already assigned or not allowed" << endl ;
252 return invalidCategory();
253 }
254
255 const auto result = theStateNames.emplace(label, index);
256 _insertionOrder.push_back(label);
257
258 if (theStateNames.size() == 1)
259 _currentIndex = index;
260
262
263 return *(result.first);
264}
265
266
267
268////////////////////////////////////////////////////////////////////////////////
269/// Delete all currently defined states
270
272{
273 _stateNames.clear();
274 _insertionOrder.clear();
276 setShapeDirty() ;
277}
278
279
280////////////////////////////////////////////////////////////////////////////////
281/// Find the index number corresponding to the state name.
282/// \see hasLabel() for checking if a given label has been defined.
283/// \return Index of the category or std::numeric_limits<int>::min() on failure.
284RooAbsCategory::value_type RooAbsCategory::lookupIndex(const std::string& stateName) const {
285 const auto item = stateNames().find(stateName);
286 if (item != stateNames().end()) {
287 return item->second;
288 }
289
290 return invalidCategory().second;
291}
292
293////////////////////////////////////////////////////////////////////////////////
294/// Find our type that matches the specified type, or return 0 for no match.
295/// \deprecated RooCatType is not used, any more. This function will create one and let it leak.
296/// Use lookupIndex() (preferred) or lookupName() instead.
297const RooCatType* RooAbsCategory::lookupType(const RooCatType &other, Bool_t printError) const
298{
299 return lookupType(other.getVal(), printError);
300}
301
302
303
304////////////////////////////////////////////////////////////////////////////////
305/// Find our type corresponding to the specified index, or return nullptr for no match.
306/// \deprecated RooCatType is not used, any more. This function will create one and let it leak.
307/// Use lookupIndex() (preferred) or lookupName() instead.
309{
310 for (const auto& item : stateNames())
311 if (item.second == index) {
312 return retrieveLegacyState(index);
313 }
314
315 if (printError) {
316 coutE(InputArguments) << ClassName() << "::" << GetName() << ":lookupType: no match for index "
317 << index << endl;
318 }
319
320 return nullptr;
321}
322
323
324
325////////////////////////////////////////////////////////////////////////////////
326/// Find our type corresponding to the specified label, or return 0 for no match.
327/// \deprecated RooCatType is not used, any more. This function will create one and let it leak.
328/// Use lookupIndex() (preferred) or lookupName() instead.
329const RooCatType* RooAbsCategory::lookupType(const char* label, Bool_t printError) const
330{
331 for (const auto& type : stateNames()) {
332 if(type.first == label)
333 return retrieveLegacyState(type.second);
334 }
335
336 // Try if label represents integer number
337 char* endptr ;
338 RooAbsCategory::value_type idx=strtol(label,&endptr,10) ;
339 if (endptr==label+strlen(label)) {
340 return lookupType(idx);
341 }
342
343 if (printError) {
344 coutE(InputArguments) << ClassName() << "::" << GetName() << ":lookupType: no match for label "
345 << label << endl;
346 }
347 return nullptr;
348}
349
350
351////////////////////////////////////////////////////////////////////////////////
352/// Check if given state is defined for this object
353
355{
356 return hasIndex(value.getVal()) ;
357}
358
359
360
361////////////////////////////////////////////////////////////////////////////////
362/// Create a table matching the shape of this category
363
365{
366 return new Roo1DTable(GetName(),label,*this) ;
367}
368
369
370
371////////////////////////////////////////////////////////////////////////////////
372/// Read object contents from stream (dummy for now)
373
375{
376 return kFALSE ;
377}
378
379
380
381////////////////////////////////////////////////////////////////////////////////
382/// Write object contents to ostream
383
384void RooAbsCategory::writeToStream(ostream& os, Bool_t /* compact */) const
385{
386 os << getCurrentLabel() ;
387}
388
389
390
391////////////////////////////////////////////////////////////////////////////////
392/// Print value (label name)
393
394void RooAbsCategory::printValue(ostream& os) const
395{
396 os << getCurrentLabel() << "(idx = " << getCurrentIndex() << ")" << endl ;
397}
398
399
400
401////////////////////////////////////////////////////////////////////////////////
402/// Print info about this object to the specified stream. In addition to the info
403/// from RooAbsArg::printStream() we add:
404///
405/// Shape : label, index, defined types
406
407void RooAbsCategory::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
408{
409 RooAbsArg::printMultiline(os,contents,verbose,indent);
410
411 os << indent << "--- RooAbsCategory ---" << endl;
412 if (stateNames().empty()) {
413 os << indent << " ** No values defined **" << endl;
414 return;
415 }
416 os << indent << " Value = " << getCurrentIndex() << " \"" << getCurrentLabel() << ')' << endl;
417 os << indent << " Possible states:" << endl;
418 indent.Append(" ");
419 for (const auto& type : stateNames()) {
420 os << indent << type.first << '\t' << type.second << "\n";
421 }
422}
423
424
425
426////////////////////////////////////////////////////////////////////////////////
427/// Attach the category index and label to as branches to the given vector store
428
430{
431 RooVectorDataStore::CatVector* cv = vstore.addCategory(this) ;
433}
434
435
436
437
438////////////////////////////////////////////////////////////////////////////////
439/// Attach the category index and label as branches to the given
440/// TTree. The index field will be attached as integer with name
441/// `<name>_idx`. If a branch `<name>` exists, it attaches to this branch.
443{
444 // First check if there is an integer branch matching the category name
445 TString cleanName(cleanBranchName()) ;
446 TBranch* branch = t.GetBranch(cleanName) ;
447 if (!branch) {
448 cleanName += "_idx";
449 branch = t.GetBranch(cleanName);
450 }
451
452 if (branch) {
453 TString typeName(((TLeaf*)branch->GetListOfLeaves()->At(0))->GetTypeName()) ;
454 if (!typeName.CompareTo("Int_t")) {
455 // Imported TTree: attach only index field as branch
456
457 coutI(DataHandling) << "RooAbsCategory::attachToTree(" << GetName() << ") TTree branch " << GetName()
458 << " will be interpreted as category index" << endl ;
459
460 t.SetBranchAddress(cleanName, &_currentIndex) ;
461 setAttribute("INTIDXONLY_TREE_BRANCH",kTRUE) ;
462 _treeVar = true;
463 return ;
464 } else if (!typeName.CompareTo("UChar_t")) {
465 coutI(DataHandling) << "RooAbsReal::attachToTree(" << GetName() << ") TTree UChar_t branch " << GetName()
466 << " will be interpreted as category index" << endl ;
467 t.SetBranchAddress(cleanName,&_byteValue) ;
468 setAttribute("UCHARIDXONLY_TREE_BRANCH",kTRUE) ;
469 _treeVar = true;
470 return ;
471 }
472 } else {
473 TString format(cleanName);
474 format.Append("/I");
475 void* ptr = &_currentIndex;
476 t.Branch(cleanName, ptr, (const Text_t*)format, bufSize);
477 }
478}
479
480
481
482////////////////////////////////////////////////////////////////////////////////
483/// Fill tree branches associated with current object with current value
484
486{
487 TString idxName(GetName()) ;
488 idxName.Append("_idx") ;
489
490 // First determine if branch is taken
491 TBranch* idxBranch = t.GetBranch(idxName) ;
492 if (!idxBranch) {
493 coutF(DataHandling) << "RooAbsCategory::fillTreeBranch(" << GetName() << ") ERROR: not attached to tree" << endl ;
494 throw std::runtime_error("RooAbsCategory::fillTreeBranch(): Category is not attached to a tree.");
495 }
496
497 idxBranch->Fill() ;
498}
499
500
501
502////////////////////////////////////////////////////////////////////////////////
503/// (De)activate associate tree branch
504
506{
507 TBranch* branch = t.GetBranch(Form("%s_idx",GetName())) ;
508 if (branch) {
509 t.SetBranchStatus(Form("%s_idx",GetName()),active?1:0) ;
510 }
511}
512
513
514
515////////////////////////////////////////////////////////////////////////////////
516/// Explicitly synchronize RooAbsCategory internal cache
517
519{
521}
522
523
524
525////////////////////////////////////////////////////////////////////////////////
526/// Copy the cached value from given source and raise dirty flag.
527/// It is the callers responsibility to ensure that the sources
528/// cache is clean(valid) before this function is called, e.g. by
529/// calling syncCache() on the source.
530
531void RooAbsCategory::copyCache(const RooAbsArg *source, Bool_t /*valueOnly*/, Bool_t setValDirty)
532{
533 auto other = static_cast<const RooAbsCategory*>(source);
534 assert(dynamic_cast<const RooAbsCategory*>(source));
535
536 _currentIndex = other->_currentIndex;
537
538 if (setValDirty) {
540 }
541
542 if (!_treeVar)
543 return;
544
545 if (source->getAttribute("INTIDXONLY_TREE_BRANCH")) {
546 // Lookup cat state from other-index because label is missing
547 if (hasIndex(other->_currentIndex)) {
548 _currentIndex = other->_currentIndex;
549 } else {
550 coutE(DataHandling) << "RooAbsCategory::copyCache(" << GetName() << ") ERROR: index of source arg "
551 << source->GetName() << " is invalid (" << other->_currentIndex
552 << "), value not updated" << endl;
553 }
554 } else if (source->getAttribute("UCHARIDXONLY_TREE_BRANCH")) {
555 // Lookup cat state from other-index because label is missing
556 Int_t tmp = static_cast<int>(other->_byteValue);
557 if (hasIndex(tmp)) {
558 _currentIndex = tmp;
559 } else {
560 coutE(DataHandling) << "RooAbsCategory::copyCache(" << GetName() << ") ERROR: index of source arg "
561 << source->GetName() << " is invalid (" << tmp << "), value not updated" << endl;
562 }
563 }
564}
565
566
567////////////////////////////////////////////////////////////////////////////////
568/// Overwrite the value stored in this object's cache.
569/// This can be used to fake a computation that resulted in `value`.
570/// \param[in] value Value to write. The argument is reinterpreted as a category state.
571/// If such a state does not exist, this will create undefined behaviour.
572/// \param[in] notifyClients If true, notify users of this object that its value changed.
573/// This is the default.
574void RooAbsCategory::setCachedValue(double value, bool notifyClients) {
575 _currentIndex = static_cast<value_type>(value);
576
577 if (notifyClients) {
579 _valueDirty = false;
580 }
581}
582
583
584////////////////////////////////////////////////////////////////////////////////
585/// Return name and index of the `n`th defined state. When states are defined using
586/// defineType() or operator[], the order of insertion is tracked, to mimic the behaviour
587/// before modernising the category classes.
588/// When directly manipulating the map with state names using states(), the order of insertion
589/// is not known, so alphabetical ordering as usual for std::map is used. The latter is faster.
590/// \param[in] n Number of state to be retrieved.
591/// \return A pair with name and index.
592const std::map<std::string, RooAbsCategory::value_type>::value_type& RooAbsCategory::getOrdinal(unsigned int n) const {
593 // Retrieve state names, trigger possible recomputation
594 auto& theStateNames = stateNames();
595
596 if (n >= theStateNames.size())
597 return invalidCategory();
598
599 if (theStateNames.size() != _insertionOrder.size())
600 return *std::next(theStateNames.begin(), n);
601
602 const auto item = theStateNames.find(_insertionOrder[n]);
603 if (item != theStateNames.end())
604 return *item;
605
606 return invalidCategory();
607}
608
609
610////////////////////////////////////////////////////////////////////////////////
611/// Return ordinal number of the current state.
613 // Retrieve state names, trigger possible recomputation
614 auto& theStateNames = stateNames();
615
616 // If we don't have the full history of inserted state names, have to go by map ordering:
617 if (theStateNames.size() != _insertionOrder.size()) {
618 const auto currentIndex = getCurrentIndex();
619 for (auto it = theStateNames.begin(); it != theStateNames.end(); ++it) {
620 if (it->second == currentIndex)
621 return std::distance(theStateNames.begin(), it);
622 }
623 }
624
625 // With full insertion history, find index of current label:
626 auto item = std::find(_insertionOrder.begin(), _insertionOrder.end(), getCurrentLabel());
627 assert(item != _insertionOrder.end());
628
629 return item - _insertionOrder.begin();
630}
631
632
633////////////////////////////////////////////////////////////////////////////////
634/// Create a RooCategory fundamental object with our properties.
635
637{
638 // Add and precalculate new category column
639 RooCategory *fund= new RooCategory(newname?newname:GetName(),GetTitle()) ;
640
641 // Copy states
642 for (const auto& type : stateNames()) {
643 fund->defineStateUnchecked(type.first, type.second);
644 }
645
646 return fund;
647}
648
649
650
651////////////////////////////////////////////////////////////////////////////////
652/// Determine if category has 2 or 3 states with index values -1,0,1
653
655{
656 const auto& theStateNames = stateNames();
657
658 if (theStateNames.size() > 3 || theStateNames.size() < 2) return false;
659 if (mustHaveZero && theStateNames.size() != 3) return false;
660
661 for (const auto& type : theStateNames) {
662 if (abs(type.second)>1)
663 return false;
664 }
665
666 return true;
667}
668
669/// \deprecated Use begin() and end() instead.
670/// \note Using this iterator creates useless RooCatType instances, which will leak
671/// unless deleted by the user.
674}
675
676const RooCatType* RooAbsCategory::defineType(const char* label) {
677 defineState(label);
678 return retrieveLegacyState(stateNames()[label]);
679}
680
681const RooCatType* RooAbsCategory::defineType(const char* label, int index) {
682 defineState(label, index);
683 return retrieveLegacyState(index);
684}
685
687 defineStateUnchecked(label, index);
688 return retrieveLegacyState(index);
689}
690
691/// Return the legacy RooCatType corresponding to `index`. If it doesn't exist, create one.
693 auto result = _legacyStates.find(index);
694 if (result == _legacyStates.end()) {
695 result = _legacyStates.emplace(index,
696 std::unique_ptr<RooCatType>(new RooCatType(lookupName(index).c_str(), index))).first;
697 }
698
699 return result->second.get();
700}
701
702
704 const auto& theStateNames = stateNames();
705
706 if (theStateNames.empty())
707 return 0;
708
709 return 1 + std::max_element(theStateNames.begin(), theStateNames.end(),
710 [](const std::map<std::string, value_type>::value_type& left,
711 const std::map<std::string, value_type>::value_type& right) {
712 return left.second < right.second; })->second;
713}
#define coutI(a)
#define coutF(a)
#define coutE(a)
char Text_t
Definition RtypesCore.h:62
const Bool_t kFALSE
Definition RtypesCore.h:101
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition TGX11.cxx:110
int type
Definition TGX11.cxx:121
char * Form(const char *fmt,...)
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:69
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition RooAbsArg.h:510
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Implement multi-line detailed printing.
Bool_t isShapeDirty() const
Definition RooAbsArg.h:431
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
Bool_t isValueDirty() const
Definition RooAbsArg.h:436
void clearValueDirty() const
Definition RooAbsArg.h:616
Bool_t _valueDirty
Definition RooAbsArg.h:731
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:505
TString cleanBranchName() const
Construct a mangled name from the actual name that is free of any math symbols that might be interpre...
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
RooAbsCategory is the base class for objects that represent a discrete value with a finite number of ...
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.
virtual void copyCache(const RooAbsArg *source, Bool_t valueOnly=kFALSE, Bool_t setValueDirty=kTRUE)
Copy the cached value from given source and raise dirty flag.
virtual bool isValid() const
WVE (08/21/01) Probably obsolete now.
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
virtual void fillTreeBranch(TTree &t)
Fill tree branches associated with current object with current value.
RooCatType * retrieveLegacyState(value_type index) const
Return the legacy RooCatType corresponding to index. If it doesn't exist, create one.
value_type _currentIndex
Bool_t operator==(value_type index) const
Equality operator with a integer (compares with state index number)
virtual void attachToVStore(RooVectorDataStore &vstore)
Attach the category index and label to as branches to the given vector store.
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.
virtual ~RooAbsCategory()
Destructor.
const RooCatType * defineTypeUnchecked(const char *label, value_type index)
virtual void attachToTree(TTree &t, Int_t bufSize=32000)
Attach the category index and label as branches to the given TTree.
value_type nextAvailableStateIndex() const
virtual Bool_t isIdentical(const RooAbsArg &other, Bool_t assumeSameType=kFALSE) const
RooAbsArg * createFundamental(const char *newname=0) const
Create a RooCategory fundamental object with our properties.
std::map< std::string, value_type >::const_iterator end() const
Iterator for category state names. Points to pairs of index and name.
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to ostream.
virtual const std::map< std::string, RooAbsCategory::value_type >::value_type & defineState(const std::string &label)
Define a new state with given label.
virtual void setTreeBranchStatus(TTree &t, Bool_t active)
(De)activate associate tree branch
virtual value_type evaluate() const =0
Evaluate the category state and return.
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.
const std::map< std::string, value_type >::value_type & getOrdinal(unsigned int n) const
Return name and index of the nth defined state.
const RooCatType * lookupType(value_type index, Bool_t printError=kFALSE) const
Find our type corresponding to the specified index, or return nullptr for no match.
UChar_t _byteValue
Keeps track in which order state numbers have been inserted. Make sure this is updated in recomputeSh...
std::map< value_type, std::unique_ptr< RooCatType, std::function< void(RooCatType *)> > > _legacyStates
Transient cache for byte values from tree branches.
bool hasIndex(value_type index) const
Check if a state with index index exists.
virtual void syncCache(const RooArgSet *set=0)
Explicitly synchronize RooAbsCategory internal cache.
std::vector< std::string > _insertionOrder
Map state names to index numbers. Make sure state names are updated in recomputeShape().
std::map< std::string, value_type > _stateNames
Current category state.
const RooCatType * defineType(const char *label)
Bool_t isSignType(Bool_t mustHaveZero=kFALSE) const
Determine if category has 2 or 3 states with index values -1,0,1.
const std::map< std::string, value_type > & stateNames() const
Access the map of state names to index numbers.
virtual void printValue(std::ostream &os) const
Print value (label name)
static const decltype(_stateNames) ::value_type & invalidCategory()
Is this category attached to a tree?
value_type lookupIndex(const std::string &stateName) const
Find the index number corresponding to the state name.
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)
Read object contents from stream (dummy for now)
bool _treeVar
Map holding pointers to RooCatType instances. Only for legacy interface. Don't use if possible.
void clearTypes()
Delete all currently defined states.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:35
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:27
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 * GetTitle() const
Returns title of object.
Definition TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
TObject * At(Int_t idx) const
Definition TObjArray.h:164
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:200
Basic string class.
Definition TString.h:136
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:442
TString & Append(const char *cs)
Definition TString.h:564
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:5279
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
Definition TTree.cxx:8356
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
Definition TTree.h:350
virtual void SetBranchStatus(const char *bname, Bool_t status=1, UInt_t *found=0)
Set branch status to Process or DoNotProcess.
Definition TTree.cxx:8505
const Int_t n
Definition legend1.C:16