#include "QFramework/TQABCDCalculator.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQCounter.h"
#include "QFramework/TQUtils.h"
#include "QFramework/TQStringUtils.h"

//#define _DEBUG_

#include "QFramework/TQLibrary.h"
#include "QFramework/TQNFChainloader.h"


ClassImp(TQABCDCalculator)

#define NaN std::numeric_limits<double>::quiet_NaN()

////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQABCDCalculator
//
// The TQABCDCalculator automates calculation of normalization factors
// for a single sample group based on the ABCD-method, i.e.
//
// NF = A<sub>data</sub>/A<sub>MC</sub>
//
// where the data-prediction is calculated as 
//
// A<sub>data</sub> = B * C/D
//
// The counter names (or cut names) for the four regions A, B, C and D can be set with
// setA/setTarget (MC)
// setB/setSource (data)
// setC/setNumerator (data)
// setD/setDenominator (data)
//
// The path of the sample group for which the correction should be calculated is set via
// setPathMC(path)
// Usually, 'path' is a path to a MC sample for which the correction should be applied.
// For a fully data-driven calculation not using the MC in question (e.g., 'bkg/sampleY').
// The TQFolder passed to the readConfiguration(TQFolder* f) method should contain a subfolder
// which itself contains a set of subfolders with "path" tags applied. These paths usually
// correspond to (MC) background samples that are subtracted from data in regions B,C and D
// before the actual ABCD calculation is performed.
//
////////////////////////////////////////////////////////////////////////////////////////////////

TQABCDCalculator::TQABCDCalculator() : TQNFBase("ABCD"),
  fResult(NaN),
  fResultErr2(NaN)
{
  // default constructor
}

TQABCDCalculator::TQABCDCalculator(TQSampleDataReader* rd) : 
  TQNFBase("ABCD"),
  fResult(NaN),
  fResultErr2(NaN)
{
  // constructor on reader
  this->setReader(rd);
}

TQABCDCalculator::TQABCDCalculator(TQSampleFolder* sf) : 
  TQNFBase("ABCD"),
  fResult(NaN),
  fResultErr2(NaN)
{
  // constructor on reader
  this->setSampleFolder(sf);
}

TQABCDCalculator::~TQABCDCalculator(){
  // default destructor
  this->finalize();
}

void TQABCDCalculator::setTarget(const TString& region){
  // set the target or "A"-region
  this->fCutTarget = region;
}

void TQABCDCalculator::setA(const TString& region){
  // set the target or "A"-region
  this->setTarget(region);
}

void TQABCDCalculator::setSource(const TString& region){
  // set the source or "B"-region
  this->fCutSource = region;
}

void TQABCDCalculator::setB(const TString& region){
  // set the source or "B"-region
  this->setSource(region);
}

void TQABCDCalculator::setNumerator(const TString& region){
  // set the numerator or "C"-region
  this->fCutNumerator = region;
}

void TQABCDCalculator::setC(const TString& region){
  // set the numerator or "C"-region
  this->setNumerator(region);
}

void TQABCDCalculator::setDenominator(const TString& region){
  // set the numerator or "D"-region
  this->fCutDenominator = region;
}

void TQABCDCalculator::setD(const TString& region){
  // set the numerator or "D"-region
  return this->setDenominator(region);
}

TString TQABCDCalculator::getTarget(){
  // get the target or "A"-region
  return this->fCutTarget;
}

TString TQABCDCalculator::getA(){
  // get the target or "A"-region
  return this->getTarget();
}

TString TQABCDCalculator::getSource(){
  // get the source or "B"-region
  return this->fCutSource;
}

TString TQABCDCalculator::getB(){
  // get the source or "B"-region
  return this->getTarget();
}

TString TQABCDCalculator::getNumerator(){
  // get the numerator or "C"-region
  return this->fCutNumerator;
}

TString TQABCDCalculator::getC(){
  // get the numerator or "C"-region
  return this->getNumerator();
}

TString TQABCDCalculator::getDenominator(){
  // get the numerator or "D"-region
  return this->fCutDenominator;
}

TString TQABCDCalculator::getD(){
  // get the numerator or "D"-region
  return this->getDenominator();
}

