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