ROOT  6.06/08
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 ),
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 ),
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 ),
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 
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),
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
Config & gConfig()
Definition: Config.cxx:40
TXMLEngine & xmlengine()
Definition: Tools.h:277
MsgLogger * fLogger
Definition: Reader.h:174
std::map< TString, IMethod * > fMethodMap
Definition: Reader.h:170
virtual const std::vector< Float_t > & GetMulticlassValues()
Definition: MethodBase.h:199
MsgLogger & Endl(MsgLogger &ml)
Definition: MsgLogger.h:162
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
Bool_t fCalculateError
Definition: Reader.h:165
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
void SetTestSignalEfficiency(Double_t effS)
Definition: MethodCuts.h:132
OptionBase * DeclareOptionRef(T &ref, const TString &name, const TString &desc="")
Double_t fMvaEventErrorUpper
Definition: Reader.h:168
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
virtual const char * GetName() const
Returns name of object.
Definition: Reader.h:126
const std::vector< Float_t > & GetRegressionValues(const TMVA::Event *const ev)
Definition: MethodBase.h:186
static const char * filename()
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
Double_t GetRarity(const TString &methodTag, Double_t mvaVal=-9999999)
evaluates the MVA&#39;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
VariableInfo & AddSpectator(const TString &expression, const TString &title, const TString &unit, Double_t min, Double_t max, char type='F', Bool_t normalized=kTRUE, void *external=0)
add a spectator (can be a complex expression) to the set of spectator variables used in the MV analys...
Bool_t fSilent
Definition: Reader.h:163
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
static void InhibitOutput()
Definition: MsgLogger.cxx:68
Tools & gTools()
Definition: Tools.cxx:79
TString GetMethodTypeFromFile(const TString &filename)
read the method type from the file
Definition: Reader.cxx:336
const Event * GetEvent() const
Definition: MethodBase.h:667
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.
bool BeginsWith(const std::string &theString, const std::string &theSubstring)
virtual Double_t GetRarity(Double_t mvaVal, Types::ESBType reftype=Types::kBackground) const
compute rarity: R(x) = Integrate_[-oo..x] { PDF(x&#39;) dx&#39; } where PDF(x) is the PDF of the classifier&#39;s...
TString & Append(const char *cs)
Definition: TString.h:492
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2220
virtual void ParseOptions()
options parser
void SetupMethod()
setup of methods
Definition: MethodBase.cxx:295
void SetMinType(EMsgType minType)
Definition: MsgLogger.h:76
IMethod * BookMVA(const TString &methodTag, const TString &weightfile)
read method name from weight file
Definition: Reader.cxx:371
virtual Double_t GetProba(const Event *ev)
DataSetManager * fDataSetManager
Definition: Reader.h:141
void ReadStateFromXMLString(const char *xmlstr)
for reading from memory
std::vector< Float_t > fTmpEvalVec
Definition: Reader.h:172
std::string GetMethodName(TCppMethod_t)
Definition: Cppyy.cxx:707
DataSetInfo & AddDataSetInfo(DataSetInfo &dsi)
stores a copy of the dataset info object
unsigned int UInt_t
Definition: RtypesCore.h:42
bool verbose
DataSetManager * fDataSetManager
Ssiz_t Length() const
Definition: TString.h:390
const TString & GetMethodName() const
Definition: MethodBase.h:296
void ReadAttr(void *node, const char *, T &value)
Definition: Tools.h:295
Bool_t Verbose(void) const
Definition: Reader.h:127
Double_t fMvaEventError
Definition: Reader.h:167
UInt_t GetNVariables() const
accessor to the number of variables
Definition: Event.cxx:303
Float_t GetValue(UInt_t ivar) const
return value of i&#39;th variable
Definition: Event.cxx:231
Reader(const TString &theOption="", Bool_t verbose=0)
constructor
Definition: Reader.cxx:126
Bool_t fVerbose
Definition: Reader.h:162
XMLDocPointer_t ParseFile(const char *filename, Int_t maxbuf=100000)
Parses content of file and tries to produce xml structures.
Bool_t fColor
Definition: Reader.h:164
virtual void CheckSetup()
check may be overridden by derived class (sometimes, eg, fitters are used which can only be implement...
Definition: MethodBase.cxx:320
#define ClassImp(name)
Definition: Rtypes.h:279
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
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
DataSetInfo fDataSetInfo
Definition: Reader.h:149
MsgLogger & Log() const
Definition: Reader.h:175
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Double_t EvaluateMVA(const std::vector< Float_t > &, const TString &methodTag, Double_t aux=0)
Evaluate a std::vector<float> 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
const TString & GetOptions() const
Definition: Configurable.h:91
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
TString GetMethodTypeName() const
Definition: MethodBase.h:297
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
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 ...
const DataSetInfo & DataInfo() const
Definition: Reader.h:130
Types::EMVA GetMethodType() const
Definition: MethodBase.h:298
const Int_t n
Definition: legend1.C:16
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