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 DESCRIPTION [CAT] --
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 <cstdio>
26
27#include "RooMappedCategory.h"
28
29#include "RooFit.h"
30#include "RooStreamParser.h"
31#include "RooMsgService.h"
32
33#include "Riostream.h"
34#include "TBuffer.h"
35#include "TString.h"
36#include "RooAbsCache.h"
37
40
41class RooMappedCategoryCache : public RooAbsCache {
42 public:
43 RooMappedCategoryCache(RooAbsArg* owner = 0) : RooAbsCache(owner)
44 { initialise(); }
45 RooMappedCategoryCache(const RooAbsCache& other, RooAbsArg* owner = 0) :
46 RooAbsCache(other, owner)
47 { initialise(); }
48
49 // look up our parent's output based on our parent's input category index
50 const RooCatType* lookup(Int_t idx) const
51 { return _map[idx]; }
52
53 virtual void wireCache()
54 { _map.clear(); initialise(); }
55
56 virtual Bool_t redirectServersHook(const RooAbsCollection& /*newServerList*/, Bool_t /*mustReplaceAll*/, Bool_t /*nameChange*/, Bool_t /*isRecursive*/)
57 { _map.clear(); initialise(); return kFALSE; }
58
59 private:
60 mutable std::map<Int_t, const RooCatType*> _map;
61
62 // pre-map categories of input category on something easily searchable
63 // like the index (not the name!)
64 void initialise()
65 {
66 const RooMappedCategory& parent = *static_cast<const RooMappedCategory*>(_owner);
67 std::unique_ptr<TIterator> tit(static_cast<const RooAbsCategory&>(
68 parent._inputCat.arg()).typeIterator());
69 for (const RooCatType* inCat = static_cast<const RooCatType*>(tit->Next());
70 inCat; inCat = static_cast<const RooCatType*>(tit->Next())) {
71 const char* inKey = inCat->GetName();
72 // Scan array of regexps
73 bool found = false;
74 for (std::map<std::string, RooMappedCategory::Entry>::const_iterator
75 iter = parent._mapArray.begin(),
76 end = parent._mapArray.end(); end != iter; ++iter) {
77 if (iter->second.match(inKey)) {
78 found = true;
79 _map[inCat->getVal()] = &(iter->second.outCat());
80 break;
81 }
82 }
83 if (!found) _map[inCat->getVal()] = parent._defCat;
84 }
85 }
86};
87
88RooMappedCategory::RooMappedCategory(const char *name, const char *title, RooAbsCategory& inputCat, const char* defOut, Int_t defOutIdx) :
89 RooAbsCategory(name, title), _inputCat("input","Input category",this,inputCat),
90 _mapcache(0)
91{
92 // Constructor with input category and name of default output state, which is assigned
93 // to all input category states that do not follow any mapping rule.
94 if (defOutIdx==NoCatIdx) {
95 _defCat = (RooCatType*) defineType(defOut) ;
96 } else {
97 _defCat = (RooCatType*) defineType(defOut,defOutIdx) ;
98 }
99}
100
101
103 RooAbsCategory(other,name), _inputCat("input",this,other._inputCat), _mapArray(other._mapArray),
104 _mapcache(0)
105{
107}
108
109
110
112{
113 // Destructor
114 delete _mapcache;
115}
116
117
118
119Bool_t RooMappedCategory::map(const char* inKeyRegExp, const char* outKey, Int_t outIdx)
120{
121 // Add mapping rule: any input category state label matching the 'inKeyRegExp'
122 // wildcard expression will be mapped to an output state with name 'outKey'
123 //
124 // Rules are evaluated in the order they were added. In case an input state
125 // matches more than one rule, the first rules output state will be assigned
126
127 if (!inKeyRegExp || !outKey) return kTRUE ;
128
129 // Check if pattern is already registered
130 if (_mapArray.find(inKeyRegExp)!=_mapArray.end()) {
131 coutE(InputArguments) << "RooMappedCategory::map(" << GetName() << "): ERROR expression "
132 << inKeyRegExp << " already mapped" << std::endl ;
133 return kTRUE ;
134 }
135
136 // Check if output type exists, if not register
137 const RooCatType* outType = lookupType(outKey) ;
138 if (!outType) {
139 if (outIdx==NoCatIdx) {
140 outType = defineType(outKey) ;
141 } else {
142 outType = defineType(outKey,outIdx) ;
143 }
144 }
145 if (!outType) {
146 coutE(InputArguments) << "RooMappedCategory::map(" << GetName()
147 << "): ERROR, unable to output type " << outKey << std::endl ;
148 return kTRUE ;
149 }
150
151 // Create new map entry ;
152 Entry e(inKeyRegExp,outType) ;
153 if (!e.ok()) {
154 coutE(InputArguments) << "RooMappedCategory::map(" << GetName()
155 << "): ERROR, expression " << inKeyRegExp << " didn't compile" << std::endl ;
156 return kTRUE ;
157 }
158
159 _mapArray[inKeyRegExp] = e ;
160 return kFALSE ;
161}
162
163
164
166{
168 return *(cache->lookup(Int_t(_inputCat)));
169}
170
171const RooMappedCategoryCache* RooMappedCategory::getOrCreateCache() const
172{
174 const_cast<RooMappedCategory*>(this));
175 return _mapcache;
176}
177
179{
180 // Print info about this mapped category to the specified stream. In addition to the info
181 // from RooAbsCategory::printStream() we add:
182 //
183 // Standard : input category
184 // Shape : default value
185 // Verbose : list of mapping rules
186
188
189 if (verbose) {
190 os << indent << "--- RooMappedCategory ---" << std::endl
191 << indent << " Maps from " ;
193
194 os << indent << " Default value is ";
196
197 os << indent << " Mapping rules:" << std::endl;
198 for (std::map<std::string,Entry>::const_iterator iter = _mapArray.begin() ; iter!=_mapArray.end() ; ++iter) {
199 os << indent << " " << iter->first << " -> " << iter->second.outCat().GetName() << std::endl ;
200 }
201 }
202}
203
204
205Bool_t RooMappedCategory::readFromStream(std::istream& is, Bool_t compact, Bool_t /*verbose*/)
206{
207 // Read object contents from given stream
208 if (compact) {
209 coutE(InputArguments) << "RooMappedCategory::readFromSteam(" << GetName() << "): can't read in compact mode" << std::endl ;
210 return kTRUE ;
211 } else {
212
213 //Clear existing definitions, but preserve default output
214 TString defCatName(_defCat->GetName()) ;
215 _mapArray.clear() ;
216 delete _mapcache;
217 _mapcache = 0;
218 clearTypes() ;
219 _defCat = (RooCatType*) defineType(defCatName) ;
220
221 TString token,errorPrefix("RooMappedCategory::readFromStream(") ;
222 errorPrefix.Append(GetName()) ;
223 errorPrefix.Append(")") ;
224 RooStreamParser parser(is,errorPrefix) ;
225 parser.setPunctuation(":,") ;
226
227 TString destKey,srcKey ;
228 Bool_t readToken(kTRUE) ;
229
230 // Loop over definition sequences
231 while(1) {
232 if (readToken) token=parser.readToken() ;
233 if (token.IsNull()) break ;
234 readToken=kTRUE ;
235
236 destKey = token ;
237 if (parser.expectToken(":",kTRUE)) return kTRUE ;
238
239 // Loop over list of sources for this destination
240 while(1) {
241 srcKey = parser.readToken() ;
242 token = parser.readToken() ;
243
244 // Map a value
245 if (map(srcKey,destKey)) return kTRUE ;
246
247 // Unless next token is ',' current token
248 // is destination part of next sequence
249 if (token.CompareTo(",")) {
250 readToken = kFALSE ;
251 break ;
252 }
253 }
254 }
255 return kFALSE ;
256 }
257 //return kFALSE ; // statement unreachable (OSF)
258}
259
260
261////////////////////////////////////////////////////////////////////////////////
262/// Customized printing of arguments of a RooMappedCategory to more intuitively reflect the contents of the
263/// product operator construction
264
265void RooMappedCategory::printMetaArgs(std::ostream& os) const
266{
267 // Scan array of regexps
268 RooCatType prevOutCat ;
270 os << "map=(" ;
271 for (std::map<std::string,Entry>::const_iterator iter = _mapArray.begin() ; iter!=_mapArray.end() ; ++iter) {
272 if (iter->second.outCat().getVal()!=prevOutCat.getVal()) {
273 if (!first) { os << " " ; }
274 first=kFALSE ;
275
276 os << iter->second.outCat().GetName() << ":" << iter->first ;
277 prevOutCat=iter->second.outCat() ;
278 } else {
279 os << "," << iter->first ;
280 }
281 }
282
283 if (!first) { os << " " ; }
284 os << _defCat->GetName() << ":*" ;
285
286 os << ") " ;
287}
288
289
290
291
292void RooMappedCategory::writeToStream(std::ostream& os, Bool_t compact) const
293{
294 // Write object contents to given stream
295 if (compact) {
296 // Write value only
297 os << getLabel() ;
298 } else {
299 // Write mapping expression
300
301 // Scan array of regexps
302 RooCatType prevOutCat ;
304 for (std::map<std::string,Entry>::const_iterator iter = _mapArray.begin() ; iter!=_mapArray.end() ; ++iter) {
305 if (iter->second.outCat().getVal()!=prevOutCat.getVal()) {
306 if (!first) { os << " " ; }
307 first=kFALSE ;
308
309 os << iter->second.outCat().GetName() << "<-" << iter->first ;
310 prevOutCat=iter->second.outCat() ;
311 } else {
312 os << "," << iter->first ;
313 }
314 }
315
316 if (!first) { os << " " ; }
317 os << _defCat->GetName() << ":*" ;
318 }
319}
320
321
322
323
324////////////////////////////////////////////////////////////////////////////////
325
327{
328 if (&other==this) return *this ;
329
330 _expr = other._expr ;
331 _cat = other._cat ;
332
333 if (_regexp) {
334 delete _regexp ;
335 }
336 _regexp = new TRegexp(_expr.Data(),kTRUE) ;
337
338 return *this;
339}
340
341
342
343////////////////////////////////////////////////////////////////////////////////
344/// Mangle name : escape regexp character '+'
345
347{
348 TString t ;
349 const char *c = exp ;
350 while(*c) {
351 if (*c=='+') t.Append('\\') ;
352 t.Append(*c) ;
353 c++ ;
354 }
355 return t ;
356}
357
358
359
360////////////////////////////////////////////////////////////////////////////////
361
362void RooMappedCategory::Entry::Streamer(TBuffer &R__b)
363{
364 typedef ::RooMappedCategory::Entry ThisClass;
365
366 // Stream an object of class RooWorkspace::CodeRepo.
367 if (R__b.IsReading()) {
368
369 UInt_t R__s, R__c;
370 R__b.ReadVersion(&R__s, &R__c);
371
372 // Stream contents of ClassFiles map
373 R__b >> _expr ;
374 _cat.Streamer(R__b) ;
375 _regexp = new TRegexp(_expr.Data(),kTRUE) ;
376 R__b.CheckByteCount(R__s, R__c, ThisClass::IsA());
377
378 } else {
379
380 UInt_t R__c;
381 R__c = R__b.WriteVersion(ThisClass::IsA(), kTRUE);
382
383 // Stream contents of ClassRelInfo map
384 R__b << _expr ;
385 _cat.Streamer(R__b) ;
386
387 R__b.SetByteCount(R__c, kTRUE);
388
389 }
390}
#define c(i)
Definition: RSha256.hxx:101
#define e(i)
Definition: RSha256.hxx:103
static void initialise(gsl_integration_workspace *workspace, double a, double b)
#define coutE(a)
Definition: RooMsgService.h:34
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition: TGX11.cxx:109
double exp(double)
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:71
RooAbsCache is the abstract base class for data members of RooAbsArgs that cache other (composite) Ro...
Definition: RooAbsCache.h:27
virtual Bool_t redirectServersHook(const RooAbsCollection &, Bool_t, Bool_t, Bool_t)
Interface for server redirect calls.
Definition: RooAbsCache.cxx:89
RooAbsArg * _owner
Definition: RooAbsCache.h:44
virtual void wireCache()
Definition: RooAbsCache.h:38
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
virtual const char * getLabel() const
Return label string of current state.
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 RooCatType * defineType(const char *label)
Define a new state with given name.
const RooCatType * lookupType(Int_t index, Bool_t printError=kFALSE) const
Find our type corresponding to the specified index, or return 0 for no match.
void clearTypes()
Delete all currently defined states.
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
RooCatType is an auxilary class for RooAbsCategory and defines a a single category state.
Definition: RooCatType.h:22
virtual const Text_t * GetName() const
Returns name of object.
Definition: RooCatType.h:44
Int_t getVal() const
Definition: RooCatType.h:79
const RooAbsCategory & arg() const
Entry & operator=(const Entry &other)
TString mangle(const char *exp) const
Mangle name : escape regexp character '+'.
const RooMappedCategoryCache * getOrCreateCache() const
RooCategoryProxy _inputCat
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)
Read object contents from stream (dummy for now)
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to ostream.
std::map< std::string, RooMappedCategory::Entry > _mapArray
friend class RooMappedCategoryCache
RooCatType * _defCat
Bool_t map(const char *inKeyRegExp, const char *outKeyName, Int_t outKeyNum=NoCatIdx)
void printMetaArgs(std::ostream &os) const
Customized printing of arguments of a RooMappedCategory to more intuitively reflect the contents of t...
virtual RooCatType evaluate() const
transient member: cache the mapping
RooMappedCategoryCache * _mapcache
void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Print info about this object to the specified stream.
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_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.
TString readToken()
Read one token separated by any of the know punctuation characters This function recognizes and handl...
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Bool_t IsReading() const
Definition: TBuffer.h:85
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Regular expression class.
Definition: TRegexp.h:31
Basic string class.
Definition: TString.h:131
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:418
const char * Data() const
Definition: TString.h:364
Bool_t IsNull() const
Definition: TString.h:402
TString & Append(const char *cs)
Definition: TString.h:559
@ InputArguments
Definition: RooGlobalFunc.h:68
Definition: first.py:1