#include "QFramework/TQNFChainloader.h"
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQUtils.h"
#include "TMath.h"
#include "TRandom.h"
#include "QFramework/TQHistogramUtils.h"
#include "QFramework/TQNFCalculator.h"
#include "QFramework/TQABCDCalculator.h"
#include "QFramework/TQNFManualSetter.h"
#include "QFramework/TQNFTop0jetEstimator.h"
#include "QFramework/TQNFTop1jetEstimator.h"
#include "QFramework/TQNFCustomCalculator.h"
#include "QFramework/TQNFUncertaintyScaler.h"
#include "TMatrixD.h"
#include "TFile.h"

#include <limits>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <fstream>

// #define _DEBUG_
#include "QFramework/TQLibrary.h"

////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQNFChainloader
//
// This class provides a single interface to all available NF calculation
// methods. Given one or more apropriate configurations it will run the
// corresponding NF calculators in an order according to the configurations
// while keeping track of all NFs saved to the sample folder provided to the
// chainloader. The NF calculators used in this class must inherit from TQNFBase.
//
// The execution of the specified NF calculators can be iterated by setting the
// integer tag "numberOfIterations" (default 1) to the desired number of iterative 
// executions.
//
// NF uncertainties and correlations are computed when the integer tag "toySize" 
// (default 1) is set and differs from its default value. The value of this tag
// determines how many toy NFs are created in order to compute sample 
// (co)variances used as uncertainty estimates. The toy NFs are created by randomly 
// varying input counters (data and MC) according to a gaussian distribution using
// the uncertainties of the input quantities. In order to have consistent variations
// within the calculation process of one toy NF the TQNFChainloader provides these 
// variations to the NF calculators upon request through getRelVariation
// (const TString& key, double value, double uncertainty).
//
////////////////////////////////////////////////////////////////////////////////////////////////

ClassImp(TQNFChainloader)

TQNFChainloader::TQNFChainloader():
TQNamedTaggable(),
  fReader(NULL),
  status(-999),
  verbosity(0)
{
  // default constructor
  rnd=TRandom3();
}

TQNFChainloader::TQNFChainloader(const std::vector<TString>& nfconfigs, TQSampleFolder* f ):
  TQNamedTaggable(),
  fReader(new TQSampleDataReader(f)),
  vNFconfig(nfconfigs),
  status(-999),
  verbosity(0)
{
  // constructor taking vector of nf config file names and a base sample folder
  rnd=TRandom3();
}

TQNFChainloader::~TQNFChainloader(){
  // default destructor, cleaning up all pointer fields
  if(fReader)
    delete fReader;
  this->finalize();
  this->clear();
}

int TQNFChainloader::addNFconfigs(const std::vector<TString>& nfconfigs) {
  this->vNFconfig.insert( this->vNFconfig.end(), nfconfigs.begin(), nfconfigs.end() );
  return 0;
}

int TQNFChainloader::setNFconfigs(const std::vector<TString>& nfconfigs){
  this->finalize();
  this->addNFconfigs(nfconfigs);
  return 0;
}

void TQNFChainloader::setSampleFolder(TQSampleFolder* f){
  if (!f) return;
  if(!this->fReader){
    this->fReader = new TQSampleDataReader(f);
  }
}


