ROOT logo
/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id: RooGenCategory.cxx 25400 2008-09-15 10:08:28Z 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)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// RooGenCategory provides the most flexibe mapping of a series of input categories
// on a output category via a global function provided in the constructor
// <p>
// The mapping function must have the form 'const char* mapFunc(const RooArgSet* catList)'
// and return the name of the output state for the list of categories supplied in the argument.
// The global function can be a ROOT interpreted function.
// <p>
// RooGenCategory builds a numerical index-to-index map from the user function
// to achieve a high performance mapping.
// END_HTML
//

#include "RooFit.h"

#include "Riostream.h"
#include "TMethodCall.h"
#include <stdlib.h>
#include <stdio.h>
#include "TString.h"
#include "TInterpreter.h"  
#include "RooGenCategory.h"
#include "RooStreamParser.h"
#include "RooMapCatEntry.h"
#include "RooErrorHandler.h"
#include "RooMsgService.h"

#if ROOT_VERSION_CODE < ROOT_VERSION(5,20,00)
#include "Api.h"
#endif

ClassImp(RooGenCategory)



//_____________________________________________________________________________
RooGenCategory::RooGenCategory(const char *name, const char *title, void *userFunc, RooArgSet& catList) :
  RooAbsCategory(name, title), 
  _superCat("superCat","Super Category",catList), 
  _superCatProxy("superCatProxy","Super Category Proxy",this,_superCat), 
  _map(0) 
{
  // Constructor with pointer to a CINT user mapping function and list of input categories
  // on which the user mapping function can operate
  
  // Convert the function pointer into a parse object using the CINT
  // dictionary in memory.

#if ROOT_VERSION_CODE >= ROOT_VERSION(5,20,00)
  _userFuncName = gCint->Getp2f2funcname(userFunc);
#else
  _userFuncName = G__p2f2funcname(userFunc);
#endif

  if(_userFuncName.IsNull()) {
    coutE(InputArguments) << GetName() << ": cannot find dictionary info for (void*)"
			  << (void*)userFunc << endl;
    return;
  }
  initialize() ;
}



//_____________________________________________________________________________
RooGenCategory::RooGenCategory(const RooGenCategory& other, const char *name) :
  RooAbsCategory(other,name), _superCat(other._superCat), 
  _superCatProxy("superCatProxy","Super Category Proxy",this,_superCat),
  _map(0), _userFuncName(other._userFuncName)
{
  // Copy constructor

  removeServer((RooAbsArg&)other._superCat) ;
  initialize() ;
}




//_____________________________________________________________________________
void RooGenCategory::initialize()
{
  // Initialization function

  // This is a static link, no need for redirection support
  addServer(_superCat,kTRUE,kTRUE) ;

  _userFunc= new TMethodCall();
  // We must use "RooArgSet*" instead of "RooArgSet&" here (why?)
  _userFunc->InitWithPrototype(_userFuncName.Data(),"RooArgSet*"); 

  updateIndexList() ;
}



//_____________________________________________________________________________
RooGenCategory::~RooGenCategory() 
{
  // Destructor

  // Server no longer exists when RooAbsArg destructor is executing  
  if (_serverList.FindObject(&_superCat)) {
    removeServer(_superCat) ;
  }

  if (_map) delete[] _map ;
}



//_____________________________________________________________________________
TString RooGenCategory::evalUserFunc(RooArgSet *vars) 
{
  // Utility function to evaluate (interpreted) user function

  assert(0 != _userFunc);
  Long_t result;
  _userArgs[0]= (Long_t)vars ;
  _userFunc->SetParamPtrs(_userArgs);
  _userFunc->Execute(result);
  const char *text= (const char *)result;
  return TString(text);
} 



