ROOT logo
// @(#)root/tmva $Id: VariablePCATransform.cxx 31458 2009-11-30 13:58:20Z stelzer $
// 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)                                          *
 **********************************************************************************/

#include <iostream>
#include <iomanip>

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

#include "TMVA/VariablePCATransform.h"

#ifndef ROOT_TMVA_MsgLogger
#include "TMVA/MsgLogger.h"
#endif
#include "TMVA/DataSet.h"
#include "TMVA/Tools.h"

ClassImp(TMVA::VariablePCATransform)

//_______________________________________________________________________
TMVA::VariablePCATransform::VariablePCATransform( DataSetInfo& dsi )
: VariableTransformBase( dsi, Types::kPCA, "PCA" )
{ 
   // constructor
}

//_______________________________________________________________________
TMVA::VariablePCATransform::~VariablePCATransform() 
{
   // destructor
   for (UInt_t i=0; i<fMeanValues.size(); i++) {
      if (fMeanValues.at(i)   != 0) delete fMeanValues.at(i);
      if (fEigenVectors.at(i) != 0) delete fEigenVectors.at(i);
   }
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::Initialize()
{
   // initialization of the transformation. 
   // Has to be called in the preparation and not in the constructor, 
   // since the number of classes it not known at construction, but
   // only after the creation of the DataSet which might be later. 
}

//_______________________________________________________________________
Bool_t TMVA::VariablePCATransform::PrepareTransformation( const std::vector<Event*>& events )
{
   // calculate the principal components using the ROOT class TPrincipal
   // and the normalization
   Initialize();

   if (!IsEnabled() || IsCreated()) return kTRUE;

   Log() << kINFO << "Preparing the Principle Component (PCA) transformation..." << Endl;

   SetNVariables(events[0]->GetNVariables());

   // TPrincipal doesn't support PCA transformation for 1 or less variables
   if (GetNVariables() <= 1) {
      Log() << kINFO << "Cannot perform PCA transformation for " << GetNVariables() << " variable only" << Endl;
      return kFALSE;
   }

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

   CalculatePrincipalComponents( events );

   SetCreated( kTRUE );

   return kTRUE;
}

//_______________________________________________________________________
const TMVA::Event* TMVA::VariablePCATransform::Transform( const Event* const ev, Int_t cls ) const
{
   // apply the principal component analysis
   if (!IsCreated()) return 0;

   const Int_t nvar = ev->GetNVariables();
   // if we have more than one class, take the last PCA analysis where all classes are combined if 
   // the cls parameter is outside the defined classes
   // If there is only one class, then no extra class for all events of all classes has to be created
   if (cls < 0 || cls > GetNClasses()) cls = (fMeanValues.size()==1?0:2);//( GetNClasses() == 1 ? 0 : 1 );  ;
   // Perform PCA and put it into PCAed events tree

   if (fTransformedEvent==0 || fTransformedEvent->GetNVariables()!=ev->GetNVariables()) {
      if(fTransformedEvent!=0) delete fTransformedEvent;
      fTransformedEvent = new Event();
   }

   // set the variable values
   const std::vector<UInt_t>* varArrange = ev->GetVariableArrangement();
   if(!varArrange) {
      std::vector<Float_t> rv = X2P( ev->GetValues(), cls );
      for (Int_t ivar=0; ivar<nvar; ++ivar)
         fTransformedEvent->SetVal(ivar, rv[ivar]);
   } else {
      std::vector<Float_t> rv(nvar);
      for (Int_t ivar=0; ivar<nvar; ++ivar)
         rv[ivar] = ev->GetValue(ivar);
      rv = X2P( rv, cls );
      for (Int_t ivar=0; ivar<nvar; ++ivar)
         fTransformedEvent->SetVal(ivar, rv[ivar]);
   }
   // set the targets
   for (UInt_t itgt=0; itgt<ev->GetNTargets(); itgt++) 
      fTransformedEvent->SetTarget( itgt, ev->GetTarget(itgt) );
   // and the rest
   fTransformedEvent->SetWeight     ( ev->GetWeight() );
   fTransformedEvent->SetBoostWeight( ev->GetBoostWeight() );
   fTransformedEvent->SetClass      ( ev->GetClass() );
   fTransformedEvent->SetSignalClass( ev->GetSignalClass() );
   return fTransformedEvent;
}

//_______________________________________________________________________
const TMVA::Event* TMVA::VariablePCATransform::InverseTransform( const Event* const ev, Int_t cls ) const
{
   // apply the principal component analysis
   // TODO: implementation of inverse transformation
   Log() << kFATAL << "Inverse transformation for PCA transformation not yet implemented. Hence, this transformation cannot be applied together with regression. Please contact the authors if necessary." << Endl;

   if (!IsCreated()) return 0;
   const Int_t nvar = ev->GetNVariables();

   // if we have more than one class, take the last PCA analysis where all classes are combined if 
   // the cls parameter is outside the defined classes
   // If there is only one class, then no extra class for all events of all classes has to be created
   if (cls < 0 || cls > GetNClasses()) cls = ( GetNClasses() == 1 ? 0 : 1 );  


   // Perform PCA and put it into PCAed events tree
   std::vector<Float_t> rv = X2P( ev->GetValues(), cls );

   if (fBackTransformedEvent==0 || fBackTransformedEvent->GetNVariables()!=ev->GetNVariables()) {
      if(fBackTransformedEvent!=0) delete fBackTransformedEvent;
      fBackTransformedEvent = new Event( *ev );
   }
   for (Int_t ivar=0; ivar<nvar; ivar++) fBackTransformedEvent->SetVal(ivar, rv[ivar]);
   fBackTransformedEvent->SetClass      ( ev->GetClass() );
   fBackTransformedEvent->SetWeight     ( ev->GetWeight() );
   fBackTransformedEvent->SetBoostWeight( ev->GetBoostWeight() );

   return fBackTransformedEvent;
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::CalculatePrincipalComponents( const std::vector<Event*>& events )
{
   // 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();

   // if we have more than one class, add another PCA analysis which combines all classes
   const UInt_t maxPCA = (GetNClasses()<=1) ? GetNClasses() : GetNClasses()+1;

   // PCA [signal/background/class x/class y/... /all classes]
   std::vector<TPrincipal*> pca(maxPCA);
   for (UInt_t i=0; i<maxPCA; i++) pca[i] = new TPrincipal(nvar,"");

   // !! Not normalizing and not storing input data, for performance reasons. Should perhaps restore normalization.

   Long64_t ievt, entries = events.size();
   Double_t *dvec = new Double_t[nvar];

   for (ievt=0; ievt<entries; ievt++) {
      Event* ev = events[ievt];
      for (Int_t i = 0; i < nvar; i++) dvec[i] = (Double_t) ev->GetValue(i);
      pca.at(ev->GetClass())->AddRow( dvec );
      if (GetNClasses() > 1) pca.at(maxPCA-1)->AddRow( dvec );
   }

   // delete possible leftovers
   for (UInt_t i=0; i<fMeanValues.size(); i++)   if (fMeanValues[i]   != 0) delete fMeanValues[i];
   for (UInt_t i=0; i<fEigenVectors.size(); i++) if (fEigenVectors[i] != 0) delete fEigenVectors[i];
   fMeanValues.resize(maxPCA,0);
   fEigenVectors.resize(maxPCA,0);

   for (UInt_t i=0; i<maxPCA; i++ ) {
      pca.at(i)->MakePrincipals();
      
      // retrieve mean values, eigenvectors and sigmas
      fMeanValues[i]   = new TVectorD( *(pca.at(i)->GetMeanValues()) ); // need to copy since we want to own
      fEigenVectors[i] = new TMatrixD( *(pca.at(i)->GetEigenVectors()) );
   }

   for (UInt_t i=0; i<maxPCA; i++) delete pca.at(i);
   delete [] dvec;
}

//_______________________________________________________________________
std::vector<Float_t> TMVA::VariablePCATransform::X2P( const std::vector<Float_t>& x, Int_t cls ) 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 = x.size();
   std::vector<Float_t> p(nvar,0);

   for (Int_t i = 0; i < nvar; i++) {
      Double_t pv = 0;
      for (Int_t j = 0; j < nvar; j++)
         pv += (((Double_t)x.at(j)) - (*fMeanValues.at(cls))(j)) * (*fEigenVectors.at(cls))(j,i);
      p[i] = pv;
   }
   return p;
}

//_______________________________________________________________________
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 " << std::endl;
      const TVectorD* means = fMeanValues[sbType];
      o << (sbType==0 ? "Signal" : "Background") << " " << means->GetNrows() << std::endl;
      for (Int_t row = 0; row<means->GetNrows(); row++) {
         o << std::setprecision(12) << std::setw(20) << (*means)[row];
      }
      o << std::endl;
   }
   o << "##" << std::endl;

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