TString TQABCDCalculator::getPathMC(){
  // return the MC path from which the information is retrieved
  return this->fPathMC;
}

void TQABCDCalculator::setPathMC(const TString& path){
  // set/change the MC path from which the information is retrieved
  this->fPathMC = path;
}


TString TQABCDCalculator::getPathData(){
  // return the MC path from which the information is retrieved
  return this->fPathData;
}

void TQABCDCalculator::setPathData(const TString& path){
  // set/change the MC path from which the information is retrieved
  this->fPathData = path;
}

bool TQABCDCalculator::readConfiguration(TQFolder*f){
  // read a configuration from a TQFolder
  // the following tags are read and interpreted:
  // - verbosity: integer, increasing number increases verbosity
  // - cutA: string, name of counter for region A (the 'target'-region)
  // - cutB: string, name of counter for region B (the 'source'-region)
  // - cutC: string, name of counter for region C (the 'numerator'-region)
  // - cutD: string, name of counter for region D (the 'denominator'-region)
  // - pathMC: the path to be used for the MC sample to be normalized (regions used: A)
  // - pathData: the path of the data sample to be used for estimation (regions used: B,C,D)
  // all tags are copied to the calculator
  if(!f){
    if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to configure from NULL folder");
    return false;
  }
  this->importTags(f);
  //@tag: verbosity This argument tag sets the verbosity level of the TQABCDCalculator object.
  this->getTagInteger("verbosity",this->verbosity);
  TString cutname;
  int n = 0;
  //@tag: [pathMC,pathData] This argument tag defines the sample folder paths of the MC and data samples used for the calculation.
  if(!f->getTagString("pathMC",this->fPathMC)){
    if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to retrieve mc path");
    return false;
  }
  if(!f->getTagString("pathData",this->fPathData)){
    if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to retrieve data path");
    return false;
  }
  //@tag: [cutA,cutB,cutC,cutD] These argument tags set the name of the cut used as the definition of the phase space regions A,B,C and D, respectively.
  if(f->getTagString("cutA",cutname)){
    this->setA(cutname);
    n++;
  } else {
    if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to retrieve cut name for cutA");
  }
  if(f->getTagString("cutB",cutname)){
    this->setB(cutname);
    n++;
  } else {
    if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to retrieve cut name for cutB");
  }
  if(f->getTagString("cutC",cutname)){
    this->setC(cutname);
    n++;
  } else {
    if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to retrieve cut name for cutC");
  }
  if(f->getTagString("cutD",cutname)){
    this->setD(cutname);
    n++;
  } else {
    if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to retrieve cut name for cutD");
  }
  
  vBkgPaths.clear();
  TQFolderIterator sitr(f->getListOfFolders("samples/?"),true);
  while(sitr.hasNext()){
    TQFolder* sample = sitr.readNext();
    if(!sample) continue;
    //@tag: [name,path] These argument tags (set on subfolders of the TQFolder passed to TQABCDCalculator::readConfiguration) define the names and paths of the MC samples which are subtracted from data in the ABCD regions. Defaults: name: name of the subfolder, path: name
    TString name = sample->getTagStringDefault("name",sample->getName());
    TString path = sample->getTagStringDefault("path",name);
    vBkgPaths.push_back(path);
  }
  
  if(n==4){
    return true;
  }
  std::cout << n << std::endl;
  messages.activeStream().flush();
  return false;
}

double TQABCDCalculator::getResult(){
  // retrieve the Result
  return this->fResult;
}

double TQABCDCalculator::getResultUncertainty(){
  // retrieve the uncertainty of the result
  return sqrt(this->fResultErr2);
}

void TQABCDCalculator::printResult(){
  // print the result to the console
  if(TQUtils::isNum(this->getResult())){
    std::cout << TQStringUtils::formatValueError(this->getResult(),this->getResultUncertainty(), "%g +/- %g") << std::endl;
    return;
  }
  std::cout << "<invalid result>" << std::endl;
}

double TQABCDCalculator::getResultVariance(){
  // retrieve the uncertainty of the result
  return this->fResultErr2;
}