//_____________________________________________________________________________
void RooGenCategory::updateIndexList()
{
  // Loop over all input state permutations and recalculate the mapped output
  // state for each input state and store these in the lookup table

  // Recreate super-index to gen-index map ;
  if (_map) delete[] _map ;
  _map = new Int_t[_superCatProxy.arg().numTypes()] ;
  clearTypes() ;

  // DeepClone super category for iteration
  RooArgSet* tmp=(RooArgSet*) RooArgSet(_superCatProxy.arg()).snapshot(kTRUE) ;
  if (!tmp) {
    coutE(ObjectHandling) << "RooGenCategory::updateIndexList(" << GetName() << ") Couldn't deep-clone super category, abort," << endl ;
    RooErrorHandler::softAbort() ;
  }
  RooSuperCategory* superClone = (RooSuperCategory*) tmp->find(_superCatProxy.arg().GetName()) ;

  TIterator* sIter = superClone->typeIterator() ;
  RooArgSet *catList = superClone->getParameters((const RooArgSet*)0) ;
  RooCatType* type ;
  while ((type=(RooCatType*)sIter->Next())) {
    // Call user function
    superClone->setIndex(type->getVal()) ;

    TString typeName = evalUserFunc(catList) ;

    // Check if type exists for given name, register otherwise
    const RooCatType* theType = lookupType(typeName,kFALSE) ;
    if (!theType) theType = defineType(typeName) ;

    // Fill map for this super-state
    _map[superClone->getIndex()] = theType->getVal() ;
    //cout << "updateIndexList(" << GetName() << ") _map[" << superClone->getLabel() << "] = " << type->GetName() << endl ;
  }

  delete tmp ;
  delete catList ;
}


RooCatType

//_____________________________________________________________________________
RooGenCategory::evaluate() const
{
  // Calculate current value of object
  
  if (isShapeDirty()) {
    const_cast<RooGenCategory*>(this)->updateIndexList() ;
  }

  const RooCatType* ret = lookupType(_map[(Int_t)_superCatProxy]) ;
  if (!ret) {
    cout << "RooGenCategory::evaluate(" << GetName() << ") ERROR: cannot lookup super index " << (Int_t) _superCatProxy << endl ;
    assert(0) ;
  }

  return *ret ;
}



//_____________________________________________________________________________
void RooGenCategory::printMultiline(ostream& os, Int_t content, Bool_t verbose, TString indent) const
{
  // Printing interface

  RooAbsCategory::printMultiline(os,content,verbose,indent);
  
  if (verbose) {     
    os << indent << "--- RooGenCategory ---" << endl;
    os << indent << "  Input category list:" << endl ;
    TString moreIndent(indent) ;
    indent.Append("   ") ;
    ((RooSuperCategory&)_superCatProxy.arg()).inputCatList().printStream(os,kName|kClassName|kArgs,kSingleLine) ;
    os << indent << "  User mapping function is 'const char* " << _userFuncName << "(RooArgSet*)'" << endl ;
  }
}



//_____________________________________________________________________________
Bool_t RooGenCategory::readFromStream(istream& /*is*/, Bool_t compact, Bool_t /*verbose*/) 
{
  // Read object contents from given stream

   if (compact) {
     coutE(InputArguments) << "RooGenCategory::readFromSteam(" << GetName() << "): can't read in compact mode" << endl ;
     return kTRUE ;    
   } else {
     return kFALSE ;
   }
   //return kFALSE ; //OSF: statement unreachable
}



