Logo ROOT  
Reference Guide
RooMappedCategory.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 /// \class RooMappedCategory
18 /// RooMappedCategory provides a category-to-category mapping defined
19 /// by pattern matching on their state labels.
20 ///
21 /// The mapping function consists of a series of wild card regular expressions.
22 /// Each expression is matched to the input categories' state labels, and an associated
23 /// output state label.
24 
25 #include "RooMappedCategory.h"
26 
27 #include "RooFit.h"
28 #include "RooStreamParser.h"
29 #include "RooMsgService.h"
30 #include "Riostream.h"
31 #include "RooAbsCache.h"
32 
33 #include "TBuffer.h"
34 #include "TString.h"
35 #include "TRegexp.h"
36 
37 
38 class RooMappedCategoryCache : public RooAbsCache {
39  public:
40  RooMappedCategoryCache(RooAbsArg* owner = 0) : RooAbsCache(owner)
41  { initialise(); }
42  RooMappedCategoryCache(const RooAbsCache& other, RooAbsArg* owner = 0) :
43  RooAbsCache(other, owner)
44  { initialise(); }
45 
46  // look up our parent's output based on our parent's input category index
47  RooAbsCategory::value_type lookup(Int_t idx) const
48  { return _map[idx]; }
49 
50  virtual void wireCache()
51  { _map.clear(); initialise(); }
52 
53  virtual Bool_t redirectServersHook(const RooAbsCollection& /*newServerList*/, Bool_t /*mustReplaceAll*/, Bool_t /*nameChange*/, Bool_t /*isRecursive*/)
54  { _map.clear(); initialise(); return kFALSE; }
55 
56  private:
57  mutable std::map<Int_t, RooAbsCategory::value_type> _map;
58 
59  // pre-map categories of input category on something easily searchable
60  // like the index (not the name!)
61  void initialise()
62  {
63  const RooMappedCategory& parent = *static_cast<const RooMappedCategory*>(_owner);
64 
65  for (const auto& inCat : *parent._inputCat) {
66  const std::string& inKey = inCat.first;
67  // Scan array of regexps
68  bool found = false;
69  for (const auto& strAndEntry : parent._mapArray) {
70  if (strAndEntry.second.match(inKey.c_str())) {
71  found = true;
72  _map[inCat.second] = strAndEntry.second.outCat();
73  break;
74  }
75  }
76 
77  if (!found)
78  _map[inCat.second] = parent._defCat;
79  }
80  }
81 };
82 
83 RooMappedCategory::RooMappedCategory(const char *name, const char *title, RooAbsCategory& inputCat, const char* defOut, Int_t defOutIdx) :
84  RooAbsCategory(name, title), _inputCat("input","Input category",this,inputCat),
85  _mapcache(0)
86 {
87  // Constructor with input category and name of default output state, which is assigned
88  // to all input category states that do not follow any mapping rule.
89  if (defOutIdx==NoCatIdx) {
90  _defCat = defineState(defOut).second;
91  } else {
92  _defCat = defineState(defOut,defOutIdx).second;
93  }
94 }
95 
96 
98  RooAbsCategory(other,name), _inputCat("input",this,other._inputCat), _mapArray(other._mapArray),
99  _mapcache(0)
100 {
101  _defCat = lookupIndex(other.lookupName(other._defCat));
102 }
103 
104 
105 
107 {
108  // Destructor
109  delete _mapcache;
110 }
111 
112 
113 
114 Bool_t RooMappedCategory::map(const char* inKeyRegExp, const char* outKey, Int_t outIdx)
115 {
116  // Add mapping rule: any input category state label matching the 'inKeyRegExp'
117  // wildcard expression will be mapped to an output state with name 'outKey'
118  //
119  // Rules are evaluated in the order they were added. In case an input state
120  // matches more than one rule, the first rules output state will be assigned
121 
122  if (!inKeyRegExp || !outKey) return kTRUE ;
123 
124  // Check if pattern is already registered
125  if (_mapArray.find(inKeyRegExp)!=_mapArray.end()) {
126  coutE(InputArguments) << "RooMappedCategory::map(" << GetName() << "): ERROR expression "
127  << inKeyRegExp << " already mapped" << std::endl ;
128  return kTRUE ;
129  }
130 
131  // Check if output type exists, if not register
132  value_type catIdx = lookupIndex(outKey);
133  if (catIdx == invalidCategory().second) {
134  if (outIdx==NoCatIdx) {
135  catIdx = defineState(outKey).second;
136  } else {
137  catIdx = defineState(outKey,outIdx).second;
138  }
139  }
140 
141  if (catIdx == invalidCategory().second) {
142  coutE(InputArguments) << "RooMappedCategory::map(" << GetName()
143  << "): ERROR, unable to define category for output type " << outKey << std::endl ;
144  return true;
145  }
146 
147  // Create new map entry ;
148  Entry e(inKeyRegExp, catIdx);
149  if (!e.ok()) {
150  coutE(InputArguments) << "RooMappedCategory::map(" << GetName()
151  << "): ERROR, expression " << inKeyRegExp << " didn't compile" << std::endl ;
152  return kTRUE ;
153  }
154 
155  _mapArray[inKeyRegExp] = e ;
156  return kFALSE ;
157 }
158 
159 
160 
162 {
163  const RooMappedCategoryCache* cache = getOrCreateCache();
164  return cache->lookup(_inputCat->getCurrentIndex());
165 }
166 
167 const RooMappedCategoryCache* RooMappedCategory::getOrCreateCache() const
168 {
170  const_cast<RooMappedCategory*>(this));
171  return _mapcache;
172 }
173 
174 void RooMappedCategory::printMultiline(std::ostream& os, Int_t content, Bool_t verbose, TString indent) const
175 {
176  // Print info about this mapped category to the specified stream. In addition to the info
177  // from RooAbsCategory::printStream() we add:
178  //
179  // Standard : input category
180  // Shape : default value
181  // Verbose : list of mapping rules
182 
184 
185  if (verbose) {
186  os << indent << "--- RooMappedCategory ---" << std::endl
187  << indent << " Maps from " ;
189 
190  os << indent << " Default value is " << lookupName(_defCat) << " = " << _defCat << '\n';
191 
192  os << indent << " Mapping rules:" << std::endl;
193  for (const auto& strAndEntry : _mapArray) {
194  os << indent << " " << strAndEntry.first << " -> " << strAndEntry.second.outCat() << std::endl ;
195  }
196  }
197 }
198 
199 
200 Bool_t RooMappedCategory::readFromStream(std::istream& is, Bool_t compact, Bool_t /*verbose*/)
201 {
202  // Read object contents from given stream
203  if (compact) {
204  coutE(InputArguments) << "RooMappedCategory::readFromSteam(" << GetName() << "): can't read in compact mode" << std::endl ;
205  return kTRUE ;
206  } else {
207 
208  //Clear existing definitions, but preserve default output
209  TString defCatName(lookupName(_defCat));
210  _mapArray.clear() ;
211  delete _mapcache;
212  _mapcache = 0;
213  clearTypes() ;
214  _defCat = defineState(defCatName.Data()).second;
215 
216  TString token,errorPrefix("RooMappedCategory::readFromStream(") ;
217  errorPrefix.Append(GetName()) ;
218  errorPrefix.Append(")") ;
219  RooStreamParser parser(is,errorPrefix) ;
220  parser.setPunctuation(":,") ;
221 
222  TString destKey,srcKey ;
223  Bool_t readToken(kTRUE) ;
224 
225  // Loop over definition sequences
226  while(1) {
227  if (readToken) token=parser.readToken() ;
228  if (token.IsNull()) break ;
229  readToken=kTRUE ;
230 
231  destKey = token ;
232  if (parser.expectToken(":",kTRUE)) return kTRUE ;
233 
234  // Loop over list of sources for this destination
235  while(1) {
236  srcKey = parser.readToken() ;
237  token = parser.readToken() ;
238 
239  // Map a value
240  if (map(srcKey,destKey)) return kTRUE ;
241 
242  // Unless next token is ',' current token
243  // is destination part of next sequence
244  if (token.CompareTo(",")) {
245  readToken = kFALSE ;
246  break ;
247  }
248  }
249  }
250  return kFALSE ;
251  }
252  //return kFALSE ; // statement unreachable (OSF)
253 }
254 
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Customized printing of arguments of a RooMappedCategory to more intuitively reflect the contents of the
258 /// product operator construction
259 
260 void RooMappedCategory::printMetaArgs(std::ostream& os) const
261 {
262  // Scan array of regexps
263  RooAbsCategory::value_type prevOutCat = invalidCategory().second;
264  Bool_t first(kTRUE) ;
265  os << "map=(" ;
266  for (const auto& iter : _mapArray) {
267  if (iter.second.outCat() != prevOutCat) {
268  if (!first) { os << " " ; }
269  first=kFALSE ;
270 
271  os << iter.second.outCat() << ":" << iter.first ;
272  prevOutCat = iter.second.outCat();
273  } else {
274  os << "," << iter.first ;
275  }
276  }
277 
278  if (!first) { os << " " ; }
279  os << lookupName(_defCat) << ":*" ;
280 
281  os << ") " ;
282 }
283 
284 
285 
286 
287 void RooMappedCategory::writeToStream(std::ostream& os, Bool_t compact) const
288 {
289  // Write object contents to given stream
290  if (compact) {
291  // Write value only
292  os << getCurrentLabel() ;
293  } else {
294  // Write mapping expression
295 
296  // Scan array of regexps
297  RooAbsCategory::value_type prevOutCat = invalidCategory().second;
298  Bool_t first(kTRUE) ;
299  for (const auto& iter : _mapArray) {
300  if (iter.second.outCat() != prevOutCat) {
301  if (!first) { os << " " ; }
302  first=kFALSE ;
303 
304  os << iter.second.outCat() << "<-" << iter.first ;
305  prevOutCat = iter.second.outCat();
306  } else {
307  os << "," << iter.first ;
308  }
309  }
310 
311  if (!first) { os << " " ; }
312  os << lookupName(_defCat) << ":*" ;
313  }
314 }
315 
316 
317 /// When the input category changes states, the cached state mappings are invalidated
319  // There is no need to recompute _stateNames and _insertionOrder, as only defining new
320  // mappings has an effect on these. When the input category changes it shape, it is sufficient
321  // to clear the cached state mappings.
322  if (_mapcache) {
323  _mapcache->wireCache();
324  }
325 }
326 
327 
329  _expr(exp), _regexp(nullptr), _catIdx(cat) {}
331  _expr(other._expr), _regexp(nullptr), _catIdx(other._catIdx) {}
332 RooMappedCategory::Entry::~Entry() { delete _regexp; }
333 bool RooMappedCategory::Entry::ok() { return (const_cast<TRegexp*>(regexp())->Status()==TRegexp::kOK) ; }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 
338 {
339  if (&other==this) return *this ;
340 
341  _expr = other._expr ;
342  _catIdx = other._catIdx;
343 
344  if (_regexp) {
345  delete _regexp ;
346  }
347 
348  return *this;
349 }
350 
351 bool RooMappedCategory::Entry::match(const char* testPattern) const {
352  return (TString(testPattern).Index(*regexp())>=0);
353 }
354 
355 ////////////////////////////////////////////////////////////////////////////////
356 /// Mangle name : escape regexp character '+'
357 
359 {
360  TString t ;
361  const char *c = exp ;
362  while(*c) {
363  if (*c=='+') t.Append('\\') ;
364  t.Append(*c) ;
365  c++ ;
366  }
367  return t ;
368 }
369 
371  if (!_regexp) {
372  _regexp = new TRegexp(mangle(_expr), true);
373  }
374 
375  return _regexp;
376 }
RooStreamParser.h
c
#define c(i)
Definition: RSha256.hxx:119
RooMappedCategory::Entry::match
Bool_t match(const char *testPattern) const
Definition: RooMappedCategory.cxx:351
first
Definition: first.py:1
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
e
#define e(i)
Definition: RSha256.hxx:121
RooMsgService.h
RooStreamParser::expectToken
Bool_t expectToken(const TString &expected, Bool_t zapOnError=kFALSE)
Read the next token and return kTRUE if it is identical to the given 'expected' token.
Definition: RooStreamParser.cxx:397
RooAbsCategory::getCurrentIndex
virtual value_type getCurrentIndex() const
Return index number of current state.
Definition: RooAbsCategory.cxx:114
RooFit.h
RooTemplateProxy::arg
const T & arg() const
Return reference to object held in proxy.
Definition: RooTemplateProxy.h:271
RooFit::InputArguments
@ InputArguments
Definition: RooGlobalFunc.h:68
RooMappedCategory::Entry
Definition: RooMappedCategory.h:50
RooMappedCategory::NoCatIdx
static constexpr value_type NoCatIdx
Definition: RooMappedCategory.h:29
RooMappedCategory::_mapcache
RooMappedCategoryCache * _mapcache
Definition: RooMappedCategory.h:78
TString::Data
const char * Data() const
Definition: TString.h:369
RooPrintable::kStandard
@ kStandard
Definition: RooPrintable.h:34
RooAbsCategory::lookupName
const std::string & lookupName(value_type index) const
Get the name corresponding to the given index.
Definition: RooAbsCategory.cxx:201
RooAbsCategory::value_type
int value_type
The type used to denote a specific category state.
Definition: RooAbsCategory.h:41
coutE
#define coutE(a)
Definition: RooMsgService.h:33
RooMappedCategory::~RooMappedCategory
virtual ~RooMappedCategory()
Definition: RooMappedCategory.cxx:106
RooMappedCategory::Entry::operator=
Entry & operator=(const Entry &other)
Definition: RooMappedCategory.cxx:337
exp
double exp(double)
RooAbsCategory::invalidCategory
static const decltype(_stateNames) ::value_type & invalidCategory()
Is this category attached to a tree?
RooMappedCategory::RooMappedCategoryCache
friend class RooMappedCategoryCache
Definition: RooMappedCategory.h:86
RooAbsCategory::defineState
virtual const std::map< std::string, RooAbsCategory::value_type >::value_type & defineState(const std::string &label)
Define a new state with given label.
Definition: RooAbsCategory.cxx:213
indent
static void indent(ostringstream &buf, int indent_level)
Definition: TClingCallFunc.cxx:87
RooMappedCategory::Entry::regexp
const TRegexp * regexp() const
Definition: RooMappedCategory.cxx:370
RooStreamParser::readToken
TString readToken()
Read one token separated by any of the know punctuation characters This function recognizes and handl...
Definition: RooStreamParser.cxx:129
RooMappedCategory::Entry::ok
bool ok()
Definition: RooMappedCategory.cxx:333
TString
Definition: TString.h:136
Bool_t
bool Bool_t
Definition: RtypesCore.h:63
RooAbsCategory::getCurrentLabel
virtual const char * getCurrentLabel() const
Return label string of current state.
Definition: RooAbsCategory.cxx:130
TString.h
RooMappedCategory::Entry::_catIdx
RooAbsCategory::value_type _catIdx
Definition: RooMappedCategory.h:68
RooAbsCache::redirectServersHook
virtual Bool_t redirectServersHook(const RooAbsCollection &, Bool_t, Bool_t, Bool_t)
Interface for server redirect calls.
Definition: RooAbsCache.cxx:89
bool
TRegexp::kOK
@ kOK
Definition: TRegexp.h:34
RooAbsCategory
Definition: RooAbsCategory.h:38
RooMappedCategory
Definition: RooMappedCategory.h:27
TRegexp.h
RooAbsCache::wireCache
virtual void wireCache()
Definition: RooAbsCache.h:38
RooStreamParser
Definition: RooStreamParser.h:21
TBuffer.h
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
RooMappedCategory::map
Bool_t map(const char *inKeyRegExp, const char *outKeyName, Int_t outKeyNum=NoCatIdx)
Definition: RooMappedCategory.cxx:114
RooMappedCategory::printMetaArgs
void printMetaArgs(std::ostream &os) const
Customized printing of arguments of a RooMappedCategory to more intuitively reflect the contents of t...
Definition: RooMappedCategory.cxx:260
RooAbsCollection
Definition: RooAbsCollection.h:30
initialise
static void initialise(gsl_integration_workspace *workspace, double a, double b)
Definition: RooAdaptiveGaussKronrodIntegrator1D.cxx:514
RooMappedCategory::Entry::mangle
TString mangle(const char *exp) const
Mangle name : escape regexp character '+'.
Definition: RooMappedCategory.cxx:358
TRegexp
Definition: TRegexp.h:31
RooMappedCategory::getOrCreateCache
const RooMappedCategoryCache * getOrCreateCache() const
Definition: RooMappedCategory.cxx:167
RooMappedCategory::_mapArray
std::map< std::string, RooMappedCategory::Entry > _mapArray
Definition: RooMappedCategory.h:77
RooAbsCategory::printMultiline
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Print info about this object to the specified stream.
Definition: RooAbsCategory.cxx:406
RooMappedCategory::RooMappedCategory
RooMappedCategory()
Definition: RooMappedCategory.h:32
RooStreamParser::setPunctuation
void setPunctuation(const TString &punct)
Change list of characters interpreted as punctuation.
Definition: RooStreamParser.cxx:99
TString::CompareTo
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:418
TString::IsNull
Bool_t IsNull() const
Definition: TString.h:407
RooMappedCategory::_inputCat
RooCategoryProxy _inputCat
Definition: RooMappedCategory.h:76
RooMappedCategory::writeToStream
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to ostream.
Definition: RooMappedCategory.cxx:287
RooAbsCache
Definition: RooAbsCache.h:27
RooMappedCategory::printMultiline
void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Print info about this object to the specified stream.
Definition: RooMappedCategory.cxx:174
RooMappedCategory::Entry::~Entry
virtual ~Entry()
Definition: RooMappedCategory.cxx:332
RooAbsCategory::lookupIndex
value_type lookupIndex(const std::string &stateName) const
Find the index number corresponding to the state name.
Definition: RooAbsCategory.cxx:283
name
char name[80]
Definition: TGX11.cxx:110
RooPrintable::printStream
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
Definition: RooPrintable.cxx:75
genreflex::verbose
bool verbose
Definition: rootcling_impl.cxx:133
RooMappedCategory::Entry::_expr
TString _expr
Definition: RooMappedCategory.h:66
RooAbsArg
Definition: RooAbsArg.h:73
RooMappedCategory::_defCat
value_type _defCat
Definition: RooMappedCategory.h:75
RooMappedCategory::evaluate
virtual value_type evaluate() const
transient member: cache the mapping
Definition: RooMappedCategory.cxx:161
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:53
RooFit::Index
RooCmdArg Index(RooCategory &icat)
Definition: RooGlobalFunc.cxx:97
RooAbsCache.h
RooMappedCategory::recomputeShape
void recomputeShape()
When the input category changes states, the cached state mappings are invalidated.
Definition: RooMappedCategory.cxx:318
Riostream.h
RooMappedCategory::readFromStream
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)
Read object contents from stream (dummy for now)
Definition: RooMappedCategory.cxx:200
TGeant4Unit::second
static constexpr double second
Definition: TGeant4SystemOfUnits.h:157
RooMappedCategory.h
RooMappedCategory::Entry::Entry
Entry()
Definition: RooMappedCategory.h:52
RooAbsCategory::clearTypes
void clearTypes()
Delete all currently defined states.
Definition: RooAbsCategory.cxx:270
RooAbsCache::_owner
RooAbsArg * _owner
Definition: RooAbsCache.h:44
int