/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 *    File: $Id: RooMappedCategory.cc,v 1.26 2005/06/20 15:44:55 wverkerke Exp $
 * 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 "Riostream.h"
#include <stdlib.h>
#include <stdio.h>
#include "TString.h"
#include "RooMappedCategory.h"
#include "RooStreamParser.h"
#include "RooMapCatEntry.h"

ClassImp(RooMappedCategory)


 RooMappedCategory::RooMappedCategory(const char *name, const char *title, RooAbsCategory& inputCat, const char* defOut, Int_t defOutIdx) :
  RooAbsCategory(name, title), _inputCat("inputCat","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("inputCat",this,other._inputCat)
{
  _defCat = (RooCatType*) lookupType(other._defCat->GetName()) ;

  // Copy constructor
  int i ;
  for (i=0 ; i<other._mapArray.GetEntries() ; i++) {
    _mapArray.Add(new RooMapCatEntry(*(RooMapCatEntry*)other._mapArray.At(i))) ;
  }
}



 RooMappedCategory::~RooMappedCategory() 
{
  // Destructor
  _mapArray.Delete() ;
}



 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.FindObject(inKeyRegExp)) {
    cout << "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) {
    cout << "RooMappedCategory::map(" << GetName() 
	 << "): ERROR, unable to output type " << outKey << endl ;
    return kTRUE ;    
  }

  // Create new map entry ;
  RooMapCatEntry *newMap = new RooMapCatEntry(inKeyRegExp,outType) ;
  if (!newMap->ok()) {
    cout << "RooMappedCategory::map(" << GetName() 
	 << "): ERROR, expression " << inKeyRegExp << " didn't compile" << endl ;
    delete newMap ;
    return kTRUE ;    
  }

  _mapArray.Add(newMap) ;  
  return kFALSE ;
}



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

  // Scan array of regexps
  for (int i=0 ; i<_mapArray.GetEntries() ; i++) {
    RooMapCatEntry* map = (RooMapCatEntry*)_mapArray.At(i) ;
    if (map->match(inKey)) {
      return map->outCat() ;
    }
  }

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


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

   RooAbsCategory::printToStream(os,opt,indent);

   if (opt > Standard) {
     os << indent << "--- RooMappedCategory ---" << endl
	<< indent << "  Maps from " ;
     _inputCat.arg().printToStream(os,Standard);
     
     os << indent << "  Default value is ";
     _defCat->printToStream(os,OneLine);

     os << indent << "  Mapping rules:" << endl;
     Int_t n= _mapArray.GetEntries();
     for(Int_t i= 0 ; i< n; i++) {
       RooMapCatEntry* map = (RooMapCatEntry*)_mapArray.At(i) ;
       os << indent << "  " << map->GetName() << " -> " << map->outCat().GetName() << endl ;
     }
   }
}


 Bool_t RooMappedCategory::readFromStream(istream& is, Bool_t compact, Bool_t /*verbose*/) 
{
  // Read object contents from given stream
   if (compact) {
     cout << "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.Delete() ;
     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::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 (int i=0 ; i<_mapArray.GetEntries() ; i++) {
      RooMapCatEntry* map = (RooMapCatEntry*)_mapArray.At(i) ;
      if (map->outCat().getVal()!=prevOutCat.getVal()) {
	if (!first) { os << " " ; }
	first=kFALSE ;

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


ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.