ROOT logo
/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id: RooMappedCategory.cxx 28259 2009-04-16 16:21:16Z wouter $
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

// -- CLASS DESCRIPTION [CAT] --
// RooMappedCategory provides a category-to-category mapping defined
// by pattern matching on their state labels
//
// The mapping function consists of a series of wild card regular expressions.
// Each expression is matched to the input categories state labels, and an associated
// output state label.


#include "RooFit.h"

#include "Riostream.h"
#include <stdlib.h>
#include <stdio.h>
#include "TString.h"
#include "RooMappedCategory.h"
#include "RooStreamParser.h"
#include "RooMsgService.h"

using namespace std ;

ClassImp(RooMappedCategory)
ClassImp(RooMappedCategory::Entry)


RooMappedCategory::RooMappedCategory(const char *name, const char *title, RooAbsCategory& inputCat, const char* defOut, Int_t defOutIdx) :
  RooAbsCategory(name, title), _inputCat("input","Input category",this,inputCat)
{
  // Constructor with input category and name of default output state, which is assigned
  // to all input category states that do not follow any mapping rule.
  if (defOutIdx==NoCatIdx) {
    _defCat = (RooCatType*) defineType(defOut) ;
  } else {
    _defCat = (RooCatType*) defineType(defOut,defOutIdx) ;
  }
}


RooMappedCategory::RooMappedCategory(const RooMappedCategory& other, const char *name) :
  RooAbsCategory(other,name), _inputCat("input",this,other._inputCat), _mapArray(other._mapArray)
{
  _defCat = (RooCatType*) lookupType(other._defCat->GetName()) ;
}



RooMappedCategory::~RooMappedCategory() 
{
  // Destructor
}



Bool_t RooMappedCategory::map(const char* inKeyRegExp, const char* outKey, Int_t outIdx)
{
  // Add mapping rule: any input category state label matching the 'inKeyRegExp'
  // wildcard expression will be mapped to an output state with name 'outKey'
  //
  // Rules are evaluated in the order they were added. In case an input state
  // matches more than one rule, the first rules output state will be assigned

  if (!inKeyRegExp || !outKey) return kTRUE ;  

  // Check if pattern is already registered
  if (_mapArray.find(inKeyRegExp)!=_mapArray.end()) {
    coutE(InputArguments) << "RooMappedCategory::map(" << GetName() << "): ERROR expression " 
			  << inKeyRegExp << " already mapped" << endl ;
    return kTRUE ;
  }

  // Check if output type exists, if not register
  const RooCatType* outType = lookupType(outKey) ;
  if (!outType) {
    if (outIdx==NoCatIdx) {
      outType = defineType(outKey) ;
    } else {
      outType = defineType(outKey,outIdx) ;
    }
  }
  if (!outType) {
    coutE(InputArguments) << "RooMappedCategory::map(" << GetName() 
			  << "): ERROR, unable to output type " << outKey << endl ;
    return kTRUE ;    
  }

  // Create new map entry ;
  Entry e(inKeyRegExp,outType) ;
  if (!e.ok()) {
    coutE(InputArguments) << "RooMappedCategory::map(" << GetName() 
			  << "): ERROR, expression " << inKeyRegExp << " didn't compile" << endl ;
    return kTRUE ;    
  }

  _mapArray[inKeyRegExp] = e ;
  return kFALSE ;
}



RooCatType RooMappedCategory::evaluate() const
{
  // Calculate the current value of the object
  const char* inKey = _inputCat.label() ;

  // Scan array of regexps
  for ( std::map<string,Entry>::const_iterator iter = _mapArray.begin() ; iter != _mapArray.end() ; iter++) {
    if (iter->second.match(inKey)) {
      return iter->second.outCat() ;
    }
  }

  // Return default if nothing found
  return *_defCat ;
}


