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
319 if (printError) {
320 coutE(InputArguments) << ClassName() << "::" << GetName() << ":lookupType: no match for index "
321 << index << std::endl;
322 }
323
324 return nullptr;
325}
326
327
328
329////////////////////////////////////////////////////////////////////////////////
330/// Find our type corresponding to the specified label, or return 0 for no match.
331/// \deprecated RooCatType is not used, any more. This function will create one and let it leak.
332/// Use lookupIndex() (preferred) or lookupName() instead.
333const RooCatType* RooAbsCategory::lookupType(const char* label, bool printError) const
334{
335 for (const auto& type : stateNames()) {
336 if(type.first == label)
337 return retrieveLegacyState(type.second);
338 }
339
340 // Try if label represents integer number
341 char* endptr ;
342 RooAbsCategory::value_type idx=strtol(label,&endptr,10) ;
343 if (endptr==label+strlen(label)) {
344 return lookupType(idx);
345 }
346
347 if (printError) {
348 coutE(InputArguments) << ClassName() << "::" << GetName() << ":lookupType: no match for label "
349 << label << std::endl;
350 }
351 return nullptr;
352}
353
354
355////////////////////////////////////////////////////////////////////////////////
356/// Check if given state is defined for this object
357
359{
360 return hasIndex(value.getVal()) ;
361}
362
363
364
365////////////////////////////////////////////////////////////////////////////////
366/// Create a table matching the shape of this category
367
369{
370 return new Roo1DTable(GetName(),label,*this) ;
371}
372
373
374
375////////////////////////////////////////////////////////////////////////////////
376/// Read object contents from stream (dummy for now)
377
378bool RooAbsCategory::readFromStream(std::istream&, bool, bool)
379{
380 return false ;
381}
382
383
384
385////////////////////////////////////////////////////////////////////////////////
386/// Write object contents to ostream
387
388void RooAbsCategory::writeToStream(std::ostream& os, bool /* compact */) const
389{
390 os << getCurrentLabel() ;
391}
392
393
394
395////////////////////////////////////////////////////////////////////////////////
396/// Print value (label name)
397
398void RooAbsCategory::printValue(std::ostream& os) const
399{
400 os << getCurrentLabel() << "(idx = " << getCurrentIndex() << ")" << std::endl;
401}
402
403
404
405////////////////////////////////////////////////////////////////////////////////
406/// Print info about this object to the specified stream. In addition to the info
407/// from RooAbsArg::printStream() we add:
408///
409/// Shape : label, index, defined types
410
411void RooAbsCategory::printMultiline(std::ostream& os, Int_t contents, bool verbose, TString indent) const
412{
413 RooAbsArg::printMultiline(os,contents,verbose,indent);
414
415 os << indent << "--- RooAbsCategory ---" << std::endl;
416 if (stateNames().empty()) {
417 os << indent << " ** No values defined **" << std::endl;
418 return;
419 }
420 os << indent << " Value = " << getCurrentIndex() << " \"" << getCurrentLabel() << ')' << std::endl;
421 os << indent << " Possible states:" << std::endl;
422 indent.Append(" ");
423 for (const auto& type : stateNames()) {
424 os << indent << type.first << '\t' << type.second << "\n";
425 }
426}
427
428
429
430////////////////////////////////////////////////////////////////////////////////
431/// Attach the category index and label to as branches to the given vector store
432
434{
435 RooVectorDataStore::CatVector* cv = vstore.addCategory(this) ;
437}
438
439
440
441
442////////////////////////////////////////////////////////////////////////////////
443/// Attach the category index and label as branches to the given
444/// TTree. The index field will be attached as integer with name
445/// `<name>_idx`. If a branch `<name>` exists, it attaches to this branch.
447{
448 // First check if there is an integer branch matching the category name
449 std::string cleanName = cleanBranchName().Data();
450 TBranch* branch = tree.GetBranch(cleanName.c_str());
451 if (!branch) {
452 cleanName += "_idx";
453 branch = tree.GetBranch(cleanName.c_str());
454 }
455
456 if (branch) {
457 TLeaf* leaf = static_cast<TLeaf*>(branch->GetListOfLeaves()->At(0));
458
459 // Check that leaf is _not_ an array
460 Int_t dummy ;
461 TLeaf* counterLeaf = leaf->GetLeafCounter(dummy) ;
462 if (counterLeaf) {
463 coutE(Eval) << "RooAbsCategory::attachToTree(" << GetName() << ") ERROR: TTree branch " << GetName()
464 << " is an array and cannot be attached to a RooAbsCategory" << std::endl;
465 return ;
466 }
467
468 const std::string typeName = leaf->GetTypeName();
469
470
471 // For different type names, store a function to attach
472 std::map<std::string, std::function<std::unique_ptr<TreeReadBuffer>()>> typeMap {
473 {"Float_t", [&](){ return createTreeReadBuffer<Float_t >(cleanName, tree); }},
474 {"Double_t", [&](){ return createTreeReadBuffer<Double_t >(cleanName, tree); }},
475 {"UChar_t", [&](){ return createTreeReadBuffer<UChar_t >(cleanName, tree); }},
476 {"Boolt_", [&](){ return createTreeReadBuffer<Bool_t >(cleanName, tree); }},
477 {"Char_t", [&](){ return createTreeReadBuffer<Char_t >(cleanName, tree); }},
478 {"UInt_t", [&](){ return createTreeReadBuffer<UInt_t >(cleanName, tree); }},
479 {"Long64_t", [&](){ return createTreeReadBuffer<Long64_t >(cleanName, tree); }},
480 {"ULong64_t", [&](){ return createTreeReadBuffer<ULong64_t>(cleanName, tree); }},
481 {"Short_t", [&](){ return createTreeReadBuffer<Short_t >(cleanName, tree); }},
482 {"UShort_t", [&](){ return createTreeReadBuffer<UShort_t >(cleanName, tree); }},
483 };
484
485 auto typeDetails = typeMap.find(typeName);
486 if (typeDetails != typeMap.end()) {
487 coutI(DataHandling) << "RooAbsCategory::attachToTree(" << GetName() << ") TTree " << typeName << " branch \"" << cleanName
488 << "\" will be converted to int." << std::endl;
489 _treeReadBuffer = typeDetails->second();
490 } else {
491 _treeReadBuffer = nullptr;
492
493 if (typeName == "Int_t") {
494 tree.SetBranchAddress(cleanName.c_str(), &_currentIndex);
495 }
496 else {
497 coutE(InputArguments) << "RooAbsCategory::attachToTree(" << GetName() << ") data type " << typeName << " is not supported." << std::endl;
498 }
499 }
500 } else {
501 void* ptr = &_currentIndex;
502 tree.Branch(cleanName.c_str(), ptr, (cleanName + "/I").c_str(), bufSize);
503 }
504}
505
506
507
508////////////////////////////////////////////////////////////////////////////////
509/// Fill tree branches associated with current object with current value
510
512{
513 // First determine if branch is taken
514 TBranch* idxBranch = t.GetBranch((std::string(GetName()) + "_idx").c_str()) ;
515 if (!idxBranch) {
516 coutF(DataHandling) << "RooAbsCategory::fillTreeBranch(" << GetName() << ") ERROR: not attached to tree" << std::endl;
517 throw std::runtime_error("RooAbsCategory::fillTreeBranch(): Category is not attached to a tree.");
518 }
519
520 idxBranch->Fill() ;
521}
522
523
524
525////////////////////////////////////////////////////////////////////////////////
526/// (De)activate associate tree branch
527
529{
530 TBranch* branch = t.GetBranch(Form("%s_idx",GetName())) ;
531 if (branch) {
532 t.SetBranchStatus(Form("%s_idx",GetName()),active?true:false) ;
533 }
534}
535
536
537
538////////////////////////////////////////////////////////////////////////////////
539/// Explicitly synchronize RooAbsCategory internal cache
540
542{
544}
545
546
547
548////////////////////////////////////////////////////////////////////////////////
549/// Copy the cached value from given source and raise dirty flag.
550/// It is the callers responsibility to ensure that the sources
551/// cache is clean(valid) before this function is called, e.g. by
552/// calling syncCache() on the source.
553
554void RooAbsCategory::copyCache(const RooAbsArg *source, bool /*valueOnly*/, bool setValDirty)
555{
556 auto other = static_cast<const RooAbsCategory*>(source);
557 assert(dynamic_cast<const RooAbsCategory*>(source));
558
559 _currentIndex = other->_treeReadBuffer ? *other->_treeReadBuffer : other->_currentIndex;
560
561 if (setValDirty) {
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 auto fund = std::make_unique<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 RooFit::makeOwningPtr<RooAbsArg>(std::move(fund));
647}
648
649
650
651////////////////////////////////////////////////////////////////////////////////
652/// Determine if category has 2 or 3 states with index values -1,0,1
653
654bool RooAbsCategory::isSignType(bool mustHaveZero) const
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 (std::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);
684}
685
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::make_unique<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 [](auto const& left, auto const& right) { return left.second < right.second; })->second;
711}
#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:2489
One-dimensional table.
Definition Roo1DTable.h:23
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition RooAbsArg.h:493
bool isShapeDirty() const
Definition RooAbsArg.h:414
void clearValueDirty() const
Definition RooAbsArg.h:602
bool _valueDirty
Definition RooAbsArg.h:711
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:488
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:419
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.
RooFit::OwningPtr< 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 auxiliary class for RooAbsCategory and defines a a single category state.
Int_t getVal() const
void setBuffer(RooAbsCategory::value_type *newBuf)
Uses std::vector to store data columns.
CatVector * addCategory(RooAbsCategory *cat)
A TTree is a list of TBranches.
Definition TBranch.h:93
TObjArray * GetListOfLeaves()
Definition TBranch.h:247
Int_t Fill()
Definition TBranch.h:205
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:376
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual void SetBranchStatus(const char *bname, bool status=true, UInt_t *found=nullptr)
Set branch status to Process or DoNotProcess.
Definition TTree.cxx:8534
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5294
const Int_t n
Definition legend1.C:16
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35