//_____________________________________________________________________________
void RooGenCategory::writeToStream(ostream& os, Bool_t compact) const
{
  // Write object contents to given stream 

  if (compact) {
    // Write value only
    os << getLabel() ;
  } else {
  }
}
 RooGenCategory.cxx:1
 RooGenCategory.cxx:2
 RooGenCategory.cxx:3
 RooGenCategory.cxx:4
 RooGenCategory.cxx:5
 RooGenCategory.cxx:6
 RooGenCategory.cxx:7
 RooGenCategory.cxx:8
 RooGenCategory.cxx:9
 RooGenCategory.cxx:10
 RooGenCategory.cxx:11
 RooGenCategory.cxx:12
 RooGenCategory.cxx:13
 RooGenCategory.cxx:14
 RooGenCategory.cxx:15
 RooGenCategory.cxx:16
 RooGenCategory.cxx:17
 RooGenCategory.cxx:18
 RooGenCategory.cxx:19
 RooGenCategory.cxx:20
 RooGenCategory.cxx:21
 RooGenCategory.cxx:22
 RooGenCategory.cxx:23
 RooGenCategory.cxx:24
 RooGenCategory.cxx:25
 RooGenCategory.cxx:26
 RooGenCategory.cxx:27
 RooGenCategory.cxx:28
 RooGenCategory.cxx:29
 RooGenCategory.cxx:30
 RooGenCategory.cxx:31
 RooGenCategory.cxx:32
 RooGenCategory.cxx:33
 RooGenCategory.cxx:34
 RooGenCategory.cxx:35
 RooGenCategory.cxx:36
 RooGenCategory.cxx:37
 RooGenCategory.cxx:38
 RooGenCategory.cxx:39
 RooGenCategory.cxx:40
 RooGenCategory.cxx:41
 RooGenCategory.cxx:42
 RooGenCategory.cxx:43
 RooGenCategory.cxx:44
 RooGenCategory.cxx:45
 RooGenCategory.cxx:46
 RooGenCategory.cxx:47
 RooGenCategory.cxx:48
 RooGenCategory.cxx:49
 RooGenCategory.cxx:50
 RooGenCategory.cxx:51
 RooGenCategory.cxx:52
 RooGenCategory.cxx:53
 RooGenCategory.cxx:54
 RooGenCategory.cxx:55
 RooGenCategory.cxx:56
 RooGenCategory.cxx:57
 RooGenCategory.cxx:58
 RooGenCategory.cxx:59
 RooGenCategory.cxx:60
 RooGenCategory.cxx:61
 RooGenCategory.cxx:62
 RooGenCategory.cxx:63
 RooGenCategory.cxx:64
 RooGenCategory.cxx:65
 RooGenCategory.cxx:66
 RooGenCategory.cxx:67
 RooGenCategory.cxx:68
 RooGenCategory.cxx:69
 RooGenCategory.cxx:70
 RooGenCategory.cxx:71
 RooGenCategory.cxx:72
 RooGenCategory.cxx:73
 RooGenCategory.cxx:74
 RooGenCategory.cxx:75
 RooGenCategory.cxx:76
 RooGenCategory.cxx:77
 RooGenCategory.cxx:78
 RooGenCategory.cxx:79
 RooGenCategory.cxx:80
 RooGenCategory.cxx:81
 RooGenCategory.cxx:82
 RooGenCategory.cxx:83
 RooGenCategory.cxx:84
 RooGenCategory.cxx:85
 RooGenCategory.cxx:86
 RooGenCategory.cxx:87
 RooGenCategory.cxx:88
 RooGenCategory.cxx:89
 RooGenCategory.cxx:90
 RooGenCategory.cxx:91
 RooGenCategory.cxx:92
 RooGenCategory.cxx:93
 RooGenCategory.cxx:94
 RooGenCategory.cxx:95
 RooGenCategory.cxx:96
 RooGenCategory.cxx:97
 RooGenCategory.cxx:98
 RooGenCategory.cxx:99
 RooGenCategory.cxx:100
 RooGenCategory.cxx:101
 RooGenCategory.cxx:102
 RooGenCategory.cxx:103
 RooGenCategory.cxx:104
 RooGenCategory.cxx:105
 RooGenCategory.cxx:106
 RooGenCategory.cxx:107
 RooGenCategory.cxx:108
 RooGenCategory.cxx:109
 RooGenCategory.cxx:110
 RooGenCategory.cxx:111
 RooGenCategory.cxx:112
 RooGenCategory.cxx:113
 RooGenCategory.cxx:114
 RooGenCategory.cxx:115
 RooGenCategory.cxx:116
 RooGenCategory.cxx:117
 RooGenCategory.cxx:118
 RooGenCategory.cxx:119
 RooGenCategory.cxx:120
 RooGenCategory.cxx:121
 RooGenCategory.cxx:122
 RooGenCategory.cxx:123
 RooGenCategory.cxx:124
 RooGenCategory.cxx:125
 RooGenCategory.cxx:126
 RooGenCategory.cxx:127
 RooGenCategory.cxx:128
 RooGenCategory.cxx:129
 RooGenCategory.cxx:130
 RooGenCategory.cxx:131
 RooGenCategory.cxx:132
 RooGenCategory.cxx:133
 RooGenCategory.cxx:134
 RooGenCategory.cxx:135
 RooGenCategory.cxx:136
 RooGenCategory.cxx:137
 RooGenCategory.cxx:138
 RooGenCategory.cxx:139
 RooGenCategory.cxx:140
 RooGenCategory.cxx:141
 RooGenCategory.cxx:142
 RooGenCategory.cxx:143
 RooGenCategory.cxx:144
 RooGenCategory.cxx:145
 RooGenCategory.cxx:146
 RooGenCategory.cxx:147
 RooGenCategory.cxx:148
 RooGenCategory.cxx:149
 RooGenCategory.cxx:150
 RooGenCategory.cxx:151
 RooGenCategory.cxx:152
 RooGenCategory.cxx:153
 RooGenCategory.cxx:154
 RooGenCategory.cxx:155
 RooGenCategory.cxx:156
 RooGenCategory.cxx:157
 RooGenCategory.cxx:158
 RooGenCategory.cxx:159
 RooGenCategory.cxx:160
 RooGenCategory.cxx:161
 RooGenCategory.cxx:162
 RooGenCategory.cxx:163
 RooGenCategory.cxx:164
 RooGenCategory.cxx:165
 RooGenCategory.cxx:166
 RooGenCategory.cxx:167
 RooGenCategory.cxx:168
 RooGenCategory.cxx:169
 RooGenCategory.cxx:170
 RooGenCategory.cxx:171
 RooGenCategory.cxx:172
 RooGenCategory.cxx:173
 RooGenCategory.cxx:174
 RooGenCategory.cxx:175
 RooGenCategory.cxx:176
 RooGenCategory.cxx:177
 RooGenCategory.cxx:178
 RooGenCategory.cxx:179
 RooGenCategory.cxx:180
 RooGenCategory.cxx:181
 RooGenCategory.cxx:182
 RooGenCategory.cxx:183
 RooGenCategory.cxx:184
 RooGenCategory.cxx:185
 RooGenCategory.cxx:186
 RooGenCategory.cxx:187
 RooGenCategory.cxx:188
 RooGenCategory.cxx:189
 RooGenCategory.cxx:190
 RooGenCategory.cxx:191
 RooGenCategory.cxx:192
 RooGenCategory.cxx:193
 RooGenCategory.cxx:194
 RooGenCategory.cxx:195
 RooGenCategory.cxx:196
 RooGenCategory.cxx:197
 RooGenCategory.cxx:198
 RooGenCategory.cxx:199
 RooGenCategory.cxx:200
 RooGenCategory.cxx:201
 RooGenCategory.cxx:202
 RooGenCategory.cxx:203
 RooGenCategory.cxx:204
 RooGenCategory.cxx:205
 RooGenCategory.cxx:206
 RooGenCategory.cxx:207
 RooGenCategory.cxx:208
 RooGenCategory.cxx:209
 RooGenCategory.cxx:210
 RooGenCategory.cxx:211
 RooGenCategory.cxx:212
 RooGenCategory.cxx:213
 RooGenCategory.cxx:214
 RooGenCategory.cxx:215
 RooGenCategory.cxx:216
 RooGenCategory.cxx:217
 RooGenCategory.cxx:218
 RooGenCategory.cxx:219
 RooGenCategory.cxx:220
 RooGenCategory.cxx:221
 RooGenCategory.cxx:222
 RooGenCategory.cxx:223
 RooGenCategory.cxx:224
 RooGenCategory.cxx:225
 RooGenCategory.cxx:226
 RooGenCategory.cxx:227
 RooGenCategory.cxx:228
 RooGenCategory.cxx:229
 RooGenCategory.cxx:230
 RooGenCategory.cxx:231
 RooGenCategory.cxx:232
 RooGenCategory.cxx:233
 RooGenCategory.cxx:234
 RooGenCategory.cxx:235
 RooGenCategory.cxx:236
 RooGenCategory.cxx:237
 RooGenCategory.cxx:238
 RooGenCategory.cxx:239
 RooGenCategory.cxx:240
 RooGenCategory.cxx:241
 RooGenCategory.cxx:242
 RooGenCategory.cxx:243
 RooGenCategory.cxx:244
 RooGenCategory.cxx:245
 RooGenCategory.cxx:246
 RooGenCategory.cxx:247
 RooGenCategory.cxx:248
 RooGenCategory.cxx:249
 RooGenCategory.cxx:250
 RooGenCategory.cxx:251
 RooGenCategory.cxx:252
 RooGenCategory.cxx:253
 RooGenCategory.cxx:254
 RooGenCategory.cxx:255