void RooMappedCategory::printMultiline(ostream& os, Int_t content, Bool_t verbose, TString indent) const
{
  // Print info about this mapped category to the specified stream. In addition to the info
  // from RooAbsCategory::printStream() we add:
  //
  //  Standard : input category
  //     Shape : default value
  //   Verbose : list of mapping rules

  RooAbsCategory::printMultiline(os,content,verbose,indent);

  if (verbose) {
    os << indent << "--- RooMappedCategory ---" << endl
       << indent << "  Maps from " ;
    _inputCat.arg().printStream(os,0,kStandard);
    
    os << indent << "  Default value is ";
    _defCat->printStream(os,kName|kValue,kSingleLine);
    
    os << indent << "  Mapping rules:" << endl;
    for (std::map<string,Entry>::const_iterator iter = _mapArray.begin() ; iter!=_mapArray.end() ; iter++) {
      os << indent << "  " << iter->first << " -> " << iter->second.outCat().GetName() << endl ;
    }
  }
}


Bool_t RooMappedCategory::readFromStream(istream& is, Bool_t compact, Bool_t /*verbose*/) 
{
  // Read object contents from given stream
   if (compact) {
     coutE(InputArguments) << "RooMappedCategory::readFromSteam(" << GetName() << "): can't read in compact mode" << endl ;
     return kTRUE ;    
   } else {

     //Clear existing definitions, but preserve default output
     TString defCatName(_defCat->GetName()) ;
     _mapArray.clear() ;
     clearTypes() ;
     _defCat = (RooCatType*) defineType(defCatName) ;

     TString token,errorPrefix("RooMappedCategory::readFromStream(") ;
     errorPrefix.Append(GetName()) ;
     errorPrefix.Append(")") ;
     RooStreamParser parser(is,errorPrefix) ;
     parser.setPunctuation(":,") ;
  
     TString destKey,srcKey ;
     Bool_t readToken(kTRUE) ;

    // Loop over definition sequences
     while(1) {      
       if (readToken) token=parser.readToken() ;
       if (token.IsNull()) break ;
       readToken=kTRUE ;

       destKey = token ;
       if (parser.expectToken(":",kTRUE)) return kTRUE ;

       // Loop over list of sources for this destination
       while(1) { 
	 srcKey = parser.readToken() ;	
	 token = parser.readToken() ;

	 // Map a value
	 if (map(srcKey,destKey)) return kTRUE ;
       
	 // Unless next token is ',' current token 
	 // is destination part of next sequence
	 if (token.CompareTo(",")) {	  	  
	   readToken = kFALSE ;
	   break ;
	 } 	
       }
     }
     return kFALSE ;
   }
   //return kFALSE ; // statement unreachable (OSF)
}


//_____________________________________________________________________________
void RooMappedCategory::printMetaArgs(ostream& os) const 
{
  // Customized printing of arguments of a RooMappedCategory to more intuitively reflect the contents of the
  // product operator construction

  // Scan array of regexps
  RooCatType prevOutCat ;
  Bool_t first(kTRUE) ;
  os << "map=(" ;
  for (std::map<string,Entry>::const_iterator iter = _mapArray.begin() ; iter!=_mapArray.end() ; iter++) {
    if (iter->second.outCat().getVal()!=prevOutCat.getVal()) {
      if (!first) { os << " " ; }
      first=kFALSE ;
      
      os << iter->second.outCat().GetName() << ":" << iter->first ;
      prevOutCat=iter->second.outCat() ;
    } else {
      os << "," << iter->first ;
    }
  }
  
  if (!first) { os << " " ; }
  os << _defCat->GetName() << ":*" ;  
  
  os << ") " ;    
}




void RooMappedCategory::writeToStream(ostream& os, Bool_t compact) const
{
  // Write object contents to given stream
  if (compact) {
    // Write value only
    os << getLabel() ;
  } else {
    // Write mapping expression

    // Scan array of regexps
    RooCatType prevOutCat ;
    Bool_t first(kTRUE) ;
    for (std::map<string,Entry>::const_iterator iter = _mapArray.begin() ; iter!=_mapArray.end() ; iter++) {
      if (iter->second.outCat().getVal()!=prevOutCat.getVal()) {
	if (!first) { os << " " ; }
	first=kFALSE ;

	os << iter->second.outCat().GetName() << "<-" << iter->first ;
	prevOutCat=iter->second.outCat() ;
      } else {
	os << "," << iter->first ;
      }
    }
    
    if (!first) { os << " " ; }
    os << _defCat->GetName() << ":*" ;  
  }
}




