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