bool TQABCDCalculator::finalizeSelf(){
  // perform the finalization and cleanup
  // return true if everything went file, false if an error occured
  if(this->cnt_mc_a){ delete cnt_mc_a; this->cnt_mc_a = NULL; }
  if(this->cnt_mc_b){ delete cnt_mc_b; this->cnt_mc_b = NULL; }
  if(this->cnt_mc_c){ delete cnt_mc_c; this->cnt_mc_c = NULL; }
  if(this->cnt_mc_d){ delete cnt_mc_d; this->cnt_mc_d = NULL; }
  if(this->cnt_data_b){ delete cnt_data_b; this->cnt_data_b = NULL; }
  if(this->cnt_data_c){ delete cnt_data_c; this->cnt_data_c = NULL; }
  if(this->cnt_data_d){ delete cnt_data_d; this->cnt_data_d = NULL; }
  for (uint i=0; i<vBkgCountersB.size(); ++i) {
    if (vBkgCountersB.at(i)) delete vBkgCountersB.at(i);
  }
  vBkgCountersB.clear();
  for (uint i=0; i<vBkgCountersC.size(); ++i) {
    if (vBkgCountersC.at(i)) delete vBkgCountersC.at(i);
  }
  vBkgCountersC.clear();
  for (uint i=0; i<vBkgCountersD.size(); ++i) {
    if (vBkgCountersD.at(i)) delete vBkgCountersD.at(i);
  }
  vBkgCountersD.clear();
  return true;
}

bool TQABCDCalculator::initializeSelf(){
  // perform the initialization
  // return true if everything went file, false if an error occured
  if(!this->fReader || !this->fReader->getSampleFolder()){
    messages.sendMessage(TQMessageStream::ERROR,"cannot perform calculation without valid sample folder!");
    return false;
  }
  if(fPathMC.IsNull() || fPathData.IsNull()){
    messages.sendMessage(TQMessageStream::ERROR,"cannot perform calculation without valid path!");
    return false;
  }
  TQTaggable tmp;
  //@tag: [readScaleScheme] This object tag defines the name of the scale scheme used when retrieving the input quantities. Default: ".abcd.read" .
  tmp.setTagString("scaleScheme",this->getTagStringDefault("readScaleScheme",".abcd.read"));
  //@tag: [applyNonClosureCorrection] If this object tag is set to true, an additional non-closure factor (A/B) / (C/D) (all from MC) is applied. Default: false
  this->doNonClosureCorrection = this->getTagBoolDefault("applyNonClosureCorrection",false);
  this->cnt_mc_a = this->fReader->getCounter(fPathMC,fCutTarget ,&tmp);
  this->cnt_mc_b = this->fReader->getCounter(fPathMC,fCutSource ,&tmp);
  this->cnt_mc_c = this->fReader->getCounter(fPathMC,fCutNumerator ,&tmp);
  this->cnt_mc_d = this->fReader->getCounter(fPathMC,fCutDenominator,&tmp);
  this->cnt_data_b = this->fReader->getCounter(fPathData,fCutSource ,&tmp);
  this->cnt_data_c = this->fReader->getCounter(fPathData,fCutNumerator ,&tmp);
  this->cnt_data_d = this->fReader->getCounter(fPathData,fCutDenominator,&tmp);
  //throw an error if some required counters could not be retrieved
  if(!(cnt_mc_a&&cnt_data_b&&cnt_data_c&&cnt_data_d&& ( doNonClosureCorrection ? (cnt_mc_b && cnt_mc_c && cnt_mc_d) : true   ) )){
    if(cnt_mc_a) delete cnt_mc_a;
    else if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' for region A from path '%s'",fCutTarget.Data(),fPathMC.Data());
    if(cnt_mc_b) delete cnt_mc_b;
    else if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' for region B from path '%s'",fCutSource.Data(),fPathMC.Data());
    if(cnt_mc_c) delete cnt_mc_c;
    else if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' for region C from path '%s'",fCutNumerator.Data(),fPathMC.Data());
    if(cnt_mc_d) delete cnt_mc_d;
    else if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' for region D from path '%s'",fCutDenominator.Data(),fPathMC.Data());
    if(cnt_data_b) delete cnt_data_b;
    else if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' for region B from path '%s'",fCutSource.Data(),fPathData.Data());
    if(cnt_data_c) delete cnt_data_c;
    else if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' for region C from path '%s'",fCutNumerator.Data(),fPathData.Data());
    if(cnt_data_d) delete cnt_data_d;
    else if(verbosity > 0) messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' for region D from path '%s'",fCutDenominator.Data(),fPathData.Data());
    return false;
  }
  
  for (uint i=0; i<vBkgCountersB.size(); ++i) {
    if (vBkgCountersB.at(i)) delete vBkgCountersB.at(i);
  }
  vBkgCountersB.clear();
  for (uint i=0; i<vBkgCountersC.size(); ++i) {
    if (vBkgCountersC.at(i)) delete vBkgCountersC.at(i);
  }
  vBkgCountersC.clear();
  for (uint i=0; i<vBkgCountersD.size(); ++i) {
    if (vBkgCountersD.at(i)) delete vBkgCountersD.at(i);
  }
  vBkgCountersD.clear();
  for (uint i=0; i<vBkgPaths.size(); ++i) {
    vBkgCountersB.push_back(this->fReader->getCounter(vBkgPaths.at(i),fCutSource ,&tmp));
    vBkgCountersC.push_back(this->fReader->getCounter(vBkgPaths.at(i),fCutNumerator ,&tmp));
    vBkgCountersD.push_back(this->fReader->getCounter(vBkgPaths.at(i),fCutDenominator ,&tmp));
  }
  
  return true;
}