bool TQNFChainloader::initialize(){
  if(!this->fReader) return false;
  //@tag: [pathprefix] This object tag is forwarded to the individual NF calculators as "saveResults.prefix", "writePostFitHistograms.prefix", "writePreFitHistograms.prefix" and  "saveLog.prefix".
  TString prefix = this->getTagStringDefault("pathprefix","");
  TQSampleFolder* sf = this->fReader->getSampleFolder();
  TQFolder * nfinfo = sf->getFolder("info/normalization+");
  TQFolder * cutinfo = sf->getFolder("info/cuts");
  for (uint v=0; v<this->vNFconfig.size(); v++) {
    bool execAtEnd = false; //will be set to true, if a method is configured which should be executed after the normal calculation cycle (e.g. TQNFUncertaintyScaler)
    TString nfconfigname = this->vNFconfig.at(v);
    TString errMsg;
    TQFolder * nfconfig = TQFolder::loadFromTextFile(nfconfigname,errMsg);
    if (!nfconfig){
      ERRORclass("unable to import configuration from '%s', error message was '%s'",nfconfigname.Data(),errMsg.Data());
      continue;
    }
    
    // replace variation and campaigns placeholders in normalization config
    nfconfig->replaceInFolderTags(this->fVariationTags,"*");
    nfconfig->replaceInFolderTags(this->fCampaignTag, "*");
    
    INFOclass("setting up normalization factor configuration '%s'",nfconfigname.Data());
    TQFolderIterator itr(nfconfig->getListOfFolders("?"),true);
    while(itr.hasNext()){
      TQFolder * conf = itr.readNext();
      if (!conf) continue;
      //@tag: [mode] This config tag determines the type of NF calculator to be called for a calculation step. Default: "TQNF", other values: "TOP0JET", "TOP1JET", "MANUAL", "ABCD", "CUSTOM", "ERRSCALE"(special, see TQNFUncertaintyScaler!)
      TString mode = conf->getTagStringDefault("mode","TQNF");
      #ifdef _DEBUG_
      std::cout<<"mode = "<<mode<<std::endl;
      #endif
      //@tag: [applyToCut,stopAtCut] The "applyToCut" config tag determines the cut at which the calculated NFs are applied. It is also applied to all subsequent cuts, untill a cut with name equal to the value listed in "stopAtCut" is reached. Please note that some NF calculators do not have a single set of start/stop cuts and need a slightly different configuration.
      if (!(conf->hasTag("applyToCut") || conf->hasTag("applyToCut.0") ) && !TQStringUtils::equal(mode,"MANUAL") && !TQStringUtils::equal(mode,"ERRSCALE") && !TQStringUtils::equal(mode,"UNCSCALE") && !TQStringUtils::equal(mode,"UNCERTSCALE")) { //TQNFManualSetter and TQNFUncertaintyScaler do not have a single starting cut
        WARNclass("skipping calculation of NFs for instance '%s - no target cut given!",conf->getName().Data());
        continue;
      }

      TString stopatcutname = conf->getTagStringDefault("stopAtCut","");
      
      TQNFBase* nfbase = NULL;
      DEBUGclass("instantiating TQNFBase of type '%s'",mode.Data());
      if(TQStringUtils::equal(mode,"TQNF")){
        TQNFCalculator* tqnf = new TQNFCalculator(this->fReader);
        if (!tqnf->readConfiguration(conf)) {
          ERRORclass("cannot calculate NFs for instance '%s' - there was an error parsing the configuration!",conf->getName().Data());
          continue;
        }
        tqnf->setTag("mode.matrix.nToyHits",1);
        nfbase = tqnf;
      } else if (TQStringUtils::equal(mode,"ABCD")) {
        TQABCDCalculator * abcd = new TQABCDCalculator(this->fReader);
        if (!abcd->readConfiguration(conf)) {
          ERRORclass("cannot perform ABCD for instance '%s' - there was an error parsing the configuration!",conf->getName().Data());
          continue;
        }
        nfbase=abcd;
      } else if (TQStringUtils::equal(mode,"TOP0JET")) {
        TQNFTop0jetEstimator * top0jet = new TQNFTop0jetEstimator(this->fReader);
        if (!top0jet->readConfiguration(conf)) {
          ERRORclass("cannot perform TOP0JET for instance '%s' - there was an error parsing the configuration!",conf->getName().Data());
          continue;
        }
        nfbase=top0jet;
      } else if (TQStringUtils::equal(mode,"TOP1JET")) {
        TQNFTop1jetEstimator * top1jet = new TQNFTop1jetEstimator(this->fReader);
        if (!top1jet->readConfiguration(conf)) {
          ERRORclass("cannot perform TOP1JET for instance '%s' - there was an error parsing the configuration!",conf->getName().Data());
          continue;
        }
        nfbase=top1jet;
      } else if (TQStringUtils::equal(mode,"MANUAL")) {
        TQNFManualSetter * manSetter = new TQNFManualSetter(this->fReader);
        if (!manSetter->readConfiguration(conf)) {
          ERRORclass("cannot perform MANUAL for instance '%s' - there was an error parsing the configuration!",conf->getName().Data());
          continue;
        }
        nfbase=manSetter;
      } else if (TQStringUtils::equal(mode,"CUSTOM")) {
        TQNFCustomCalculator * custCalc = new TQNFCustomCalculator(this->fReader);
        if (!custCalc->readConfiguration(conf)) {
          ERRORclass("cannot perform MANUAL for instance '%s' - there was an error parsing the configuration!",conf->getName().Data());
          continue;
        }
        nfbase=custCalc;
      } else if (TQStringUtils::equal(mode,"ERRSCALE") || TQStringUtils::equal(mode,"UNCSCALE") || TQStringUtils::equal(mode,"UNCERTSCALE")) {
        TQNFUncertaintyScaler * uncScaler = new TQNFUncertaintyScaler(this->fReader);
        if (!uncScaler->readConfiguration(conf)) {
          ERRORclass("cannot perform ERRSCALE/UNCSCALE/UNCERTSCALE for instance '%s' - there was an error parsing the configuration!",conf->getName().Data());
          continue;
        }
        nfbase=uncScaler;
        execAtEnd = true;
      }
      DEBUGclass("done");
      if(nfbase){
        DEBUGclass("performing final setup");
	//        nfbase->setTagString("applyToCut",cutname);
	//        nfbase->setTagString("stopAtCut",stopatcutname);
	nfbase->importTags(conf);
        nfbase->setTagString("saveLog.prefix",prefix);
        nfbase->setTagString("writePreFitHistograms.prefix",prefix);
        nfbase->setTagString("writePostFitHistograms.prefix",prefix);
        nfbase->setTagString("saveResults.prefix",prefix);
        nfbase->setChainLoader(this);
        nfbase->setCutInfoFolder(cutinfo);
        nfbase->setInfoFolder(nfinfo);
        if (!execAtEnd) {
        this->vNFcalc.push_back(nfbase);
        } else {
        this->vNFpostCalc.push_back(nfbase);
        }
        DEBUGclass("done");
      } else {
        WARNclass("unable to initialize NF calculator '%s'",conf->GetName());
      }
    }
  }
  this->initialized = true;
  return true;
}


bool TQNFChainloader::finalize(){
  if(this->initialized){
    for(size_t i=0; i<vNFcalc.size(); ++i){
      #ifdef _DEBUG_
      DEBUGclass("finalizing NFBase '%s'",vNFcalc[i]->GetName());
      #endif
      vNFcalc[i]->finalize();
      #ifdef _DEBUG_
      DEBUGclass("deleting");
      #endif
      delete vNFcalc[i];
      #ifdef _DEBUG_
      DEBUGclass("done");
      #endif
    }
    this->vNFcalc.clear();
    if (this->vNFpostCalc.size()>0) {
      #ifdef _DEBUG_
      DEBUGclass("Executing post-calculation methods)");
      #endif
      for (size_t i=0; i<vNFpostCalc.size(); ++i) {
        //########################################
        TQNFBase* nfcalc = this->vNFpostCalc[i];
        #ifdef _DEBUG_
        DEBUGclass("initializing '%s'",nfcalc->GetName());
        #endif
        if(!nfcalc->initialize()){
          ERRORclass("unable to initialize calculator '%s'",nfcalc->GetName());
          continue;
        }
        #ifdef _DEBUG_
        DEBUGclass("executing '%s'",nfcalc->GetName());
        #endif
        int retval = nfcalc->execute(-1);
        if (0 != retval){
          ERRORclass("an error occured while performing calculation '%s' (return value: %d)!",nfcalc->GetName(),retval);
          continue;
        }
        std::vector<TString> startAtCutNames = nfcalc->getTagVString("applyToCut");
        std::vector<TString> stopatcutname = nfcalc->getTagVString("stopAtCut");
        if (!nfcalc->success()){
          WARN("TQNFBase '%s' failed to calculate NFs for cut(s) '%s' with status %d: %s!",nfcalc->GetName(),TQListUtils::makeCSV(startAtCutNames).Data(),nfcalc->getStatus(),nfcalc->getStatusMessage().Data());
          return false;
        } else if (!(nfcalc->deployResult(startAtCutNames,stopatcutname)>0)){
          ERRORclass("unable to deploy results of NF calculation!");
          return false;
        }
        #ifdef _DEBUG_
        DEBUGclass("finalizing '%s'",nfcalc->GetName());
        #endif
        nfcalc->finalize();
        //########################################################
      }
    }
  }
  for(size_t i=0; i<vNFpostCalc.size(); ++i){
      #ifdef _DEBUG_
      DEBUGclass("finalizing NFBase '%s'",vNFpostCalc[i]->GetName());
      #endif
      vNFpostCalc[i]->finalize();
      #ifdef _DEBUG_
      DEBUGclass("deleting");
      #endif
      delete vNFpostCalc[i];
      #ifdef _DEBUG_
      DEBUGclass("done");
      #endif
    }
  this->vNFpostCalc.clear();
  //perform post calculation operations  (e.g. uncertainty scaling via TQNFUncertaintyScaler)
  this->initialized = false;
  return true;
}

