ROOT logo
// @(#)root/tmva $Id: VariablePCATransform.cxx 21630 2008-01-10 19:40:44Z brun $
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : VariablePCATransform                                                  *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation (see header for description)                               *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Joerg Stelzer   <Joerg.Stelzer@cern.ch>  - CERN, Switzerland              *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         *
 *      MPI-K Heidelberg, Germany                                                 *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

//______________________________________________________________________
/*
  PCA transformation of input variables (uses Root's principal
  component analysis TPrincipal)
*/
//______________________________________________________________________

#include <cassert>

#include "Riostream.h"
#include "TVectorF.h"
#include "TVectorD.h"
#include "TMatrixD.h"
#include "TMatrixDBase.h"

#include "TMVA/VariablePCATransform.h"
#include "TMVA/Tools.h"

using std::endl;

ClassImp(TMVA::VariablePCATransform)

//_______________________________________________________________________
TMVA::VariablePCATransform::VariablePCATransform( std::vector<VariableInfo>& varinfo )
   : VariableTransformBase( varinfo, Types::kPCA )
{ 
   // constructor
   SetName("PCATransform");
   fPCA[0] = fPCA[1] = 0;

   // sanity check --> ROOT bug: TPrincipal crashes if dimension <=1
   if (varinfo.size() <= 1) {
      fLogger << kFATAL << "More than one input variables required for PCA to work ... sorry :-("
              << Endl;
   }

   for (Int_t i=0; i<2; i++) { fMeanValues[i] = 0; fEigenVectors[i] = 0; }
}

//_______________________________________________________________________
TMVA::VariablePCATransform::~VariablePCATransform() 
{
   // destructor
   for (Int_t i=0; i<2; i++)
      if (fPCA[i]) delete fPCA[i];
}