//_______________________________________________________________________
void TMVA::VariablePCATransform::AttachXMLTo(void* parent) {
   // create XML description of PCA transformation

   void* trfxml = gTools().xmlengine().NewChild(parent, 0, "Transform");
   gTools().xmlengine().NewAttr(trfxml, 0, "Name", "PCA");

   // write mean values to stream
   for (UInt_t sbType=0; sbType<fMeanValues.size(); sbType++) {
      void* meanxml = gTools().xmlengine().NewChild( trfxml, 0, "Statistics");
      const TVectorD* means = fMeanValues[sbType];
      gTools().AddAttr( meanxml, "Class",     (sbType==0 ? "Signal" :(sbType==1 ? "Background":"Combined")) );
      gTools().AddAttr( meanxml, "ClassIndex", sbType );
      gTools().AddAttr( meanxml, "NRows",      means->GetNrows() );
      TString meansdef = "";
      for (Int_t row = 0; row<means->GetNrows(); row++)
         meansdef += gTools().StringFromDouble((*means)[row]) + " ";
      gTools().xmlengine().AddRawLine( meanxml, meansdef );      
   }

   // write eigenvectors to stream
   for (UInt_t sbType=0; sbType<fEigenVectors.size(); sbType++) {
      void* evxml = gTools().xmlengine().NewChild( trfxml, 0, "Eigenvectors");
      const TMatrixD* mat = fEigenVectors[sbType];
      gTools().AddAttr( evxml, "Class",      (sbType==0 ? "Signal" :(sbType==1 ? "Background":"Combined") ) );
      gTools().AddAttr( evxml, "ClassIndex", sbType );
      gTools().AddAttr( evxml, "NRows",      mat->GetNrows() );
      gTools().AddAttr( evxml, "NCols",      mat->GetNcols() );
      TString evdef = "";
      for (Int_t row = 0; row<mat->GetNrows(); row++)
         for (Int_t col = 0; col<mat->GetNcols(); col++)
            evdef += gTools().StringFromDouble((*mat)[row][col]) + " ";
      gTools().xmlengine().AddRawLine( evxml, evdef );
   }
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::ReadFromXML( void* trfnode ) 
{
   // Read the transformation matrices from the xml node

   Int_t nrows, ncols;
   UInt_t clsIdx;
   TString classtype;
   TString nodeName;

   void* ch = gTools().xmlengine().GetChild(trfnode);
   while (ch) {
      nodeName = gTools().xmlengine().GetNodeName(ch);
      if (nodeName == "Statistics") {
         // read mean values
         gTools().ReadAttr(ch, "Class",      classtype);
         gTools().ReadAttr(ch, "ClassIndex", clsIdx);
         gTools().ReadAttr(ch, "NRows",      nrows);

         // set the correct size
         if (fMeanValues.size()<=clsIdx) fMeanValues.resize(clsIdx+1,0);
         if (fMeanValues[clsIdx]==0) fMeanValues[clsIdx] = new TVectorD( nrows );
         fMeanValues[clsIdx]->ResizeTo( nrows );
         
         // now read vector entries
         std::stringstream s(gTools().xmlengine().GetNodeContent(ch));
         for (Int_t row = 0; row<nrows; row++) s >> (*fMeanValues[clsIdx])(row);
      } 
      else if ( nodeName == "Eigenvectors" ) {
         // Read eigenvectors
         gTools().ReadAttr(ch, "Class",      classtype);
         gTools().ReadAttr(ch, "ClassIndex", clsIdx);
         gTools().ReadAttr(ch, "NRows",      nrows);
         gTools().ReadAttr(ch, "NCols",      ncols);

         if (fEigenVectors.size()<=clsIdx) fEigenVectors.resize(clsIdx+1,0);
         if (fEigenVectors[clsIdx]==0) fEigenVectors[clsIdx] = new TMatrixD( nrows, ncols );
         fEigenVectors[clsIdx]->ResizeTo( nrows, ncols );

         // now read matrix entries
         std::stringstream s(gTools().xmlengine().GetNodeContent(ch));
         for (Int_t row = 0; row<nrows; row++)
            for (Int_t col = 0; col<ncols; col++)
               s >> (*fEigenVectors[clsIdx])[row][col];
      } // done reading eigenvectors
      ch = gTools().xmlengine().GetNext(ch);
   }

   SetCreated();
}

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

   for (UInt_t i=0; i<fMeanValues.size(); i++) {
      if (fMeanValues.at(i)   != 0) delete fMeanValues.at(i);
      if (fEigenVectors.at(i) != 0) delete fEigenVectors.at(i);
   }
   fMeanValues.resize(3);
   fEigenVectors.resize(3);

   std::cout << "VariablePCATransform::ReadTransformationFromStream(): " << std::endl;

   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
   }
   fMeanValues[2] = new TVectorD( *fMeanValues[classIdx] );
   fEigenVectors[2] = new TMatrixD( *fEigenVectors[classIdx] );

   SetCreated();
}