bool TQABCDCalculator::calculate(){
  // actually perform the calculation of the ABCD estimate and save the results
  // return true if everything went file, false if an error occured
  if (!chainLoader) iterationNumber = -1;
  //copy data (B,C,D) and mc (A) counters to temporary ones 
  TQCounter* ca = new TQCounter(cnt_mc_a);
  TQCounter* cb = new TQCounter(cnt_data_b);
  TQCounter* cc = new TQCounter(cnt_data_c);
  TQCounter* cd = new TQCounter(cnt_data_d);
  DEBUGclass("Starting with counters A(MC) = %g, B(data) = %g, C(data) = %g, D(data) = %g",ca->getCounter(),cb->getCounter(),cc->getCounter(),cd->getCounter());
  if (! (iterationNumber < 0)) {
    if (verbosity > 1) messages.sendMessage(TQMessageStream::VERBOSE,"applying random variations to counters");
    ca->scale(this->chainLoader->getRelVariation((fPathMC+":"+fCutTarget),ca->getCounter(),ca->getError() ) );
    cb->scale(this->chainLoader->getRelVariation((fPathData+":"+fCutSource),cb->getCounter(),cb->getError() ) );
    cc->scale(this->chainLoader->getRelVariation((fPathData+":"+fCutNumerator),cc->getCounter(),cc->getError() ) );
    cd->scale(this->chainLoader->getRelVariation((fPathData+":"+fCutDenominator),cd->getCounter(),cd->getError() ) );
  }
  DEBUGclass("Scaled counters A(MC) = %g, B(data) = %g, C(data) = %g, D(data) = %g",ca->getCounter(),cb->getCounter(),cc->getCounter(),cd->getCounter());
  for (uint i=0; i<vBkgPaths.size(); ++i) {
      if (vBkgCountersB.at(i)) cb->subtract(vBkgCountersB.at(i), ((iterationNumber < 0) ? 1. : this->chainLoader->getRelVariation((vBkgPaths.at(i)+":"+fCutSource),vBkgCountersB.at(i)->getCounter(),vBkgCountersB.at(i)->getError() ) ) );
      else WARNclass("Missing MC background counter in region B (%s)",vBkgPaths.at(i).Data());
      if (vBkgCountersC.at(i)) cc->subtract(vBkgCountersC.at(i), ((iterationNumber < 0) ? 1. : this->chainLoader->getRelVariation((vBkgPaths.at(i)+":"+fCutNumerator),vBkgCountersC.at(i)->getCounter(),vBkgCountersC.at(i)->getError() ) ) );
      else WARNclass("Missing MC background counter in region C (%s)",vBkgPaths.at(i).Data());
      if (vBkgCountersD.at(i)) cd->subtract(vBkgCountersD.at(i), ((iterationNumber < 0) ? 1. : this->chainLoader->getRelVariation((vBkgPaths.at(i)+":"+fCutDenominator),vBkgCountersC.at(i)->getCounter(),vBkgCountersD.at(i)->getError() ) ) );
      else WARNclass("Missing MC background counter in region D (%s)",vBkgPaths.at(i).Data());
    }
  DEBUGclass("Counters after scaling and other background subtraction: A(MC) = %g, B(data-MC') = %g, C(data-MC') = %g, D(data-MC') = %g",ca->getCounter(),cb->getCounter(),cc->getCounter(),cd->getCounter());
  double a = ca->getCounter();
  double b = cb->getCounter();
  double c = cc->getCounter();
  double d = cd->getCounter();
  double sa2 = ca->getErrorSquared();
  double sb2 = cb->getErrorSquared();
  double sc2 = cc->getErrorSquared();
  double sd2 = cd->getErrorSquared();
  delete ca;
  delete cb;
  delete cc;
  delete cd;
  if(verbosity > 1){
    messages.sendMessage(TQMessageStream::VERBOSE,"retrieved mc counter for region A: %g +/- %g",a,sqrt(sa2));
    messages.sendMessage(TQMessageStream::VERBOSE,"calculated value for region B: %g +/- %g",b,sqrt(sb2));
    messages.sendMessage(TQMessageStream::VERBOSE,"calculated value for region C: %g +/- %g",c,sqrt(sc2));
    messages.sendMessage(TQMessageStream::VERBOSE,"calculated value for region D: %g +/- %g",d,sqrt(sd2));
  }
  //this is just to make the following lines a little more readable, ownership is untouched
  TQCounter* ncb = this->cnt_mc_b;
  TQCounter* ncc = this->cnt_mc_c;
  TQCounter* ncd = this->cnt_mc_d;

  double a1 = b * c/d;
  double a1err2 = sb2*pow(c/d,2) + sc2*pow(b/d,2) + sd2*pow((b*c)/(d*d),2);
  //non closure correction factor is (all mc): (A/B)/(C/D)
  this->fResult = doNonClosureCorrection ? 
     a1 / (ncb->getCounter()*chainLoader->getRelVariation(fPathMC+":"+fCutSource,ncb->getCounter(), ncb->getError())) /
    (ncc->getCounter()*chainLoader->getRelVariation(fPathMC+":"+fCutNumerator,ncc->getCounter(), ncc->getError()) ) *
    ncd->getCounter()*chainLoader->getRelVariation(fPathMC+":"+fCutDenominator,ncd->getCounter(), ncd->getError()) 
   : a1/a;
  this->fResultErr2 = doNonClosureCorrection ? 
    (pow(ncb->getCounter()*ncc->getCounter()*ncd->getCounter(),2)*a1err2 + pow(a1*ncc->getCounter()*ncd->getCounter(),2)* ncb->getErrorSquared() + pow(a1*ncb->getCounter()*ncd->getCounter(),2)* ncc->getErrorSquared() + pow(a1*ncc->getCounter()*ncb->getCounter(),2)* ncd->getErrorSquared()) / pow(ncb->getCounter()*ncc->getCounter(),4)
   : a1err2/(a*a) + sa2*pow(a1/(a*a),2);
  messages.sendMessage(TQMessageStream::VERBOSE,"calculated ABCD NF: %g +/- %g",this->fResult,sqrt(this->fResultErr2));
  return true;
}

