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