int TQNFChainloader::execute() {
  if(!this->initialized){
    ERRORclass("cannot bootstrap NF calculation uninitialized!");
    return -1;
  }
  //@tag: [numberOfIterations] This object tag specifies how often the serial calculation of NFs --as specified in the respective config file-- should be repeated. Since the order in which the calculations are performed generally influences the result, this can be used this option can be used to possibly make the resulting NFs converge, i.e. become independent from the order of calculation. Default: 1
  //@tag: [toySize] This specifies the number of toy NFs created to estimate the uncertainty of the resulting NFs (and their correlation). For each toy NF all input quantities are varied within their uncertainties as present in the sample file at the time of calculation. This usually does not include systematic uncertainties! The variations are ensured to be constant during the calculation of one toy. If the default value of 1 is not changed, no variations and no uncertainty estimate is performed.
  int iterations = this->getTagDefault("numberOfIterations",1);
  int nToy = this->getTagDefault("toySize",1);
  bool doVariations = (nToy>1);
  #ifdef _DEBUG_
  DEBUGclass("bootstrapping nf calculations");
  #endif
  INFOclass("running calculation of normalization factors with %d toys!", nToy);
  for (int t = 0;t<nToy;t++) {
    #ifdef _DEBUG_
    DEBUGclass("rolling toy %d/%d",t+1,nToy);
    #endif
    for (int i=0;i<iterations;++i) {
      #ifdef _DEBUG_
      DEBUGclass("undergoing iteration %d/%d",i+1,iterations);
      #endif
      for(size_t k=0; k<this->vNFcalc.size(); k++){
        TQNFBase* nfcalc = this->vNFcalc[k];
        #ifdef _DEBUG_
        DEBUGclass("initializing '%s'",nfcalc->GetName());
        #endif
        if(!nfcalc->initialize()){
          ERRORclass("unable to initialize calculator '%s'",nfcalc->GetName());
          continue;
        }
        #ifdef _DEBUG_
        DEBUGclass("executing '%s'",nfcalc->GetName());
        #endif
        int retval = nfcalc->execute(doVariations ? t : -1);
        if (0 != retval){
          ERRORclass("an error occured while performing calculation '%s' (return value: %d)!",nfcalc->GetName(),retval);
          continue;
        }

        std::vector<TString> startAtCutNames = nfcalc->getTagVString("applyToCut");
        std::vector<TString> stopatcutname = nfcalc->getTagVString("stopAtCut");
        if (!nfcalc->success()){
          WARN("TQNFBase '%s' failed to calculate NFs for cut '%s' with status %d: %s!",nfcalc->GetName(),TQListUtils::makeCSV(startAtCutNames).Data(),nfcalc->getStatus(),nfcalc->getStatusMessage().Data());
          return -1;
        } else if (!nfcalc->deployResult(startAtCutNames,stopatcutname)){
          ERRORclass("unable to deploy results of NF calculation!");
          return -1;
        } else {
          DEBUGclass("successfully deployed results for '%s' to cuts '%s'-'%s'",nfcalc->GetName(),TQStringUtils::concat(startAtCutNames,",").Data(),TQStringUtils::concat(stopatcutname,",").Data());
        }
        if (t==0 && doVariations){
          this->registerTargetPaths(nfcalc->getNFpaths()); //only required during first toy-iteration
        }
        #ifdef _DEBUG_
        DEBUGclass("finalizing '%s'",nfcalc->GetName());
        #endif
        nfcalc->finalize();
        #ifdef _DEBUG_
        DEBUGclass("done!");
        #endif
      }
    }
    if (doVariations) {
      this->relativeVariationMap.clear();
      this->collectNFs();
    }
    #ifdef _DEBUG_
    DEBUGclass("end of iteration");
    #endif
  }
  if (doVariations) {
#ifdef _DEBUG_
    DEBUGclass("deploying NFs");
    for(size_t i=0; i<this->vNFcalc.size(); ++i){
      this->vNFcalc[i]->printNFPaths();
    }
#endif
    this->deployNFs();
  }
  DEBUGclass("end of function");
  return 0;
}

double TQNFChainloader::getRelVariation(const TString& key, double value, double uncertainty) {
  // key = [path to counter]:[cut name]
  // This function allows for NF calculators to retrieve consistent random variations of
  // their input (event)counters in order to create toy samples and estimate NF uncertainties.
  // The returned value is a multiplicative factor, allowing for it to be applied to the nominal
  // counter even if some (preliminary) scale factors have already been applied.
  // If no variation is present for key, a new one is generated using 
  // TRandom3::Gaus(value,uncertainty) and stored unless value == 0.
  if (key=="") {
    WARN("No valid key has been given! Returning 0!");
    return 0;
  }
 
  if (this->relativeVariationMap.count(key)==0) { //entry does not yet exist, so we create a new one
    if (value == 0) return 0; //in case the value is zero, the relative variation does not matter anyways. However, this might be due to some scale factor, so we do not want to store a variation.
    this->relativeVariationMap[key] = (rnd.Gaus(value,uncertainty))/value;
  }
  double retval = this->relativeVariationMap[key];
  return retval;
 
}

int TQNFChainloader::registerTargetPaths(const std::vector<TString>& vec){
  int npre = this->targetNFpaths.size();
  for (uint i=0;i<vec.size();i++){
    this->targetNFpaths[vec[i]] = true;
  }
  return this->targetNFpaths.size()-npre;
}

int TQNFChainloader::collectNFs() {
  int nNFs = 0;
  for (auto& item : this->targetNFpaths) {
    TString path = item.first;
    TString cut = TQFolder::getPathTail(path);
    TString scheme = TQStringUtils::readPrefix(cut, ":", ".default");
    double nf = 1;
    TQSampleFolder* sf = this->fReader->getSampleFolder();
    if (sf->getSampleFolder(path)){
      nf = sf->getSampleFolder(path)->getScaleFactor(scheme+":"+cut);
      sf->getSampleFolder(path)->setScaleFactor(scheme+":"+cut,1.,0.);
    }else {
      ERRORclass("Failed to retrieve scale factor, results may be unreliable!");
    }
    mNFvectors[item.first].push_back(nf);
    nNFs++;
  }
  return nNFs;
}

