#include "QFramework/TQAlgorithm.h"
#include "QFramework/TQSample.h"
#include "QFramework/TQSampleFolder.h"
#include "QFramework/TQObservable.h"
#include "TTree.h"
#include "QFramework/TQLibrary.h"
bool TQAlgorithm::Manager::addAlgorithm(TQAlgorithm* newAlgorithm){
for(size_t i=0; i<this->gAlgorithmList.size(); ++i){
if(TQStringUtils::equal(gAlgorithmList[i]->GetName(),newAlgorithm->GetName())){
return false;
}
}
this->gAlgorithmList.push_back(newAlgorithm);
return true;
}
void TQAlgorithm::Manager::clearAlgorithms(){
for(size_t i=0; i< this->gAlgorithmList.size(); ++i){
delete this->gAlgorithmList[i];
}
this->gAlgorithmList.clear();
}
void TQAlgorithm::Manager::clearClonedAlgorithms() {
for (auto& origAlgAndSubMapPair: this->gAlgorithmStore) {
for (auto& stringAndClonedAlgPair : origAlgAndSubMapPair.second) {
delete stringAndClonedAlgPair.second;
}
origAlgAndSubMapPair.second.clear();
}
this->gAlgorithmStore.clear();
}
const std::vector<TQAlgorithm*>& TQAlgorithm::Manager::getAlgorithms(){
return this->gAlgorithmList;
}
void TQAlgorithm::Manager::printAlgorithms() const {
std::cout<<"Registered algorithms:"<<std::endl;
for (TQAlgorithm* const& alg : gAlgorithmList) {
std::cout<<" "<<(alg?alg->GetName():"NULL")<<std::endl;
}
}
void TQAlgorithm::Manager::printActiveAlgorithms() const {
std::cout<<"Active algorithms:"<<std::endl;
for (TQAlgorithm* const& alg : gActiveAlgorithms) {
std::cout<<" "<<(alg?alg->GetName():"NULL")<<std::endl;
}
}
TQAlgorithm* TQAlgorithm::getClone() const {
return static_cast<TQAlgorithm*>( this->Clone() );
}
bool TQAlgorithm::Manager::initializeAlgorithms(TQSample*s){
for(size_t i=0; i<this->gAlgorithmList.size(); ++i){
if(!this->gAlgorithmList[i]->initialize(s)) return false;
}
return true;
}
bool TQAlgorithm::Manager::initializeAlgorithms(TQSampleFolder*s){
for(size_t i=0; i<this->gAlgorithmList.size(); ++i){
if(!this->gAlgorithmList[i]->initializeSampleFolder(s)) return false;
}
return true;
}
void TQAlgorithm::Manager::resetActiveAlgorithms() {
gActiveAlgorithms.clear();
}
namespace {
template<class T> bool initAlg(TQAlgorithm* alg, T* obj);
template<> bool initAlg<TQSample>(TQAlgorithm* alg, TQSample* obj){
return alg->initialize(obj);
}
template<> bool initAlg<TQSampleFolder>(TQAlgorithm* alg, TQSampleFolder* obj){
return alg->initializeSampleFolder(obj);
}
template<class T> bool initAlgSingleton(TQAlgorithm* alg, std::vector<T*>& obj);
template<> bool initAlgSingleton<TQSample>(TQAlgorithm* alg, std::vector<TQSample*>& obj){
return alg->initializeSingleton(obj);
}
template<> bool initAlgSingleton<TQSampleFolder>(TQAlgorithm* alg, std::vector<TQSampleFolder*>& obj){
return alg->initializeSampleFolderSingleton(obj);
}
template<class T> bool finAlg(TQAlgorithm* alg, T* obj);
template<> bool finAlg<TQSample>(TQAlgorithm* alg, TQSample*){
return alg->finalize();
}
template<> bool finAlg<TQSampleFolder>(TQAlgorithm* alg, TQSampleFolder* obj){
return alg->finalizeSampleFolder(obj);
}
template<class T> bool finAlgSingleton(TQAlgorithm* alg, std::vector<T*>& obj);
template<> bool finAlgSingleton<TQSample>(TQAlgorithm* alg, std::vector<TQSample*>&){
return alg->finalizeSingleton();
}
template<> bool finAlgSingleton<TQSampleFolder>(TQAlgorithm* alg, std::vector<TQSampleFolder*>& obj){
return alg->finalizeSampleFolderSingleton(obj);
}
}
bool TQAlgorithm::Manager::isActiveAlgorithm(const TQAlgorithm* alg) const {
for (const TQAlgorithm* ref : this->gActiveAlgorithms) {
if (ref==alg) return true;
}
return false;
}
template <class T> std::map<TQAlgorithm*,T*> TQAlgorithm::Manager::getAlgorithmToSampleFolderMap(const std::vector<T*>& samples, const TString& tagKey) {
std::map<TQAlgorithm*, T*> algMap;
for (auto* s: samples) {
TString key;
if (!s->getTagString(tagKey,key)) { continue; }
for (const auto& origToChannels : this->gAlgorithmStore) {
if (origToChannels.second.count(key)>0) {
algMap[origToChannels.second.at(key)] = s;
}
}
}
return algMap;
}
template std::map<TQAlgorithm*,TQSample*> TQAlgorithm::Manager::getAlgorithmToSampleFolderMap<TQSample>(const std::vector<TQSample*> & samples, const TString& tagKey);
template std::map<TQAlgorithm*,TQSampleFolder*> TQAlgorithm::Manager::getAlgorithmToSampleFolderMap<TQSampleFolder>(const std::vector<TQSampleFolder*> & samples, const TString& tagKey);
template<class T> bool TQAlgorithm::Manager::finalizeClonedAlgorithms(std::vector<T*> & samples, const TString& tagKey){
for (TQAlgorithm*const & alg : gActiveAlgorithms) {
if(alg->isSingleton()){
finAlgSingleton(alg,samples);
} else {
continue;
}
}
std::map<TQAlgorithm*,T*> algMap = this->getAlgorithmToSampleFolderMap(samples, tagKey);
for (const auto& algSF: algMap) {
if (algSF.first->isSingleton()) continue;
finAlg(algSF.first,algSF.second);
}
return true;
}
template bool TQAlgorithm::Manager::finalizeClonedAlgorithms<TQSample>(std::vector<TQSample*> & samples, const TString& tagKey);
template bool TQAlgorithm::Manager::finalizeClonedAlgorithms<TQSampleFolder>(std::vector<TQSampleFolder*> & samples, const TString& tagKey);
template<class T> bool TQAlgorithm::Manager::initializeClonedAlgorithms(std::vector<T*> & samples, const TString& tagKey, bool switchObservableSets){
this->resetActiveAlgorithms();
for (TQAlgorithm* & origAlg: this->gAlgorithmList) {
if (!origAlg) continue;
if (origAlg->isSingleton()) {
if (!initAlgSingleton(origAlg,samples)) {
throw std::runtime_error(TString::Format("Failed to initialize algorithm '%s' as singleton",origAlg->GetName()).Data());
return false;
}
gActiveAlgorithms.push_back(origAlg);
continue;
}
if (gAlgorithmStore.count(origAlg) == 0) {
std::map<TString,TQAlgorithm*> algMap;
for ( auto s : samples) {
TString key;
if (!s->getTagString(tagKey,key)) {
throw std::runtime_error(TString::Format("Could not obtain channel identifier from sample '%s' using key '%s'",s->getPath().Data(), tagKey.Data()).Data());
return false;
}
if(switchObservableSets && !TQObservable::manager.setActiveSet(key)){
TQObservable::manager.cloneActiveSet(key);
}
TQAlgorithm* clone = origAlg->getClone();
bool initSuccess = initAlg(clone,s);
algMap[key] = clone;
gActiveAlgorithms.push_back(clone);
if (!initSuccess) {
ERRORclass("Failed to initialize algorithm '%s' on Sample(Folder)",origAlg->GetName(), s->getPath().Data());
return false;
}
}
gAlgorithmStore[origAlg] = algMap;
} else {
std::map<TString,TQAlgorithm*>& algMap = gAlgorithmStore[origAlg];
for ( auto s : samples) {
TString key;
if (!s->getTagString(tagKey,key)) {
throw std::runtime_error(TString::Format("Could not obtain channel identifier from sample '%s' using key '%s'",s->getPath().Data(), tagKey.Data()).Data());
return false;
}
if(switchObservableSets && !TQObservable::manager.setActiveSet(key)){
TQObservable::manager.cloneActiveSet(key);
}
bool initSuccess = false;
if (algMap.count(key) == 0) {
TQAlgorithm* clone = origAlg->getClone();
initSuccess = initAlg(clone,s);
algMap[key] = clone;
gActiveAlgorithms.push_back(clone);
} else {
TQAlgorithm* clone = algMap[key];
initSuccess = initAlg(clone,s);
gActiveAlgorithms.push_back(clone);
}
if (!initSuccess) {
ERRORclass("Failed to initialize algorithm '%s' on Sample(Folder)",origAlg->GetName(), s->getPath().Data());
return false;
}
}
}
}
return true;
}
template bool TQAlgorithm::Manager::initializeClonedAlgorithms<TQSample>(std::vector<TQSample*> & samples, const TString& tagKey, bool switchObservableSets);
template bool TQAlgorithm::Manager::initializeClonedAlgorithms<TQSampleFolder>(std::vector<TQSampleFolder*> & samples, const TString& tagKey, bool switchObservableSets);
bool TQAlgorithm::Manager::finalizeAlgorithms(){
for (const auto& alg : gAlgorithmList) {
if (!alg->finalize()) return false;
}
return true;
}
bool TQAlgorithm::Manager::finalizeAlgorithmsSampleFolder(TQSampleFolder* sf){
for (const auto& alg : gAlgorithmList) {
if (!alg->finalizeSampleFolder(sf)) return false;
}
return true;
}
bool TQAlgorithm::Manager::executeAlgorithms(){
for (const auto& alg : gAlgorithmList) {
if (!alg->execute()) return false;
}
return true;
}
bool TQAlgorithm::Manager::executeClonedAlgorithms(){
for (TQAlgorithm* const & alg : gActiveAlgorithms) {
if (!alg->execute()) return false;
}
return true;
}
bool TQAlgorithm::Manager::cleanupAlgorithms(){
for (TQAlgorithm* const & alg : gAlgorithmList) {
if (!alg->cleanup()) return false;
}
return true;
}
bool TQAlgorithm::Manager::cleanupClonedAlgorithms(){
for ( TQAlgorithm* const & alg : gActiveAlgorithms) {
if (!alg->cleanup()) return false;
}
return true;
}
bool TQAlgorithm::isSingleton() const {
return false;
}
bool TQAlgorithm::finalizeSingleton(){
this->finalize();
return true;
}
bool TQAlgorithm::finalizeSampleFolderSingleton(const std::vector<TQSampleFolder*>& ) {
return true;
}
bool TQAlgorithm::initializeSingleton(const std::vector<TQSample*>& ) {
ERRORclass("initialization with a list of samples is not implemented for TQAlgorithm with name '%s'!", this->GetName());
return false;
}
bool TQAlgorithm::initialize(TQSample* ) {
ERRORclass("initialization with single TQSample is not implemented for TQAlgorithm with name '%s'!",this->GetName());
return false;
}
bool TQAlgorithm::initializeSampleFolderSingleton(const std::vector<TQSampleFolder*>& ) {
return true;
}
bool TQAlgorithm::initializeSampleFolder(TQSampleFolder* ) {
return true;
}
bool TQAlgorithm::finalizeSampleFolder(TQSampleFolder* ){
return true;
}