//_______________________________________________________________________
void TMVA::VariablePCATransform::MakeFunction( std::ostream& fout, const TString& fcncName, 
                                               Int_t part, UInt_t trCounter, Int_t ) 
{
   // creates C++ code fragment of the PCA transform for inclusion in standalone C++ class

   UInt_t nvar = fEigenVectors[0]->GetNrows();

   // creates a PCA transformation function
   UInt_t numC = fMeanValues.size();
   if (part==1) {
      fout << std::endl;
      fout << "   void X2P_"<<trCounter<<"( const double*, double*, int ) const;" << std::endl;
      fout << "   double fMeanValues_"<<trCounter<<"["<<numC<<"]["
           << fMeanValues[0]->GetNrows()   << "];" << std::endl;   // mean values
      fout << "   double fEigenVectors_"<<trCounter<<"["<<numC<<"]["
           << fEigenVectors[0]->GetNrows() << "]["
           << fEigenVectors[0]->GetNcols() <<"];" << std::endl;   // eigenvectors
      fout << std::endl;
   }

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

   if (part==2) {

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

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

      // fill matrix of eigenvectors
      fout << std::endl;
      fout << "   // initialise matrix of eigenvectors" << std::endl;
      for (UInt_t index=0; index<numC; index++) {
         for (int i=0; i<fEigenVectors[index]->GetNrows(); i++) {
            for (int j=0; j<fEigenVectors[index]->GetNcols(); j++) {
               fout << "   fEigenVectors_"<<trCounter<<"["<<index<<"]["<<i<<"]["<<j<<"] = " << std::setprecision(12) 
                    << (*fEigenVectors[index])(i,j) << ";" << std::endl;
            }
         }
      }
      fout << "}" << std::endl;
      fout << std::endl;
      fout << "//_______________________________________________________________________" << std::endl;
      fout << "inline void " << fcncName << "::Transform_"<<trCounter<<"( std::vector<double>& iv, int cls ) const" << std::endl;
      fout << "{" << std::endl;      
      fout << "   const int nvar = " << nvar << ";" << std::endl;
      fout << "   double *dv = new double[nvar];" << std::endl;
      fout << "   double *rv = new double[nvar];" << std::endl;
      fout << "   if (cls < 0 || cls > "<<GetNClasses()<<") {"<< std::endl;
      fout << "       if ("<<GetNClasses()<<" > 1 ) cls = "<<GetNClasses()<<";"<< std::endl;
      fout << "       else cls = "<<(numC==1?0:2)<<";"<< std::endl;
      fout << "   }"<< std::endl;
      fout << "   for (int ivar=0; ivar<nvar; ivar++) dv[ivar] = iv[ivar];" << std::endl;
      fout << std::endl;
      fout << "   // Perform PCA and put it into PCAed events tree" << std::endl;
      fout << "   this->X2P_"<<trCounter<<"( dv, rv, cls );" << std::endl;
      fout << "   for (int ivar=0; ivar<nvar; ivar++) iv[ivar] = rv[ivar];" << std::endl;
      fout << std::endl;
      fout << "   delete [] dv;" << std::endl;
      fout << "   delete [] rv;" << std::endl;
      fout << "}" << std::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
 VariablePCATransform.cxx:381
 VariablePCATransform.cxx:382
 VariablePCATransform.cxx:383
 VariablePCATransform.cxx:384
 VariablePCATransform.cxx:385
 VariablePCATransform.cxx:386
 VariablePCATransform.cxx:387
 VariablePCATransform.cxx:388
 VariablePCATransform.cxx:389
 VariablePCATransform.cxx:390
 VariablePCATransform.cxx:391
 VariablePCATransform.cxx:392
 VariablePCATransform.cxx:393
 VariablePCATransform.cxx:394
 VariablePCATransform.cxx:395
 VariablePCATransform.cxx:396
 VariablePCATransform.cxx:397
 VariablePCATransform.cxx:398
 VariablePCATransform.cxx:399
 VariablePCATransform.cxx:400
 VariablePCATransform.cxx:401
 VariablePCATransform.cxx:402
 VariablePCATransform.cxx:403
 VariablePCATransform.cxx:404
 VariablePCATransform.cxx:405
 VariablePCATransform.cxx:406
 VariablePCATransform.cxx:407
 VariablePCATransform.cxx:408
 VariablePCATransform.cxx:409
 VariablePCATransform.cxx:410
 VariablePCATransform.cxx:411
 VariablePCATransform.cxx:412
 VariablePCATransform.cxx:413
 VariablePCATransform.cxx:414
 VariablePCATransform.cxx:415
 VariablePCATransform.cxx:416
 VariablePCATransform.cxx:417
 VariablePCATransform.cxx:418
 VariablePCATransform.cxx:419
 VariablePCATransform.cxx:420
 VariablePCATransform.cxx:421
 VariablePCATransform.cxx:422
 VariablePCATransform.cxx:423
 VariablePCATransform.cxx:424
 VariablePCATransform.cxx:425
 VariablePCATransform.cxx:426
 VariablePCATransform.cxx:427
 VariablePCATransform.cxx:428
 VariablePCATransform.cxx:429
 VariablePCATransform.cxx:430
 VariablePCATransform.cxx:431
 VariablePCATransform.cxx:432
 VariablePCATransform.cxx:433
 VariablePCATransform.cxx:434
 VariablePCATransform.cxx:435
 VariablePCATransform.cxx:436
 VariablePCATransform.cxx:437
 VariablePCATransform.cxx:438
 VariablePCATransform.cxx:439
 VariablePCATransform.cxx:440
 VariablePCATransform.cxx:441
 VariablePCATransform.cxx:442
 VariablePCATransform.cxx:443
 VariablePCATransform.cxx:444
 VariablePCATransform.cxx:445
 VariablePCATransform.cxx:446
 VariablePCATransform.cxx:447
 VariablePCATransform.cxx:448
 VariablePCATransform.cxx:449
 VariablePCATransform.cxx:450
 VariablePCATransform.cxx:451
 VariablePCATransform.cxx:452
 VariablePCATransform.cxx:453
 VariablePCATransform.cxx:454
 VariablePCATransform.cxx:455
 VariablePCATransform.cxx:456
 VariablePCATransform.cxx:457
 VariablePCATransform.cxx:458
 VariablePCATransform.cxx:459
 VariablePCATransform.cxx:460
 VariablePCATransform.cxx:461
 VariablePCATransform.cxx:462
 VariablePCATransform.cxx:463
 VariablePCATransform.cxx:464
 VariablePCATransform.cxx:465
 VariablePCATransform.cxx:466
 VariablePCATransform.cxx:467
 VariablePCATransform.cxx:468
 VariablePCATransform.cxx:469
 VariablePCATransform.cxx:470
 VariablePCATransform.cxx:471
 VariablePCATransform.cxx:472
 VariablePCATransform.cxx:473
 VariablePCATransform.cxx:474
 VariablePCATransform.cxx:475
 VariablePCATransform.cxx:476
 VariablePCATransform.cxx:477
 VariablePCATransform.cxx:478
 VariablePCATransform.cxx:479
 VariablePCATransform.cxx:480
 VariablePCATransform.cxx:481
 VariablePCATransform.cxx:482
 VariablePCATransform.cxx:483
 VariablePCATransform.cxx:484
 VariablePCATransform.cxx:485
 VariablePCATransform.cxx:486
 VariablePCATransform.cxx:487
 VariablePCATransform.cxx:488
 VariablePCATransform.cxx:489
 VariablePCATransform.cxx:490
 VariablePCATransform.cxx:491
 VariablePCATransform.cxx:492
 VariablePCATransform.cxx:493
 VariablePCATransform.cxx:494
 VariablePCATransform.cxx:495
 VariablePCATransform.cxx:496
 VariablePCATransform.cxx:497
 VariablePCATransform.cxx:498
 VariablePCATransform.cxx:499
 VariablePCATransform.cxx:500
 VariablePCATransform.cxx:501
 VariablePCATransform.cxx:502
 VariablePCATransform.cxx:503
 VariablePCATransform.cxx:504
 VariablePCATransform.cxx:505
 VariablePCATransform.cxx:506
 VariablePCATransform.cxx:507
 VariablePCATransform.cxx:508
 VariablePCATransform.cxx:509
 VariablePCATransform.cxx:510
 VariablePCATransform.cxx:511
 VariablePCATransform.cxx:512
 VariablePCATransform.cxx:513
 VariablePCATransform.cxx:514
 VariablePCATransform.cxx:515
 VariablePCATransform.cxx:516
 VariablePCATransform.cxx:517
 VariablePCATransform.cxx:518
 VariablePCATransform.cxx:519
 VariablePCATransform.cxx:520
 VariablePCATransform.cxx:521
 VariablePCATransform.cxx:522
 VariablePCATransform.cxx:523
 VariablePCATransform.cxx:524
 VariablePCATransform.cxx:525
 VariablePCATransform.cxx:526
 VariablePCATransform.cxx:527
 VariablePCATransform.cxx:528
 VariablePCATransform.cxx:529
 VariablePCATransform.cxx:530
 VariablePCATransform.cxx:531
 VariablePCATransform.cxx:532
 VariablePCATransform.cxx:533
 VariablePCATransform.cxx:534
 VariablePCATransform.cxx:535
 VariablePCATransform.cxx:536