int TQNFChainloader::deployNFs() {
  int nNFs = 0;
  std::vector<TString> names;
  std::vector<TString> identifier;
  std::vector<std::vector<double>> toys;
  for (auto& item : this->mNFvectors) {
    names.push_back(item.first);
    toys.push_back(item.second);
  }
  //@tag: [doNFplots] If this object tag is set to true, a root file is produced with distributions of the obtained toy NFs. Default: false.
  //@tag: [NFplotsPattern,NFplotsFile] The vector valued object tag "NFplotsPattern" specifies filtes specifying which NF toy distributions are to be exported to the root file specified in the object tag "NFplotsFile". The distribution of an NF is exported if it matches any of the comma seperated filter expressions. Example: *bkg/ee/*/.default:CutWeights (syntax: path/scaleScheme:cut)
  if (this->getTagBoolDefault("doNFplots",false)) {
    std::vector<TString> NFpatterns;
    this->getTag("NFplotsPattern",NFpatterns);
    if (NFpatterns.size()>0) {
      //we first collect the indices of the NFs we want to plot
      std::vector<uint> indicesToPlot;
      for (uint i=0; i<names.size(); ++i) {
        for (uint j=0;j<NFpatterns.size();++j) {
          if (TQStringUtils::matches(names.at(i),NFpatterns.at(j))) {
            indicesToPlot.push_back(i);
            break;
          }
        }
      }
      TString NFPlotsFileName = this->getTagStringDefault("NFplotsFile","NFplots.root");
      TQUtils::ensureDirectoryForFile(NFPlotsFileName);
      TFile* f = TFile::Open(NFPlotsFileName,"RECREATE");
      for (uint i=0; i<indicesToPlot.size();++i) {
        uint index = indicesToPlot.at(i);
        double avg =  TQUtils::getAverage(toys.at(index));
        double stddev = sqrt(TQUtils::getSampleVariance(toys.at(index)));
        //@tag: [NFplotsEntriesPerBin] When histograms of NF distributions are produced, this object tag determines the binning of the histograms. It is chosen such, that the average number of toy NFs per bin is (roughly) equal to the value specified in this tag. Default: 10.
        //generic histograms showing +/-3sigma around average and 
        TH1F* hist1 = new TH1F(names.at(index),names.at(index), (int)ceil(this->getTagIntegerDefault("toySize",1)/this->getTagDoubleDefault("NFplotsEntriesPerBin",10.)) ,avg-3*stddev , avg+3*stddev);
        for (uint j=0; j<toys.at(index).size();++j) {
          hist1->Fill(toys[index][j]);
        }
        hist1->Write();
        delete hist1;
        //@tag: [NFplotsLow,NFplotsHigh] These object tags specify custom lower and upper boundaries for histograms of the NF toy distributions if both are set. Please note that dynamic versions showing a +/- 3 sigma interval are produced independently from whether these tags are seet or not.
        //if xmin and xmax for NF plots has been specified we also make plots according to these values:
        if (this->hasTagDouble("NFplotsLow") && this->hasTagDouble("NFplotsHigh") ) {
          TH1F* hist2 = new TH1F(names.at(index),names.at(index), (int)ceil(this->getTagIntegerDefault("toySize",1)/this->getTagDoubleDefault("NFplotsEntriesPerBin",10.)) ,this->getTagDoubleDefault("NFplotsLow",0.) , this->getTagDoubleDefault("NFplotsHigh",2.));
          for (uint j=0; j<toys.at(index).size();++j) {
            hist2->Fill(toys[index][j]);
          }
          hist2->Write();
          delete hist2;
        }
        
        //for correlation (scatter) plots we provide only one version for now
        //@tag: [doNFcorrelationPlots] If this object tag is set to true, 2D correlation plots (scatter plots) of all combinations of NFs passing the filter specified via the object tag "NFplotsPattern" are produced. Default: false.
        if (this->getTagBoolDefault("doNFcorrelationPlots",false) && i<indicesToPlot.size()-1) {
          for (uint j=i+1; j<indicesToPlot.size(); ++j) {
            uint index2 = indicesToPlot.at(j);
            TGraph* gr = TQHistogramUtils::scatterPlot(names.at(index) + " vs " + names.at(index2), toys.at(index), toys.at(index2), names.at(index), names.at(index2) );
            gr->Write();
            delete gr;
          }
        } 
      }
      f->Close();
    } else {
      WARN("No pattern for NF plots given, skipping!");
    }
    
  }
  
  
  for (uint i=0; i<names.size(); ++i) {
    identifier.push_back(TString::Format("%lu_%d",TQUtils::getCurrentTime(),i)); //create a unique identifier for each NF (used for correlation treatment)
  }
#ifdef _DEBUG_
  for(size_t i=0; i<names.size(); ++i){
    std::cout << names[i] << "\t";
    for(size_t j = 0; j < toys[i].size(); ++j){
      std::cout << toys[i][j] << " ";
    }
    std::cout << std::endl;
  }
#endif

  TMatrixD correlations(names.size(),names.size());
  bool ok = true;
  for (uint i=0;i<names.size();i++) {
    for (uint j=0;j<names.size();j++) {
      double val = TQUtils::getSampleCorrelation(toys.at(i),toys.at(j),ok);
      if(TQUtils::isNum(val)){
        correlations[i][j] = val;
      } else {
        ok = false;
        correlations[i][j] = 0;
      } 
    }
  }
  TQSampleFolder* sf = this->fReader->getSampleFolder();
  TQSampleFolder* writeOut = NULL;
  if (this->hasTagString("exportNFsTo")) writeOut = TQSampleFolder::newSampleFolder("writeOut");
  
  //TString savePlotsTo;
  //TFile* f = NULL;
  //this needs to be reimplemented in a reasonable way: (saving NF (toy-)distribution plots somewhere)
  //if (this->getTagString("saveNFplots",savePlotsTo) ) f = TFile::Open(savePlotsTo,"RECREATE");
  //else std::cout<<"No target file specified for NF plots!"<<std::endl;
  for (uint i=0;i<names.size();i++) {
    TString path = names.at(i); //format: path/.scalescheme:cut
    TString cut = TQFolder::getPathTail(path);
    TString scheme = TQStringUtils::readPrefix(cut, ":", ".default");
    TQSampleFolder* subFolder = sf->getSampleFolder(path);
    TQSampleFolder* subWriteOut = NULL;
    if (writeOut) subWriteOut = writeOut->getSampleFolder(path+"+");
    
    if (!subFolder || (writeOut && !subWriteOut) ) {
      ERRORclass("Failed to deploy NF!");
      break;
    }
    double average = TQUtils::getAverage(toys.at(i));
    double uncertainty = sqrt(TQUtils::getSampleVariance(toys.at(i)));
    #ifdef _DEBUG_
    DEBUGclass("setting scale factor '%s:%s' = %f +/- %f with ID='%s' on '%s'",scheme.Data(),cut.Data(),average,uncertainty,identifier.at(i).Data(),subFolder->getPath().Data());
    #endif
    int n = subFolder->setScaleFactor(scheme+":"+cut,identifier.at(i),average,uncertainty);
    if (subWriteOut) subWriteOut->setScaleFactor(scheme+":"+cut,identifier.at(i),average,uncertainty);
    if(n == 0){
      WARNclass("failure to set scale factor on '%s', skipping",subFolder->getPath().Data());
    } else {
      //save  correlation information
      if (this->getTagBoolDefault("saveNFCorrelations", true)) {
        TQFolder* corrFolder = subFolder->getFolder(TQFolder::concatPaths(".scalefactors/",scheme,".correlations/",identifier.at(i))+"+");
        TQFolder* corrWriteOut = NULL;
        if (subWriteOut) corrWriteOut = subWriteOut->getFolder(TQFolder::concatPaths(".scalefactors/",scheme,".correlations/",identifier.at(i))+"+");
        for(uint j=0; j<identifier.size();++j) {
          TQCounter* corrCounter = new TQCounter(identifier.at(j),correlations[i][j],0.);
          corrFolder->addObject(corrCounter,"");
          if (corrWriteOut) {
            TQCounter* corrCounterWriteOut = new TQCounter(identifier.at(j),correlations[i][j],0.);
            corrWriteOut->addObject(corrCounterWriteOut,"");
          }
        }
      }
    }
    nNFs+=n;
  }
  if (writeOut) {
    //@tag: [exportNFsTo] Sets the name of a file to which the calculated NFs should be exported (in addition to storing them in the regular sample folder).
    TString exportFileName =  this->getTagStringDefault("exportNFsTo","");
    if (exportFileName.EndsWith(".root",TString::kIgnoreCase)) writeOut->writeToFile(exportFileName, true,-1,true);
    else writeOut->exportToTextFile(exportFileName,true);
    delete writeOut;
  }
   
  return nNFs;
}


