Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
VariableDecorrTransform.cxx
Go to the documentation of this file.
1// @(#)root/tmva $Id$
2// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Eckhard von Toerne
3
4/**********************************************************************************
5 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6 * Package: TMVA *
7 * Class : VariableDecorrTransform *
8 * *
9 * *
10 * Description: *
11 * Implementation (see header for description) *
12 * *
13 * Authors (alphabetical): *
14 * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
15 * Peter Speckmayer <Peter.Speckmayer@cern.ch> - CERN, Switzerland *
16 * Joerg Stelzer <Joerg.Stelzer@cern.ch> - CERN, Switzerland *
17 * Helge Voss <Helge.Voss@cern.ch> - MPI-K Heidelberg, Germany *
18 * *
19 * Copyright (c) 2005-2011: *
20 * CERN, Switzerland *
21 * MPI-K Heidelberg, Germany *
22 * U. of Bonn, Germany *
23 * *
24 * Redistribution and use in source and binary forms, with or without *
25 * modification, are permitted according to the terms listed in LICENSE *
26 * (see tmva/doc/LICENSE) *
27 **********************************************************************************/
28
29/*! \class TMVA::VariableDecorrTransform
30\ingroup TMVA
31Linear interpolation class
32*/
33
35
36#include "TMVA/DataSet.h"
37#include "TMVA/Event.h"
38#include "TMVA/MsgLogger.h"
39#include "TMVA/Tools.h"
40#include "TMVA/Types.h"
41#include "TMVA/VariableInfo.h"
42
43#include "TVectorF.h"
44#include "TVectorD.h"
45#include "TMatrixD.h"
46#include "TMatrixDBase.h"
47
48#include <iostream>
49#include <iomanip>
50#include <algorithm>
51
52
53////////////////////////////////////////////////////////////////////////////////
54/// constructor
55
60
61////////////////////////////////////////////////////////////////////////////////
62/// destructor
63
65{
66 for (std::vector<TMatrixD*>::iterator it = fDecorrMatrices.begin(); it != fDecorrMatrices.end(); ++it) {
67 if ((*it) != 0) delete (*it);
68 }
69}
70
71////////////////////////////////////////////////////////////////////////////////
72/// initialisation
73
77
78////////////////////////////////////////////////////////////////////////////////
79/// calculate the decorrelation matrix and the normalization
80
82{
83 Initialize();
84
85 if (!IsEnabled() || IsCreated()) return kTRUE;
86
87 Log() << kINFO << "Preparing the Decorrelation transformation..." << Endl;
88
89 Int_t inputSize = fGet.size();
90 SetNVariables(inputSize);
91
92 if (inputSize > 200) {
93 Log() << kINFO << "----------------------------------------------------------------------------"
94 << Endl;
95 Log() << kINFO
96 << ": More than 200 variables, will not calculate decorrelation matrix "
97 << "!" << Endl;
98 Log() << kINFO << "----------------------------------------------------------------------------"
99 << Endl;
100 return kFALSE;
101 }
102
103 CalcSQRMats( events, GetNClasses() );
104
105 SetCreated( kTRUE );
106
107 return kTRUE;
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// creates string with variable transformations applied
112
114{
116 // if cls (the class chosen by the user) not existing, assume that user wants to
117 // have the matrix for all classes together.
118
119 if (cls < 0 || cls > GetNClasses()) whichMatrix = GetNClasses();
120
121 TMatrixD* m = fDecorrMatrices.at(whichMatrix);
122 if (m == 0) {
123 if (whichMatrix == GetNClasses() )
124 Log() << kFATAL << "Transformation matrix all classes is not defined"
125 << Endl;
126 else
127 Log() << kFATAL << "Transformation matrix for class " << whichMatrix << " is not defined"
128 << Endl;
129 }
130
131 const Int_t nvar = fGet.size();
132 std::vector<TString>* strVec = new std::vector<TString>;
133
134 // fill vector
135 for (Int_t ivar=0; ivar<nvar; ivar++) {
136 TString str( "" );
137 for (Int_t jvar=0; jvar<nvar; jvar++) {
138 str += ((*m)(ivar,jvar) > 0) ? " + " : " - ";
139
140 Char_t type = fGet.at(jvar).first;
141 Int_t idx = fGet.at(jvar).second;
142
143 switch( type ) {
144 case 'v':
145 str += TString::Format( "%10.5g*[%s]", TMath::Abs((*m)(ivar,jvar)), Variables()[idx].GetLabel().Data() );
146 break;
147 case 't':
148 str += TString::Format( "%10.5g*[%s]", TMath::Abs((*m)(ivar,jvar)), Targets()[idx].GetLabel().Data() );
149 break;
150 case 's':
151 str += TString::Format( "%10.5g*[%s]", TMath::Abs((*m)(ivar,jvar)), Spectators()[idx].GetLabel().Data() );
152 break;
153 default:
154 Log() << kFATAL << "VariableDecorrTransform::GetTransformationStrings : unknown type '" << type << "'." << Endl;
155 }
156 }
157 strVec->push_back( str );
158 }
159
160 return strVec;
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// apply the decorrelation transformation
165
167{
168 if (!IsCreated())
169 Log() << kFATAL << "Transformation matrix not yet created"
170 << Endl;
171
173 // if cls (the class chosen by the user) not existing, assume that he wants to have the matrix for all classes together.
174 // EVT this is a workaround to address the reader problem with transforma and EvaluateMVA(std::vector<float/double> ,...)
175 if (cls < 0 || cls >= (int) fDecorrMatrices.size()) whichMatrix = fDecorrMatrices.size()-1;
176 //EVT workaround end
177 //if (cls < 0 || cls > GetNClasses()) {
178 // whichMatrix = GetNClasses();
179 // if (GetNClasses() == 1 ) whichMatrix = (fDecorrMatrices.size()==1?0:2);
180 //}
181
182 TMatrixD* m = fDecorrMatrices.at(whichMatrix);
183 if (m == 0) {
184 if (whichMatrix == GetNClasses() )
185 Log() << kFATAL << "Transformation matrix all classes is not defined"
186 << Endl;
187 else
188 Log() << kFATAL << "Transformation matrix for class " << whichMatrix << " is not defined"
189 << Endl;
190 }
191
192 if (fTransformedEvent==0 || fTransformedEvent->GetNVariables()!=ev->GetNVariables()) {
193 if (fTransformedEvent!=0) { delete fTransformedEvent; fTransformedEvent = 0; }
194 fTransformedEvent = new Event();
195 }
196
197 // transformation to decorrelate the variables
198 const Int_t nvar = fGet.size();
199
200 std::vector<Float_t> input;
201 std::vector<Char_t> mask; // entries with kTRUE must not be transformed
202 Bool_t hasMaskedEntries = GetInput( ev, input, mask );
203
204 if( hasMaskedEntries ){ // targets might be masked (for events where the targets have not been computed yet)
205 UInt_t numMasked = std::count(mask.begin(), mask.end(), (Char_t)kTRUE);
206 UInt_t numOK = std::count(mask.begin(), mask.end(), (Char_t)kFALSE);
207 if( numMasked>0 && numOK>0 ){
208 Log() << kFATAL << "You mixed variables and targets in the decorrelation transformation. This is not possible." << Endl;
209 }
210 SetOutput( fTransformedEvent, input, mask, ev );
211 return fTransformedEvent;
212 }
213
214 TVectorD vec( nvar );
215 for (Int_t ivar=0; ivar<nvar; ivar++) vec(ivar) = input.at(ivar);
216
217 // diagonalise variable vectors
218 vec *= *m;
219
220 input.clear();
221 for (Int_t ivar=0; ivar<nvar; ivar++) input.push_back( vec(ivar) );
222
223 SetOutput( fTransformedEvent, input, mask, ev );
224
225 return fTransformedEvent;
226}
227
228////////////////////////////////////////////////////////////////////////////////
229/// apply the inverse decorrelation transformation ...
230/// TODO : ... build the inverse transformation
231
233{
234 Log() << kFATAL << "Inverse transformation for decorrelation transformation not yet implemented. Hence, this transformation cannot be applied together with regression if targets should be transformed. Please contact the authors if necessary." << Endl;
235
236
237 return fBackTransformedEvent;
238}
239
240////////////////////////////////////////////////////////////////////////////////
241/// compute square-root matrices for signal and background
242
243void TMVA::VariableDecorrTransform::CalcSQRMats( const std::vector< Event*>& events, Int_t maxCls )
244{
245 // delete old matrices if any
246 for (std::vector<TMatrixD*>::iterator it = fDecorrMatrices.begin();
247 it != fDecorrMatrices.end(); ++it)
248 if (0 != (*it) ) { delete (*it); *it=0; }
249
250
251 // if more than one classes, then produce one matrix for all events as well (beside the matrices for each class)
252 const UInt_t matNum = (maxCls<=1)?maxCls:maxCls+1;
253 fDecorrMatrices.resize( matNum, (TMatrixD*) 0 );
254
255 std::vector<TMatrixDSym*>* covMat = gTools().CalcCovarianceMatrices( events, maxCls, this );
256
257
258 for (UInt_t cls=0; cls<matNum; cls++) {
260 if ( sqrMat==0 )
261 Log() << kFATAL << "<GetSQRMats> Zero pointer returned for SQR matrix" << Endl;
262 fDecorrMatrices[cls] = sqrMat;
263 delete (*covMat)[cls];
264 }
265 delete covMat;
266}
267
268////////////////////////////////////////////////////////////////////////////////
269/// write the decorrelation matrix to the stream
270
272{
273 Int_t cls = 0;
274 Int_t dp = o.precision();
275 for (std::vector<TMatrixD*>::const_iterator itm = fDecorrMatrices.begin(); itm != fDecorrMatrices.end(); ++itm) {
276 o << "# correlation matrix " << std::endl;
277 TMatrixD* mat = (*itm);
278 o << cls << " " << mat->GetNrows() << " x " << mat->GetNcols() << std::endl;
279 for (Int_t row = 0; row<mat->GetNrows(); row++) {
280 for (Int_t col = 0; col<mat->GetNcols(); col++) {
281 o << std::setprecision(12) << std::setw(20) << (*mat)[row][col] << " ";
282 }
283 o << std::endl;
284 }
285 cls++;
286 }
287 o << "##" << std::endl;
288 o << std::setprecision(dp);
289}
290
291////////////////////////////////////////////////////////////////////////////////
292/// node attachment to parent
293
295{
296 void* trf = gTools().AddChild(parent, "Transform");
297 gTools().AddAttr(trf,"Name", "Decorrelation");
298
300
301 for (std::vector<TMatrixD*>::const_iterator itm = fDecorrMatrices.begin(); itm != fDecorrMatrices.end(); ++itm) {
302 TMatrixD* mat = (*itm);
303 /*void* decmat = gTools().xmlengine().NewChild(trf, nullptr, "Matrix");
304 gTools().xmlengine().NewAttr(decmat, nullptr, "Rows", gTools().StringFromInt(mat->GetNrows()) );
305 gTools().xmlengine().NewAttr(decmat, nullptr, "Columns", gTools().StringFromInt(mat->GetNcols()) );
306
307 std::stringstream s;
308 for (Int_t row = 0; row<mat->GetNrows(); row++) {
309 for (Int_t col = 0; col<mat->GetNcols(); col++) {
310 s << (*mat)[row][col] << " ";
311 }
312 }
313 gTools().xmlengine().AddRawLine( decmat, s.str().c_str() );*/
314 gTools().WriteTMatrixDToXML(trf,"Matrix",mat);
315 }
316}
317
318////////////////////////////////////////////////////////////////////////////////
319/// Read the transformation matrices from the xml node
320
322{
323 // first delete the old matrices
324 for( std::vector<TMatrixD*>::iterator it = fDecorrMatrices.begin(); it != fDecorrMatrices.end(); ++it )
325 if( (*it) != 0 ) delete (*it);
326 fDecorrMatrices.clear();
327
329
330 void* inpnode = NULL;
331
332 inpnode = gTools().GetChild(trfnode, "Selection"); // new xml format
333 if( inpnode!=NULL )
334 newFormat = kTRUE; // new xml format
335
336 void* ch = NULL;
337 if( newFormat ){
338 // ------------- new format --------------------
339 // read input
341
343 }else
344 ch = gTools().GetChild(trfnode);
345
346 // Read the transformation matrices from the xml node
347 while(ch!=0) {
349 gTools().ReadAttr(ch, "Rows", nrows);
350 gTools().ReadAttr(ch, "Columns", ncols);
352 const char* content = gTools().GetContent(ch);
353 std::stringstream s(content);
354 for (Int_t row = 0; row<nrows; row++) {
355 for (Int_t col = 0; col<ncols; col++) {
356 s >> (*mat)[row][col];
357 }
358 }
359 fDecorrMatrices.push_back(mat);
360 ch = gTools().GetNextChild(ch);
361 }
362 SetCreated();
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Read the decorellation matrix from an input stream
367
369{
370 char buf[512];
371 istr.getline(buf,512);
372 TString strvar, dummy;
373 Int_t nrows(0), ncols(0);
375 while (!(buf[0]=='#'&& buf[1]=='#')) { // if line starts with ## return
376 char* p = buf;
377 while (*p==' ' || *p=='\t') p++; // 'remove' leading whitespace
378 if (*p=='#' || *p=='\0') {
379 istr.getline(buf,512);
380 continue; // if comment or empty line, read the next line
381 }
382 std::stringstream sstr(buf);
383
384 sstr >> strvar;
385 if (strvar=="signal" || strvar=="background") {
386 UInt_t cls=0;
387 if(strvar=="background") cls=1;
388 if(strvar==classname) classIdx = cls;
389 // coverity[tainted_data_argument]
390 sstr >> nrows >> dummy >> ncols;
391 if (fDecorrMatrices.size() <= cls ) fDecorrMatrices.resize(cls+1);
392 if (fDecorrMatrices.at(cls) != 0) delete fDecorrMatrices.at(cls);
393 TMatrixD* mat = fDecorrMatrices.at(cls) = new TMatrixD(nrows,ncols);
394 // now read all matrix parameters
395 for (Int_t row = 0; row<mat->GetNrows(); row++) {
396 for (Int_t col = 0; col<mat->GetNcols(); col++) {
397 istr >> (*mat)[row][col];
398 }
399 }
400 } // done reading a matrix
401 istr.getline(buf,512); // reading the next line
402 }
403
404 fDecorrMatrices.push_back( new TMatrixD(*fDecorrMatrices[classIdx]) );
405
406 SetCreated();
407}
408
409////////////////////////////////////////////////////////////////////////////////
410/// prints the transformation matrix
411
413{
414 Int_t cls = 0;
415 for (std::vector<TMatrixD*>::iterator itm = fDecorrMatrices.begin(); itm != fDecorrMatrices.end(); ++itm) {
416 Log() << kINFO << "Transformation matrix "<< cls <<":" << Endl;
417 (*itm)->Print();
418 }
419}
420
421////////////////////////////////////////////////////////////////////////////////
422/// creates C++ code fragment of the decorrelation transform for inclusion in standalone C++ class
423
425{
426 Int_t dp = fout.precision();
427
428 UInt_t numC = fDecorrMatrices.size();
429 // creates a decorrelation function
430 if (part==1) {
431 TMatrixD* mat = fDecorrMatrices.at(0); // ToDo check if all Decorr matrices have identical dimensions
432 fout << std::endl;
433 fout << " double fDecTF_"<<trCounter<<"["<<numC<<"]["<<mat->GetNrows()<<"]["<<mat->GetNcols()<<"];" << std::endl;
434 }
435
436 if (part==2) {
437 fout << std::endl;
438 fout << "//_______________________________________________________________________" << std::endl;
439 fout << "inline void " << fcncName << "::InitTransform_"<<trCounter<<"()" << std::endl;
440 fout << "{" << std::endl;
441 fout << " // Decorrelation transformation, initialisation" << std::endl;
442 for (UInt_t icls = 0; icls < numC; icls++){
443 TMatrixD* matx = fDecorrMatrices.at(icls);
444 for (int i=0; i<matx->GetNrows(); i++) {
445 for (int j=0; j<matx->GetNcols(); j++) {
446 fout << " fDecTF_"<<trCounter<<"["<<icls<<"]["<<i<<"]["<<j<<"] = " << std::setprecision(12) << (*matx)[i][j] << ";" << std::endl;
447 }
448 }
449 }
450 fout << "}" << std::endl;
451 fout << std::endl;
452 TMatrixD* matx = fDecorrMatrices.at(0); // ToDo check if all Decorr matrices have identical dimensions
453 fout << "//_______________________________________________________________________" << std::endl;
454 fout << "inline void " << fcncName << "::Transform_"<<trCounter<<"( std::vector<double>& iv, int cls) const" << std::endl;
455 fout << "{" << std::endl;
456 fout << " // Decorrelation transformation" << std::endl;
457 fout << " if (cls < 0 || cls > "<<GetNClasses()<<") {"<< std::endl;
458 fout << " if ("<<GetNClasses()<<" > 1 ) cls = "<<GetNClasses()<<";"<< std::endl;
459 fout << " else cls = "<<(fDecorrMatrices.size()==1?0:2)<<";"<< std::endl;
460 fout << " }"<< std::endl;
461
463
464 fout << " std::vector<double> tv;" << std::endl;
465 fout << " for (int i=0; i<"<<matx->GetNrows()<<";i++) {" << std::endl;
466 fout << " double v = 0;" << std::endl;
467 fout << " for (int j=0; j<"<<matx->GetNcols()<<"; j++)" << std::endl;
468 fout << " v += iv[indicesGet.at(j)] * fDecTF_"<<trCounter<<"[cls][i][j];" << std::endl;
469 fout << " tv.push_back(v);" << std::endl;
470 fout << " }" << std::endl;
471 fout << " for (int i=0; i<"<<matx->GetNrows()<<";i++) iv[indicesPut.at(i)] = tv[i];" << std::endl;
472 fout << "}" << std::endl;
473 }
474
475 fout << std::setprecision(dp);
476}
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
TMatrixT< Double_t > TMatrixD
Definition TMatrixDfwd.h:23
const_iterator begin() const
const_iterator end() const
Class that contains all the data information.
Definition DataSetInfo.h:62
TMatrixD * GetSQRootMatrix(TMatrixDSym *symMat)
square-root of symmetric matrix of course the resulting sqrtMat is also symmetric,...
Definition Tools.cxx:271
const char * GetContent(void *node)
XML helpers.
Definition Tools.cxx:1174
void WriteTMatrixDToXML(void *node, const char *name, TMatrixD *mat)
XML helpers.
Definition Tools.cxx:1243
void ReadAttr(void *node, const char *, T &value)
read attribute from xml
Definition Tools.h:329
void * GetChild(void *parent, const char *childname=nullptr)
get child node
Definition Tools.cxx:1150
void AddAttr(void *node, const char *, const T &value, Int_t precision=16)
add attribute to xml
Definition Tools.h:347
void * AddChild(void *parent, const char *childname, const char *content=nullptr, bool isRootNode=false)
add child node
Definition Tools.cxx:1124
std::vector< TMatrixDSym * > * CalcCovarianceMatrices(const std::vector< Event * > &events, Int_t maxCls, VariableTransformBase *transformBase=nullptr)
compute covariance matrices
Definition Tools.cxx:1513
void * GetNextChild(void *prevchild, const char *childname=nullptr)
XML helpers.
Definition Tools.cxx:1162
Singleton class for Global types used by TMVA.
Definition Types.h:71
void PrintTransformation(std::ostream &o) override
prints the transformation matrix
virtual ~VariableDecorrTransform(void)
destructor
void WriteTransformationToStream(std::ostream &) const override
write the decorrelation matrix to the stream
VariableDecorrTransform(DataSetInfo &dsi)
constructor
void ReadTransformationFromStream(std::istream &, const TString &) override
Read the decorellation matrix from an input stream.
const Event * InverseTransform(const Event *const, Int_t cls) const override
apply the inverse decorrelation transformation ... TODO : ... build the inverse transformation
std::vector< TString > * GetTransformationStrings(Int_t cls) const override
creates string with variable transformations applied
void CalcSQRMats(const std::vector< Event * > &, Int_t maxCls)
compute square-root matrices for signal and background
void AttachXMLTo(void *parent) override
node attachment to parent
void ReadFromXML(void *trfnode) override
Read the transformation matrices from the xml node.
void MakeFunction(std::ostream &fout, const TString &fncName, Int_t part, UInt_t trCounter, Int_t cls) override
creates C++ code fragment of the decorrelation transform for inclusion in standalone C++ class
Bool_t PrepareTransformation(const std::vector< Event * > &) override
calculate the decorrelation matrix and the normalization
const Event * Transform(const Event *const, Int_t cls) const override
apply the decorrelation transformation
void Initialize() override
initialisation
Linear interpolation class.
virtual void MakeFunction(std::ostream &fout, const TString &fncName, Int_t part, UInt_t trCounter, Int_t cls)=0
getinput and setoutput equivalent
virtual void ReadFromXML(void *trfnode)=0
Read the input variables from the XML node.
virtual void AttachXMLTo(void *parent)=0
create XML description the transformation (write out info of selected variables)
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:655
Basic string class.
Definition TString.h:138
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Tools & gTools()
MsgLogger & Endl(MsgLogger &ml)
Definition MsgLogger.h:148
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
TMarker m
Definition textangle.C:8