//_____________________________________________________________________________
RooMappedCategory::Entry& RooMappedCategory::Entry::operator=(const RooMappedCategory::Entry& other)
{
  if (&other==this) return *this ;

  _expr = other._expr ;
  _cat = other._cat ;

  if (_regexp) {
    delete _regexp ;
  }
  _regexp = new TRegexp(_expr.Data(),kTRUE) ;

  return *this;  
}



//_____________________________________________________________________________
TString RooMappedCategory::Entry::mangle(const char* exp) const
{
  // Mangle name : escape regexp character '+'
  TString t ;
  const char *c = exp ;
  while(*c) {
    if (*c=='+') t.Append('\\') ;
    t.Append(*c) ;
    c++ ;
  }
  return t ;
}



//_____________________________________________________________________________
void RooMappedCategory::Entry::Streamer(TBuffer &R__b)
{
  typedef ::RooMappedCategory::Entry ThisClass;

   // Stream an object of class RooWorkspace::CodeRepo.
   if (R__b.IsReading()) {

     UInt_t R__s, R__c;
     R__b.ReadVersion(&R__s, &R__c); 
     
     // Stream contents of ClassFiles map     
     R__b >> _expr ;
     _cat.Streamer(R__b) ;     
     _regexp = new TRegexp(_expr.Data(),kTRUE) ;
     R__b.CheckByteCount(R__s, R__c, ThisClass::IsA());

   } else {
     
     UInt_t R__c;
     R__c = R__b.WriteVersion(ThisClass::IsA(), kTRUE);
     
     // Stream contents of ClassRelInfo map
     R__b << _expr ;
     _cat.Streamer(R__b) ;

     R__b.SetByteCount(R__c, kTRUE);
     
   }
}
 RooMappedCategory.cxx:1
 RooMappedCategory.cxx:2
 RooMappedCategory.cxx:3
 RooMappedCategory.cxx:4
 RooMappedCategory.cxx:5
 RooMappedCategory.cxx:6
 RooMappedCategory.cxx:7
 RooMappedCategory.cxx:8
 RooMappedCategory.cxx:9
 RooMappedCategory.cxx:10
 RooMappedCategory.cxx:11
 RooMappedCategory.cxx:12
 RooMappedCategory.cxx:13
 RooMappedCategory.cxx:14
 RooMappedCategory.cxx:15
 RooMappedCategory.cxx:16
 RooMappedCategory.cxx:17
 RooMappedCategory.cxx:18
 RooMappedCategory.cxx:19
 RooMappedCategory.cxx:20
 RooMappedCategory.cxx:21
 RooMappedCategory.cxx:22
 RooMappedCategory.cxx:23
 RooMappedCategory.cxx:24
 RooMappedCategory.cxx:25
 RooMappedCategory.cxx:26
 RooMappedCategory.cxx:27
 RooMappedCategory.cxx:28
 RooMappedCategory.cxx:29
 RooMappedCategory.cxx:30
 RooMappedCategory.cxx:31
 RooMappedCategory.cxx:32
 RooMappedCategory.cxx:33
 RooMappedCategory.cxx:34
 RooMappedCategory.cxx:35
 RooMappedCategory.cxx:36
 RooMappedCategory.cxx:37
 RooMappedCategory.cxx:38
 RooMappedCategory.cxx:39
 RooMappedCategory.cxx:40
 RooMappedCategory.cxx:41
 RooMappedCategory.cxx:42
 RooMappedCategory.cxx:43
 RooMappedCategory.cxx:44
 RooMappedCategory.cxx:45
 RooMappedCategory.cxx:46
 RooMappedCategory.cxx:47
 RooMappedCategory.cxx:48
 RooMappedCategory.cxx:49
 RooMappedCategory.cxx:50
 RooMappedCategory.cxx:51
 RooMappedCategory.cxx:52
 RooMappedCategory.cxx:53
 RooMappedCategory.cxx:54
 RooMappedCategory.cxx:55
 RooMappedCategory.cxx:56
 RooMappedCategory.cxx:57
 RooMappedCategory.cxx:58
 RooMappedCategory.cxx:59
 RooMappedCategory.cxx:60
 RooMappedCategory.cxx:61
 RooMappedCategory.cxx:62
 RooMappedCategory.cxx:63
 RooMappedCategory.cxx:64
 RooMappedCategory.cxx:65
 RooMappedCategory.cxx:66
 RooMappedCategory.cxx:67
 RooMappedCategory.cxx:68
 RooMappedCategory.cxx:69
 RooMappedCategory.cxx:70
 RooMappedCategory.cxx:71
 RooMappedCategory.cxx:72
 RooMappedCategory.cxx:73
 RooMappedCategory.cxx:74
 RooMappedCategory.cxx:75
 RooMappedCategory.cxx:76
 RooMappedCategory.cxx:77
 RooMappedCategory.cxx:78
 RooMappedCategory.cxx:79
 RooMappedCategory.cxx:80
 RooMappedCategory.cxx:81
 RooMappedCategory.cxx:82
 RooMappedCategory.cxx:83
 RooMappedCategory.cxx:84
 RooMappedCategory.cxx:85
 RooMappedCategory.cxx:86
 RooMappedCategory.cxx:87
 RooMappedCategory.cxx:88
 RooMappedCategory.cxx:89
 RooMappedCategory.cxx:90
 RooMappedCategory.cxx:91
 RooMappedCategory.cxx:92
 RooMappedCategory.cxx:93
 RooMappedCategory.cxx:94
 RooMappedCategory.cxx:95
 RooMappedCategory.cxx:96
 RooMappedCategory.cxx:97
 RooMappedCategory.cxx:98
 RooMappedCategory.cxx:99
 RooMappedCategory.cxx:100
 RooMappedCategory.cxx:101
 RooMappedCategory.cxx:102
 RooMappedCategory.cxx:103
 RooMappedCategory.cxx:104
 RooMappedCategory.cxx:105
 RooMappedCategory.cxx:106
 RooMappedCategory.cxx:107
 RooMappedCategory.cxx:108
 RooMappedCategory.cxx:109
 RooMappedCategory.cxx:110
 RooMappedCategory.cxx:111
 RooMappedCategory.cxx:112
 RooMappedCategory.cxx:113
 RooMappedCategory.cxx:114
 RooMappedCategory.cxx:115
 RooMappedCategory.cxx:116
 RooMappedCategory.cxx:117
 RooMappedCategory.cxx:118
 RooMappedCategory.cxx:119
 RooMappedCategory.cxx:120
 RooMappedCategory.cxx:121
 RooMappedCategory.cxx:122
 RooMappedCategory.cxx:123
 RooMappedCategory.cxx:124
 RooMappedCategory.cxx:125
 RooMappedCategory.cxx:126
 RooMappedCategory.cxx:127
 RooMappedCategory.cxx:128
 RooMappedCategory.cxx:129
 RooMappedCategory.cxx:130
 RooMappedCategory.cxx:131
 RooMappedCategory.cxx:132
 RooMappedCategory.cxx:133
 RooMappedCategory.cxx:134
 RooMappedCategory.cxx:135
 RooMappedCategory.cxx:136
 RooMappedCategory.cxx:137
 RooMappedCategory.cxx:138
 RooMappedCategory.cxx:139
 RooMappedCategory.cxx:140
 RooMappedCategory.cxx:141
 RooMappedCategory.cxx:142
 RooMappedCategory.cxx:143
 RooMappedCategory.cxx:144
 RooMappedCategory.cxx:145
 RooMappedCategory.cxx:146
 RooMappedCategory.cxx:147
 RooMappedCategory.cxx:148
 RooMappedCategory.cxx:149
 RooMappedCategory.cxx:150
 RooMappedCategory.cxx:151
 RooMappedCategory.cxx:152
 RooMappedCategory.cxx:153
 RooMappedCategory.cxx:154
 RooMappedCategory.cxx:155
 RooMappedCategory.cxx:156
 RooMappedCategory.cxx:157
 RooMappedCategory.cxx:158
 RooMappedCategory.cxx:159
 RooMappedCategory.cxx:160
 RooMappedCategory.cxx:161
 RooMappedCategory.cxx:162
 RooMappedCategory.cxx:163
 RooMappedCategory.cxx:164
 RooMappedCategory.cxx:165
 RooMappedCategory.cxx:166
 RooMappedCategory.cxx:167
 RooMappedCategory.cxx:168
 RooMappedCategory.cxx:169
 RooMappedCategory.cxx:170
 RooMappedCategory.cxx:171
 RooMappedCategory.cxx:172
 RooMappedCategory.cxx:173
 RooMappedCategory.cxx:174
 RooMappedCategory.cxx:175
 RooMappedCategory.cxx:176
 RooMappedCategory.cxx:177
 RooMappedCategory.cxx:178
 RooMappedCategory.cxx:179
 RooMappedCategory.cxx:180
 RooMappedCategory.cxx:181
 RooMappedCategory.cxx:182
 RooMappedCategory.cxx:183
 RooMappedCategory.cxx:184
 RooMappedCategory.cxx:185
 RooMappedCategory.cxx:186
 RooMappedCategory.cxx:187
 RooMappedCategory.cxx:188
 RooMappedCategory.cxx:189
 RooMappedCategory.cxx:190
 RooMappedCategory.cxx:191
 RooMappedCategory.cxx:192
 RooMappedCategory.cxx:193
 RooMappedCategory.cxx:194
 RooMappedCategory.cxx:195
 RooMappedCategory.cxx:196
 RooMappedCategory.cxx:197
 RooMappedCategory.cxx:198
 RooMappedCategory.cxx:199
 RooMappedCategory.cxx:200
 RooMappedCategory.cxx:201
 RooMappedCategory.cxx:202
 RooMappedCategory.cxx:203
 RooMappedCategory.cxx:204
 RooMappedCategory.cxx:205
 RooMappedCategory.cxx:206
 RooMappedCategory.cxx:207
 RooMappedCategory.cxx:208
 RooMappedCategory.cxx:209
 RooMappedCategory.cxx:210
 RooMappedCategory.cxx:211
 RooMappedCategory.cxx:212
 RooMappedCategory.cxx:213
 RooMappedCategory.cxx:214
 RooMappedCategory.cxx:215
 RooMappedCategory.cxx:216
 RooMappedCategory.cxx:217
 RooMappedCategory.cxx:218
 RooMappedCategory.cxx:219
 RooMappedCategory.cxx:220
 RooMappedCategory.cxx:221
 RooMappedCategory.cxx:222
 RooMappedCategory.cxx:223
 RooMappedCategory.cxx:224
 RooMappedCategory.cxx:225
 RooMappedCategory.cxx:226
 RooMappedCategory.cxx:227
 RooMappedCategory.cxx:228
 RooMappedCategory.cxx:229
 RooMappedCategory.cxx:230
 RooMappedCategory.cxx:231
 RooMappedCategory.cxx:232
 RooMappedCategory.cxx:233
 RooMappedCategory.cxx:234
 RooMappedCategory.cxx:235
 RooMappedCategory.cxx:236
 RooMappedCategory.cxx:237
 RooMappedCategory.cxx:238
 RooMappedCategory.cxx:239
 RooMappedCategory.cxx:240
 RooMappedCategory.cxx:241
 RooMappedCategory.cxx:242
 RooMappedCategory.cxx:243
 RooMappedCategory.cxx:244
 RooMappedCategory.cxx:245
 RooMappedCategory.cxx:246
 RooMappedCategory.cxx:247
 RooMappedCategory.cxx:248
 RooMappedCategory.cxx:249
 RooMappedCategory.cxx:250
 RooMappedCategory.cxx:251
 RooMappedCategory.cxx:252
 RooMappedCategory.cxx:253
 RooMappedCategory.cxx:254
 RooMappedCategory.cxx:255
 RooMappedCategory.cxx:256
 RooMappedCategory.cxx:257
 RooMappedCategory.cxx:258
 RooMappedCategory.cxx:259
 RooMappedCategory.cxx:260
 RooMappedCategory.cxx:261
 RooMappedCategory.cxx:262
 RooMappedCategory.cxx:263
 RooMappedCategory.cxx:264
 RooMappedCategory.cxx:265
 RooMappedCategory.cxx:266
 RooMappedCategory.cxx:267
 RooMappedCategory.cxx:268
 RooMappedCategory.cxx:269
 RooMappedCategory.cxx:270
 RooMappedCategory.cxx:271
 RooMappedCategory.cxx:272
 RooMappedCategory.cxx:273
 RooMappedCategory.cxx:274
 RooMappedCategory.cxx:275
 RooMappedCategory.cxx:276
 RooMappedCategory.cxx:277
 RooMappedCategory.cxx:278
 RooMappedCategory.cxx:279
 RooMappedCategory.cxx:280
 RooMappedCategory.cxx:281
 RooMappedCategory.cxx:282
 RooMappedCategory.cxx:283
 RooMappedCategory.cxx:284
 RooMappedCategory.cxx:285
 RooMappedCategory.cxx:286
 RooMappedCategory.cxx:287
 RooMappedCategory.cxx:288
 RooMappedCategory.cxx:289
 RooMappedCategory.cxx:290
 RooMappedCategory.cxx:291
 RooMappedCategory.cxx:292
 RooMappedCategory.cxx:293
 RooMappedCategory.cxx:294
 RooMappedCategory.cxx:295
 RooMappedCategory.cxx:296
 RooMappedCategory.cxx:297
 RooMappedCategory.cxx:298
 RooMappedCategory.cxx:299
 RooMappedCategory.cxx:300
 RooMappedCategory.cxx:301
 RooMappedCategory.cxx:302
 RooMappedCategory.cxx:303
 RooMappedCategory.cxx:304
 RooMappedCategory.cxx:305
 RooMappedCategory.cxx:306
 RooMappedCategory.cxx:307
 RooMappedCategory.cxx:308
 RooMappedCategory.cxx:309
 RooMappedCategory.cxx:310
 RooMappedCategory.cxx:311
 RooMappedCategory.cxx:312
 RooMappedCategory.cxx:313
 RooMappedCategory.cxx:314
 RooMappedCategory.cxx:315
 RooMappedCategory.cxx:316
 RooMappedCategory.cxx:317
 RooMappedCategory.cxx:318
 RooMappedCategory.cxx:319
 RooMappedCategory.cxx:320
 RooMappedCategory.cxx:321
 RooMappedCategory.cxx:322
 RooMappedCategory.cxx:323
 RooMappedCategory.cxx:324
 RooMappedCategory.cxx:325
 RooMappedCategory.cxx:326
 RooMappedCategory.cxx:327
 RooMappedCategory.cxx:328
 RooMappedCategory.cxx:329
 RooMappedCategory.cxx:330
 RooMappedCategory.cxx:331
 RooMappedCategory.cxx:332
 RooMappedCategory.cxx:333
 RooMappedCategory.cxx:334
 RooMappedCategory.cxx:335
 RooMappedCategory.cxx:336
 RooMappedCategory.cxx:337
 RooMappedCategory.cxx:338
 RooMappedCategory.cxx:339
 RooMappedCategory.cxx:340