TList* TQNFChainloader::getListOfFolders(){
  TQSampleFolder* sf = this->fReader->getSampleFolder();
  TList* l = new TList();
  for(auto itr=this->targetNFpaths.begin(); itr!=this->targetNFpaths.end(); ++itr){
    TQFolder* f = sf->getFolder(itr->first);
    if(f){
      l->Add(f);
    }
  }
  return l;
}

int TQNFChainloader::setVariationTags(const TQTaggable& tags) {
  this->fVariationTags.clear();
  return this->fVariationTags.importTags(tags);
}

int TQNFChainloader::setVariationTags(TQTaggable* tags) {
  this->fVariationTags.clear();
  return this->fVariationTags.importTags(tags);
}

int TQNFChainloader::setCampaignTag(TQTaggable* tag) {
  this->fCampaignTag.clear();
  return this->fCampaignTag.importTags(tag);
}

 TQNFChainloader.cxx:1
 TQNFChainloader.cxx:2
 TQNFChainloader.cxx:3
 TQNFChainloader.cxx:4
 TQNFChainloader.cxx:5
 TQNFChainloader.cxx:6
 TQNFChainloader.cxx:7
 TQNFChainloader.cxx:8
 TQNFChainloader.cxx:9
 TQNFChainloader.cxx:10
 TQNFChainloader.cxx:11
 TQNFChainloader.cxx:12
 TQNFChainloader.cxx:13
 TQNFChainloader.cxx:14
 TQNFChainloader.cxx:15
 TQNFChainloader.cxx:16
 TQNFChainloader.cxx:17
 TQNFChainloader.cxx:18
 TQNFChainloader.cxx:19
 TQNFChainloader.cxx:20
 TQNFChainloader.cxx:21
 TQNFChainloader.cxx:22
 TQNFChainloader.cxx:23
 TQNFChainloader.cxx:24
 TQNFChainloader.cxx:25
 TQNFChainloader.cxx:26
 TQNFChainloader.cxx:27
 TQNFChainloader.cxx:28
 TQNFChainloader.cxx:29
 TQNFChainloader.cxx:30
 TQNFChainloader.cxx:31
 TQNFChainloader.cxx:32
 TQNFChainloader.cxx:33
 TQNFChainloader.cxx:34
 TQNFChainloader.cxx:35
 TQNFChainloader.cxx:36
 TQNFChainloader.cxx:37
 TQNFChainloader.cxx:38
 TQNFChainloader.cxx:39
 TQNFChainloader.cxx:40
 TQNFChainloader.cxx:41
 TQNFChainloader.cxx:42
 TQNFChainloader.cxx:43
 TQNFChainloader.cxx:44
 TQNFChainloader.cxx:45
 TQNFChainloader.cxx:46
 TQNFChainloader.cxx:47
 TQNFChainloader.cxx:48
 TQNFChainloader.cxx:49
 TQNFChainloader.cxx:50
 TQNFChainloader.cxx:51
 TQNFChainloader.cxx:52
 TQNFChainloader.cxx:53
 TQNFChainloader.cxx:54
 TQNFChainloader.cxx:55
 TQNFChainloader.cxx:56
 TQNFChainloader.cxx:57
 TQNFChainloader.cxx:58
 TQNFChainloader.cxx:59
 TQNFChainloader.cxx:60
 TQNFChainloader.cxx:61
 TQNFChainloader.cxx:62
 TQNFChainloader.cxx:63
 TQNFChainloader.cxx:64
 TQNFChainloader.cxx:65
 TQNFChainloader.cxx:66
 TQNFChainloader.cxx:67
 TQNFChainloader.cxx:68
 TQNFChainloader.cxx:69
 TQNFChainloader.cxx:70
 TQNFChainloader.cxx:71
 TQNFChainloader.cxx:72
 TQNFChainloader.cxx:73
 TQNFChainloader.cxx:74
 TQNFChainloader.cxx:75
 TQNFChainloader.cxx:76
 TQNFChainloader.cxx:77
 TQNFChainloader.cxx:78
 TQNFChainloader.cxx:79
 TQNFChainloader.cxx:80
 TQNFChainloader.cxx:81
 TQNFChainloader.cxx:82
 TQNFChainloader.cxx:83
 TQNFChainloader.cxx:84
 TQNFChainloader.cxx:85
 TQNFChainloader.cxx:86
 TQNFChainloader.cxx:87
 TQNFChainloader.cxx:88
 TQNFChainloader.cxx:89
 TQNFChainloader.cxx:90
 TQNFChainloader.cxx:91
 TQNFChainloader.cxx:92
 TQNFChainloader.cxx:93
 TQNFChainloader.cxx:94
 TQNFChainloader.cxx:95
 TQNFChainloader.cxx:96
 TQNFChainloader.cxx:97
 TQNFChainloader.cxx:98
 TQNFChainloader.cxx:99
 TQNFChainloader.cxx:100
 TQNFChainloader.cxx:101
 TQNFChainloader.cxx:102
 TQNFChainloader.cxx:103
 TQNFChainloader.cxx:104
 TQNFChainloader.cxx:105
 TQNFChainloader.cxx:106
 TQNFChainloader.cxx:107
 TQNFChainloader.cxx:108
 TQNFChainloader.cxx:109
 TQNFChainloader.cxx:110
 TQNFChainloader.cxx:111
 TQNFChainloader.cxx:112
 TQNFChainloader.cxx:113
 TQNFChainloader.cxx:114
 TQNFChainloader.cxx:115
 TQNFChainloader.cxx:116
 TQNFChainloader.cxx:117
 TQNFChainloader.cxx:118
 TQNFChainloader.cxx:119
 TQNFChainloader.cxx:120
 TQNFChainloader.cxx:121
 TQNFChainloader.cxx:122
 TQNFChainloader.cxx:123
 TQNFChainloader.cxx:124
 TQNFChainloader.cxx:125
 TQNFChainloader.cxx:126
 TQNFChainloader.cxx:127
 TQNFChainloader.cxx:128
 TQNFChainloader.cxx:129
 TQNFChainloader.cxx:130
 TQNFChainloader.cxx:131
 TQNFChainloader.cxx:132
 TQNFChainloader.cxx:133
 TQNFChainloader.cxx:134
 TQNFChainloader.cxx:135
 TQNFChainloader.cxx:136
 TQNFChainloader.cxx:137
 TQNFChainloader.cxx:138
 TQNFChainloader.cxx:139
 TQNFChainloader.cxx:140
 TQNFChainloader.cxx:141
 TQNFChainloader.cxx:142
 TQNFChainloader.cxx:143
 TQNFChainloader.cxx:144
 TQNFChainloader.cxx:145
 TQNFChainloader.cxx:146
 TQNFChainloader.cxx:147
 TQNFChainloader.cxx:148
 TQNFChainloader.cxx:149
 TQNFChainloader.cxx:150
 TQNFChainloader.cxx:151
 TQNFChainloader.cxx:152
 TQNFChainloader.cxx:153
 TQNFChainloader.cxx:154
 TQNFChainloader.cxx:155
 TQNFChainloader.cxx:156
 TQNFChainloader.cxx:157
 TQNFChainloader.cxx:158
 TQNFChainloader.cxx:159
 TQNFChainloader.cxx:160
 TQNFChainloader.cxx:161
 TQNFChainloader.cxx:162
 TQNFChainloader.cxx:163
 TQNFChainloader.cxx:164
 TQNFChainloader.cxx:165
 TQNFChainloader.cxx:166
 TQNFChainloader.cxx:167
 TQNFChainloader.cxx:168
 TQNFChainloader.cxx:169
 TQNFChainloader.cxx:170
 TQNFChainloader.cxx:171
 TQNFChainloader.cxx:172
 TQNFChainloader.cxx:173
 TQNFChainloader.cxx:174
 TQNFChainloader.cxx:175
 TQNFChainloader.cxx:176
 TQNFChainloader.cxx:177
 TQNFChainloader.cxx:178
 TQNFChainloader.cxx:179
 TQNFChainloader.cxx:180
 TQNFChainloader.cxx:181
 TQNFChainloader.cxx:182
 TQNFChainloader.cxx:183
 TQNFChainloader.cxx:184
 TQNFChainloader.cxx:185
 TQNFChainloader.cxx:186
 TQNFChainloader.cxx:187
 TQNFChainloader.cxx:188
 TQNFChainloader.cxx:189
 TQNFChainloader.cxx:190
 TQNFChainloader.cxx:191
 TQNFChainloader.cxx:192
 TQNFChainloader.cxx:193
 TQNFChainloader.cxx:194
 TQNFChainloader.cxx:195
 TQNFChainloader.cxx:196
 TQNFChainloader.cxx:197
 TQNFChainloader.cxx:198
 TQNFChainloader.cxx:199
 TQNFChainloader.cxx:200
 TQNFChainloader.cxx:201
 TQNFChainloader.cxx:202
 TQNFChainloader.cxx:203
 TQNFChainloader.cxx:204
 TQNFChainloader.cxx:205
 TQNFChainloader.cxx:206
 TQNFChainloader.cxx:207
 TQNFChainloader.cxx:208
 TQNFChainloader.cxx:209
 TQNFChainloader.cxx:210
 TQNFChainloader.cxx:211
 TQNFChainloader.cxx:212
 TQNFChainloader.cxx:213
 TQNFChainloader.cxx:214
 TQNFChainloader.cxx:215
 TQNFChainloader.cxx:216
 TQNFChainloader.cxx:217
 TQNFChainloader.cxx:218
 TQNFChainloader.cxx:219
 TQNFChainloader.cxx:220
 TQNFChainloader.cxx:221
 TQNFChainloader.cxx:222
 TQNFChainloader.cxx:223
 TQNFChainloader.cxx:224
 TQNFChainloader.cxx:225
 TQNFChainloader.cxx:226
 TQNFChainloader.cxx:227
 TQNFChainloader.cxx:228
 TQNFChainloader.cxx:229
 TQNFChainloader.cxx:230
 TQNFChainloader.cxx:231
 TQNFChainloader.cxx:232
 TQNFChainloader.cxx:233
 TQNFChainloader.cxx:234
 TQNFChainloader.cxx:235
 TQNFChainloader.cxx:236
 TQNFChainloader.cxx:237
 TQNFChainloader.cxx:238
 TQNFChainloader.cxx:239
 TQNFChainloader.cxx:240
 TQNFChainloader.cxx:241
 TQNFChainloader.cxx:242
 TQNFChainloader.cxx:243
 TQNFChainloader.cxx:244
 TQNFChainloader.cxx:245
 TQNFChainloader.cxx:246
 TQNFChainloader.cxx:247
 TQNFChainloader.cxx:248
 TQNFChainloader.cxx:249
 TQNFChainloader.cxx:250
 TQNFChainloader.cxx:251
 TQNFChainloader.cxx:252
 TQNFChainloader.cxx:253
 TQNFChainloader.cxx:254
 TQNFChainloader.cxx:255
 TQNFChainloader.cxx:256
 TQNFChainloader.cxx:257
 TQNFChainloader.cxx:258
 TQNFChainloader.cxx:259
 TQNFChainloader.cxx:260
 TQNFChainloader.cxx:261
 TQNFChainloader.cxx:262
 TQNFChainloader.cxx:263
 TQNFChainloader.cxx:264
 TQNFChainloader.cxx:265
 TQNFChainloader.cxx:266
 TQNFChainloader.cxx:267
 TQNFChainloader.cxx:268
 TQNFChainloader.cxx:269
 TQNFChainloader.cxx:270
 TQNFChainloader.cxx:271
 TQNFChainloader.cxx:272
 TQNFChainloader.cxx:273
 TQNFChainloader.cxx:274
 TQNFChainloader.cxx:275
 TQNFChainloader.cxx:276
 TQNFChainloader.cxx:277
 TQNFChainloader.cxx:278
 TQNFChainloader.cxx:279
 TQNFChainloader.cxx:280
 TQNFChainloader.cxx:281
 TQNFChainloader.cxx:282
 TQNFChainloader.cxx:283
 TQNFChainloader.cxx:284
 TQNFChainloader.cxx:285
 TQNFChainloader.cxx:286
 TQNFChainloader.cxx:287
 TQNFChainloader.cxx:288
 TQNFChainloader.cxx:289
 TQNFChainloader.cxx:290
 TQNFChainloader.cxx:291
 TQNFChainloader.cxx:292
 TQNFChainloader.cxx:293
 TQNFChainloader.cxx:294
 TQNFChainloader.cxx:295
 TQNFChainloader.cxx:296
 TQNFChainloader.cxx:297
 TQNFChainloader.cxx:298
 TQNFChainloader.cxx:299
 TQNFChainloader.cxx:300
 TQNFChainloader.cxx:301
 TQNFChainloader.cxx:302
 TQNFChainloader.cxx:303
 TQNFChainloader.cxx:304
 TQNFChainloader.cxx:305
 TQNFChainloader.cxx:306
 TQNFChainloader.cxx:307
 TQNFChainloader.cxx:308
 TQNFChainloader.cxx:309
 TQNFChainloader.cxx:310
 TQNFChainloader.cxx:311
 TQNFChainloader.cxx:312
 TQNFChainloader.cxx:313
 TQNFChainloader.cxx:314
 TQNFChainloader.cxx:315
 TQNFChainloader.cxx:316
 TQNFChainloader.cxx:317
 TQNFChainloader.cxx:318
 TQNFChainloader.cxx:319
 TQNFChainloader.cxx:320
 TQNFChainloader.cxx:321
 TQNFChainloader.cxx:322
 TQNFChainloader.cxx:323
 TQNFChainloader.cxx:324
 TQNFChainloader.cxx:325
 TQNFChainloader.cxx:326
 TQNFChainloader.cxx:327
 TQNFChainloader.cxx:328
 TQNFChainloader.cxx:329
 TQNFChainloader.cxx:330
 TQNFChainloader.cxx:331
 TQNFChainloader.cxx:332
 TQNFChainloader.cxx:333
 TQNFChainloader.cxx:334
 TQNFChainloader.cxx:335
 TQNFChainloader.cxx:336
 TQNFChainloader.cxx:337
 TQNFChainloader.cxx:338
 TQNFChainloader.cxx:339
 TQNFChainloader.cxx:340
 TQNFChainloader.cxx:341
 TQNFChainloader.cxx:342
 TQNFChainloader.cxx:343
 TQNFChainloader.cxx:344
 TQNFChainloader.cxx:345
 TQNFChainloader.cxx:346
 TQNFChainloader.cxx:347
 TQNFChainloader.cxx:348
 TQNFChainloader.cxx:349
 TQNFChainloader.cxx:350
 TQNFChainloader.cxx:351
 TQNFChainloader.cxx:352
 TQNFChainloader.cxx:353
 TQNFChainloader.cxx:354
 TQNFChainloader.cxx:355
 TQNFChainloader.cxx:356
 TQNFChainloader.cxx:357
 TQNFChainloader.cxx:358
 TQNFChainloader.cxx:359
 TQNFChainloader.cxx:360
 TQNFChainloader.cxx:361
 TQNFChainloader.cxx:362
 TQNFChainloader.cxx:363
 TQNFChainloader.cxx:364
 TQNFChainloader.cxx:365
 TQNFChainloader.cxx:366
 TQNFChainloader.cxx:367
 TQNFChainloader.cxx:368
 TQNFChainloader.cxx:369
 TQNFChainloader.cxx:370
 TQNFChainloader.cxx:371
 TQNFChainloader.cxx:372
 TQNFChainloader.cxx:373
 TQNFChainloader.cxx:374
 TQNFChainloader.cxx:375
 TQNFChainloader.cxx:376
 TQNFChainloader.cxx:377
 TQNFChainloader.cxx:378
 TQNFChainloader.cxx:379
 TQNFChainloader.cxx:380
 TQNFChainloader.cxx:381
 TQNFChainloader.cxx:382
 TQNFChainloader.cxx:383
 TQNFChainloader.cxx:384
 TQNFChainloader.cxx:385
 TQNFChainloader.cxx:386
 TQNFChainloader.cxx:387
 TQNFChainloader.cxx:388
 TQNFChainloader.cxx:389
 TQNFChainloader.cxx:390
 TQNFChainloader.cxx:391
 TQNFChainloader.cxx:392
 TQNFChainloader.cxx:393
 TQNFChainloader.cxx:394
 TQNFChainloader.cxx:395
 TQNFChainloader.cxx:396
 TQNFChainloader.cxx:397
 TQNFChainloader.cxx:398
 TQNFChainloader.cxx:399
 TQNFChainloader.cxx:400
 TQNFChainloader.cxx:401
 TQNFChainloader.cxx:402
 TQNFChainloader.cxx:403
 TQNFChainloader.cxx:404
 TQNFChainloader.cxx:405
 TQNFChainloader.cxx:406
 TQNFChainloader.cxx:407
 TQNFChainloader.cxx:408
 TQNFChainloader.cxx:409
 TQNFChainloader.cxx:410
 TQNFChainloader.cxx:411
 TQNFChainloader.cxx:412
 TQNFChainloader.cxx:413
 TQNFChainloader.cxx:414
 TQNFChainloader.cxx:415
 TQNFChainloader.cxx:416
 TQNFChainloader.cxx:417
 TQNFChainloader.cxx:418
 TQNFChainloader.cxx:419
 TQNFChainloader.cxx:420
 TQNFChainloader.cxx:421
 TQNFChainloader.cxx:422
 TQNFChainloader.cxx:423
 TQNFChainloader.cxx:424
 TQNFChainloader.cxx:425
 TQNFChainloader.cxx:426
 TQNFChainloader.cxx:427
 TQNFChainloader.cxx:428
 TQNFChainloader.cxx:429
 TQNFChainloader.cxx:430
 TQNFChainloader.cxx:431
 TQNFChainloader.cxx:432
 TQNFChainloader.cxx:433
 TQNFChainloader.cxx:434
 TQNFChainloader.cxx:435
 TQNFChainloader.cxx:436
 TQNFChainloader.cxx:437
 TQNFChainloader.cxx:438
 TQNFChainloader.cxx:439
 TQNFChainloader.cxx:440
 TQNFChainloader.cxx:441
 TQNFChainloader.cxx:442
 TQNFChainloader.cxx:443
 TQNFChainloader.cxx:444
 TQNFChainloader.cxx:445
 TQNFChainloader.cxx:446
 TQNFChainloader.cxx:447
 TQNFChainloader.cxx:448
 TQNFChainloader.cxx:449
 TQNFChainloader.cxx:450
 TQNFChainloader.cxx:451
 TQNFChainloader.cxx:452
 TQNFChainloader.cxx:453
 TQNFChainloader.cxx:454
 TQNFChainloader.cxx:455
 TQNFChainloader.cxx:456
 TQNFChainloader.cxx:457
 TQNFChainloader.cxx:458
 TQNFChainloader.cxx:459
 TQNFChainloader.cxx:460
 TQNFChainloader.cxx:461
 TQNFChainloader.cxx:462
 TQNFChainloader.cxx:463
 TQNFChainloader.cxx:464
 TQNFChainloader.cxx:465
 TQNFChainloader.cxx:466
 TQNFChainloader.cxx:467
 TQNFChainloader.cxx:468
 TQNFChainloader.cxx:469
 TQNFChainloader.cxx:470
 TQNFChainloader.cxx:471
 TQNFChainloader.cxx:472
 TQNFChainloader.cxx:473
 TQNFChainloader.cxx:474
 TQNFChainloader.cxx:475
 TQNFChainloader.cxx:476
 TQNFChainloader.cxx:477
 TQNFChainloader.cxx:478
 TQNFChainloader.cxx:479
 TQNFChainloader.cxx:480
 TQNFChainloader.cxx:481
 TQNFChainloader.cxx:482
 TQNFChainloader.cxx:483
 TQNFChainloader.cxx:484
 TQNFChainloader.cxx:485
 TQNFChainloader.cxx:486
 TQNFChainloader.cxx:487
 TQNFChainloader.cxx:488
 TQNFChainloader.cxx:489
 TQNFChainloader.cxx:490
 TQNFChainloader.cxx:491
 TQNFChainloader.cxx:492
 TQNFChainloader.cxx:493
 TQNFChainloader.cxx:494
 TQNFChainloader.cxx:495
 TQNFChainloader.cxx:496
 TQNFChainloader.cxx:497
 TQNFChainloader.cxx:498
 TQNFChainloader.cxx:499
 TQNFChainloader.cxx:500
 TQNFChainloader.cxx:501
 TQNFChainloader.cxx:502
 TQNFChainloader.cxx:503
 TQNFChainloader.cxx:504
 TQNFChainloader.cxx:505
 TQNFChainloader.cxx:506
 TQNFChainloader.cxx:507
 TQNFChainloader.cxx:508
 TQNFChainloader.cxx:509
 TQNFChainloader.cxx:510
 TQNFChainloader.cxx:511
 TQNFChainloader.cxx:512
 TQNFChainloader.cxx:513
 TQNFChainloader.cxx:514
 TQNFChainloader.cxx:515
 TQNFChainloader.cxx:516
 TQNFChainloader.cxx:517
 TQNFChainloader.cxx:518
 TQNFChainloader.cxx:519
 TQNFChainloader.cxx:520
 TQNFChainloader.cxx:521
 TQNFChainloader.cxx:522
 TQNFChainloader.cxx:523
 TQNFChainloader.cxx:524
 TQNFChainloader.cxx:525
 TQNFChainloader.cxx:526
 TQNFChainloader.cxx:527
 TQNFChainloader.cxx:528
 TQNFChainloader.cxx:529
 TQNFChainloader.cxx:530
 TQNFChainloader.cxx:531
 TQNFChainloader.cxx:532
 TQNFChainloader.cxx:533
 TQNFChainloader.cxx:534
 TQNFChainloader.cxx:535
 TQNFChainloader.cxx:536
 TQNFChainloader.cxx:537
 TQNFChainloader.cxx:538
 TQNFChainloader.cxx:539
 TQNFChainloader.cxx:540
 TQNFChainloader.cxx:541
 TQNFChainloader.cxx:542
 TQNFChainloader.cxx:543
 TQNFChainloader.cxx:544
 TQNFChainloader.cxx:545
 TQNFChainloader.cxx:546
 TQNFChainloader.cxx:547
 TQNFChainloader.cxx:548
 TQNFChainloader.cxx:549
 TQNFChainloader.cxx:550
 TQNFChainloader.cxx:551
 TQNFChainloader.cxx:552
 TQNFChainloader.cxx:553
 TQNFChainloader.cxx:554
 TQNFChainloader.cxx:555
 TQNFChainloader.cxx:556
 TQNFChainloader.cxx:557
 TQNFChainloader.cxx:558
 TQNFChainloader.cxx:559
 TQNFChainloader.cxx:560
 TQNFChainloader.cxx:561
 TQNFChainloader.cxx:562
 TQNFChainloader.cxx:563
 TQNFChainloader.cxx:564
 TQNFChainloader.cxx:565
 TQNFChainloader.cxx:566
 TQNFChainloader.cxx:567
 TQNFChainloader.cxx:568
 TQNFChainloader.cxx:569
 TQNFChainloader.cxx:570
 TQNFChainloader.cxx:571
 TQNFChainloader.cxx:572
 TQNFChainloader.cxx:573
 TQNFChainloader.cxx:574
 TQNFChainloader.cxx:575
 TQNFChainloader.cxx:576
 TQNFChainloader.cxx:577
 TQNFChainloader.cxx:578
 TQNFChainloader.cxx:579
 TQNFChainloader.cxx:580
 TQNFChainloader.cxx:581
 TQNFChainloader.cxx:582
 TQNFChainloader.cxx:583
 TQNFChainloader.cxx:584
 TQNFChainloader.cxx:585
 TQNFChainloader.cxx:586
 TQNFChainloader.cxx:587
 TQNFChainloader.cxx:588
 TQNFChainloader.cxx:589
 TQNFChainloader.cxx:590
 TQNFChainloader.cxx:591
 TQNFChainloader.cxx:592
 TQNFChainloader.cxx:593
 TQNFChainloader.cxx:594
 TQNFChainloader.cxx:595
 TQNFChainloader.cxx:596
 TQNFChainloader.cxx:597
 TQNFChainloader.cxx:598
 TQNFChainloader.cxx:599
 TQNFChainloader.cxx:600
 TQNFChainloader.cxx:601
 TQNFChainloader.cxx:602
 TQNFChainloader.cxx:603
 TQNFChainloader.cxx:604
 TQNFChainloader.cxx:605
 TQNFChainloader.cxx:606
 TQNFChainloader.cxx:607
 TQNFChainloader.cxx:608
 TQNFChainloader.cxx:609
 TQNFChainloader.cxx:610
 TQNFChainloader.cxx:611
 TQNFChainloader.cxx:612
 TQNFChainloader.cxx:613
 TQNFChainloader.cxx:614
 TQNFChainloader.cxx:615
 TQNFChainloader.cxx:616
 TQNFChainloader.cxx:617