ROOT  6.06/09
Reference Guide
Reader.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Eckhard von Toerne, Jan Therhaag
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : Reader *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Reader class to be used in the user application to interpret the trained *
12  * MVAs in an analysis context *
13  * *
14  * Authors (alphabetical order): *
15  * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
16  * Peter Speckmayer <peter.speckmayer@cern.ch> - CERN, Switzerland *
17  * Joerg Stelzer <Joerg.Stelzer@cern.ch> - CERN, Switzerland *
18  * Jan Therhaag <Jan.Therhaag@cern.ch> - U of Bonn, Germany *
19  * Eckhard v. Toerne <evt@uni-bonn.de> - U of Bonn, Germany *
20  * Helge Voss <Helge.Voss@cern.ch> - MPI-K Heidelberg, Germany *
21  * Kai Voss <Kai.Voss@cern.ch> - U. of Victoria, Canada *
22  * *
23  * Copyright (c) 2005-2011: *
24  * CERN, Switzerland *
25  * U. of Victoria, Canada *
26  * MPI-K Heidelberg, Germany *
27  * U. of Bonn, Germany *
28  * *
29  * Redistribution and use in source and binary forms, with or without *
30  * modification, are permitted according to the terms listed in LICENSE *
31  * (http://ttmva.sourceforge.net/LICENSE) *
32  **********************************************************************************/
33 
34 //_______________________________________________________________________
35 //
36 // The Reader class serves to use the MVAs in a specific analysis context.
37 // Within an event loop, a vector is filled that corresponds to the variables
38 // that were used to train the MVA(s) during the training stage. This vector
39 // is transfered to the Reader, who takes care of interpreting the weight
40 // file of the MVA of choice, and to return the MVA's output. This is then
41 // used by the user for further analysis.
42 //
43 // ---------------------------------------------------------------------
44 // Usage:
45 //
46 // // ------ before starting the event loop (eg, in the initialisation step)
47 //
48 // //
49 // // create TMVA::Reader object
50 // //
51 // TMVA::Reader *reader = new TMVA::Reader();
52 //
53 // // create a set of variables and declare them to the reader
54 // // - the variable names must corresponds in name and type to
55 // // those given in the weight file(s) that you use
56 // Float_t var1, var2, var3, var4;
57 // reader->AddVariable( "var1", &var1 );
58 // reader->AddVariable( "var2", &var2 );
59 // reader->AddVariable( "var3", &var3 );
60 // reader->AddVariable( "var4", &var4 );
61 //
62 // // book the MVA of your choice (prior training of these methods, ie,
63 // // existence of the weight files is required)
64 // reader->BookMVA( "Fisher method", "weights/Fisher.weights.txt" );
65 // reader->BookMVA( "MLP method", "weights/MLP.weights.txt" );
66 // // ... etc
67 //
68 // // ------- start your event loop
69 //
70 // for (Long64_t ievt=0; ievt<myTree->GetEntries();ievt++) {
71 //
72 // // fill vector with values of variables computed from those in the tree
73 // var1 = myvar1;
74 // var2 = myvar2;
75 // var3 = myvar3;
76 // var4 = myvar4;
77 //
78 // // retrieve the corresponding MVA output
79 // double mvaFi = reader->EvaluateMVA( "Fisher method" );
80 // double mvaNN = reader->EvaluateMVA( "MLP method" );
81 //
82 // // do something with these ...., e.g., fill them into your ntuple
83 //
84 // } // end of event loop
85 //
86 // delete reader;
87 // ---------------------------------------------------------------------
88 //
89 // An example application of the Reader can be found in TMVA/macros/TMVApplication.C.
90 //_______________________________________________________________________
91 
92 #include "TMVA/Reader.h"
93 
94 #include "TTree.h"
95 #include "TLeaf.h"
96 #include "TString.h"
97 #include "TClass.h"
98 #include "TH1D.h"
99 #include "TKey.h"
100 #include "TVector.h"
101 #include "TXMLEngine.h"
102 #include "TMath.h"
103 
104 #include <cstdlib>
105 
106 #include <string>
107 #include <vector>
108 #include <fstream>
109 
110 #include <iostream>
111 #ifndef ROOT_TMVA_Tools
112 #include "TMVA/Tools.h"
113 #endif
114 #include "TMVA/Config.h"
115 #include "TMVA/ClassifierFactory.h"
116 #include "TMVA/IMethod.h"
117 #include "TMVA/MethodCuts.h"
118 #include "TMVA/MethodCategory.h"
119 #include "TMVA/DataSetManager.h"
120 
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// constructor
125 
126 TMVA::Reader::Reader( const TString& theOption, Bool_t verbose )
127  : Configurable( theOption ),
128  fDataSetManager( NULL ), // DSMTEST
129  fDataSetInfo(),
130  fVerbose( verbose ),
131  fSilent ( kFALSE ),
132  fColor ( kFALSE ),
133  fCalculateError(kFALSE),
134  fMvaEventError( 0 ),
135  fMvaEventErrorUpper( 0 ),
136  fLogger ( 0 )
137 {
138  fDataSetManager = new DataSetManager( fDataInputHandler );
139  fDataSetManager->AddDataSetInfo(fDataSetInfo);
140  fLogger = new MsgLogger(this);
141  SetConfigName( GetName() );
142  DeclareOptions();
143  ParseOptions();
144 
145  Init();
146 }
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// constructor
150 
151 TMVA::Reader::Reader( std::vector<TString>& inputVars, const TString& theOption, Bool_t verbose )
152  : Configurable( theOption ),
153  fDataSetManager( NULL ), // DSMTEST
154  fDataSetInfo(),
155  fVerbose( verbose ),
156  fSilent ( kFALSE ),
157  fColor ( kFALSE ),
158  fCalculateError(kFALSE),
159  fMvaEventError( 0 ),
160  fMvaEventErrorUpper( 0 ), //zjh
161  fLogger ( 0 )
162 {
165  fLogger = new MsgLogger(this);
166  SetConfigName( GetName() );
167  DeclareOptions();
168  ParseOptions();
169 
170  // arguments: names of input variables (vector)
171  // verbose flag
172  for (std::vector<TString>::iterator ivar = inputVars.begin(); ivar != inputVars.end(); ivar++)
173  DataInfo().AddVariable( *ivar );
174 
175  Init();
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// constructor
180 
181 TMVA::Reader::Reader( std::vector<std::string>& inputVars, const TString& theOption, Bool_t verbose )
182  : Configurable( theOption ),
183  fDataSetManager( NULL ), // DSMTEST
184  fDataSetInfo(),
185  fVerbose( verbose ),
186  fSilent ( kFALSE ),
187  fColor ( kFALSE ),
188  fCalculateError(kFALSE),
189  fMvaEventError( 0 ),
190  fMvaEventErrorUpper( 0 ),
191  fLogger ( 0 )
192 {
195  fLogger = new MsgLogger(this);
196  SetConfigName( GetName() );
197  DeclareOptions();
198  ParseOptions();
199 
200  // arguments: names of input variables (vector)
201  // verbose flag
202  for (std::vector<std::string>::iterator ivar = inputVars.begin(); ivar != inputVars.end(); ivar++)
203  DataInfo().AddVariable( ivar->c_str() );
204 
205  Init();
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// constructor
210 
211 TMVA::Reader::Reader( const std::string& varNames, const TString& theOption, Bool_t verbose )
212  : Configurable( theOption ),
213  fDataSetManager( NULL ), // DSMTEST
214  fDataSetInfo(),
215  fVerbose( verbose ),
216  fSilent ( kFALSE ),
217  fColor ( kFALSE ),
218  fCalculateError(kFALSE),
219  fMvaEventError( 0 ),
220  fMvaEventErrorUpper( 0 ),
221  fLogger ( 0 )
222 {
225  fLogger = new MsgLogger(this);
226  SetConfigName( GetName() );
227  DeclareOptions();
228  ParseOptions();
229 
230  // arguments: names of input variables given in form: "name1:name2:name3"
231  // verbose flag
232  DecodeVarNames(varNames);
233  Init();
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// constructor
238 
239 TMVA::Reader::Reader( const TString& varNames, const TString& theOption, Bool_t verbose )
240  : Configurable( theOption ),
241  fDataSetManager( NULL ), // DSMTEST
242  fDataSetInfo(),
243  fVerbose( verbose ),
244  fSilent ( kFALSE ),
245  fColor ( kFALSE ),
246  fCalculateError(kFALSE),
247  fMvaEventError( 0 ),
248  fMvaEventErrorUpper( 0 ),
249  fLogger ( 0 )
250 {
253  fLogger = new MsgLogger(this);
254  SetConfigName( GetName() );
255  DeclareOptions();
256  ParseOptions();
257 
258  // arguments: names of input variables given in form: "name1:name2:name3"
259  // verbose flag
260  DecodeVarNames(varNames);
261  Init();
262 }
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// declaration of configuration options
266 
268 {
269  if (gTools().CheckForSilentOption( GetOptions() )) Log().InhibitOutput(); // make sure is silent if wanted to
270 
271  DeclareOptionRef( fVerbose, "V", "Verbose flag" );
272  DeclareOptionRef( fColor, "Color", "Color flag (default True)" );
273  DeclareOptionRef( fSilent, "Silent", "Boolean silent flag (default False)" );
274  DeclareOptionRef( fCalculateError, "Error", "Calculates errors (default False)" );
275 }
276 
277 ////////////////////////////////////////////////////////////////////////////////
278 /// destructor
279 
281 {
282  delete fDataSetManager; // DSMTEST
283 
284  delete fLogger;
285 }
286 
287 ////////////////////////////////////////////////////////////////////////////////
288 /// default initialisation (no member variables)
289 /// default initialisation (no member variables)
290 
291 void TMVA::Reader::Init( void )
292 {
293  if (Verbose()) fLogger->SetMinType( kVERBOSE );
294 
295  gConfig().SetUseColor( fColor );
296  gConfig().SetSilent ( fSilent );
297 }
298 
299 ////////////////////////////////////////////////////////////////////////////////
300 /// Add a float variable or expression to the reader
301 
302 void TMVA::Reader::AddVariable( const TString& expression, Float_t* datalink )
303 {
304  DataInfo().AddVariable( expression, "", "", 0, 0, 'F', kFALSE ,(void*)datalink ); // <= should this be F or rather T?
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 
309 void TMVA::Reader::AddVariable( const TString& expression, Int_t* datalink )
310 {
311  Log() << kFATAL << "Reader::AddVariable( const TString& expression, Int_t* datalink ), this function is deprecated, please provide all variables to the reader as floats" << Endl;
312  // Add an integer variable or expression to the reader
313  Log() << kFATAL << "Reader::AddVariable( const TString& expression, Int_t* datalink ), this function is deprecated, please provide all variables to the reader as floats" << Endl;
314  DataInfo().AddVariable(expression, "", "", 0, 0, 'I', kFALSE, (void*)datalink ); // <= should this be F or rather T?
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Add a float spectator or expression to the reader
319 
320 void TMVA::Reader::AddSpectator( const TString& expression, Float_t* datalink )
321 {
322  DataInfo().AddSpectator( expression, "", "", 0, 0, 'F', kFALSE ,(void*)datalink );
323 }
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 /// Add an integer spectator or expression to the reader
327 
328 void TMVA::Reader::AddSpectator( const TString& expression, Int_t* datalink )
329 {
330  DataInfo().AddSpectator(expression, "", "", 0, 0, 'I', kFALSE, (void*)datalink );
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// read the method type from the file
335 
337 {
338  std::ifstream fin( filename );
339  if (!fin.good()) { // file not found --> Error
340  Log() << kFATAL << "<BookMVA> fatal error: "
341  << "unable to open input weight file: " << filename << Endl;
342  }
343 
344  TString fullMethodName("");
345  if (filename.EndsWith(".xml")) {
346  fin.close();
347 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,29,0)
348  void* doc = gTools().xmlengine().ParseFile(filename,gTools().xmlenginebuffersize());// the default buffer size in TXMLEngine::ParseFile is 100k. Starting with ROOT 5.29 one can set the buffer size, see: http://savannah.cern.ch/bugs/?78864. This might be necessary for large XML files
349 #else
350  void* doc = gTools().xmlengine().ParseFile(filename);
351 #endif
352  void* rootnode = gTools().xmlengine().DocGetRootElement(doc); // node "MethodSetup"
353  gTools().ReadAttr(rootnode, "Method", fullMethodName);
354  gTools().xmlengine().FreeDoc(doc);
355  }
356  else {
357  char buf[512];
358  fin.getline(buf,512);
359  while (!TString(buf).BeginsWith("Method")) fin.getline(buf,512);
360  fullMethodName = TString(buf);
361  fin.close();
362  }
363  TString methodType = fullMethodName(0,fullMethodName.Index("::"));
364  if (methodType.Contains(" ")) methodType = methodType(methodType.Last(' ')+1,methodType.Length());
365  return methodType;
366 }
367 
368 ////////////////////////////////////////////////////////////////////////////////
369 /// read method name from weight file
370 
371 TMVA::IMethod* TMVA::Reader::BookMVA( const TString& methodTag, const TString& weightfile )
372 {
373  // assert non-existence
374  if (fMethodMap.find( methodTag ) != fMethodMap.end())
375  Log() << kFATAL << "<BookMVA> method tag \"" << methodTag << "\" already exists!" << Endl;
376 
377  TString methodType(GetMethodTypeFromFile(weightfile));
378 
379  Log() << kINFO << "Booking \"" << methodTag << "\" of type \"" << methodType << "\" from " << weightfile << "." << Endl;
380 
381  MethodBase* method = dynamic_cast<MethodBase*>(this->BookMVA( Types::Instance().GetMethodType(methodType),
382  weightfile ) );
383  if( method && method->GetMethodType() == Types::kCategory ){
384  MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
385  if( !methCat )
386  Log() << kFATAL << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
387  methCat->fDataSetManager = fDataSetManager;
388  }
389 
390  return fMethodMap[methodTag] = method;
391 }
392 
393 ////////////////////////////////////////////////////////////////////////////////
394 /// books MVA method from weightfile
395 
397 {
398  IMethod* im = ClassifierFactory::Instance().Create(std::string(Types::Instance().GetMethodName( methodType )),
399  DataInfo(), weightfile );
400 
401  MethodBase *method = (dynamic_cast<MethodBase*>(im));
402 
403  if (method==0) return im;
404 
405  if( method->GetMethodType() == Types::kCategory ){
406  MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
407  if( !methCat )
408  Log() << kERROR << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
409  methCat->fDataSetManager = fDataSetManager;
410  }
411 
412  method->SetupMethod();
413 
414  // when reading older weight files, they could include options
415  // that are not supported any longer
416  method->DeclareCompatibilityOptions();
417 
418  // read weight file
419  method->ReadStateFromFile();
420 
421  // check for unused options
422  method->CheckSetup();
423 
424  Log() << kINFO << "Booked classifier \"" << method->GetMethodName()
425  << "\" of type: \"" << method->GetMethodTypeName() << "\"" << Endl;
426 
427  return method;
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 
432 TMVA::IMethod* TMVA::Reader::BookMVA( TMVA::Types::EMVA methodType, const char* xmlstr )
433 {
434 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
435 
436  // books MVA method from weightfile
437  IMethod* im = ClassifierFactory::Instance().Create(std::string(Types::Instance().GetMethodName( methodType )),
438  DataInfo(), "" );
439 
440  MethodBase *method = (dynamic_cast<MethodBase*>(im));
441 
442  if(!method) return 0;
443 
444  if( method->GetMethodType() == Types::kCategory ){
445  MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
446  if( !methCat )
447  Log() << kFATAL << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
448  methCat->fDataSetManager = fDataSetManager;
449  }
450 
451  method->SetupMethod();
452 
453  // when reading older weight files, they could include options
454  // that are not supported any longer
455  method->DeclareCompatibilityOptions();
456 
457  // read weight file
458  method->ReadStateFromXMLString( xmlstr );
459 
460  // check for unused options
461  method->CheckSetup();
462 
463  Log() << kINFO << "Booked classifier \"" << method->GetMethodName()
464  << "\" of type: \"" << method->GetMethodTypeName() << "\"" << Endl;
465 
466  return method;
467 #else
468  Log() << kFATAL << "Method Reader::BookMVA(TMVA::Types::EMVA methodType = " << methodType
469  << ", const char* xmlstr = " << xmlstr
470  << " ) is not available for ROOT versions prior to 5.26/00." << Endl;
471  return 0;
472 #endif
473 }
474 
475 ////////////////////////////////////////////////////////////////////////////////
476 /// Evaluate a std::vector<float> of input data for a given method
477 /// The parameter aux is obligatory for the cuts method where it represents the efficiency cutoff
478 
479 Double_t TMVA::Reader::EvaluateMVA( const std::vector<Float_t>& inputVec, const TString& methodTag, Double_t aux )
480 {
481  // create a temporary event from the vector.
482  IMethod* imeth = FindMVA( methodTag );
483  MethodBase* meth = dynamic_cast<TMVA::MethodBase*>(imeth);
484  if(meth==0) return 0;
485 
486 // Event* tmpEvent=new Event(inputVec, 2); // ToDo resolve magic 2 issue
487  Event* tmpEvent=new Event(inputVec, DataInfo().GetNVariables()); // is this the solution?
488  for (UInt_t i=0; i<inputVec.size(); i++){
489  if (TMath::IsNaN(inputVec[i])) {
490  Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
491  delete tmpEvent;
492  return -999;
493  }
494  }
495 
496  if (meth->GetMethodType() == TMVA::Types::kCuts) {
497  TMVA::MethodCuts* mc = dynamic_cast<TMVA::MethodCuts*>(meth);
498  if(mc)
499  mc->SetTestSignalEfficiency( aux );
500  }
501  Double_t val = meth->GetMvaValue( tmpEvent, (fCalculateError?&fMvaEventError:0));
502  delete tmpEvent;
503  return val;
504 }
505 
506 ////////////////////////////////////////////////////////////////////////////////
507 /// Evaluate a std::vector<double> of input data for a given method
508 /// The parameter aux is obligatory for the cuts method where it represents the efficiency cutoff
509 
510 Double_t TMVA::Reader::EvaluateMVA( const std::vector<Double_t>& inputVec, const TString& methodTag, Double_t aux )
511 {
512  // performs a copy to float values which are internally used by all methods
513  if(fTmpEvalVec.size() != inputVec.size())
514  fTmpEvalVec.resize(inputVec.size());
515 
516  for (UInt_t idx=0; idx!=inputVec.size(); idx++ )
517  fTmpEvalVec[idx]=inputVec[idx];
518 
519  return EvaluateMVA( fTmpEvalVec, methodTag, aux );
520 }
521 
522 ////////////////////////////////////////////////////////////////////////////////
523 /// evaluates MVA for given set of input variables
524 
526 {
527  IMethod* method = 0;
528 
529  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
530  if (it == fMethodMap.end()) {
531  Log() << kINFO << "<EvaluateMVA> unknown classifier in map; "
532  << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
533  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
534  Log() << "Check calling string" << kFATAL << Endl;
535  }
536 
537  else method = it->second;
538 
539  MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);
540 
541  if(kl==0)
542  Log() << kFATAL << methodTag << " is not a method" << Endl;
543 
544  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
545  // it is not again checked in each of these subsequet calls..
546  const Event* ev = kl->GetEvent();
547  for (UInt_t i=0; i<ev->GetNVariables(); i++){
548  if (TMath::IsNaN(ev->GetValue(i))) {
549  Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
550  return -999;
551  }
552  }
553  return this->EvaluateMVA( kl, aux );
554 }
555 
556 ////////////////////////////////////////////////////////////////////////////////
557 /// evaluates the MVA
558 
560 {
561  // the aux value is only needed for MethodCuts: it sets the
562  // required signal efficiency
563  if (method->GetMethodType() == TMVA::Types::kCuts) {
564  TMVA::MethodCuts* mc = dynamic_cast<TMVA::MethodCuts*>(method);
565  if(mc)
566  mc->SetTestSignalEfficiency( aux );
567  }
568 
569  return method->GetMvaValue( (fCalculateError?&fMvaEventError:0),
570  (fCalculateError?&fMvaEventErrorUpper:0) );
571 }
572 
573 ////////////////////////////////////////////////////////////////////////////////
574 /// evaluates MVA for given set of input variables
575 
576 const std::vector< Float_t >& TMVA::Reader::EvaluateRegression( const TString& methodTag, Double_t aux )
577 {
578  IMethod* method = 0;
579 
580  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
581  if (it == fMethodMap.end()) {
582  Log() << kINFO << "<EvaluateMVA> unknown method in map; "
583  << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
584  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
585  Log() << "Check calling string" << kFATAL << Endl;
586  }
587  else method = it->second;
588 
589  MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);
590 
591  if(kl==0)
592  Log() << kFATAL << methodTag << " is not a method" << Endl;
593  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
594  // it is not again checked in each of these subsequet calls..
595  const Event* ev = kl->GetEvent();
596  for (UInt_t i=0; i<ev->GetNVariables(); i++){
597  if (TMath::IsNaN(ev->GetValue(i))) {
598  Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
599  }
600  }
601 
602  return this->EvaluateRegression( kl, aux );
603 }
604 
605 ////////////////////////////////////////////////////////////////////////////////
606 /// evaluates the regression MVA
607 /// check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
608 /// it is not again checked in each of these subsequet calls..
609 
610 const std::vector< Float_t >& TMVA::Reader::EvaluateRegression( MethodBase* method, Double_t /*aux*/ )
611 {
612  const Event* ev = method->GetEvent();
613  for (UInt_t i=0; i<ev->GetNVariables(); i++){
614  if (TMath::IsNaN(ev->GetValue(i))) {
615  Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
616  }
617  }
618  return method->GetRegressionValues();
619 }
620 
621 
622 ////////////////////////////////////////////////////////////////////////////////
623 /// evaluates the regression MVA
624 
626 {
627  try {
628  return EvaluateRegression(methodTag, aux).at(tgtNumber);
629  }
630  catch (std::out_of_range e) {
631  Log() << kWARNING << "Regression could not be evaluated for target-number " << tgtNumber << Endl;
632  return 0;
633  }
634 }
635 
636 
637 
638 ////////////////////////////////////////////////////////////////////////////////
639 /// evaluates MVA for given set of input variables
640 
641 const std::vector< Float_t >& TMVA::Reader::EvaluateMulticlass( const TString& methodTag, Double_t aux )
642 {
643  IMethod* method = 0;
644 
645  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
646  if (it == fMethodMap.end()) {
647  Log() << kINFO << "<EvaluateMVA> unknown method in map; "
648  << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
649  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
650  Log() << "Check calling string" << kFATAL << Endl;
651  }
652  else method = it->second;
653 
654  MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);
655 
656  if(kl==0)
657  Log() << kFATAL << methodTag << " is not a method" << Endl;
658  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
659  // it is not again checked in each of these subsequet calls..
660 
661  const Event* ev = kl->GetEvent();
662  for (UInt_t i=0; i<ev->GetNVariables(); i++){
663  if (TMath::IsNaN(ev->GetValue(i))) {
664  Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
665  }
666  }
667 
668  return this->EvaluateMulticlass( kl, aux );
669 }
670 
671 ////////////////////////////////////////////////////////////////////////////////
672 /// evaluates the multiclass MVA
673 /// check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
674 /// it is not again checked in each of these subsequet calls..
675 
676 const std::vector< Float_t >& TMVA::Reader::EvaluateMulticlass( MethodBase* method, Double_t /*aux*/ )
677 {
678  const Event* ev = method->GetEvent();
679  for (UInt_t i=0; i<ev->GetNVariables(); i++){
680  if (TMath::IsNaN(ev->GetValue(i))) {
681  Log() << kERROR << i << "-th variable of the event is NaN, \n regression values might evaluate to .. what do I know. \n sorry this warning is all I can do, please fix or remove this event." << Endl;
682  }
683  }
684  return method->GetMulticlassValues();
685 }
686 
687 
688 ////////////////////////////////////////////////////////////////////////////////
689 /// evaluates the multiclass MVA
690 
692 {
693  try {
694  return EvaluateMulticlass(methodTag, aux).at(clsNumber);
695  }
696  catch (std::out_of_range e) {
697  Log() << kWARNING << "Multiclass could not be evaluated for class-number " << clsNumber << Endl;
698  return 0;
699  }
700 }
701 
702 
703 ////////////////////////////////////////////////////////////////////////////////
704 /// return pointer to method with tag "methodTag"
705 
707 {
708  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
709  if (it != fMethodMap.end()) return it->second;
710  Log() << kERROR << "Method " << methodTag << " not found!" << Endl;
711  return 0;
712 }
713 
714 ////////////////////////////////////////////////////////////////////////////////
715 /// special function for Cuts to avoid dynamic_casts in ROOT macros,
716 /// which are not properly handled by CINT
717 
719 {
720  return dynamic_cast<MethodCuts*>(FindMVA(methodTag));
721 }
722 
723 ////////////////////////////////////////////////////////////////////////////////
724 /// evaluates probability of MVA for given set of input variables
725 
726 Double_t TMVA::Reader::GetProba( const TString& methodTag, Double_t ap_sig, Double_t mvaVal )
727 {
728  IMethod* method = 0;
729  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
730  if (it == fMethodMap.end()) {
731  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << "M" << it->first << Endl;
732  Log() << kFATAL << "<EvaluateMVA> unknown classifier in map: " << method << "; "
733  << "you looked for " << methodTag<< " while the available methods are : " << Endl;
734  }
735  else method = it->second;
736 
737  MethodBase* kl = dynamic_cast<MethodBase*>(method);
738  if(kl==0) return -1;
739  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
740  // it is not again checked in each of these subsequet calls..
741  const Event* ev = kl->GetEvent();
742  for (UInt_t i=0; i<ev->GetNVariables(); i++){
743  if (TMath::IsNaN(ev->GetValue(i))) {
744  Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
745  return -999;
746  }
747  }
748 
749  if (mvaVal == -9999999) mvaVal = kl->GetMvaValue();
750 
751  return kl->GetProba( mvaVal, ap_sig );
752 }
753 
754 ////////////////////////////////////////////////////////////////////////////////
755 /// evaluates the MVA's rarity
756 
758 {
759  IMethod* method = 0;
760  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
761  if (it == fMethodMap.end()) {
762  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << "M" << it->first << Endl;
763  Log() << kFATAL << "<EvaluateMVA> unknown classifier in map: \"" << method << "\"; "
764  << "you looked for \"" << methodTag<< "\" while the available methods are : " << Endl;
765  }
766  else method = it->second;
767 
768  MethodBase* kl = dynamic_cast<MethodBase*>(method);
769  if(kl==0) return -1;
770  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
771  // it is not again checked in each of these subsequet calls..
772  const Event* ev = kl->GetEvent();
773  for (UInt_t i=0; i<ev->GetNVariables(); i++){
774  if (TMath::IsNaN(ev->GetValue(i))) {
775  Log() << kERROR << i << "-th variable of the event is NaN --> return MVA value -999, \n that's all I can do, please fix or remove this event." << Endl;
776  return -999;
777  }
778  }
779 
780  if (mvaVal == -9999999) mvaVal = kl->GetMvaValue();
781 
782  return kl->GetRarity( mvaVal );
783 }
784 
785 // ---------------------------------------------------------------------------------------
786 // ----- methods related to the decoding of the input variable names ---------------------
787 // ---------------------------------------------------------------------------------------
788 
789 ////////////////////////////////////////////////////////////////////////////////
790 /// decodes "name1:name2:..." form
791 
792 void TMVA::Reader::DecodeVarNames( const std::string& varNames )
793 {
794  size_t ipos = 0, f = 0;
795  while (f != varNames.length()) {
796  f = varNames.find( ':', ipos );
797  if (f > varNames.length()) f = varNames.length();
798  std::string subs = varNames.substr( ipos, f-ipos ); ipos = f+1;
799  DataInfo().AddVariable( subs.c_str() );
800  }
801 }
802 
803 ////////////////////////////////////////////////////////////////////////////////
804 /// decodes "name1:name2:..." form
805 
806 void TMVA::Reader::DecodeVarNames( const TString& varNames )
807 {
808  TString format;
809  Int_t n = varNames.Length();
810  TString format_obj;
811 
812  for (int i=0; i< n+1 ; i++) {
813  format.Append(varNames(i));
814  if (varNames(i) == ':' || i == n) {
815  format.Chop();
816  format_obj = format;
817  format_obj.ReplaceAll("@","");
818  DataInfo().AddVariable( format_obj );
819  format.Resize(0);
820  }
821  }
822 }
IMethod * Create(const std::string &name, const TString &job, const TString &title, DataSetInfo &dsi, const TString &option)
creates the method if needed based on the method name using the creator function the factory has stor...
static ClassifierFactory & Instance()
access to the ClassifierFactory singleton creates the instance if needed
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
TXMLEngine & xmlengine()
Definition: Tools.h:277
MsgLogger * fLogger
Definition: Reader.h:174
virtual const std::vector< Float_t > & GetMulticlassValues()
Definition: MethodBase.h:199
const DataSetInfo & DataInfo() const
Definition: Reader.h:130
MsgLogger & Endl(MsgLogger &ml)
Definition: MsgLogger.h:162
Ssiz_t Length() const
Definition: TString.h:390
virtual Double_t GetMvaValue(Double_t *errLower=0, Double_t *errUpper=0)=0
virtual ~Reader(void)
destructor
Definition: Reader.cxx:280
float Float_t
Definition: RtypesCore.h:53
void AddVariable(const TString &expression, Float_t *)
Add a float variable or expression to the reader.
Definition: Reader.cxx:302
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
void SetTestSignalEfficiency(Double_t effS)
Definition: MethodCuts.h:132
Config & gConfig()
const std::vector< Float_t > & EvaluateRegression(const TString &methodTag, Double_t aux=0)
evaluates MVA for given set of input variables
Definition: Reader.cxx:576
const std::vector< Float_t > & GetRegressionValues(const TMVA::Event *const ev)
Definition: MethodBase.h:186
static const char * filename()
Double_t GetRarity(const TString &methodTag, Double_t mvaVal=-9999999)
evaluates the MVA's rarity
Definition: Reader.cxx:757
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
static std::string format(double x, double y, int digits, int width)
void FreeDoc(XMLDocPointer_t xmldoc)
frees allocated document data and deletes document itself
const TString & GetMethodName() const
Definition: MethodBase.h:296
Float_t GetValue(UInt_t ivar) const
return value of i'th variable
Definition: Event.cxx:231
void DecodeVarNames(const std::string &varNames)
decodes "name1:name2:..." form
Definition: Reader.cxx:792
static Types & Instance()
the the single instance of "Types" if existin already, or create it (Signleton)
Definition: Types.cxx:61
Tools & gTools()
Definition: Tools.cxx:79
TString GetMethodTypeFromFile(const TString &filename)
read the method type from the file
Definition: Reader.cxx:336
DataInputHandler fDataInputHandler
Definition: Reader.h:151
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:118
void DeclareOptions()
declaration of configuration options
Definition: Reader.cxx:267
void ReadStateFromFile()
Function to write options and weights to file.
ClassImp(TMVA::Reader) TMVA
constructor
Definition: Reader.cxx:121
bool BeginsWith(const std::string &theString, const std::string &theSubstring)
TString & Append(const char *cs)
Definition: TString.h:492
virtual void ParseOptions()
options parser
virtual const char * GetName() const
Returns name of object.
Definition: Reader.h:126
void SetupMethod()
setup of methods
Definition: MethodBase.cxx:295
IMethod * BookMVA(const TString &methodTag, const TString &weightfile)
read method name from weight file
Definition: Reader.cxx:371
Types::EMVA GetMethodType() const
Definition: MethodBase.h:298
virtual Double_t GetProba(const Event *ev)
DataSetManager * fDataSetManager
Definition: Reader.h:141
UInt_t GetNVariables() const
accessor to the number of variables
Definition: Event.cxx:303
void ReadStateFromXMLString(const char *xmlstr)
for reading from memory
std::string GetMethodName(TCppMethod_t)
Definition: Cppyy.cxx:707
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2220
DataSetInfo & AddDataSetInfo(DataSetInfo &dsi)
stores a copy of the dataset info object
unsigned int UInt_t
Definition: RtypesCore.h:42
const Event * GetEvent() const
Definition: MethodBase.h:667
bool verbose
DataSetManager * fDataSetManager
void ReadAttr(void *node, const char *, T &value)
Definition: Tools.h:295
Reader(const TString &theOption="", Bool_t verbose=0)
XMLDocPointer_t ParseFile(const char *filename, Int_t maxbuf=100000)
Parses content of file and tries to produce xml structures.
virtual void CheckSetup()
check may be overridden by derived class (sometimes, eg, fitters are used which can only be implement...
Definition: MethodBase.cxx:320
double f(double x)
void AddSpectator(const TString &expression, Float_t *)
Add a float spectator or expression to the reader.
Definition: Reader.cxx:320
double Double_t
Definition: RtypesCore.h:55
DataSetInfo fDataSetInfo
Definition: Reader.h:149
RooCmdArg Verbose(Bool_t flag=kTRUE)
Double_t EvaluateMVA(const std::vector< Float_t > &, const TString &methodTag, Double_t aux=0)
Evaluate a std::vector of input data for a given method The parameter aux is obligatory for th...
Definition: Reader.cxx:479
void Init(void)
default initialisation (no member variables) default initialisation (no member variables) ...
Definition: Reader.cxx:291
void SetUseColor(Bool_t uc)
Definition: Config.h:61
void SetConfigName(const char *n)
Definition: Configurable.h:70
Abstract ClassifierFactory template that handles arbitrary types.
IMethod * FindMVA(const TString &methodTag)
return pointer to method with tag "methodTag"
Definition: Reader.cxx:706
virtual void DeclareCompatibilityOptions()
options that are used ONLY for the READER to ensure backward compatibility they are hence without any...
Definition: MethodBase.cxx:599
void SetSilent(Bool_t s)
Definition: Config.h:64
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Int_t IsNaN(Double_t x)
Definition: TMath.h:617
XMLNodePointer_t DocGetRootElement(XMLDocPointer_t xmldoc)
returns root node of document
#define NULL
Definition: Rtypes.h:82
VariableInfo & AddVariable(const TString &expression, const TString &title="", const TString &unit="", Double_t min=0, Double_t max=0, char varType='F', Bool_t normalized=kTRUE, void *external=0)
add a variable (can be a complex expression) to the set of variables used in the MV analysis ...
virtual Double_t GetRarity(Double_t mvaVal, Types::ESBType reftype=Types::kBackground) const
compute rarity: R(x) = Integrate_[-oo..x] { PDF(x') dx' } where PDF(x) is the PDF of the classifier's...
TString GetMethodTypeName() const
Definition: MethodBase.h:297
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
const Int_t n
Definition: legend1.C:16
Definition: math.cpp:60
Double_t GetProba(const TString &methodTag, Double_t ap_sig=0.5, Double_t mvaVal=-9999999)
evaluates probability of MVA for given set of input variables
Definition: Reader.cxx:726
const std::vector< Float_t > & EvaluateMulticlass(const TString &methodTag, Double_t aux=0)
evaluates MVA for given set of input variables
Definition: Reader.cxx:641
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1058
TString & Chop()
Definition: TString.h:622
MethodCuts * FindCutsMVA(const TString &methodTag)
special function for Cuts to avoid dynamic_casts in ROOT macros, which are not properly handled by CI...
Definition: Reader.cxx:718