#include "QFramework/TQPCAAnalysisJob.h"
#include "QFramework/TQCompiledCut.h"
#include "QFramework/TQAnalysisJob.h"
#include "QFramework/TQCounter.h"
#include "QFramework/TQSample.h"
#include "QFramework/TQUtils.h"
#include <QFramework/TQLibrary.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
ClassImp(TQPCAAnalysisJob)
TQPCAAnalysisJob::TQPCAAnalysisJob() :
TQAnalysisJob("PCA"),
weightCutoff(std::numeric_limits<double>::epsilon())
{
}
TQPCAAnalysisJob::TQPCAAnalysisJob(TString name_) :
TQAnalysisJob(name_),
weightCutoff(std::numeric_limits<double>::epsilon())
{
}
TQPCAAnalysisJob::TQPCAAnalysisJob(TQPCAAnalysisJob &job) :
TQAnalysisJob(job.GetName()),
poolAt(job.poolAt),
weightCutoff(job.weightCutoff)
{
for(size_t i=0; i<job.fObservables.size(); i++){
this->fObservables.push_back(fObservables[i]);
}
}
TQPCAAnalysisJob::TQPCAAnalysisJob(TQPCAAnalysisJob *job) :
TQAnalysisJob(job ? job->GetName() : "PCA"),
poolAt(job ? job->poolAt : NULL),
weightCutoff(job ? job->weightCutoff : std::numeric_limits<double>::epsilon())
{
if(job){
for(size_t i=0; i<job->fObservables.size(); i++){
this->fObservables.push_back(fObservables[i]);
}
}
}
TQPCAAnalysisJob* TQPCAAnalysisJob::copy(){
return new TQPCAAnalysisJob(this);
}
TQPCAAnalysisJob* TQPCAAnalysisJob::getClone(){
return new TQPCAAnalysisJob(this);
}
bool TQPCAAnalysisJob::initializePCA() {
if(this->fPCA) delete this->fPCA;
int nVars = this->fObservables.size();
if(!this->fValues){
this->fValues = (double*)calloc(nVars,sizeof(double));
}
this->fPCA = new TQPCA(this->GetName(),nVars);
for(size_t i=0; i<this->fNames.size(); i++){
this->fPCA->setTagString(TString::Format("varname.%lu", (long unsigned int)i),fNames[i].Data());
this->fPCA->setTagString(TString::Format("vartitle.%lu", (long unsigned int)i),fTitles[i].Data());
this->fPCA->setTagString(TString::Format("varexpression.%lu",(long unsigned int)i),fExpressions[i].Data());
}
return true;
}
bool TQPCAAnalysisJob::finalizePCA() {
if(!this->poolAt) return false;
TString folderName = TString::Format(".pca/%s+",this->getCut()->GetName());
TQFolder * cfFolder = this->poolAt->getFolder(folderName);
if (!cfFolder) { return false; }
TObject* o = cfFolder->FindObject(this->GetName());
if(o){
cfFolder->Remove(o);
}
if(!cfFolder->addObject(this->fPCA)){
return false;
}
this->fPCA = NULL;
return true;
}
bool TQPCAAnalysisJob::initializeSelf() {
if(!this->fPCA) this->initializePCA();
for (unsigned int i = 0; i < fNames.size(); i++) {
TQObservable* obs = TQObservable::getObservable(this->fExpressions[i],this->fSample);
if (!obs->initialize(this->fSample)) {
ERRORclass("Failed to initialize observable obtained from expression '%s' in TQPCAAnalysisJob '%s' for sample '%s'",this->fExpressions[i].Data(),this->GetName(),this->fSample->getPath().Data());
return false;
}
this->fObservables.push_back(obs);
}
return true;
}
bool TQPCAAnalysisJob::finalizeSelf() {
if(this->fSample == this->poolAt)
this->finalizePCA();
for (unsigned int i = 0; i < fObservables.size(); i++) {
this->fObservables[i]->finalize();
}
this->fObservables.clear();
return true;
}
bool TQPCAAnalysisJob::initializeSampleFolder(TQSampleFolder * sf) {
bool pool = false;
sf->getTagBool(".aj.pool.pca",pool);
if(pool && !this->fPCA){
this->poolAt = sf;
}
return true;
}
bool TQPCAAnalysisJob::finalizeSampleFolder(TQSampleFolder* sf) {
bool pool =(sf == this->poolAt);
if (!sf) { return false; }
if(pool)
return this->finalizePCA();
return true;
}
bool TQPCAAnalysisJob::execute(double weight) {
if(weight < this->weightCutoff) return true;
for(size_t i=0; i<this->fObservables.size(); i++){
this->fValues[i] = this->fObservables[i]->getValue();
}
if(this->checkValues()){
this->fPCA->fill(weight,this->fValues);
}
return true;
}
bool TQPCAAnalysisJob::checkValues() {
for(size_t i=0; i<this->fObservables.size(); i++){
if(!TQUtils::isNum(this->fValues[i])) return false;
}
return true;
}
TQPCAAnalysisJob::~TQPCAAnalysisJob() {
if(this->fPCA)
delete this->fPCA;
for(size_t i=0; i<this->fObservables.size(); i++){
delete this->fObservables[i];
}
if(this->fValues)
free(this->fValues);
}
TObjArray * TQPCAAnalysisJob::getBranchNames() {
TObjArray * bNames = new TObjArray();
for(size_t i=0; i<this->fObservables.size(); i++){
TObjArray* branchNames = this->fObservables[i]->getBranchNames();
bNames->AddAll(branchNames);
delete branchNames;
}
return bNames;
}
void TQPCAAnalysisJob::bookVariable(const TString& name, const TString& title, const TString& expression){
this->fNames.push_back(name);
this->fTitles.push_back(title);
this->fExpressions.push_back(expression);
}
void TQPCAAnalysisJob::bookVariable(const TString& expression){
this->fNames.push_back(expression);
this->fTitles.push_back(expression);
this->fExpressions.push_back(expression);
}
void TQPCAAnalysisJob::setWeightCutoff(double cutoff){
this->weightCutoff = cutoff;
}
double TQPCAAnalysisJob::getWeightCutoff(){
return this->weightCutoff;
}