int TQABCDCalculator::deployResult(const std::vector<TString>& startAtCutNames, const std::vector<TString>& stopAtCutNames, int doOverwrite, bool applyToStopCut){
  // set the NF according to the desired scale scheme
  // the NF will be deployed at the given path
  if(!TQUtils::isNum(this->fResult)) return false;
  bool overwrite = (doOverwrite == 1);
  
  /*
  bool last = false;
  for (size_t i=0; i<stopAtCutNames.size(); ++i) {
    if (TQStringUtils::matches(cutName, stopAtCutNames[i])) {
      last = true;
      break;
    }
  }
  */
  
  //@tag: [writeScaleScheme] This vector valued object tag defines the names of the scale schemes the result of the calculation is written to. Default: ".default"
  // set the NF according to the desired scale scheme(s)
  std::vector<TString> writeScaleSchemes = this->getTagVString("writeScaleScheme");
  if(writeScaleSchemes.size() < 1){
    writeScaleSchemes.push_back(this->getTagStringDefault("writeScaleScheme",".default"));
  }
  int retval = 0;
  //@tag: [targetPath] This object tag defines the sample folder path, the calculated NF is applied/written to. Default: path set via config passed to TQABCDCalculator::readConfiguration, argument tag "pathMC".
  TString path = this->getTagStringDefault("targetPath",this->fPathMC);
  //--------------------------------------------------
  std::vector<TString> targets = this->getTargetCuts(startAtCutNames,stopAtCutNames,applyToStopCut);
  for (size_t c=0; c<targets.size(); ++c) {
    TString cutName = targets.at(c);
    TQSampleFolderIterator itr(this->fReader->getListOfSampleFolders(path),true);
    while(itr.hasNext()){
      TQSampleFolder* sf = itr.readNext();
      if(!sf) continue;
      for(size_t k=0; k<writeScaleSchemes.size(); k++){
        int n = sf->setScaleFactor(writeScaleSchemes[k]+":"+cutName+(overwrite?"":"<<"), this->getResult(), this->getResultUncertainty());
        this->addNFPath(sf->getPath(),cutName,writeScaleSchemes[k]);
        if(n == 0){
          ERRORclass("unable to set scale factor for cut '%s' on path '%s' with scheme '%s'",cutName.Data(),sf->getPath().Data(),writeScaleSchemes[k].Data());
        }
        retval += n;
      }
    }
    // if the info folder is set and valid, we should keep track of all the processes that have NFs applied
    if(this->infoFolder){
      // get the folder which contains the list of processes for which we have NFs
      //@tag: [nfListPattern] This object tag specifies the pattern of the folder name (inside the "info" folder) where information about the existence of the NF is stored. Default: ".cut.%s+" (the "+" enforces creation of the folder if it is not existing yet)
      TQFolder * sfProcessList = this->infoFolder->getFolder(TString::Format(this->getTagStringDefault("nfListPattern",".cut.%s+").Data(),cutName.Data()));
      // get the sample folder which contains the samples for this process
      TList* sflist = this->fReader->getListOfSampleFolders(path);
      TQSampleFolder * processSampleFolder = ( sflist && sflist->GetEntries() > 0 ) ? (TQSampleFolder*)(sflist->First()) : NULL;
      if(sflist) delete sflist;
      // retrieve the correct title of the process from this folder
      // if there is no process title set, we will use the process name instead
      TString processTitle = path;
      if (processSampleFolder)
      //@tag: [processTitleKey] This object tag defines the name of the process tag from which the title of the normalized process is obtained. Default: "style.default.title" 
        processSampleFolder->getTagString(this->getTagStringDefault("processTitleKey","style.default.title"), processTitle);
      // after we have aquired all necessary information, we add a new entry 
      // to the list of processes to which NFs have been applied
      sfProcessList->setTagString(TQFolder::makeValidIdentifier(processTitle),processTitle);
    }
  }
  //--------------------
  
  // if no recursion was required, we can stop here
  /*
  if(stopAtCutNames.size() == 0 || !this->cutInfoFolder || last)
    return retval;
  // if stopAtCutNames is set, we need to recurse over the cut structure
  // therefore, we first need to find out how the cuts are structured
  */
  //TList * cuts = this->cutInfoFolder->getListOfFolders(TString::Format("*/%s/?",cutName.Data()));
  /*
  if(!cuts) return retval;
  TQFolderIterator cutitr(cuts,true);
  // iterate over all the cuts below the one we are investigating now
  while(cutitr.hasNext()){
    TQFolder* f = cutitr.readNext();
    if(!f) continue;
    // and deploy NFs at the corresponding cuts
    retval += this->deployResult(f->GetName(),stopAtCutNames,doOverwrite);
  }
  */
  return retval;
}

int TQABCDCalculator::execute(int itrNumber) {
	// execute the iteration with the given number
  this->iterationNumber = itrNumber;
  fSuccess = this->calculate();
  if (fSuccess) return 0;
  return -1;
}

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