Logo ROOT   6.07/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 "TMVA/Config.h"
95 #include "TMVA/Configurable.h"
96 #include "TMVA/ClassifierFactory.h"
97 #include "TMVA/DataInputHandler.h"
98 #include "TMVA/DataSetInfo.h"
99 #include "TMVA/DataSetManager.h"
100 #include "TMVA/IMethod.h"
101 #include "TMVA/MethodBase.h"
102 #include "TMVA/MethodCuts.h"
103 #include "TMVA/MethodCategory.h"
104 #include "TMVA/MsgLogger.h"
105 #include "TMVA/Tools.h"
106 #include "TMVA/Types.h"
107 
108 #include "TTree.h"
109 #include "TLeaf.h"
110 #include "TString.h"
111 #include "TClass.h"
112 #include "TH1D.h"
113 #include "TKey.h"
114 #include "TVector.h"
115 #include "TXMLEngine.h"
116 #include "TMath.h"
117 
118 #include <cstdlib>
119 
120 #include <string>
121 #include <vector>
122 #include <fstream>
123 
124 #include <iostream>
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// constructor
128 
130 : Configurable( theOption ),
131  fDataSetManager( NULL ), // DSMTEST
132  fDataSetInfo(),
133  fVerbose( verbose ),
134  fSilent ( kFALSE ),
135  fColor ( kFALSE ),
136  fCalculateError(kFALSE),
137  fMvaEventError( 0 ),
138  fMvaEventErrorUpper( 0 ),
139  fLogger ( 0 )
140 {
143  fLogger = new MsgLogger(this);
144  SetConfigName( GetName() );
145  DeclareOptions();
146  ParseOptions();
147 
148  Init();
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// constructor
153 
154 TMVA::Reader::Reader( std::vector<TString>& inputVars, const TString& theOption, Bool_t verbose )
155  : Configurable( theOption ),
156  fDataSetManager( NULL ), // DSMTEST
157  fDataSetInfo(),
158  fVerbose( verbose ),
159  fSilent ( kFALSE ),
160  fColor ( kFALSE ),
162  fMvaEventError( 0 ),
163  fMvaEventErrorUpper( 0 ), //zjh
164  fLogger ( 0 )
165 {
168  fLogger = new MsgLogger(this);
169  SetConfigName( GetName() );
170  DeclareOptions();
171  ParseOptions();
172 
173  // arguments: names of input variables (vector)
174  // verbose flag
175  for (std::vector<TString>::iterator ivar = inputVars.begin(); ivar != inputVars.end(); ivar++)
176  DataInfo().AddVariable( *ivar );
177 
178  Init();
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// constructor
183 
184 TMVA::Reader::Reader( std::vector<std::string>& inputVars, const TString& theOption, Bool_t verbose )
185  : Configurable( theOption ),
186  fDataSetManager( NULL ), // DSMTEST
187  fDataSetInfo(),
188  fVerbose( verbose ),
189  fSilent ( kFALSE ),
190  fColor ( kFALSE ),
192  fMvaEventError( 0 ),
193  fMvaEventErrorUpper( 0 ),
194  fLogger ( 0 )
195 {
198  fLogger = new MsgLogger(this);
199  SetConfigName( GetName() );
200  DeclareOptions();
201  ParseOptions();
202 
203  // arguments: names of input variables (vector)
204  // verbose flag
205  for (std::vector<std::string>::iterator ivar = inputVars.begin(); ivar != inputVars.end(); ivar++)
206  DataInfo().AddVariable( ivar->c_str() );
207 
208  Init();
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 /// constructor
213 
214 TMVA::Reader::Reader( const std::string& varNames, const TString& theOption, Bool_t verbose )
215  : Configurable( theOption ),
216  fDataSetManager( NULL ), // DSMTEST
217  fDataSetInfo(),
218  fVerbose( verbose ),
219  fSilent ( kFALSE ),
220  fColor ( kFALSE ),
222  fMvaEventError( 0 ),
223  fMvaEventErrorUpper( 0 ),
224  fLogger ( 0 )
225 {
228  fLogger = new MsgLogger(this);
229  SetConfigName( GetName() );
230  DeclareOptions();
231  ParseOptions();
232 
233  // arguments: names of input variables given in form: "name1:name2:name3"
234  // verbose flag
235  DecodeVarNames(varNames);
236  Init();
237 }
238 
239 ////////////////////////////////////////////////////////////////////////////////
240 /// constructor
241 
242 TMVA::Reader::Reader( const TString& varNames, const TString& theOption, Bool_t verbose )
243  : Configurable( theOption ),
244  fDataSetManager( NULL ), // DSMTEST
245  fDataSetInfo(),
246  fVerbose( verbose ),
247  fSilent ( kFALSE ),
248  fColor ( kFALSE ),
250  fMvaEventError( 0 ),
251  fMvaEventErrorUpper( 0 ),
252  fLogger ( 0 )
253 {
256  fLogger = new MsgLogger(this);
257  SetConfigName( GetName() );
258  DeclareOptions();
259  ParseOptions();
260 
261  // arguments: names of input variables given in form: "name1:name2:name3"
262  // verbose flag
263  DecodeVarNames(varNames);
264  Init();
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// declaration of configuration options
269 
271 {
272  if (gTools().CheckForSilentOption( GetOptions() )) Log().InhibitOutput(); // make sure is silent if wanted to
273 
274  DeclareOptionRef( fVerbose, "V", "Verbose flag" );
275  DeclareOptionRef( fColor, "Color", "Color flag (default True)" );
276  DeclareOptionRef( fSilent, "Silent", "Boolean silent flag (default False)" );
277  DeclareOptionRef( fCalculateError, "Error", "Calculates errors (default False)" );
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// destructor
282 
284 {
285  delete fDataSetManager; // DSMTEST
286 
287  delete fLogger;
288 
289  for (auto it=fMethodMap.begin(); it!=fMethodMap.end(); it++){
290  MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(it->second);
291  delete kl;
292  }
293 }
294 
295 ////////////////////////////////////////////////////////////////////////////////
296 /// default initialisation (no member variables)
297 
298 void TMVA::Reader::Init( void )
299 {
300  if (Verbose()) fLogger->SetMinType( kVERBOSE );
301 
303  gConfig().SetSilent ( fSilent );
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////
307 /// Add a float variable or expression to the reader
308 
309 void TMVA::Reader::AddVariable( const TString& expression, Float_t* datalink )
310 {
311  DataInfo().AddVariable( expression, "", "", 0, 0, 'F', kFALSE ,(void*)datalink ); // <= should this be F or rather T?
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 
316 void TMVA::Reader::AddVariable( const TString& expression, Int_t* datalink )
317 {
318  Log() << kFATAL << "Reader::AddVariable( const TString& expression, Int_t* datalink ), this function is deprecated, please provide all variables to the reader as floats" << Endl;
319  // Add an integer variable or expression to the reader
320  Log() << kFATAL << "Reader::AddVariable( const TString& expression, Int_t* datalink ), this function is deprecated, please provide all variables to the reader as floats" << Endl;
321  DataInfo().AddVariable(expression, "", "", 0, 0, 'I', kFALSE, (void*)datalink ); // <= should this be F or rather T?
322 }
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// Add a float spectator or expression to the reader
326 
327 void TMVA::Reader::AddSpectator( const TString& expression, Float_t* datalink )
328 {
329  DataInfo().AddSpectator( expression, "", "", 0, 0, 'F', kFALSE ,(void*)datalink );
330 }
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 /// Add an integer spectator or expression to the reader
334 
335 void TMVA::Reader::AddSpectator( const TString& expression, Int_t* datalink )
336 {
337  DataInfo().AddSpectator(expression, "", "", 0, 0, 'I', kFALSE, (void*)datalink );
338 }
339 
340 ////////////////////////////////////////////////////////////////////////////////
341 /// read the method type from the file
342 
344 {
345  std::ifstream fin( filename );
346  if (!fin.good()) { // file not found --> Error
347  Log() << kFATAL << "<BookMVA> fatal error: "
348  << "unable to open input weight file: " << filename << Endl;
349  }
350 
351  TString fullMethodName("");
352  if (filename.EndsWith(".xml")) {
353  fin.close();
354 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,29,0)
355  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
356 #else
357  void* doc = gTools().xmlengine().ParseFile(filename);
358 #endif
359  void* rootnode = gTools().xmlengine().DocGetRootElement(doc); // node "MethodSetup"
360  gTools().ReadAttr(rootnode, "Method", fullMethodName);
361  gTools().xmlengine().FreeDoc(doc);
362  }
363  else {
364  char buf[512];
365  fin.getline(buf,512);
366  while (!TString(buf).BeginsWith("Method")) fin.getline(buf,512);
367  fullMethodName = TString(buf);
368  fin.close();
369  }
370  TString methodType = fullMethodName(0,fullMethodName.Index("::"));
371  if (methodType.Contains(" ")) methodType = methodType(methodType.Last(' ')+1,methodType.Length());
372  return methodType;
373 }
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 /// read method name from weight file
377 
378 TMVA::IMethod* TMVA::Reader::BookMVA( const TString& methodTag, const TString& weightfile )
379 {
380  // assert non-existence
381  if (fMethodMap.find( methodTag ) != fMethodMap.end())
382  Log() << kFATAL << "<BookMVA> method tag \"" << methodTag << "\" already exists!" << Endl;
383 
384  TString methodType(GetMethodTypeFromFile(weightfile));
385 
386  Log() << kINFO << "Booking \"" << methodTag << "\" of type \"" << methodType << "\" from " << weightfile << "." << Endl;
387 
388  MethodBase* method = dynamic_cast<MethodBase*>(this->BookMVA( Types::Instance().GetMethodType(methodType),
389  weightfile ) );
390  if( method && method->GetMethodType() == Types::kCategory ){
391  MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
392  if( !methCat )
393  Log() << kFATAL << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
394  methCat->fDataSetManager = fDataSetManager;
395  }
396 
397  return fMethodMap[methodTag] = method;
398 }
399 
400 ////////////////////////////////////////////////////////////////////////////////
401 /// books MVA method from weightfile
402 
404 {
405  IMethod* im = ClassifierFactory::Instance().Create(std::string(Types::Instance().GetMethodName( methodType )),
406  DataInfo(), weightfile );
407 
408  MethodBase *method = (dynamic_cast<MethodBase*>(im));
409 
410  if (method==0) return im;
411 
412  if( method->GetMethodType() == Types::kCategory ){
413  MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
414  if( !methCat )
415  Log() << kERROR << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
416  methCat->fDataSetManager = fDataSetManager;
417  }
418 
419  method->SetupMethod();
420 
421  // when reading older weight files, they could include options
422  // that are not supported any longer
423  method->DeclareCompatibilityOptions();
424 
425  // read weight file
426  method->ReadStateFromFile();
427 
428  // check for unused options
429  method->CheckSetup();
430 
431  Log() << kINFO << "Booked classifier \"" << method->GetMethodName()
432  << "\" of type: \"" << method->GetMethodTypeName() << "\"" << Endl;
433 
434  return method;
435 }
436 
437 ////////////////////////////////////////////////////////////////////////////////
438 
439 TMVA::IMethod* TMVA::Reader::BookMVA( TMVA::Types::EMVA methodType, const char* xmlstr )
440 {
441 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
442 
443  // books MVA method from weightfile
444  IMethod* im = ClassifierFactory::Instance().Create(std::string(Types::Instance().GetMethodName( methodType )),
445  DataInfo(), "" );
446 
447  MethodBase *method = (dynamic_cast<MethodBase*>(im));
448 
449  if(!method) return 0;
450 
451  if( method->GetMethodType() == Types::kCategory ){
452  MethodCategory *methCat = (dynamic_cast<MethodCategory*>(method));
453  if( !methCat )
454  Log() << kFATAL << "Method with type kCategory cannot be casted to MethodCategory. /Reader" << Endl;
455  methCat->fDataSetManager = fDataSetManager;
456  }
457 
458  method->SetupMethod();
459 
460  // when reading older weight files, they could include options
461  // that are not supported any longer
462  method->DeclareCompatibilityOptions();
463 
464  // read weight file
465  method->ReadStateFromXMLString( xmlstr );
466 
467  // check for unused options
468  method->CheckSetup();
469 
470  Log() << kINFO << "Booked classifier \"" << method->GetMethodName()
471  << "\" of type: \"" << method->GetMethodTypeName() << "\"" << Endl;
472 
473  return method;
474 #else
475  Log() << kFATAL << "Method Reader::BookMVA(TMVA::Types::EMVA methodType = " << methodType
476  << ", const char* xmlstr = " << xmlstr
477  << " ) is not available for ROOT versions prior to 5.26/00." << Endl;
478  return 0;
479 #endif
480 }
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 /// Evaluate a std::vector<float> of input data for a given method
484 /// The parameter aux is obligatory for the cuts method where it represents the efficiency cutoff
485 
486 Double_t TMVA::Reader::EvaluateMVA( const std::vector<Float_t>& inputVec, const TString& methodTag, Double_t aux )
487 {
488  // create a temporary event from the vector.
489  IMethod* imeth = FindMVA( methodTag );
490  MethodBase* meth = dynamic_cast<TMVA::MethodBase*>(imeth);
491  if(meth==0) return 0;
492 
493  // Event* tmpEvent=new Event(inputVec, 2); // ToDo resolve magic 2 issue
494  Event* tmpEvent=new Event(inputVec, DataInfo().GetNVariables()); // is this the solution?
495  for (UInt_t i=0; i<inputVec.size(); i++){
496  if (TMath::IsNaN(inputVec[i])) {
497  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;
498  delete tmpEvent;
499  return -999;
500  }
501  }
502 
503  if (meth->GetMethodType() == TMVA::Types::kCuts) {
504  TMVA::MethodCuts* mc = dynamic_cast<TMVA::MethodCuts*>(meth);
505  if(mc)
506  mc->SetTestSignalEfficiency( aux );
507  }
508  Double_t val = meth->GetMvaValue( tmpEvent, (fCalculateError?&fMvaEventError:0));
509  delete tmpEvent;
510  return val;
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 /// Evaluate a std::vector<double> of input data for a given method
515 /// The parameter aux is obligatory for the cuts method where it represents the efficiency cutoff
516 
517 Double_t TMVA::Reader::EvaluateMVA( const std::vector<Double_t>& inputVec, const TString& methodTag, Double_t aux )
518 {
519  // performs a copy to float values which are internally used by all methods
520  if(fTmpEvalVec.size() != inputVec.size())
521  fTmpEvalVec.resize(inputVec.size());
522 
523  for (UInt_t idx=0; idx!=inputVec.size(); idx++ )
524  fTmpEvalVec[idx]=inputVec[idx];
525 
526  return EvaluateMVA( fTmpEvalVec, methodTag, aux );
527 }
528 
529 ////////////////////////////////////////////////////////////////////////////////
530 /// evaluates MVA for given set of input variables
531 
533 {
534  IMethod* method = 0;
535 
536  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
537  if (it == fMethodMap.end()) {
538  Log() << kINFO << "<EvaluateMVA> unknown classifier in map; "
539  << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
540  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
541  Log() << "Check calling string" << kFATAL << Endl;
542  }
543 
544  else method = it->second;
545 
546  MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);
547 
548  if(kl==0)
549  Log() << kFATAL << methodTag << " is not a method" << Endl;
550 
551  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
552  // it is not again checked in each of these subsequet calls..
553  const Event* ev = kl->GetEvent();
554  for (UInt_t i=0; i<ev->GetNVariables(); i++){
555  if (TMath::IsNaN(ev->GetValue(i))) {
556  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;
557  return -999;
558  }
559  }
560  return this->EvaluateMVA( kl, aux );
561 }
562 
563 ////////////////////////////////////////////////////////////////////////////////
564 /// evaluates the MVA
565 
567 {
568  // the aux value is only needed for MethodCuts: it sets the
569  // required signal efficiency
570  if (method->GetMethodType() == TMVA::Types::kCuts) {
571  TMVA::MethodCuts* mc = dynamic_cast<TMVA::MethodCuts*>(method);
572  if(mc)
573  mc->SetTestSignalEfficiency( aux );
574  }
575 
576  return method->GetMvaValue( (fCalculateError?&fMvaEventError:0),
578 }
579 
580 ////////////////////////////////////////////////////////////////////////////////
581 /// evaluates MVA for given set of input variables
582 
583 const std::vector< Float_t >& TMVA::Reader::EvaluateRegression( const TString& methodTag, Double_t aux )
584 {
585  IMethod* method = 0;
586 
587  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
588  if (it == fMethodMap.end()) {
589  Log() << kINFO << "<EvaluateMVA> unknown method in map; "
590  << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
591  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
592  Log() << "Check calling string" << kFATAL << Endl;
593  }
594  else method = it->second;
595 
596  MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);
597 
598  if(kl==0)
599  Log() << kFATAL << methodTag << " is not a method" << Endl;
600  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
601  // it is not again checked in each of these subsequet calls..
602  const Event* ev = kl->GetEvent();
603  for (UInt_t i=0; i<ev->GetNVariables(); i++){
604  if (TMath::IsNaN(ev->GetValue(i))) {
605  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;
606  }
607  }
608 
609  return this->EvaluateRegression( kl, aux );
610 }
611 
612 ////////////////////////////////////////////////////////////////////////////////
613 /// evaluates the regression MVA
614 /// check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
615 /// it is not again checked in each of these subsequet calls..
616 
617 const std::vector< Float_t >& TMVA::Reader::EvaluateRegression( MethodBase* method, Double_t /*aux*/ )
618 {
619  const Event* ev = method->GetEvent();
620  for (UInt_t i=0; i<ev->GetNVariables(); i++){
621  if (TMath::IsNaN(ev->GetValue(i))) {
622  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;
623  }
624  }
625  return method->GetRegressionValues();
626 }
627 
628 
629 ////////////////////////////////////////////////////////////////////////////////
630 /// evaluates the regression MVA
631 
633 {
634  try {
635  return EvaluateRegression(methodTag, aux).at(tgtNumber);
636  }
637  catch (std::out_of_range e) {
638  Log() << kWARNING << "Regression could not be evaluated for target-number " << tgtNumber << Endl;
639  return 0;
640  }
641 }
642 
643 
644 
645 ////////////////////////////////////////////////////////////////////////////////
646 /// evaluates MVA for given set of input variables
647 
648 const std::vector< Float_t >& TMVA::Reader::EvaluateMulticlass( const TString& methodTag, Double_t aux )
649 {
650  IMethod* method = 0;
651 
652  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
653  if (it == fMethodMap.end()) {
654  Log() << kINFO << "<EvaluateMVA> unknown method in map; "
655  << "you looked for \"" << methodTag << "\" within available methods: " << Endl;
656  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << " --> " << it->first << Endl;
657  Log() << "Check calling string" << kFATAL << Endl;
658  }
659  else method = it->second;
660 
661  MethodBase * kl = dynamic_cast<TMVA::MethodBase*>(method);
662 
663  if(kl==0)
664  Log() << kFATAL << methodTag << " is not a method" << Endl;
665  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
666  // it is not again checked in each of these subsequet calls..
667 
668  const Event* ev = kl->GetEvent();
669  for (UInt_t i=0; i<ev->GetNVariables(); i++){
670  if (TMath::IsNaN(ev->GetValue(i))) {
671  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;
672  }
673  }
674 
675  return this->EvaluateMulticlass( kl, aux );
676 }
677 
678 ////////////////////////////////////////////////////////////////////////////////
679 /// evaluates the multiclass MVA
680 /// check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
681 /// it is not again checked in each of these subsequet calls..
682 
683 const std::vector< Float_t >& TMVA::Reader::EvaluateMulticlass( MethodBase* method, Double_t /*aux*/ )
684 {
685  const Event* ev = method->GetEvent();
686  for (UInt_t i=0; i<ev->GetNVariables(); i++){
687  if (TMath::IsNaN(ev->GetValue(i))) {
688  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;
689  }
690  }
691  return method->GetMulticlassValues();
692 }
693 
694 
695 ////////////////////////////////////////////////////////////////////////////////
696 /// evaluates the multiclass MVA
697 
699 {
700  try {
701  return EvaluateMulticlass(methodTag, aux).at(clsNumber);
702  }
703  catch (std::out_of_range e) {
704  Log() << kWARNING << "Multiclass could not be evaluated for class-number " << clsNumber << Endl;
705  return 0;
706  }
707 }
708 
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// return pointer to method with tag "methodTag"
712 
714 {
715  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
716  if (it != fMethodMap.end()) return it->second;
717  Log() << kERROR << "Method " << methodTag << " not found!" << Endl;
718  return 0;
719 }
720 
721 ////////////////////////////////////////////////////////////////////////////////
722 /// special function for Cuts to avoid dynamic_casts in ROOT macros,
723 /// which are not properly handled by CINT
724 
726 {
727  return dynamic_cast<MethodCuts*>(FindMVA(methodTag));
728 }
729 
730 ////////////////////////////////////////////////////////////////////////////////
731 /// evaluates probability of MVA for given set of input variables
732 
733 Double_t TMVA::Reader::GetProba( const TString& methodTag, Double_t ap_sig, Double_t mvaVal )
734 {
735  IMethod* method = 0;
736  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
737  if (it == fMethodMap.end()) {
738  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << "M" << it->first << Endl;
739  Log() << kFATAL << "<EvaluateMVA> unknown classifier in map: " << method << "; "
740  << "you looked for " << methodTag<< " while the available methods are : " << Endl;
741  }
742  else method = it->second;
743 
744  MethodBase* kl = dynamic_cast<MethodBase*>(method);
745  if(kl==0) return -1;
746  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
747  // it is not again checked in each of these subsequet calls..
748  const Event* ev = kl->GetEvent();
749  for (UInt_t i=0; i<ev->GetNVariables(); i++){
750  if (TMath::IsNaN(ev->GetValue(i))) {
751  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;
752  return -999;
753  }
754  }
755 
756  if (mvaVal == -9999999) mvaVal = kl->GetMvaValue();
757 
758  return kl->GetProba( mvaVal, ap_sig );
759 }
760 
761 ////////////////////////////////////////////////////////////////////////////////
762 /// evaluates the MVA's rarity
763 
765 {
766  IMethod* method = 0;
767  std::map<TString, IMethod*>::iterator it = fMethodMap.find( methodTag );
768  if (it == fMethodMap.end()) {
769  for (it = fMethodMap.begin(); it!=fMethodMap.end(); it++) Log() << "M" << it->first << Endl;
770  Log() << kFATAL << "<EvaluateMVA> unknown classifier in map: \"" << method << "\"; "
771  << "you looked for \"" << methodTag<< "\" while the available methods are : " << Endl;
772  }
773  else method = it->second;
774 
775  MethodBase* kl = dynamic_cast<MethodBase*>(method);
776  if(kl==0) return -1;
777  // check for NaN in event data: (note: in the factory, this check was done already at the creation of the datasets, hence
778  // it is not again checked in each of these subsequet calls..
779  const Event* ev = kl->GetEvent();
780  for (UInt_t i=0; i<ev->GetNVariables(); i++){
781  if (TMath::IsNaN(ev->GetValue(i))) {
782  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;
783  return -999;
784  }
785  }
786 
787  if (mvaVal == -9999999) mvaVal = kl->GetMvaValue();
788 
789  return kl->GetRarity( mvaVal );
790 }
791 
792 // ---------------------------------------------------------------------------------------
793 // ----- methods related to the decoding of the input variable names ---------------------
794 // ---------------------------------------------------------------------------------------
795 
796 ////////////////////////////////////////////////////////////////////////////////
797 /// decodes "name1:name2:..." form
798 
799 void TMVA::Reader::DecodeVarNames( const std::string& varNames )
800 {
801  size_t ipos = 0, f = 0;
802  while (f != varNames.length()) {
803  f = varNames.find( ':', ipos );
804  if (f > varNames.length()) f = varNames.length();
805  std::string subs = varNames.substr( ipos, f-ipos ); ipos = f+1;
806  DataInfo().AddVariable( subs.c_str() );
807  }
808 }
809 
810 ////////////////////////////////////////////////////////////////////////////////
811 /// decodes "name1:name2:..." form
812 
813 void TMVA::Reader::DecodeVarNames( const TString& varNames )
814 {
815  TString format;
816  Int_t n = varNames.Length();
817  TString format_obj;
818 
819  for (int i=0; i< n+1 ; i++) {
820  format.Append(varNames(i));
821  if (varNames(i) == ':' || i == n) {
822  format.Chop();
823  format_obj = format;
824  format_obj.ReplaceAll("@","");
825  DataInfo().AddVariable( format_obj );
826  format.Resize(0);
827  }
828  }
829 }
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:43
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:865
TXMLEngine & xmlengine()
Definition: Tools.h:278
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:230
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:283
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:309
Bool_t fCalculateError
Definition: Reader.h:165
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
static Types & Instance()
the the single instance of "Types" if existin already, or create it (Signleton)
Definition: Types.cxx:64
void SetTestSignalEfficiency(Double_t effS)
Definition: MethodCuts.h:130
OptionBase * DeclareOptionRef(T &ref, const TString &name, const TString &desc="")
MsgLogger & Log() const
Definition: Reader.h:175
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:583
const std::vector< Float_t > & GetRegressionValues(const TMVA::Event *const ev)
Definition: MethodBase.h:217
Double_t GetRarity(const TString &methodTag, Double_t mvaVal=-9999999)
evaluates the MVA&#39;s rarity
Definition: Reader.cxx:764
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:327
Float_t GetValue(UInt_t ivar) const
return value of i&#39;th variable
Definition: Event.cxx:233
Bool_t fSilent
Definition: Reader.h:163
void DecodeVarNames(const std::string &varNames)
decodes "name1:name2:..." form
Definition: Reader.cxx:799
static void InhibitOutput()
Definition: MsgLogger.cxx:69
Tools & gTools()
Definition: Tools.cxx:79
TString GetMethodTypeFromFile(const TString &filename)
read the method type from the file
Definition: Reader.cxx:343
DataInputHandler fDataInputHandler
Definition: Reader.h:151
void DeclareOptions()
declaration of configuration options
Definition: Reader.cxx:270
void ReadStateFromFile()
Function to write options and weights to file.
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:403
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:378
Types::EMVA GetMethodType() const
Definition: MethodBase.h:329
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:305
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
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2221
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:745
bool verbose
DataSetManager * fDataSetManager
void ReadAttr(void *node, const char *, T &value)
Definition: Tools.h:296
Double_t fMvaEventError
Definition: Reader.h:167
Reader(const TString &theOption="", Bool_t verbose=0)
constructor
Definition: Reader.cxx:129
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:430
double f(double x)
void AddSpectator(const TString &expression, Float_t *)
Add a float spectator or expression to the reader.
Definition: Reader.cxx:327
double Double_t
Definition: RtypesCore.h:55
DataSetInfo fDataSetInfo
Definition: Reader.h:149
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
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:486
void Init(void)
default initialisation (no member variables)
Definition: Reader.cxx:298
void SetUseColor(Bool_t uc)
Definition: Config.h:61
void SetConfigName(const char *n)
Definition: Configurable.h:69
Bool_t Verbose(void) const
Definition: Reader.h:127
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...
IMethod * FindMVA(const TString &methodTag)
return pointer to method with tag "methodTag"
Definition: Reader.cxx:713
virtual void DeclareCompatibilityOptions()
options that are used ONLY for the READER to ensure backward compatibility they are hence without any...
Definition: MethodBase.cxx:590
void SetSilent(Bool_t s)
Definition: Config.h:64
const TString & GetOptions() const
Definition: Configurable.h:90
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Int_t IsNaN(Double_t x)
Definition: TMath.h:613
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 ...
TString()
TString default ctor.
Definition: TString.cxx:88
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 GetMethodTypeName() const
Definition: MethodBase.h:328
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
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:733
const std::vector< Float_t > & EvaluateMulticlass(const TString &methodTag, Double_t aux=0)
evaluates MVA for given set of input variables
Definition: Reader.cxx:648
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1059
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:725