//_______________________________________________________________________
Bool_t TMVA::VariablePCATransform::PrepareTransformation( TTree* inputTree )
{
   // calculate the principal components using the ROOT class TPrincipal
   // and the normalization
   if (!IsEnabled() || IsCreated()) return kTRUE;

   if (inputTree == 0) return kFALSE;

   if (GetNVariables() > 200) { 
      fLogger << kINFO << "----------------------------------------------------------------------------" 
              << Endl;
      fLogger << kINFO 
              << ": More than 200 variables, will not calculate PCA "
              << inputTree->GetName() << "!" << Endl;
      fLogger << kINFO << "----------------------------------------------------------------------------" 
              << Endl;
      return kFALSE;
   }   

   CalculatePrincipalComponents( inputTree );

   SetCreated( kTRUE );

   CalcNorm( inputTree );

   return kTRUE;
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::ApplyTransformation( Types::ESBType type ) const
{
   // apply the principal component analysis
   if (!IsCreated()) return;
   const Int_t nvar = GetNVariables();

   Double_t *dv = new Double_t[nvar];
   Double_t *rv = new Double_t[nvar];
   for (Int_t ivar=0; ivar<nvar; ivar++) dv[ivar] = GetEventRaw().GetVal(ivar);
      
   // Perform PCA and put it into PCAed events tree
   this->X2P( dv, rv, type==Types::kSignal ? 0 : 1 );
   for (Int_t ivar=0; ivar<nvar; ivar++) GetEvent().SetVal(ivar, rv[ivar]);
   GetEvent().SetType       ( GetEventRaw().Type() );
   GetEvent().SetWeight     ( GetEventRaw().GetWeight() );
   GetEvent().SetBoostWeight( GetEventRaw().GetBoostWeight() );

   delete [] dv;
   delete [] rv;
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::CalculatePrincipalComponents( TTree* tr )
{
   // calculate the principal components for the signal and the background data
   // it uses the MakePrincipal method of ROOT's TPrincipal class

   const Int_t nvar = GetNVariables();

   for (Int_t i=0; i<2; i++ ) {
      if (fPCA[i] != NULL) delete fPCA[i];
      fPCA[i] = new TPrincipal( nvar, "" ); // note: following code assumes that option "N" is NOT set !
   }
   // !! Not normalizing and not storing input data, for performance reasons. Should perhaps restore normalization.

   ResetBranchAddresses( tr );

   Long64_t ievt, entries = tr->GetEntries();
   Double_t *dvec = new Double_t[nvar];

   for (ievt=0; ievt<entries; ievt++) {
      ReadEvent(tr, ievt, Types::kSignal);
      for (Int_t i = 0; i < nvar; i++) dvec[i] = (Double_t) GetEventRaw().GetVal(i);
      fPCA[GetEventRaw().IsSignal()?0:1]->AddRow( dvec );
   }

   for (Int_t i=0; i<2; i++ ) {
      fPCA[i]->MakePrincipals();

      // retrieve mean values, eigenvectors and sigmas
      fMeanValues[i]   = const_cast<TVectorD*>( fPCA[i]->GetMeanValues() );
      fEigenVectors[i] = const_cast<TMatrixD*>( fPCA[i]->GetEigenVectors() );
   }
   delete [] dvec;
}

//_______________________________________________________________________
std::vector<TString>* TMVA::VariablePCATransform::GetTransformationStrings( Types::ESBType type ) const
{
   // creates string with variable transformations applied

   const Int_t nvar = GetNVariables();
   std::vector<TString>* strVec = new std::vector<TString>;

   // index
   const Int_t index = (type==Types::kSignal) ? 0 : 1;
   
   // fill vector
   for (Int_t ivar=0; ivar<nvar; ivar++) {
      TString str( "" );
      for (Int_t jvar=0; jvar<nvar; jvar++) {
         if (jvar > 0) str += " + ";
         str += Form( "(%s", (TString("[") + Variable(jvar).GetExpression() + "]").Data() );
         str += ((*fMeanValues[index])(jvar) > 0) ? " + " : " - ";
         str += Form( "%10.5g)", TMath::Abs((*fMeanValues[index])(jvar)) );
         str += Form( "*(%10.5g)", (*fEigenVectors[index])(jvar,ivar) );
      }
      strVec->push_back( str );
   }      

   return strVec;
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::X2P( const Double_t* x, Double_t* p, Int_t index ) const
{
   // Calculate the principal components from the original data vector
   // x, and return it in p (function extracted from TPrincipal::X2P)
   // It's the users responsibility to make sure that both x and p are
   // of the right size (i.e., memory must be allocated for p).
   const Int_t nvar = GetNVariables();

   // need this assert
   assert( index >= 0 && index < 2 );   

   for (Int_t i = 0; i < nvar; i++) {
      p[i] = 0;
      for (Int_t j = 0; j < nvar; j++) p[i] += (x[j] - (*fMeanValues[index])(j)) * (*fEigenVectors[index])(j,i);
   }
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::WriteTransformationToStream( std::ostream& o ) const
{
   // write mean values to stream
   for (Int_t sbType=0; sbType<2; sbType++) {
      o << "# PCA mean values " << endl;
      const TVectorD* means = fMeanValues[sbType];
      o << (sbType==0 ? "signal" : "background") << " " << means->GetNrows() << endl;
      for (Int_t row = 0; row<means->GetNrows(); row++) {
         o << setprecision(12) << setw(20) << (*means)[row];
      }
      o << endl;
   }
   o << "##" << endl;

   // write eigenvectors to stream
   for (Int_t sbType=0; sbType<2; sbType++) {
      o << "# PCA eigenvectors " << endl;
      const TMatrixD* mat = fEigenVectors[sbType];
      o << (sbType==0 ? "signal" : "background") << " " << mat->GetNrows() << " x " << mat->GetNcols() << endl;
      for (Int_t row = 0; row<mat->GetNrows(); row++) {
         for (Int_t col = 0; col<mat->GetNcols(); col++) {
            o << setprecision(12) << setw(20) << (*mat)[row][col] << " ";
         }
         o << endl;
      }
   }
   o << "##" << endl;
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::ReadTransformationFromStream( std::istream& istr )
{
   // Read mean values from input stream
   char buf[512];
   istr.getline(buf,512);
   TString strvar, dummy;
   Int_t nrows(0), ncols(0);

   while (!(buf[0]=='#'&& buf[1]=='#')) { // if line starts with ## return
      char* p = buf;
      while (*p==' ' || *p=='\t') p++; // 'remove' leading whitespace
      if (*p=='#' || *p=='\0') {
         istr.getline(buf,512);
         continue; // if comment or empty line, read the next line
      }
      std::stringstream sstr(buf);
      sstr >> strvar;
      if (strvar=="signal" || strvar=="background") {

         sstr >> nrows;
         Int_t sbType = (strvar=="signal" ? 0 : 1);
        
         if (fMeanValues[sbType] == 0) fMeanValues[sbType] = new TVectorD( nrows );
         else                          fMeanValues[sbType]->ResizeTo( nrows );

         // now read vector entries
         for (Int_t row = 0; row<nrows; row++) istr >> (*fMeanValues[sbType])(row);

      } // done reading vector

      istr.getline(buf,512); // reading the next line
   }

   // Read eigenvectors from input stream
   istr.getline(buf,512);
   while (!(buf[0]=='#'&& buf[1]=='#')) { // if line starts with ## return
      char* p = buf;
      while(*p==' ' || *p=='\t') p++; // 'remove' leading whitespace
      if (*p=='#' || *p=='\0') {
         istr.getline(buf,512);
         continue; // if comment or empty line, read the next line
      }
      std::stringstream sstr(buf);
      sstr >> strvar;
      if (strvar=="signal" || strvar=="background") {

         sstr >> nrows >> dummy >> ncols;
         Int_t sbType = (strvar=="signal" ? 0 : 1);

         if (fEigenVectors[sbType] == 0) fEigenVectors[sbType] = new TMatrixD( nrows, ncols );
         else                            fEigenVectors[sbType]->ResizeTo( nrows, ncols );

         // now read matrix entries
         for (Int_t row = 0; row<fEigenVectors[sbType]->GetNrows(); row++) {
            for (Int_t col = 0; col<fEigenVectors[sbType]->GetNcols(); col++) {
               istr >> (*fEigenVectors[sbType])[row][col];
            }
         }

      } // done reading matrix
      istr.getline(buf,512); // reading the next line
   }

   SetCreated();
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::MakeFunction( std::ostream& fout, const TString& fcncName, Int_t part ) 
{
   // creates a PCA transformation function
   if (part==1) {
      fout << endl;
      fout << "   void X2P( const double*, double*, int ) const;" << endl;
      fout << "   double fMeanValues[2]["   
           << fMeanValues[0]->GetNrows()   << "];" << endl;   // mean values
      fout << "   double fEigenVectors[2][" 
           << fEigenVectors[0]->GetNrows() << "][" 
           << fEigenVectors[0]->GetNcols() <<"];" << endl;   // eigenvectors
      fout << endl;
   }

   // sanity check
   if (fMeanValues[0]->GetNrows()   != fMeanValues[1]->GetNrows() ||
       fEigenVectors[0]->GetNrows() != fEigenVectors[1]->GetNrows() ||
       fEigenVectors[0]->GetNcols() != fEigenVectors[1]->GetNcols()) {
      fLogger << kFATAL << "<MakeFunction> Mismatch in vector/matrix dimensions" << Endl;
   }

   if (part==2) {

      fout << "inline void " << fcncName << "::X2P( const double* x, double* p, int index ) const" << endl;
      fout << "{" << endl;
      fout << "   // Calculate the principal components from the original data vector" << endl;
      fout << "   // x, and return it in p (function extracted from TPrincipal::X2P)" << endl;
      fout << "   // It's the users responsibility to make sure that both x and p are" << endl;
      fout << "   // of the right size (i.e., memory must be allocated for p)." << endl;
      fout << "   const int nvar = " << GetNVariables() << ";" << endl;
      fout << endl;
      fout << "   for (int i = 0; i < nvar; i++) {" << endl;
      fout << "      p[i] = 0;" << endl;
      fout << "      for (int j = 0; j < nvar; j++) p[i] += (x[j] - fMeanValues[index][j]) * fEigenVectors[index][j][i];" << endl;
      fout << "   }" << endl;
      fout << "}" << endl;
      fout << endl;
      fout << "inline void " << fcncName << "::InitTransform()" << endl;
      fout << "{" << endl;

      // fill vector of mean values
      fout << "   // initialise vector of mean values" << endl;
      for (int index=0; index<2; index++) {
         for (int i=0; i<fMeanValues[index]->GetNrows(); i++) {
            fout << "   fMeanValues["<<index<<"]["<<i<<"] = " << std::setprecision(12) 
                 << (*fMeanValues[index])(i) << ";" << endl;
         }
      }

      // fill matrix of eigenvectors
      fout << endl;
      fout << "   // initialise matrix of eigenvectors" << endl;
      for (int index=0; index<2; index++) {
         for (int i=0; i<fEigenVectors[index]->GetNrows(); i++) {
            for (int j=0; j<fEigenVectors[index]->GetNcols(); j++) {
               fout << "   fEigenVectors["<<index<<"]["<<i<<"]["<<j<<"] = " << std::setprecision(12) 
                    << (*fEigenVectors[index])(i,j) << ";" << endl;
            }
         }
      }
      fout << "}" << endl;
      fout << endl;
      fout << "inline void " << fcncName << "::Transform( std::vector<double>& iv, int sigOrBgd ) const" << endl;
      fout << "{" << endl;      
      fout << "   const int nvar = " << GetNVariables() << ";" << endl;
      fout << "   double *dv = new double[nvar];" << endl;
      fout << "   double *rv = new double[nvar];" << endl;
      fout << "   for (int ivar=0; ivar<nvar; ivar++) dv[ivar] = iv[ivar];" << endl;
      fout << endl;
      fout << "   // Perform PCA and put it into PCAed events tree" << endl;
      fout << "   this->X2P( dv, rv, (sigOrBgd==0 ? 0 : 1 ) );" << endl;
      fout << "   for (int ivar=0; ivar<nvar; ivar++) iv[ivar] = rv[ivar];" << endl;
      fout << endl;
      fout << "   delete [] dv;" << endl;
      fout << "   delete [] rv;" << endl;
      fout << "}" << endl;
   }
}
 VariablePCATransform.cxx:1
 VariablePCATransform.cxx:2
 VariablePCATransform.cxx:3
 VariablePCATransform.cxx:4
 VariablePCATransform.cxx:5
 VariablePCATransform.cxx:6
 VariablePCATransform.cxx:7
 VariablePCATransform.cxx:8
 VariablePCATransform.cxx:9
 VariablePCATransform.cxx:10
 VariablePCATransform.cxx:11
 VariablePCATransform.cxx:12
 VariablePCATransform.cxx:13
 VariablePCATransform.cxx:14
 VariablePCATransform.cxx:15
 VariablePCATransform.cxx:16
 VariablePCATransform.cxx:17
 VariablePCATransform.cxx:18
 VariablePCATransform.cxx:19
 VariablePCATransform.cxx:20
 VariablePCATransform.cxx:21
 VariablePCATransform.cxx:22
 VariablePCATransform.cxx:23
 VariablePCATransform.cxx:24
 VariablePCATransform.cxx:25
 VariablePCATransform.cxx:26
 VariablePCATransform.cxx:27
 VariablePCATransform.cxx:28
 VariablePCATransform.cxx:29
 VariablePCATransform.cxx:30
 VariablePCATransform.cxx:31
 VariablePCATransform.cxx:32
 VariablePCATransform.cxx:33
 VariablePCATransform.cxx:34
 VariablePCATransform.cxx:35
 VariablePCATransform.cxx:36
 VariablePCATransform.cxx:37
 VariablePCATransform.cxx:38
 VariablePCATransform.cxx:39
 VariablePCATransform.cxx:40
 VariablePCATransform.cxx:41
 VariablePCATransform.cxx:42
 VariablePCATransform.cxx:43
 VariablePCATransform.cxx:44
 VariablePCATransform.cxx:45
 VariablePCATransform.cxx:46
 VariablePCATransform.cxx:47
 VariablePCATransform.cxx:48
 VariablePCATransform.cxx:49
 VariablePCATransform.cxx:50
 VariablePCATransform.cxx:51
 VariablePCATransform.cxx:52
 VariablePCATransform.cxx:53
 VariablePCATransform.cxx:54
 VariablePCATransform.cxx:55
 VariablePCATransform.cxx:56
 VariablePCATransform.cxx:57
 VariablePCATransform.cxx:58
 VariablePCATransform.cxx:59
 VariablePCATransform.cxx:60
 VariablePCATransform.cxx:61
 VariablePCATransform.cxx:62
 VariablePCATransform.cxx:63
 VariablePCATransform.cxx:64
 VariablePCATransform.cxx:65
 VariablePCATransform.cxx:66
 VariablePCATransform.cxx:67
 VariablePCATransform.cxx:68
 VariablePCATransform.cxx:69
 VariablePCATransform.cxx:70
 VariablePCATransform.cxx:71
 VariablePCATransform.cxx:72
 VariablePCATransform.cxx:73
 VariablePCATransform.cxx:74
 VariablePCATransform.cxx:75
 VariablePCATransform.cxx:76
 VariablePCATransform.cxx:77
 VariablePCATransform.cxx:78
 VariablePCATransform.cxx:79
 VariablePCATransform.cxx:80
 VariablePCATransform.cxx:81
 VariablePCATransform.cxx:82
 VariablePCATransform.cxx:83
 VariablePCATransform.cxx:84
 VariablePCATransform.cxx:85
 VariablePCATransform.cxx:86
 VariablePCATransform.cxx:87
 VariablePCATransform.cxx:88
 VariablePCATransform.cxx:89
 VariablePCATransform.cxx:90
 VariablePCATransform.cxx:91
 VariablePCATransform.cxx:92
 VariablePCATransform.cxx:93
 VariablePCATransform.cxx:94
 VariablePCATransform.cxx:95
 VariablePCATransform.cxx:96
 VariablePCATransform.cxx:97
 VariablePCATransform.cxx:98
 VariablePCATransform.cxx:99
 VariablePCATransform.cxx:100
 VariablePCATransform.cxx:101
 VariablePCATransform.cxx:102
 VariablePCATransform.cxx:103
 VariablePCATransform.cxx:104
 VariablePCATransform.cxx:105
 VariablePCATransform.cxx:106
 VariablePCATransform.cxx:107
 VariablePCATransform.cxx:108
 VariablePCATransform.cxx:109
 VariablePCATransform.cxx:110
 VariablePCATransform.cxx:111
 VariablePCATransform.cxx:112
 VariablePCATransform.cxx:113
 VariablePCATransform.cxx:114
 VariablePCATransform.cxx:115
 VariablePCATransform.cxx:116
 VariablePCATransform.cxx:117
 VariablePCATransform.cxx:118
 VariablePCATransform.cxx:119
 VariablePCATransform.cxx:120
 VariablePCATransform.cxx:121
 VariablePCATransform.cxx:122
 VariablePCATransform.cxx:123
 VariablePCATransform.cxx:124
 VariablePCATransform.cxx:125
 VariablePCATransform.cxx:126
 VariablePCATransform.cxx:127
 VariablePCATransform.cxx:128
 VariablePCATransform.cxx:129
 VariablePCATransform.cxx:130
 VariablePCATransform.cxx:131
 VariablePCATransform.cxx:132
 VariablePCATransform.cxx:133
 VariablePCATransform.cxx:134
 VariablePCATransform.cxx:135
 VariablePCATransform.cxx:136
 VariablePCATransform.cxx:137
 VariablePCATransform.cxx:138
 VariablePCATransform.cxx:139
 VariablePCATransform.cxx:140
 VariablePCATransform.cxx:141
 VariablePCATransform.cxx:142
 VariablePCATransform.cxx:143
 VariablePCATransform.cxx:144
 VariablePCATransform.cxx:145
 VariablePCATransform.cxx:146
 VariablePCATransform.cxx:147
 VariablePCATransform.cxx:148
 VariablePCATransform.cxx:149
 VariablePCATransform.cxx:150
 VariablePCATransform.cxx:151
 VariablePCATransform.cxx:152
 VariablePCATransform.cxx:153
 VariablePCATransform.cxx:154
 VariablePCATransform.cxx:155
 VariablePCATransform.cxx:156
 VariablePCATransform.cxx:157
 VariablePCATransform.cxx:158
 VariablePCATransform.cxx:159
 VariablePCATransform.cxx:160
 VariablePCATransform.cxx:161
 VariablePCATransform.cxx:162
 VariablePCATransform.cxx:163
 VariablePCATransform.cxx:164
 VariablePCATransform.cxx:165
 VariablePCATransform.cxx:166
 VariablePCATransform.cxx:167
 VariablePCATransform.cxx:168
 VariablePCATransform.cxx:169
 VariablePCATransform.cxx:170
 VariablePCATransform.cxx:171
 VariablePCATransform.cxx:172
 VariablePCATransform.cxx:173
 VariablePCATransform.cxx:174
 VariablePCATransform.cxx:175
 VariablePCATransform.cxx:176
 VariablePCATransform.cxx:177
 VariablePCATransform.cxx:178
 VariablePCATransform.cxx:179
 VariablePCATransform.cxx:180
 VariablePCATransform.cxx:181
 VariablePCATransform.cxx:182
 VariablePCATransform.cxx:183
 VariablePCATransform.cxx:184
 VariablePCATransform.cxx:185
 VariablePCATransform.cxx:186
 VariablePCATransform.cxx:187
 VariablePCATransform.cxx:188
 VariablePCATransform.cxx:189
 VariablePCATransform.cxx:190
 VariablePCATransform.cxx:191
 VariablePCATransform.cxx:192
 VariablePCATransform.cxx:193
 VariablePCATransform.cxx:194
 VariablePCATransform.cxx:195
 VariablePCATransform.cxx:196
 VariablePCATransform.cxx:197
 VariablePCATransform.cxx:198
 VariablePCATransform.cxx:199
 VariablePCATransform.cxx:200
 VariablePCATransform.cxx:201
 VariablePCATransform.cxx:202
 VariablePCATransform.cxx:203
 VariablePCATransform.cxx:204
 VariablePCATransform.cxx:205
 VariablePCATransform.cxx:206
 VariablePCATransform.cxx:207
 VariablePCATransform.cxx:208
 VariablePCATransform.cxx:209
 VariablePCATransform.cxx:210
 VariablePCATransform.cxx:211
 VariablePCATransform.cxx:212
 VariablePCATransform.cxx:213
 VariablePCATransform.cxx:214
 VariablePCATransform.cxx:215
 VariablePCATransform.cxx:216
 VariablePCATransform.cxx:217
 VariablePCATransform.cxx:218
 VariablePCATransform.cxx:219
 VariablePCATransform.cxx:220
 VariablePCATransform.cxx:221
 VariablePCATransform.cxx:222
 VariablePCATransform.cxx:223
 VariablePCATransform.cxx:224
 VariablePCATransform.cxx:225
 VariablePCATransform.cxx:226
 VariablePCATransform.cxx:227
 VariablePCATransform.cxx:228
 VariablePCATransform.cxx:229
 VariablePCATransform.cxx:230
 VariablePCATransform.cxx:231
 VariablePCATransform.cxx:232
 VariablePCATransform.cxx:233
 VariablePCATransform.cxx:234
 VariablePCATransform.cxx:235
 VariablePCATransform.cxx:236
 VariablePCATransform.cxx:237
 VariablePCATransform.cxx:238
 VariablePCATransform.cxx:239
 VariablePCATransform.cxx:240
 VariablePCATransform.cxx:241
 VariablePCATransform.cxx:242
 VariablePCATransform.cxx:243
 VariablePCATransform.cxx:244
 VariablePCATransform.cxx:245
 VariablePCATransform.cxx:246
 VariablePCATransform.cxx:247
 VariablePCATransform.cxx:248
 VariablePCATransform.cxx:249
 VariablePCATransform.cxx:250
 VariablePCATransform.cxx:251
 VariablePCATransform.cxx:252
 VariablePCATransform.cxx:253
 VariablePCATransform.cxx:254
 VariablePCATransform.cxx:255
 VariablePCATransform.cxx:256
 VariablePCATransform.cxx:257
 VariablePCATransform.cxx:258
 VariablePCATransform.cxx:259
 VariablePCATransform.cxx:260
 VariablePCATransform.cxx:261
 VariablePCATransform.cxx:262
 VariablePCATransform.cxx:263
 VariablePCATransform.cxx:264
 VariablePCATransform.cxx:265
 VariablePCATransform.cxx:266
 VariablePCATransform.cxx:267
 VariablePCATransform.cxx:268
 VariablePCATransform.cxx:269
 VariablePCATransform.cxx:270
 VariablePCATransform.cxx:271
 VariablePCATransform.cxx:272
 VariablePCATransform.cxx:273
 VariablePCATransform.cxx:274
 VariablePCATransform.cxx:275
 VariablePCATransform.cxx:276
 VariablePCATransform.cxx:277
 VariablePCATransform.cxx:278
 VariablePCATransform.cxx:279
 VariablePCATransform.cxx:280
 VariablePCATransform.cxx:281
 VariablePCATransform.cxx:282
 VariablePCATransform.cxx:283
 VariablePCATransform.cxx:284
 VariablePCATransform.cxx:285
 VariablePCATransform.cxx:286
 VariablePCATransform.cxx:287
 VariablePCATransform.cxx:288
 VariablePCATransform.cxx:289
 VariablePCATransform.cxx:290
 VariablePCATransform.cxx:291
 VariablePCATransform.cxx:292
 VariablePCATransform.cxx:293
 VariablePCATransform.cxx:294
 VariablePCATransform.cxx:295
 VariablePCATransform.cxx:296
 VariablePCATransform.cxx:297
 VariablePCATransform.cxx:298
 VariablePCATransform.cxx:299
 VariablePCATransform.cxx:300
 VariablePCATransform.cxx:301
 VariablePCATransform.cxx:302
 VariablePCATransform.cxx:303
 VariablePCATransform.cxx:304
 VariablePCATransform.cxx:305
 VariablePCATransform.cxx:306
 VariablePCATransform.cxx:307
 VariablePCATransform.cxx:308
 VariablePCATransform.cxx:309
 VariablePCATransform.cxx:310
 VariablePCATransform.cxx:311
 VariablePCATransform.cxx:312
 VariablePCATransform.cxx:313
 VariablePCATransform.cxx:314
 VariablePCATransform.cxx:315
 VariablePCATransform.cxx:316
 VariablePCATransform.cxx:317
 VariablePCATransform.cxx:318
 VariablePCATransform.cxx:319
 VariablePCATransform.cxx:320
 VariablePCATransform.cxx:321
 VariablePCATransform.cxx:322
 VariablePCATransform.cxx:323
 VariablePCATransform.cxx:324
 VariablePCATransform.cxx:325
 VariablePCATransform.cxx:326
 VariablePCATransform.cxx:327
 VariablePCATransform.cxx:328
 VariablePCATransform.cxx:329
 VariablePCATransform.cxx:330
 VariablePCATransform.cxx:331
 VariablePCATransform.cxx:332
 VariablePCATransform.cxx:333
 VariablePCATransform.cxx:334
 VariablePCATransform.cxx:335
 VariablePCATransform.cxx:336
 VariablePCATransform.cxx:337
 VariablePCATransform.cxx:338
 VariablePCATransform.cxx:339
 VariablePCATransform.cxx:340
 VariablePCATransform.cxx:341
 VariablePCATransform.cxx:342
 VariablePCATransform.cxx:343
 VariablePCATransform.cxx:344
 VariablePCATransform.cxx:345
 VariablePCATransform.cxx:346
 VariablePCATransform.cxx:347
 VariablePCATransform.cxx:348
 VariablePCATransform.cxx:349
 VariablePCATransform.cxx:350
 VariablePCATransform.cxx:351
 VariablePCATransform.cxx:352
 VariablePCATransform.cxx:353
 VariablePCATransform.cxx:354
 VariablePCATransform.cxx:355
 VariablePCATransform.cxx:356
 VariablePCATransform.cxx:357
 VariablePCATransform.cxx:358
 VariablePCATransform.cxx:359
 VariablePCATransform.cxx:360
 VariablePCATransform.cxx:361
 VariablePCATransform.cxx:362
 VariablePCATransform.cxx:363
 VariablePCATransform.cxx:364
 VariablePCATransform.cxx:365
 VariablePCATransform.cxx:366
 VariablePCATransform.cxx:367
 VariablePCATransform.cxx:368
 VariablePCATransform.cxx:369
 VariablePCATransform.cxx:370
 VariablePCATransform.cxx:371
 VariablePCATransform.cxx:372
 VariablePCATransform.cxx:373
 VariablePCATransform.cxx:374
 VariablePCATransform.cxx:375
 VariablePCATransform.cxx:376
 VariablePCATransform.cxx:377
 VariablePCATransform.cxx:378
 VariablePCATransform.cxx:379
 VariablePCATransform.cxx:380