Logo ROOT   6.14/05
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 
41 class 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 
88 RooMappedCategory::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 {
106  _defCat = (RooCatType*) lookupType(other._defCat->GetName()) ;
107 }
108 
109 
110 
112 {
113  // Destructor
114  delete _mapcache;
115 }
116 
117 
118 
119 Bool_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 {
167  const RooMappedCategoryCache* cache = getOrCreateCache();
168  return *(cache->lookup(Int_t(_inputCat)));
169 }
170 
172 {
174  const_cast<RooMappedCategory*>(this));
175  return _mapcache;
176 }
177 
178 void RooMappedCategory::printMultiline(std::ostream& os, Int_t content, Bool_t verbose, TString indent) const
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 
187  RooAbsCategory::printMultiline(os,content,verbose,indent);
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 
205 Bool_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 
265 void RooMappedCategory::printMetaArgs(std::ostream& os) const
266 {
267  // Scan array of regexps
268  RooCatType prevOutCat ;
269  Bool_t first(kTRUE) ;
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 
292 void 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 ;
303  Bool_t first(kTRUE) ;
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 
362 void 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 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Bool_t IsReading() const
Definition: TBuffer.h:83
#define coutE(a)
Definition: RooMsgService.h:34
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, which is interpreted as an OR of &#39;enum ContentsOptions&#39; values and in the style given by &#39;enum StyleOption&#39;.
RooMappedCategoryCache * _mapcache
RooAbsArg * _owner
Definition: RooAbsCache.h:44
RooCatType * _defCat
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
Regular expression class.
Definition: TRegexp.h:31
void clearTypes()
Delete all currently defined states.
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Basic string class.
Definition: TString.h:131
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual RooCatType evaluate() const
transient member: cache the mapping
Entry & operator=(const Entry &other)
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
RooAbsCache is the abstract base class for data members of RooAbsArgs that cache other (composite) Ro...
Definition: RooAbsCache.h:27
friend class RooMappedCategoryCache
TString & Append(const char *cs)
Definition: TString.h:559
const RooAbsCategory & arg() const
virtual Bool_t redirectServersHook(const RooAbsCollection &, Bool_t, Bool_t, Bool_t)
Interface for server redirect calls.
Definition: RooAbsCache.cxx:89
RooCatType is an auxilary class for RooAbsCategory and defines a a single category state...
Definition: RooCatType.h:22
TString mangle(const char *exp) const
Mangle name : escape regexp character &#39;+&#39;.
const RooCatType * defineType(const char *label)
Define a new state with given name.
Bool_t map(const char *inKeyRegExp, const char *outKeyName, Int_t outKeyNum=NoCatIdx)
const RooMappedCategoryCache * getOrCreateCache() const
virtual const Text_t * GetName() const
Returns name of object.
Definition: RooCatType.h:44
TString readToken()
Read one token separated by any of the know punctuation characters This function recognizes and handl...
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.
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void wireCache()
Definition: RooAbsCache.h:38
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
virtual const char * getLabel() const
Return label string of current state.
Bool_t expectToken(const TString &expected, Bool_t zapOnError=kFALSE)
Read the next token and return kTRUE if it is identical to the given &#39;expected&#39; token.
static void initialise(gsl_integration_workspace *workspace, double a, double b)
const Bool_t kFALSE
Definition: RtypesCore.h:88
#define ClassImp(name)
Definition: Rtypes.h:359
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.
void printMetaArgs(std::ostream &os) const
Customized printing of arguments of a RooMappedCategory to more intuitively reflect the contents of t...
std::map< std::string, RooMappedCategory::Entry > _mapArray
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:406
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)
Read object contents from stream (dummy for now)
void setPunctuation(const TString &punct)
Change list of characters interpreted as punctuation.
Bool_t IsNull() const
Definition: TString.h:402
RooCategoryProxy _inputCat
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects...
virtual void writeToStream(std::ostream &os, Bool_t compact) const
Write object contents to ostream.
Int_t getVal() const
Definition: RooCatType.h:79
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
#define c(i)
Definition: RSha256.hxx:101
Definition: first.py:1
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
double exp(double)
void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Print info about this object to the specified stream.
const Bool_t kTRUE
Definition: RtypesCore.h:87
char name[80]
Definition: TGX11.cxx:109
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0