#include "QFramework/TQNFCalculator.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/TQNFChainloader.h"


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

#include "TFractionFitter.h"

//#define _DEBUG_

#include "QFramework/TQLibrary.h"

////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQNFCalculator
//
// The TQNFCalculator is a class that automates calculation of
// normalization factors based on control regions.
// It works based on a TQSampleDataReader.
//
// The TQNFCalculator supports two different operational modes
// 1) manual subtraction of unscaled samples 
// To use the TQNFCalculator in this mode, you should
// set the default data path to your data path 
// subtracting all samples that have no NF applied, e.g.
// NFCalculator::setDefaultDataPath("data - sig - bkg/unscaled")
// 2) automatic handling of fixed samples
// To use the TQNFCalculator in this mode, you should call
// TQNFCalculator::addFixSample(path)
// you can choose to either use the combined path, e.g.
// "sig - bkg/unscaled"
// or make several calls for individual sample groups, e.g.
// TQNFCalculator::addFixSample("sig")
// TQNFCalculator::addFixSample("bkg/unscaled")
// The central values should be the same for both methods,
// but the error calculation is more correct when using automatic mode.
// 
// It is possible to set bounds on individual NFs for floating (non-fixed)
// samples by using the variant
// TQNFCalculator::addSample(name,path,lowerBound,upperBound);
// This should be done whenever possible, since the precision of some methods
// relies heavily on sensible bounds.
// 
// Additionally, the TQNFCalculator supports different methods calculation
// - 'simple' or 'single mode': in cases when there is only one floating
// sample this method is not using any elaborate technique, but instead
// calculates the NF arithmeticall ('by hand')
// - 'TFractionFitter': a TFractionFitter is used to simulatenously fit all
// NFs in all regions. The error calculation is not entirely correct since
// event weights are not handled propery
// - 'MatrixInversion' : this mode is only possible if the number of floating
// samples equals the number of regions. Here, all are filled into a matrix
// which is then inverted. While this yields correct central values in principle,
// the precision and especially the correctness of the error propagation depends 
// heavily on the condition of the matrix. For optimal results, lower and upper bounds
// should be set for each NF and the NFs and regions should be appended in the correct
// order, i.e. such that the matrix is mostly diagonal
// It is possible to have the TQNFCalculator try different methods successively, via
// TQNFCalculator::addMethod(methodName)
// For this purpose, two 'fallback'-methods exist:
// - 'Unity' will set all NFs to unity (NF=1)
// - 'FAIL' will unset all NFs and report an error
//
////////////////////////////////////////////////////////////////////////////////////////////////

ClassImp(TQNFCalculator)


TQNFCalculator::TQNFCalculator(TQSampleFolder* f):
TQNFBase("TQNF"),
  status(-999),
  defaultDataPath("data"),
  data(NULL),
  mc(NULL),
  epsilon(std::numeric_limits<double>::epsilon())
{
  // default constructor taking base sample folder
  this->setSampleFolder(f);
}

TQNFCalculator::TQNFCalculator(TQSampleDataReader* rd):
  TQNFBase("TQNF"),
  status(-999),
  defaultDataPath("data"),
  data(NULL),
  mc(NULL),
  epsilon(std::numeric_limits<double>::epsilon())
{
  // default constructor taking base sample folder
  this->setReader(rd);
}

TString TQNFCalculator::getDefaultDataPath(){
  // retrieve the default data path currently set
  return this->defaultDataPath;
}

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

int TQNFCalculator::deployNF(const TString& name, const std::vector<TString>& startAtCutNames,  const std::vector<TString>& stopAtCutNames, int overwrite, bool applyToStopCut){
  // deploys a selected NF in all known locations
  // stop if this cut is an point of tree of cuts on which to apply the NFs
  /*
  std::cout<<"deployNF called with cutName = "<< cutName.Data()<<", stopAtCutNames:"<<std::endl;
  TQListUtils::print(stopAtCutNames);
  std::cout<<"This is where I'd apply NFs with the new code:"<<std::endl;
  std::vector<TString> startCuts;
  startCuts.push_back(cutName);
  std::vector<TString> targets = this->getTargetCuts(startCuts,stopAtCutNames);
  TQListUtils::print(targets);
  std::cout<<"Now go and compare if I did it right ;)"<<std::endl;
  */
  if(!this->success()){ //cutName.Data(),
    WARNclassargs(TQStringUtils::concat(3,name.Data(),TQStringUtils::concat(stopAtCutNames).Data(),TQStringUtils::getStringFromBool(overwrite).Data(),TQStringUtils::getStringFromBool(applyToStopCut).Data()),"cannot deploy NF, no results available, status is %d!",this->status);
    return -1;
  }
  /*
  bool last = false;
  for (size_t i=0; i<stopAtCutNames.size(); ++i) {
    if (TQStringUtils::matches(cutName, stopAtCutNames[i])) {
      last = true;
      break;
    }
  }
  */
  
  // get the NF
  double nf = 0;
  double sigma = 0;
  int retval = 0;
  this->getNFandUncertainty(name,nf,sigma);
  //if((overwrite > 1) || std::fabs(nf-1.) > this->epsilon){
    // get the monte carlo path for this sample
    TString mcpath = this->getMCPath(name);
    // set the NF according to the desired scale scheme(s)
    //@tag:[writeScaleScheme] This object tag determines the list of scale schemes the results of the NF calculation are written to. Default: ".default"
    std::vector<TString> writeScaleSchemes = this->getTagVString("writeScaleScheme");
    if(writeScaleSchemes.size() < 1){
      writeScaleSchemes.push_back(this->getTagStringDefault("writeScaleScheme",".default"));
    }
    std::vector<TString> targets = this->getTargetCuts(startAtCutNames,stopAtCutNames,applyToStopCut);
    //--------------------------------------------------------
    for (size_t c = 0; c<targets.size(); ++c) {
      TString cutName = targets.at(c);
      DEBUGclass("deploying NF for %s at %s (overwrite=%d)",name.Data(),cutName.Data(),overwrite);
      TQSampleFolderIterator itr(this->fReader->getListOfSampleFolders(mcpath),true);
      while(itr.hasNext()){
        TQSampleFolder* s = itr.readNext();
        if(!s) continue;
        for(size_t k=0; k<writeScaleSchemes.size(); k++){
          int n = s->setScaleFactor(writeScaleSchemes[k]+":"+cutName+(overwrite>0?"":"<<"), nf,sigma);
          if(n == 0){
            ERRORclass("unable to set scale factor for cut '%s' on path '%s' with scheme '%s'",cutName.Data(),s->getPath().Data(),writeScaleSchemes[k].Data());
          } else {
          DEBUG("Set scale factor for cut '%s' on path '%s' with scheme '%s' (value: %.2f +/- %.2f, overwrite: %s) ",cutName.Data(),s->getPath().Data(),writeScaleSchemes[k].Data(),nf,sigma, (overwrite>0?"true":"false") );
          }
          //keep track where a NF has been written to as required by TQNFBase for use in TQNFChainloader
          this->addNFPath(s->getPath(),cutName,writeScaleSchemes[k]);
          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 determines the format how the existence of NFs for the target paths/cuts is written to the info folder (if present). Default: ".cut.%s+"
        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(mcpath);
        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 = name;
        if (processSampleFolder)
          //@tag:[processTitleKey] This object tag determines the name of the process tag used to retrieve the process title from. 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 or we arrived at a stop cut, 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()));//HERE!!!
  /*
  if(!cuts) return retval;
  TQIterator iter(cuts,true);
  // iterate over all the cuts below the one we are investigating now
  while(iter.hasNext()){
    TQFolder* f = dynamic_cast<TQFolder*>(iter.readNext());
    if(!f) continue;
    // and deploy NFs at the corresponding cuts
    retval += this->deployNF(name,f->GetName(),stopAtCutNames,overwrite);
  }
  */
  return retval;
}

int TQNFCalculator::deployResult(const std::vector<TString>& startAtCutNames,  const std::vector<TString>& stopAtCutNames, int overwrite, bool applyToStopCut){
  if(!this->success()){
    WARNclassargs(TQStringUtils::concat(3,TQListUtils::makeCSV(startAtCutNames).Data(),TQStringUtils::concat(stopAtCutNames).Data(),TQStringUtils::getStringFromBool(overwrite).Data()),TQStringUtils::getStringFromBool(applyToStopCut).Data(),"cannot deploy NFs, no results available, status is %d!",this->status);
    return -1;
  }
  // deploys all NFs in all known locations
  int retval = 0;
  for(size_t i=0; i<mcNames.size(); i++){
    if(mcFixed[i]) continue;
    retval += this->deployNF(mcNames[i],startAtCutNames, stopAtCutNames,overwrite,applyToStopCut);
  }
  return retval;
}

void TQNFCalculator::clear(){
  // clear all names, paths and results
  this->dataPaths.clear();
  this->cutNames.clear();
  this->mcNames.clear();
  this->mcPaths.clear();
  this->mcFixed.clear();
  this->NFs.clear();
  this->NFuncertainties.clear();
  this->nfBoundUpper.clear();
  this->nfBoundLower.clear();
  this->initialized = false;
  this->status = -999;
  if(data){
    delete this->data;
    this->data = NULL;
  }
  if(mc){
    delete this->mc;
    this->mc = NULL;
  }
} 

void TQNFCalculator::setDefaultDataPath(TString path){
  // set the default data path 
  // this path is going to be used if no path is supplied 
  // when adding regions via addRegion(...)
  this->defaultDataPath = path;
}

bool TQNFCalculator::addRegion(TString cutName, TString myDataPath){
  // add a new region. the region name will be the cut name
  // optional argument: supply a data path from which data will be obtained
  if(this->initialized){
    ERRORclass("cowardly refusing to add region to already initialized instance - please call TQNFCalculator::clear() before reusing this instance!");
    return false;
  }
  if(myDataPath.IsNull())
    myDataPath=defaultDataPath;
  // let's first see if there is already a region with this cut name
  // if so, we just update the data path
  for(size_t i=0; i<this->cutNames.size(); i++){
    if(cutNames[i] == cutName){
      dataPaths[i] = myDataPath;
      return false;
    }
  }
  // otherwise, we add it
  this->cutNames.push_back(cutName);
  this->dataPaths.push_back(myDataPath);
  return true;
}

bool TQNFCalculator::addSample(TString mcPath, TString name, bool fixed){
  // add a new monte carlo sample group from the given location
  // optional argument: supply a name for easy reference
  if(this->initialized){
    ERRORclass("cowardly refusing to add sample to already initialized instance - please call TQNFCalculator::clear() before reusing this instance!");
    return false;
  }
  if(name.IsNull()) name = mcPath;
  // let's first see if there is already a sample group with this name
  // if so, we update the path
  for(size_t i=0; i<this->mcNames.size(); i++){
    if(mcNames[i] == name){
      mcPaths[i] = mcPath;
      mcFixed[i] = fixed;
      return false;
    }
  }
  // otherwise, we add it
  this->mcPaths.push_back(mcPath);
  this->mcNames.push_back(name);
  this->mcFixed.push_back(fixed);
  //@tag:[defaultBoundLower,defaultBoundUpper] When adding individual samples via addSample, these object tags determine the minimum/maximum allowed value for the NF of the process unless process specific limits are set. Defaults: 0., 2. .
  this->nfBoundLower.push_back(this->getTagDoubleDefault("defaultBoundLower",0.));
  this->nfBoundUpper.push_back(this->getTagDoubleDefault("defaultBoundUpper",2.));
  return true;
}

bool TQNFCalculator::addSample(TString mcPath, TString name, double boundLower, double boundUpper){
  // add a new monte carlo sample group from the given location
  // optional argument: supply a name for easy reference
  if(this->initialized){
    ERRORclass("cowardly refusing to add sample to already initialized instance - please call TQNFCalculator::clear() before reusing this instance!");
    return false;
  }
  if(name.IsNull()) name = mcPath;
  // let's first see if there is already a sample group with this name
  // if so, we update the path
  for(size_t i=0; i<this->mcNames.size(); i++){
    if(mcNames[i] == name){
      mcPaths[i] = mcPath;
      mcFixed[i] = false;
      nfBoundLower[i] = boundLower;
      nfBoundUpper[i] = boundUpper;
      return false;
    }
  }
  // otherwise, we add it
  this->mcPaths.push_back(mcPath);
  this->mcNames.push_back(name);
  this->mcFixed.push_back(false);
  this->nfBoundLower.push_back(boundLower);
  this->nfBoundUpper.push_back(boundUpper);
  return true;
}

bool TQNFCalculator::addFixSample(TString mcPath, TString name){
  // add a new monte carlo sample group from the given location
  // as opposed to TQNFCalculator::addSample, no NF will be fitted
  // instead, the NF will be fixed to 1
  return this->addSample(mcPath,name,true);
}


bool TQNFCalculator::initializeData(){
  // initialize the data histogram
  if(!this->fReader) return false;
  if(this->data) delete this->data;
  // create the nominal/observed/data histogram
  this->data = new TH1F("data","data",dataPaths.size(),0,dataPaths.size());
  this->data->SetDirectory(NULL);
  // fill it with the nominal values from the default data path
  // here, each region has a separate bin
  //@tag:[readScaleScheme] This object tag determines which scale scheme is used when retrieving values entering the NF calculation (e.g. to include results from previous NF calculation steps). Default: ".nfc.read"
  TString scaleScheme = this->getTagStringDefault("readScaleScheme",".nfc.read");
  scaleScheme.Prepend("scaleScheme=");
  for(size_t i=0; i<this->dataPaths.size(); i++){
    TQCounter* c = this->fReader->getCounter(dataPaths[i],cutNames[i],scaleScheme);
    if(!c){
      ERRORclass("unable to obtain counter '%s' from '%s'!",cutNames[i].Data(),dataPaths[i].Data());
      return false;
    }
    if (chainLoader && iterationNumber > -1) {
      const TString path(dataPaths[i]+":"+cutNames[i]);
      const double variation = chainLoader->getRelVariation(path,c->getCounter(),c->getError());
      DEBUG("variation of path '%s' is '%f'",path.Data(),variation);
      //do not change the uncertainty of c.
      c->setCounter(c->getCounter()*variation);
    }
    this->data->SetBinContent(i+1,c->getCounter());
    this->data->SetBinError(i+1,c->getError());
    this->data->GetXaxis()->SetBinLabel(i+1,cutNames[i]);
    delete c;
  }
  return true;
}

bool TQNFCalculator::ensurePositiveMC(){
  // ensure positive mc for all samples
  bool action = false;
  for(int j=0; j<this->mc->GetEntries(); j++){
    TH1* hist = dynamic_cast<TH1*>(this->mc->At(j));
    for(int i=0; i<hist->GetNbinsX(); i++){
      double val = hist->GetBinContent(i);
      if(val < 0){
        hist->SetBinContent(i,0);
        hist->SetBinError(i,std::max(val,hist->GetBinError(i)));
        action = true;
      }
    }
  }
  return action;
}

bool TQNFCalculator::initializeMC(){
  // initialize all mc histograms
  if(!fReader) return false;
  if(this->mc) delete this->mc;
  this->mc = new TObjArray();
  this->mc->SetOwner(true);
  //tag documentation see initializeData()
  TString scaleScheme = this->getTagStringDefault("readScaleScheme",".nfc.read");
  scaleScheme.Prepend("scaleScheme=");
  for(size_t j=0; j<this->mcPaths.size(); j++){
    // create the histogram corresponding to this sample group
    TH1F* hist = new TH1F(mcNames[j],mcNames[j],cutNames.size(),0,cutNames.size());
    hist->SetDirectory(NULL);
    // fill it with the mc predictions from each sample group
    // here, each region has a separate bin
    for(size_t i=0; i<this->dataPaths.size(); i++){
      TQCounter* c = this->fReader->getCounter(mcPaths[j],cutNames[i],scaleScheme);//running on nominal value
      if(!c){
        this->messages.sendMessage(TQMessageStream::ERROR,"unable to obtain counter '%s' from '%s'!" ,cutNames[i].Data(),mcPaths[j].Data());
        return false;
      }
      if (this->chainLoader && iterationNumber> -1) {// If a TQNFchainloader has been set, we (possibly) run with variations 
        //apply variation without changing the uncertainty of c.
        const TString path(mcPaths[j]+":"+cutNames[i]);
        const double variation = chainLoader->getRelVariation(path,c->getCounter(),c->getError());
        DEBUG("variation of path '%s' is '%f'",path.Data(),variation);
        c->setCounter(c->getCounter()*variation);
      }
      DEBUG("Retrieved counter from path '%s' with value %.2f +/- %.2f",TString(mcPaths[j]+":"+cutNames[i]).Data(),c->getCounter(),c->getError());
      hist->SetBinContent(i+1,c->getCounter());
      hist->SetBinError(i+1,c->getError());
      hist->GetXaxis()->SetBinLabel(i+1,cutNames[i]);
      delete c;
    }
    this->mc->Add(hist);
  }
  return true;
}


bool TQNFCalculator::finalizeSelf(){
  if(this->mc) delete this->mc;
  this->mc = NULL;
  if(this->data) delete this->data;
  this->data = NULL;
  this->NFs.clear();
  this->NFuncertainties.clear();
  return true;
}

bool TQNFCalculator::initializeSelf(){
  // initialize the NF Calculator
  // - initializes the data histogram
  // - initializeds the mc histograms
  // will set the initialize flag to true
  // further calls of initialize will have no effect
  // until clear is called
  if(!this->fReader)
    return false;
  DEBUGclass("initializing data histogram");
  if(!this->initializeData())
    return false;
  DEBUGclass("initializing mc histograms");
  if(!this->initializeMC())
    return false;
  return true;
}

size_t TQNFCalculator::getFloatingSamples(){
  // return the number of "floating" (i.e. non-fixed) samples
  size_t n = 0;
  for(size_t i=0; i<this->mcFixed.size(); i++){
    if(!this->mcFixed[i]){
      n++;
    }
  }
  return n;
}

void TQNFCalculator::calculateNFs_MatrixMode(){
  // in the case where the number of samples
  // and the number of regions are identical
  // the TFractionFitter cannot be used
  // hence, this function implements a matrix calculation
  // for this particular case
  const unsigned int n(data->GetNbinsX());
  if(n != this->getFloatingSamples()){
    this->messages.sendMessage(TQMessageStream::WARNING,"cannot use matrix mode for %d samples in %d regions - only possible for equal N", this->getFloatingSamples(),n);
    this->status = -10;
    return;
  }

  if(verbosity > 1){
    this->messages.sendMessage(TQMessageStream::INFO,"entering matrix mode");
  }
  // setup the data vector and monte carlo matrix
  std::vector<TString> vSampleNames;
  TVectorD vData(n);
  TVectorD vDataErr(n);
  TMatrixD mMC(n,n);
  TMatrixD mMCerr(n,n);
  double max = 1;
  for(size_t i=0; i<n; i++){
    double dataVal = data->GetBinContent(i+1);
    double dataErr2 = pow(data->GetBinError(i+1),2);
    int j = 0;
    for(size_t idx=0; idx<this->mcFixed.size(); idx++){
      if(this->mcFixed[idx]){
        TH1* hist = (TH1*)(this->mc->At(idx));
        dataVal -= hist->GetBinContent(i+1);
        dataErr2 += pow(hist->GetBinError(i+1),2);
      } else {
        TH1* hist = (TH1*)(this->mc->At(idx));
        mMC[i][j] = hist->GetBinContent(i+1);
        if(verbosity > 1) this->messages.sendMessage(TQMessageStream::INFO,"%s in %s is %.3f",mcNames[idx].Data(),cutNames[i].Data(),mMC[i][j]);
        vSampleNames.push_back(mcNames[idx]);
        mMCerr[i][j] = hist->GetBinError(i+1);
        j++;
      }
    }
    max = std::max(max,dataVal);
    vData [i] = dataVal;
    vDataErr[i] = sqrt(dataErr2);
  }
  
  // do the error calculation
  TH1F** tmphists = (TH1F**)malloc(n*sizeof(TH1F*));
  int i = 0;
  for(size_t idx=0; idx<this->mcFixed.size(); idx++){
    if(mcFixed[idx]) continue;
    tmphists[i] = new TH1F(mcNames[idx],TString::Format("Distribution for NF[%s]",mcNames[idx].Data()),100,nfBoundLower[idx],nfBoundUpper[idx]);
    tmphists[i]->SetDirectory(NULL);
    i++;
  }
 
  //@tag:[mode.matrix.nToyHits] (legacy!) This object tag sets the number of toys created when using the matrix inversion method to estimate the uncertainty and improve numerical stability. This is deprecated, use the TQNFChainloader and it's toy capabilities instead! Default: 100
  size_t nSamples = this->getTagIntegerDefault("mode.matrix.nToyHits",100);
  TVectorD vecNFErrs(n);
  TVectorD vecNFs(n);
  if(nSamples > 1){
    // do internal error calculation via random sampling
    TRandom rand;
    TVectorD vtmp(vData);
    for(size_t i=0; i<n; ++i){// loop over MC rows
      for(size_t j=0; j<n; ++j){// loop over MC columns
        for(size_t x = 0; x<nSamples; ++x){// sample mc random hits
          TMatrixD mattmp(mMC);
          mattmp[i][j] = rand.Gaus(mMC[i][j],mMCerr[i][j]);
          mattmp.Invert();
          for(size_t k=0; k<n; ++k){// loop over data entries
            for(size_t y = 0; y<nSamples; ++y){// sample data random hits
              vtmp[k] = rand.Gaus(vData[k],vDataErr[k]);
              TVectorD tmpNFs(mattmp * vtmp);
              for(size_t l=0; l<n; l++){// fill the results
                tmphists[l]->Fill(tmpNFs[l]);
              }
              vtmp[k] = vData[k];
            }
          }
        }
      }
    }
    for(size_t i=0; i<n; ++i){
      vecNFs[i] = tmphists[i]->GetMean();
      vecNFErrs[i] = tmphists[i]->GetRMS();
      if(verbosity > 2){
        this->messages.newline();
        TQHistogramUtils::printHistogramASCII(this->messages.activeStream(),tmphists[i],"");
        this->messages.newline();
      }
      delete tmphists[i];
    }
    free(tmphists);
  } else {
    // do not estimate errors, this was not requested / will be done from outside somehow
    TVectorD vtmp(vData);
    TMatrixD mattmp(mMC);
    #ifdef _DEBUG_
    DEBUG("Printing MC matrix before inversion");
    mattmp.Print();
    #endif
    mattmp.Invert();
    #ifdef _DEBUG_
    DEBUG("Printing MC matrix after inversion");
    mattmp.Print();
    #endif
    TVectorD tmpNFs(mattmp * vtmp);
    for(size_t l=0; l<n; l++){// fill the results
      vecNFs[l] = tmpNFs[l];
      vecNFErrs[l] = 0;
    }
  }

  // test the results and calculate closure
  bool ok = true;
  TVectorD vClosure = mMC * vecNFs;
  double closure = 0;
  for(size_t i=0; i<n; i++){
    /* this check is disabled since sometimes negative results can occur (in particular during toy creation) and not storing anything can mess up the chainloader (to be FIXME'd, this also includes fixes in this class like registering destination paths despite a failed calculation!)
    if(vecNFs[i] <= 0 ){ //
      if(verbosity > 0) this->messages.sendMessage(TQMessageStream::ERROR,"NF[%s] = %.2f <= 0",mcNames[i].Data(),vecNFs[i]);
      ok = false;
    }
    */
    closure += fabs(vClosure[i] - vData[i]);
  }

  this->messages.newline();
  // some printout
  if(verbosity > 2){              
    const int numwidth = log10(max)+3;
    for(size_t i=0; i<n; i++){
      TString line = "( ";
      for(size_t j=0; j<n; j++){
        line += TString::Format("%*.1f ",numwidth,mMC[i][j]);
      }
      line += ") ";
      if(i==0) line += "*";
      else line += " ";
      line += TString::Format(" ( %*.1f ) ",4,vecNFs[i]);
      if(i==0) line += "=";
      else line += " ";
      line += TString::Format(" ( %*.1f ) ",numwidth,vData[i]);
      this->messages.sendMessage(TQMessageStream::INFO,line);
    }
  }

  if(verbosity > 1){
    this->messages.sendMessage(TQMessageStream::INFO,"closure = %g",closure);
    int j = 0;
    for(size_t idx=0; idx<this->mcFixed.size(); idx++){
      if(this->mcFixed[idx]) continue;
      this->messages.sendMessage(TQMessageStream::INFO,"NF[%s] = %.3f +/- %.3f",mcNames[idx].Data(),vecNFs[j],vecNFErrs[j]);
      j++;
    }
  }

  if(!ok){
    this->status = 20;
    return;
  }

  double maxClosure;
  //@tag:[mode.matrix.maxClosure] This object tag determines the maximum closure value allowed (results are discarded if this value is exceeded). Closure is ignored if tag is not set.
  if(this->getTagDouble("mode.matrix.maxClosure",maxClosure) && closure > maxClosure){
    if(verbosity > 1) this->messages.sendMessage(TQMessageStream::WARNING,"closure exceeds maximum '%g', discarding results",maxClosure);
    status = 1;
    return;
  }

  // save the results
  int j = 0;
  for(size_t idx=0; idx<this->mcFixed.size(); idx++){
    if(this->mcFixed[idx]){
      this->NFs.push_back (1);
      this->NFuncertainties.push_back(0);
    } else {
      DEBUG("saving result entry %d : %.2f",j,vecNFs[j]);
      this->NFs.push_back (vecNFs[j]);
      this->NFuncertainties.push_back(vecNFErrs[j]);
      j++;
    }
  }
  status = 0;
}

void TQNFCalculator::calculateNFs_singleMode(){
  // in the case of only one sample group
  // the TFractionFitter cannot be used
  // hence, this function implements a manual calculation
  // for the case of only one sample group
  if(this->getFloatingSamples() > 1){
    this->messages.sendMessage(TQMessageStream::WARNING,"cannot use single mode for %d samples - only possible for nSamples=1", this->getFloatingSamples());
    this->status = -5;
    return;
  }
  double sum = 0;
  double sumw = 0;
  TH1* mchist = NULL;
  if(verbosity > 1){
    this->messages.sendMessage(TQMessageStream::INFO,"entering single mode");
  }
  for(int i=0; i<this->data->GetNbinsX(); i++){
    // we sum up all the different NFs from all regions
    // and calculate the weighted average of the NF 
    // for our one and only sample group
    if(verbosity > 1) this->messages.sendMessage(TQMessageStream::INFO,"looking at region %s",cutNames[i].Data());
    double targetVal = data->GetBinContent(i+1);
    if(verbosity > 1) this->messages.sendMessage(TQMessageStream::INFO,"data is %.3f +/- %.3f",targetVal,data->GetBinError(i+1));
    double targetErr2 = pow(data->GetBinError(i+1),2);
    // first we need to calculate the background-subtracted data value
    // that is, the "target value" we want to use as a reference 
    // to calculate the normalization scale factor.
    for(int j=0; j<this->mc->GetEntries(); j++){
      // fixed samples get subtracted from data
      // while the first (and only) non-fixed sample
      // will become the value we try to scale accordingly
      if(this->mcFixed[j]){
        TH1* hist = (TH1*)(this->mc->At(j));
        if(verbosity > 1) this->messages.sendMessage(TQMessageStream::INFO,"%s is %.3f +/- %.3f",mcNames[j].Data(),hist->GetBinContent(i+1),hist->GetBinError(i+1));
        targetVal -= hist->GetBinContent(i+1);
        targetErr2 += pow(hist->GetBinError(i+1),2);
      } else mchist = (TH1*)(this->mc->At(j));
    }
    if(verbosity > 1){
      this->messages.sendMessage(TQMessageStream::INFO,"background subtracted data: %.3f +/- %.3f",targetVal,sqrt(targetErr2));
      this->messages.sendMessage(TQMessageStream::INFO,"contribution from %s is %.3f +/- %.3f",mchist->GetName(),mchist->GetBinContent(i+1),mchist->GetBinError(i+1));
    }
    // we calculate the weighted average over all contributions we collected
    // including the uncertainty on this value
    // hence, we keep track of the weighted values and the sum of weights
    double val = targetVal/mchist->GetBinContent(i+1);
    double weight = 1./(val*val * (targetErr2 / pow(targetVal,2)
                                   + pow(mchist->GetBinError(i+1),2) / pow(mchist->GetBinContent(i+1),2)));
    if(verbosity > 1) this->messages.sendMessage(TQMessageStream::INFO,"collecting NF = %.3f +/- %.3f from %s",val,1.0/sqrt(weight),cutNames[i].Data());
    sum += val * weight;
    sumw += weight;
  }
  if(verbosity > 1) this->messages.sendMessage(TQMessageStream::INFO,"total resulting NF = %.3f +/- %.3f",sum/sumw,1.0/sqrt(sumw));
  // after the calculation is finished, all we need to do is set the scale factor
  // according to our calculation result
  // for consistency, we need to push an NF of 1 +/- 0 for all fixed samples
  for(size_t i=0; i<this->mcFixed.size(); i++){
    if(this->mcFixed[i]){
      this->NFs.push_back (1);
      this->NFuncertainties.push_back(0);
    } else {
      this->NFs.push_back (sum/sumw);
      this->NFuncertainties.push_back(1.0/sqrt(sumw));
    }
  }
  this->status = 0;
  if(verbosity > 0){
    this->messages.sendMessage(TQMessageStream::INFO,"Results of the NF Calculation are as follows:");
    this->printResults(&(this->messages.activeStream()));
  }
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-security"

void TQNFCalculator::calculateNFs_TFractionFitterMode(){
  // this is the worker function 
  // actually performing the NF calculation
  // in the default case of more than one sample group
  if(this->getFloatingSamples() < 2){
    this->messages.sendMessage(TQMessageStream::WARNING,"cannot use TFractionFitter mode for %d samples - only possible for nSamples>1, please use single mode instead", this->getFloatingSamples());
    this->status = -3;
    return;
  }
  const unsigned int n(data->GetNbinsX());
  if(n <= this->getFloatingSamples()){
    this->messages.sendMessage(TQMessageStream::WARNING,"cannot use TFractionFitter mode for %d samples in %d regions - only possible for #regions > #samples, please use MatrixInversion for #regions == #samples or Simple mode instead", this->getFloatingSamples(),n);
    this->status = -5;
    return;
  }
  if(this->verbosity > 1){
    this->messages.sendMessage(TQMessageStream::INFO,"entering fraction fitter mode");
  }
  if(this->ensurePositiveMC()){
    this->messages.sendMessage(TQMessageStream::INFO,"one or more bins was shifted to yield positive bin contents");
  }
  if(this->messages.isFile()){
    TQLibrary::redirect(this->messages.getFilename(),true);
    this->messages.close();
  } 
  TString voption = "Q";
  if(this->verbosity == 1) voption = "";
  if(this->verbosity > 1) voption = "V";
  TFractionFitter fitter(this->data, this->mc, voption);
  int nFloat = 0;
  for(int i=0; i<this->mc->GetEntries(); i++){
    TH1* mchist = (TH1*)(this->mc->At(i));
    double fraction = mchist->Integral() / this->data->Integral();
    if(mcFixed[i]){
      if(this->verbosity > 0){
        printf("\n\n");
        TString msg = this->messages.formatMessage(TQMessageStream::INFO,"fraction for %s is %.3f (fixed=true)\n",mcNames[i].Data(),fraction);
        printf(msg.Data());
      }
      // for fix samples, we constrain the fraction to the current value
      // watch out, the TFractionFitter starts counting MC samples at i=1
      fitter.Constrain(i+1,std::max(fraction - epsilon,0.),std::min(fraction + epsilon,1.));
    } else {
      if(this->verbosity > 0){
        printf("\n\n");
        TString msg = this->messages.formatMessage(TQMessageStream::INFO,"fraction for %s is %.3f (fixed=false)\n",mcNames[i].Data(),fraction);
        printf(msg.Data());
      }
      // else, we allow it to float in the range [0,1]
      // watch out, the TFractionFitter starts counting MC samples at i=1
      fitter.Constrain(i+1,fraction*this->nfBoundLower[i],fraction*this->nfBoundUpper[i]);
      nFloat++;
    }
  }
  if(this->verbosity > 0){
    printf("\n\n");
    TString msg = this->messages.formatMessage(TQMessageStream::INFO,"running simultaneous fit of %d NFs in %d regions\n",nFloat,(int)cutNames.size()).Data();
    printf(msg.Data());
  }
  this->status = fitter.Fit();
  if(this->messages.isFile()){
    TQLibrary::restore();
    this->messages.reopen();
  }
  if(this->verbosity > 0){
    this->messages.newlines(2);
    this->messages.sendMessage(TQMessageStream::INFO,"performed fit, status is %d\n",this->status);
  }
  if(this->success()){
    for(size_t i=0; i<this->mcNames.size(); i++){
      DEBUGclass("retrieving NF for '%s'",this->mcNames[i].Data());
      double nf = 0;
      double sigma = 0;
      fitter.GetResult(i,nf,sigma);
      // the TFractionFitter returns the relative fraction
      // the given histogram contributes to the data
      // thus, to obtain the NFs, we need to divide the result
      // by the current fraction the histogram contributes to data
      TH1* mchist = dynamic_cast<TH1*>(this->mc->At(i));
      double fraction = 1;
      if(!mchist){
        ERRORclass("internal error: invalid histogram pointer for '%s' at position %d/%d!",this->mcNames[i].Data(),(int)i,this->mc->GetEntries());
      } else {
        fraction = mchist->Integral() / this->data->Integral();
      }
      this->NFs.push_back(nf / fraction);
      this->NFuncertainties.push_back(sigma / fraction);
    }
  }
}

#pragma GCC diagnostic pop

int TQNFCalculator::calculateNFs(const TString& modename){
  // calculate the NFs with a certain method (given by the string)
  // the following tags control the side-effects of this function:
  // - saveLog: string, name of the log file to be used
  // if not given, print to the console
  // - writePreFitHistograms: string, name of the root file to be created
  // if not given, nothing will be written
  // - writePostFitHistograms: string, name of the root file to be created
  // if not given, nothing will be written
  // - saveResults: string, name of the text file to be used for result output
  // if not given, nothing will be written

  if(!this->initialize()){
    this->status = -10;
    return this->status;
  }

  TString rootfilename;
  //@tag:[writePreFitHistograms] This object tag determines if and where (filename) pre-fit histograms are written to.
  if(this->getTagString("writePreFitHistograms",rootfilename)){
    this->exportHistogramsToFile(rootfilename);
  }

  this->calculateNFs(this->getMethod(modename));
  if(this->success()){
    //@tag:[writePostFitHistograms] This object tag determines if and where (filename) post-fit histograms are written to.
    if(this->getTagString("writePostFitHistograms",rootfilename)){
      this->exportHistogramsToFile(rootfilename);
    }
    TString resultfilename;
    //@tag:[saveResults] This object tag determines if and where (filename) results are written to (this is independent from storing the results in the TQSampleFolder structure).
    if(this->getTagString("saveResults",resultfilename)){
      this->writeResultsToFile(resultfilename);
    }
  }
  return this->status;
}

int TQNFCalculator::calculateNFs(){
  // actually perform the NF calculation
  // based on all information supplied earlier
  // the following tags control the side-effects of this function:
  // - saveLog: string, name of the log file to be used
  // if not given, print to the console
  // - writePreFitHistograms: string, name of the root file to be created
  // if not given, nothing will be written
  // - writePostFitHistograms: string, name of the root file to be created
  // if not given, nothing will be written
  // - saveResults: string, name of the text file to be used for result output
  // if not given, nothing will be written
  this->messages.sendMessage(TQMessageStream::INFO,"initializing");
  this->messages.newline();
  if(!this->initialize()){
    this->status = -10;
    return this->status;
  }
  TString prefitrootfilename = this->getPathTag("writePreFitHistograms");
  if(!prefitrootfilename.IsNull()){
    this->exportHistogramsToFile(prefitrootfilename);
  }
  this->messages.sendMessage(TQMessageStream::INFO,"calculateNFs entering evaluation");
  for(size_t i=0; i<this->methods.size(); i++){
    this->messages.newline();
    this->messages.sendMessage(TQMessageStream::INFO,TQStringUtils::repeat("-",40));
    this->messages.newline();
    this->calculateNFs(methods[i]); 
    if(this->success()){
      if(verbosity > 1){
        this->messages.sendMessage(TQMessageStream::INFO,"succeeded in calculating NFs with method '%s'",this->getMethodName(methods[i]).Data());
      }
      break;
    } else {
      this->messages.activeStream().flush();
    }
  }
  if(this->success()){
    TString postrootfilename = this->getPathTag("writePostFitHistograms");
    if(!postrootfilename.IsNull()){
      this->exportHistogramsToFile(postrootfilename);
    }
    TString resultfilename = this->getPathTag("saveResults");
    if(!resultfilename.IsNull()){
      this->writeResultsToFile(resultfilename);
    }
  }
  this->messages.activeStream().flush();
  return status;
}

void TQNFCalculator::setNFsUnity(){
  // set all the NFs to one
  this->NFs.clear();
  this->NFuncertainties.clear();
  this->messages.sendMessage(TQMessageStream::WARNING,"TQNFCalculator::setNFsUnity() was called, all NFs are set to unity");
  for(size_t i=0; i<this->mcPaths.size(); i++){
    this->NFs.push_back(1);
    this->NFuncertainties.push_back(0);
  }
  this->status = 0;
}

void TQNFCalculator::fail(){
  // acquire failure state
  this->NFs.clear();
  this->NFuncertainties.clear();
  this->messages.sendMessage(TQMessageStream::WARNING,"TQNFCalculator::fail() was called, all NFs erased, failure state acquired");
  this->status = -1;
}

int TQNFCalculator::calculateNFs(TQNFCalculator::Method method){
  // actually perform the NF calculation
  // based on all information supplied earlier
  if(!this->initialize()){
    this->status = -10;
    return this->status;
  }
  int nsamples = this->getFloatingSamples();
  if(this->mc->GetEntries() == 0 || nsamples == 0){
    // check if we have anything to do
    // if not, well, let's do nothing at all
    this->status = -100;
    return this->status;
  }
  switch(method){
  case Single:
    // if we only have one sample group
    // we need not (and in fact cannot)
    // use the TFractionFitter
    // instead, we calculate the result manually
    this->calculateNFs_singleMode();
    break;
  case MatrixInversion:
    // if we have one region per sample
    // we can use matrix inversion to obtain
    // the NFs
    this->calculateNFs_MatrixMode();
    break;
  case FractionFitter:
    // if everything went smooth up to here
    // we have at least two sample groups
    // and can invoke the TFractionFitter
    this->calculateNFs_TFractionFitterMode();
    break;
  case Unity:
    this->setNFsUnity();
    break;
  default:
    this->fail();
  }
  this->messages.activeStream().flush();
  return this->status;
}

size_t TQNFCalculator::findIndex(TString name){
  // get the contribution index coresponding to the given NF name
  for(size_t i=0; i<this->mcNames.size(); i++){
    if(mcNames[i] == name)
      return i;
  }
  return -1;
}

double TQNFCalculator::getNF(TString name){
  // get the value of the NF with the given name
  size_t n = this->findIndex(name);
  if(!this->success() || (n > this->mcNames.size())) return std::numeric_limits<double>::quiet_NaN();
  return this->NFs[n];
}


double TQNFCalculator::getNFUncertainty(TString name){
  // get the uncertainty of the NF with the given name
  size_t n = this->findIndex(name);
  if(!this->success() || (n > this->mcNames.size())) return std::numeric_limits<double>::quiet_NaN();
  return this->NFuncertainties[n];
}


bool TQNFCalculator::getNFandUncertainty(TString name, double& nf, double& sigma){
  // get the value and uncertainty of the NF with the given name
  // store both in the values supplied as second and third argument
  size_t n = this->findIndex(name);
  if(n > this->mcNames.size()) return false;
  if(this->mcFixed[n]) return false;
  nf = this->NFs[n];
  sigma = this->NFuncertainties[n];
  //ensure that the NF is within the configured limits. TODO: What to do with the uncertainty in this case?
  nf = std::max(nfBoundLower[n],std::min(nfBoundUpper[n],nf));
  return true;
}

void TQNFCalculator::printRegions(std::ostream* os){
  // print all regions scheduled for NF calculation
  if(!os) return;
  for(size_t i=0; i<cutNames.size(); i++){
    *os << cutNames[i] << "\t" << dataPaths[i] << std::endl;
  }
}

void TQNFCalculator::printSamples(std::ostream* os){
  // print all sample groups scheduled for NF calculatrion
  if(!os) return;
  for(size_t i=0; i<mcNames.size(); i++){
    *os << mcNames[i] << "\t" << mcPaths[i];
    if(this->mcFixed[i]) *os << "\t(fixed)";
    else *os << "(" << this->nfBoundLower[i] << "<NF<" << this->nfBoundUpper[i] << ")";
    *os << std::endl;
  }
}

void TQNFCalculator::printResults(std::ostream* os){
  // print the results of the evaluation
  if(!os || !os->good()) return;
  if(!this->success()){
    WARNclass("no results obtained, status is %d",this->status);
    return;
  }
  for(size_t i=0; i<this->NFs.size(); i++){
    double percent = 100*(this->NFs[i]-1);
    *os << this->mcNames.at(i) << "\t" << this->NFs.at(i) << " +/- " << this->NFuncertainties.at(i) << "\t~ ";
    if(TMath::AreEqualAbs(percent,0,0.05))
      *os << "no NF ";
    if(this->mcFixed.at(i))
      *os << "(fixed)";
    else {
      if(percent > 0)
        *os << "+";
      *os << TString::Format("%.2f",percent) << " %";
    }
    *os << std::endl;
  }
}

TH1* TQNFCalculator::getHistogram(const TString& name){
  // obtain the histogram associated with the given sample group
  // will accept all mc names as well as "data" (for the data histogram)
  if(!this->initialize()) return NULL;
  if(name=="data")
    return this->data;
  for(size_t i=0; i<this->mcNames[i]; i++){
    if(name == mcNames[i])
      return (TH1*)(this->mc->At(i));
  }
  return NULL;
}

bool TQNFCalculator::scaleSample(const TString& name, double val){
  // scale the histogram associated to the sample with the given name by the
  // given value
  if(!TQUtils::isNum(val)) return false;
  TH1* hist = this->getHistogram(name);
  if(!hist) return false;
  hist->Scale(val);
  return true;
}

const TString& TQNFCalculator::getMCPath(const TString& name){
  // retrieve the sample path 
  // corresponding to the sample
  // with the given name
  for(size_t i=0; i<this->mcPaths.size(); i++){
    if(mcNames[i] == name)
      return mcPaths[i];
  }
  return TQStringUtils::emptyString;
}
 
int TQNFCalculator::getStatus(){
  // retrieve the status
  return this->status;
}

TString TQNFCalculator::getStatusMessage(){
  // decode the integer status code
  switch(this->status){
  case -999:
    return "uninitialized";
  case -100: 
    return "no data";
  case -50:
    return "method not implemented";
  case -10:
    return "error during initialization";
  case -5:
    return "method not applicable";
  case -1: 
    return "no method succeeded - fail() called";
  case 0:
    return "all OK";
  case 4: 
    return "TFractionFitter failed to converge";
  case 20: 
    return "matrix method encountered negative NFs";
  default:
    return "unkown error";
  }
}

void TQNFCalculator::printStatus(){
  // print the status
  INFOclass("current status of instance '%s' is '%d': %s",this->GetName(),(int)(this->status),this->getStatusMessage().Data());
}

int TQNFCalculator::execute(int itrNumber) {
  //start calculation
  this->iterationNumber = itrNumber;
  return calculateNFs();
}

bool TQNFCalculator::success(){
  // return true if calculation was successful
  // false otherwise
  if(this->initialized && (this->status == 0))
    return true;
  return false;
}

void TQNFCalculator::setEpsilon(double e){
  // set the epsilon deviation allowed for fixed samples
  // smaller values will increase the accuracy of the calculation
  // but also increase the probability of the fit to fail
  this->epsilon = e;
}

double TQNFCalculator::getEpsilon(){
  // get the current value of the epsilon deviation
  // allowed for fixed samples
  return this->epsilon;
}

int TQNFCalculator::writeResultsToFile(const TString& filename){
  // dump the results of the NF calculation to a text file
  if(!this->success()) return -1;
  TQUtils::ensureDirectoryForFile(filename);
  std::ofstream outfile(filename.Data());
  if(!outfile.is_open()){
    return -1;
  }
  int retval = this->writeResultsToStream(&outfile);
  outfile.close();
  return retval;
}

TString TQNFCalculator::getResultsAsString(const TString& name){
  // dump the results of the NF calculation for a particular contribution
  // into a string that is formatted according to the TQTaggable syntax
  if(!this->success()) return "";
  for(size_t i=0; i<mcNames.size(); i++){
    if(name == mcNames[i]){
      TQTaggable* tags = this->getResultsAsTags(i);
      TString s = tags->exportTagsAsString();
      delete tags;
      return s;
    }
  }
  return "";
}

TQTaggable* TQNFCalculator::getResultsAsTags(const TString& name){
  // dump the results of the NF calculation for a particular contribution
  // into an object of the TQTaggable type
  if(!this->success()) return NULL;
  for(size_t i=0; i<mcNames.size(); i++){
    if(name == mcNames[i]){
      return this->getResultsAsTags(i);
    }
  }
  return NULL;
}

TQTaggable* TQNFCalculator::getResultsAsTags(size_t i){
  // dump the results of the NF calculation for a particular entry
  // into an object of the TQTaggable type
  if(!this->success()) return NULL;
  double nf = 0;
  double sigma = 0;
  if (!this->getNFandUncertainty(mcNames[i],nf,sigma)) return 0;
  TQTaggable* tags = new TQTaggable();
  tags->setTagDouble("normalization",nf);
  tags->setTagDouble("normalizationUncertainty",sigma);
  tags->setTagString("path",this->mcPaths[i]);
  if(!this->mcNames[i].IsNull() && (this->mcNames[i] != this->mcPaths[i])){
    tags->setTagString("name",mcNames[i]);
  }
  TQSampleFolder* sf = this->fReader->getSampleFolder();
  TQSampleFolder * processSampleFolder = sf->getSampleFolder(this->mcPaths[i]);
  TString processTitle = "";
  if (processSampleFolder)
  //@tag:[processTitleKey] This object tag determines the name of the process tag used to retrieve the process title from. Default: "style.default.title".
    processSampleFolder->getTagString(this->getTagStringDefault("processTitleKey","style.default.title"), processTitle);
  if(!processTitle.IsNull()){
    tags->setTagString("title",mcNames[i]);
  }
  if(this->cutInfoFolder && sf && (this->cutInfoFolder->getRoot() == sf->getRoot())){
    tags->setTagString("info",this->cutInfoFolder->getPath());
  }
  return tags;
}

int TQNFCalculator::writeResultsToStream(std::ostream* out){
  // dump the results of the NF calculation to an output stream
  if(!this->success()) return -1;
  TQTaggable* tags;
  for(size_t i=0; i<mcNames.size(); i++){
    tags = this->getResultsAsTags(i);
    if (!tags) continue;
    *out << tags->exportTagsAsString() << std::endl;
    delete tags;
  }
  return 1;
}
 

bool TQNFCalculator::readConfiguration(TQFolder* f){
  // read a configuration from a TQFolder instance
  // the following tags are interpreted:
  // verbosity: integer, increasing value increases verbosity
  // epsilon: double, the 'epsilon'-value for the calculation
  // defaultDataPath: string, the default data path
  // methods: list, methods to be used in order of priority
  // all tags are copied to the calculator
  // 
  // a subfolder 'samples' is expected
  // each folder in 'samples/?' is interpreted as one sample group
  // the following parameters are accepted and interpreted
  // name: string, the name of this group
  // path: string, the path of this group
  // fixed: bool, true for fixed samples, false for floating ones
  // upper: upper bound for this NF (recommended, but not required)
  // lower: lower bound for this NF (recommended, but not required)
  //
  // a subfolder 'regions' is expected
  // each folder in 'regions/?' is interpreted as one sample group
  // the following parameters are accepted and interpreted
  // name: string, the name of this region (name of the counter)
  // datapath: string, the data path to be used for this region
  // if not set, the defaultDataPath will be used
  // active: bool. if false, this region is ignored. default is true.
  // 
  // this function returns true if at least one region and at least one floating
  // sample group have been found and added successfully.
  if(!f) return false;
  this->SetName(f->GetName());
  //@tag:[defaultDataPath] This argument tag sets the default TQFolder path for data (can be overwritten for each region, see tag "datapath").
  this->setDefaultDataPath(f->getTagStringDefault("defaultDataPath","data"));
  //@tag:[epsilon] This argument tag sets the maximum allowed margin inevitable for some numerical methods.
  this->setEpsilon(f->getTagDoubleDefault("epsilon",std::numeric_limits<double>::epsilon()));
  //@tag:[verbosity] This object tag sets the objects verbosity. Imported from argument in TQNFTop1jetEstimator::readConfiguration unless already present. Default: 5 .
  this->setVerbosity(f->getTagIntegerDefault("verbosity",5));
  //@tag:[methods] This argument tag determines the method (and their order) used by the TQNFCalculator. The result is the one by the first successful method.
  std::vector<TString> methodStrings = f->getTagVString("methods");
  for(size_t i=0; i<methodStrings.size(); i++){
    this->addMethod(methodStrings[i]);
  }

  this->importTags(f);

  TQFolderIterator sitr(f->getListOfFolders("samples/?"),true);
  int nSamples = 0;
  while(sitr.hasNext()){
    TQFolder* sample = sitr.readNext();
    if(!sample) continue;
    //@tag:[name] This sub-folder("samples/?") argument tag sets the name of the sample. Defaults to the name of the folder it is read from.
    TString name = sample->getTagStringDefault("name",sample->getName());
    //@tag:[path] This sub-folder("samples/?") argument tag sets the path of the sample. Defaults to the value of the "name" tag.
    TString path = sample->getTagStringDefault("path",name);
    //@tag:[fixed] If this sub-folder("samples/?") argument tag is set to true the sample is left unscaled. Instead it is subtracted from data for the calculation.
    bool fixed = sample->getTagBoolDefault("fixed",false);
    //@tag:[lower,upper] These sub-folder("samples/?") argument tags set the lowest/highest allowed value for the NF corresponding to the sample. Defaults: 0., 2. .
    double boundLower = sample->getTagDoubleDefault("lower",this->getTagDoubleDefault("defaultBoundLower",0.));
    double boundUpper = sample->getTagDoubleDefault("upper",this->getTagDoubleDefault("defaultBoundUpper",2.));
    nSamples += !fixed;
    if(fixed) this->addFixSample(path,name);
    else this->addSample(path,name,boundLower,boundUpper);
  }
  if(nSamples < 1) return false;
 
  int nRegions = 0;
  TQFolderIterator ritr(f->getListOfFolders("regions/?"),true);
  while(ritr.hasNext()){
    TQFolder* region = ritr.readNext();
    if(!region) continue;
    //@tag:[name] This sub-folder("regions/?") argument tag sets the name of the (control) region. Defaults to the name of the respective folder it is read from.
    TString name = region->getTagStringDefault("name",region->getName());
    //@tag:[datapath] This sub-folder("regions/?") argument tag determines the TQFolder path where data for this region should be retrieved from. Default: "".
    TString mydatapath = region->getTagStringDefault("datapath","");
    //@tag:[active] This sub-folder("regions/?") argument tag allows to disable a region by setting the tag to false. Default: true.
    bool active = region->getTagBoolDefault("active",true);
    if(active){
      this->addRegion(name,mydatapath);
      nRegions++;
    }
  }
  if(nRegions < 1) return false;

  return true;
}

TH1* TQNFCalculator::getMCHistogram(const TString& name){
  // retrieve the histogram 
  // corresponding to the sample
  // with the given name
  if(!this->initialize()) return NULL;
  for(size_t i=0; i<this->mcPaths.size(); i++){
    if(mcNames[i] == name)
      return dynamic_cast<TH1*>(mc->At(i));
  }
  return NULL;
} 

TQSampleFolder* TQNFCalculator::exportHistograms(bool postFit){
  // export the histograms to a new sample folder
  if(!this->initialize()) return NULL;
  TQSampleFolder* folder = TQSampleFolder::newSampleFolder(this->GetName());
  if(!this->exportHistogramsToSampleFolder(folder,postFit)){
    delete folder;
    return NULL;
  }
  return folder;
}

bool TQNFCalculator::exportHistogramsToFile(const TString& destination, bool recreate, bool postFit){
  // export the histograms to some root file
  // the 'recreate' flag controls if the file is opened in APPEND or RECREATE mode
  // if postfit=true, the post-fit histograms are saved (if possible)
  // if the calculation has not yet been performed or has failed, the pre-fit ones are saved instead
  TQSampleFolder* folder = this->exportHistograms(postFit);
  if(!folder) return false;
  if(!TQUtils::ensureDirectoryForFile(destination)){
    ERRORclass("unable to access or create directory for file '%s'",destination.Data());
    return false;
  }
  if(!folder->writeToFile(destination,recreate)){
    ERRORclass("unable to write folder '%s' to file '%s'",folder->GetName(),destination.Data());
    delete folder;
    return false;
  }
  delete folder;
  return true;
}

bool TQNFCalculator::exportHistogramsToSampleFolder(TQSampleFolder* folder, bool postFit){
  // export the histograms to an existing sample folder
  // if postfit=true, the post-fit histograms are saved (if possible)
  // if the calculation has not yet been performed or has failed, the pre-fit ones are saved instead
  if(!this->initialize() || !folder) return false;
  TQFolder* plotconf = folder->getFolder("scheme+");
  TQSampleFolder* s = folder->getSampleFolder("data+");
  TList* sources = this->fReader->getListOfSampleFolders(defaultDataPath);
  if(sources && sources->GetEntries() > 0){
    TQFolder* source = dynamic_cast<TQFolder*>(sources->First());
    source->exportTags(s,"","style.*",true);
  }
  delete sources;
  TQFolder* f = s->getFolder(".histograms+");
  TH1* hist = dynamic_cast<TH1*>(this->data->Clone());
  if(!hist) return false;
  hist->SetName(this->GetName());
  f->addObject(hist);
  plotconf->setTagString(".processes.0..path","data");
  plotconf->setTagString(".processes.0..name","data");
  plotconf->setTagBool(".processes.0..isData",true);
  for(size_t i=0; i<this->mcPaths.size(); i++){
    TString processTag = TString::Format(".processes.%d.",(int)i+1);
    TQSampleFolder* s = folder->getSampleFolder(mcNames[i]+"+");
    TList* sources = this->fReader->getListOfSampleFolders(mcPaths[i]);
    plotconf->setTagString(processTag+".path",mcNames[i]);
    plotconf->setTagString(processTag+".name",mcNames[i]);
    plotconf->setTagBool(processTag+".isBackground",true);
    plotconf->setTagBool(processTag+".isFixed",mcFixed[i]);
    if(sources && sources->GetEntries() > 0){
      TQFolder* source = dynamic_cast<TQFolder*>(sources->First());
      source->exportTags(s,"","style.*",true);
    }
    delete sources;
    TQFolder* f = s->getFolder(".histograms+");
    TH1* hist = dynamic_cast<TH1*>(mc->At(i)->Clone());
    if(this->success() && postFit) hist->Scale(this->NFs[i]);
    hist->SetName(this->GetName());
    f->addObject(hist);
  }
  return true;
}


bool TQNFCalculator::addMethod(const TString& methodName){
  // add a method at the back of the queue
  Method method = this->getMethod(methodName);
  if(method != UNDEFINED){
    this->methods.push_back(method);
    return true;
  }
  return false;
}
void TQNFCalculator::clearMethods(){
  // empty the method queue
  this->methods.clear();
}
void TQNFCalculator::printMethods(){
  // print all currently scheduled methods in order of priority
  for(size_t i=0; i<this->methods.size(); i++){
    std::cout << i+1 << ") " << this->getMethodName(methods[i]);
  }
}
 
 TQNFCalculator.cxx:1
 TQNFCalculator.cxx:2
 TQNFCalculator.cxx:3
 TQNFCalculator.cxx:4
 TQNFCalculator.cxx:5
 TQNFCalculator.cxx:6
 TQNFCalculator.cxx:7
 TQNFCalculator.cxx:8
 TQNFCalculator.cxx:9
 TQNFCalculator.cxx:10
 TQNFCalculator.cxx:11
 TQNFCalculator.cxx:12
 TQNFCalculator.cxx:13
 TQNFCalculator.cxx:14
 TQNFCalculator.cxx:15
 TQNFCalculator.cxx:16
 TQNFCalculator.cxx:17
 TQNFCalculator.cxx:18
 TQNFCalculator.cxx:19
 TQNFCalculator.cxx:20
 TQNFCalculator.cxx:21
 TQNFCalculator.cxx:22
 TQNFCalculator.cxx:23
 TQNFCalculator.cxx:24
 TQNFCalculator.cxx:25
 TQNFCalculator.cxx:26
 TQNFCalculator.cxx:27
 TQNFCalculator.cxx:28
 TQNFCalculator.cxx:29
 TQNFCalculator.cxx:30
 TQNFCalculator.cxx:31
 TQNFCalculator.cxx:32
 TQNFCalculator.cxx:33
 TQNFCalculator.cxx:34
 TQNFCalculator.cxx:35
 TQNFCalculator.cxx:36
 TQNFCalculator.cxx:37
 TQNFCalculator.cxx:38
 TQNFCalculator.cxx:39
 TQNFCalculator.cxx:40
 TQNFCalculator.cxx:41
 TQNFCalculator.cxx:42
 TQNFCalculator.cxx:43
 TQNFCalculator.cxx:44
 TQNFCalculator.cxx:45
 TQNFCalculator.cxx:46
 TQNFCalculator.cxx:47
 TQNFCalculator.cxx:48
 TQNFCalculator.cxx:49
 TQNFCalculator.cxx:50
 TQNFCalculator.cxx:51
 TQNFCalculator.cxx:52
 TQNFCalculator.cxx:53
 TQNFCalculator.cxx:54
 TQNFCalculator.cxx:55
 TQNFCalculator.cxx:56
 TQNFCalculator.cxx:57
 TQNFCalculator.cxx:58
 TQNFCalculator.cxx:59
 TQNFCalculator.cxx:60
 TQNFCalculator.cxx:61
 TQNFCalculator.cxx:62
 TQNFCalculator.cxx:63
 TQNFCalculator.cxx:64
 TQNFCalculator.cxx:65
 TQNFCalculator.cxx:66
 TQNFCalculator.cxx:67
 TQNFCalculator.cxx:68
 TQNFCalculator.cxx:69
 TQNFCalculator.cxx:70
 TQNFCalculator.cxx:71
 TQNFCalculator.cxx:72
 TQNFCalculator.cxx:73
 TQNFCalculator.cxx:74
 TQNFCalculator.cxx:75
 TQNFCalculator.cxx:76
 TQNFCalculator.cxx:77
 TQNFCalculator.cxx:78
 TQNFCalculator.cxx:79
 TQNFCalculator.cxx:80
 TQNFCalculator.cxx:81
 TQNFCalculator.cxx:82
 TQNFCalculator.cxx:83
 TQNFCalculator.cxx:84
 TQNFCalculator.cxx:85
 TQNFCalculator.cxx:86
 TQNFCalculator.cxx:87
 TQNFCalculator.cxx:88
 TQNFCalculator.cxx:89
 TQNFCalculator.cxx:90
 TQNFCalculator.cxx:91
 TQNFCalculator.cxx:92
 TQNFCalculator.cxx:93
 TQNFCalculator.cxx:94
 TQNFCalculator.cxx:95
 TQNFCalculator.cxx:96
 TQNFCalculator.cxx:97
 TQNFCalculator.cxx:98
 TQNFCalculator.cxx:99
 TQNFCalculator.cxx:100
 TQNFCalculator.cxx:101
 TQNFCalculator.cxx:102
 TQNFCalculator.cxx:103
 TQNFCalculator.cxx:104
 TQNFCalculator.cxx:105
 TQNFCalculator.cxx:106
 TQNFCalculator.cxx:107
 TQNFCalculator.cxx:108
 TQNFCalculator.cxx:109
 TQNFCalculator.cxx:110
 TQNFCalculator.cxx:111
 TQNFCalculator.cxx:112
 TQNFCalculator.cxx:113
 TQNFCalculator.cxx:114
 TQNFCalculator.cxx:115
 TQNFCalculator.cxx:116
 TQNFCalculator.cxx:117
 TQNFCalculator.cxx:118
 TQNFCalculator.cxx:119
 TQNFCalculator.cxx:120
 TQNFCalculator.cxx:121
 TQNFCalculator.cxx:122
 TQNFCalculator.cxx:123
 TQNFCalculator.cxx:124
 TQNFCalculator.cxx:125
 TQNFCalculator.cxx:126
 TQNFCalculator.cxx:127
 TQNFCalculator.cxx:128
 TQNFCalculator.cxx:129
 TQNFCalculator.cxx:130
 TQNFCalculator.cxx:131
 TQNFCalculator.cxx:132
 TQNFCalculator.cxx:133
 TQNFCalculator.cxx:134
 TQNFCalculator.cxx:135
 TQNFCalculator.cxx:136
 TQNFCalculator.cxx:137
 TQNFCalculator.cxx:138
 TQNFCalculator.cxx:139
 TQNFCalculator.cxx:140
 TQNFCalculator.cxx:141
 TQNFCalculator.cxx:142
 TQNFCalculator.cxx:143
 TQNFCalculator.cxx:144
 TQNFCalculator.cxx:145
 TQNFCalculator.cxx:146
 TQNFCalculator.cxx:147
 TQNFCalculator.cxx:148
 TQNFCalculator.cxx:149
 TQNFCalculator.cxx:150
 TQNFCalculator.cxx:151
 TQNFCalculator.cxx:152
 TQNFCalculator.cxx:153
 TQNFCalculator.cxx:154
 TQNFCalculator.cxx:155
 TQNFCalculator.cxx:156
 TQNFCalculator.cxx:157
 TQNFCalculator.cxx:158
 TQNFCalculator.cxx:159
 TQNFCalculator.cxx:160
 TQNFCalculator.cxx:161
 TQNFCalculator.cxx:162
 TQNFCalculator.cxx:163
 TQNFCalculator.cxx:164
 TQNFCalculator.cxx:165
 TQNFCalculator.cxx:166
 TQNFCalculator.cxx:167
 TQNFCalculator.cxx:168
 TQNFCalculator.cxx:169
 TQNFCalculator.cxx:170
 TQNFCalculator.cxx:171
 TQNFCalculator.cxx:172
 TQNFCalculator.cxx:173
 TQNFCalculator.cxx:174
 TQNFCalculator.cxx:175
 TQNFCalculator.cxx:176
 TQNFCalculator.cxx:177
 TQNFCalculator.cxx:178
 TQNFCalculator.cxx:179
 TQNFCalculator.cxx:180
 TQNFCalculator.cxx:181
 TQNFCalculator.cxx:182
 TQNFCalculator.cxx:183
 TQNFCalculator.cxx:184
 TQNFCalculator.cxx:185
 TQNFCalculator.cxx:186
 TQNFCalculator.cxx:187
 TQNFCalculator.cxx:188
 TQNFCalculator.cxx:189
 TQNFCalculator.cxx:190
 TQNFCalculator.cxx:191
 TQNFCalculator.cxx:192
 TQNFCalculator.cxx:193
 TQNFCalculator.cxx:194
 TQNFCalculator.cxx:195
 TQNFCalculator.cxx:196
 TQNFCalculator.cxx:197
 TQNFCalculator.cxx:198
 TQNFCalculator.cxx:199
 TQNFCalculator.cxx:200
 TQNFCalculator.cxx:201
 TQNFCalculator.cxx:202
 TQNFCalculator.cxx:203
 TQNFCalculator.cxx:204
 TQNFCalculator.cxx:205
 TQNFCalculator.cxx:206
 TQNFCalculator.cxx:207
 TQNFCalculator.cxx:208
 TQNFCalculator.cxx:209
 TQNFCalculator.cxx:210
 TQNFCalculator.cxx:211
 TQNFCalculator.cxx:212
 TQNFCalculator.cxx:213
 TQNFCalculator.cxx:214
 TQNFCalculator.cxx:215
 TQNFCalculator.cxx:216
 TQNFCalculator.cxx:217
 TQNFCalculator.cxx:218
 TQNFCalculator.cxx:219
 TQNFCalculator.cxx:220
 TQNFCalculator.cxx:221
 TQNFCalculator.cxx:222
 TQNFCalculator.cxx:223
 TQNFCalculator.cxx:224
 TQNFCalculator.cxx:225
 TQNFCalculator.cxx:226
 TQNFCalculator.cxx:227
 TQNFCalculator.cxx:228
 TQNFCalculator.cxx:229
 TQNFCalculator.cxx:230
 TQNFCalculator.cxx:231
 TQNFCalculator.cxx:232
 TQNFCalculator.cxx:233
 TQNFCalculator.cxx:234
 TQNFCalculator.cxx:235
 TQNFCalculator.cxx:236
 TQNFCalculator.cxx:237
 TQNFCalculator.cxx:238
 TQNFCalculator.cxx:239
 TQNFCalculator.cxx:240
 TQNFCalculator.cxx:241
 TQNFCalculator.cxx:242
 TQNFCalculator.cxx:243
 TQNFCalculator.cxx:244
 TQNFCalculator.cxx:245
 TQNFCalculator.cxx:246
 TQNFCalculator.cxx:247
 TQNFCalculator.cxx:248
 TQNFCalculator.cxx:249
 TQNFCalculator.cxx:250
 TQNFCalculator.cxx:251
 TQNFCalculator.cxx:252
 TQNFCalculator.cxx:253
 TQNFCalculator.cxx:254
 TQNFCalculator.cxx:255
 TQNFCalculator.cxx:256
 TQNFCalculator.cxx:257
 TQNFCalculator.cxx:258
 TQNFCalculator.cxx:259
 TQNFCalculator.cxx:260
 TQNFCalculator.cxx:261
 TQNFCalculator.cxx:262
 TQNFCalculator.cxx:263
 TQNFCalculator.cxx:264
 TQNFCalculator.cxx:265
 TQNFCalculator.cxx:266
 TQNFCalculator.cxx:267
 TQNFCalculator.cxx:268
 TQNFCalculator.cxx:269
 TQNFCalculator.cxx:270
 TQNFCalculator.cxx:271
 TQNFCalculator.cxx:272
 TQNFCalculator.cxx:273
 TQNFCalculator.cxx:274
 TQNFCalculator.cxx:275
 TQNFCalculator.cxx:276
 TQNFCalculator.cxx:277
 TQNFCalculator.cxx:278
 TQNFCalculator.cxx:279
 TQNFCalculator.cxx:280
 TQNFCalculator.cxx:281
 TQNFCalculator.cxx:282
 TQNFCalculator.cxx:283
 TQNFCalculator.cxx:284
 TQNFCalculator.cxx:285
 TQNFCalculator.cxx:286
 TQNFCalculator.cxx:287
 TQNFCalculator.cxx:288
 TQNFCalculator.cxx:289
 TQNFCalculator.cxx:290
 TQNFCalculator.cxx:291
 TQNFCalculator.cxx:292
 TQNFCalculator.cxx:293
 TQNFCalculator.cxx:294
 TQNFCalculator.cxx:295
 TQNFCalculator.cxx:296
 TQNFCalculator.cxx:297
 TQNFCalculator.cxx:298
 TQNFCalculator.cxx:299
 TQNFCalculator.cxx:300
 TQNFCalculator.cxx:301
 TQNFCalculator.cxx:302
 TQNFCalculator.cxx:303
 TQNFCalculator.cxx:304
 TQNFCalculator.cxx:305
 TQNFCalculator.cxx:306
 TQNFCalculator.cxx:307
 TQNFCalculator.cxx:308
 TQNFCalculator.cxx:309
 TQNFCalculator.cxx:310
 TQNFCalculator.cxx:311
 TQNFCalculator.cxx:312
 TQNFCalculator.cxx:313
 TQNFCalculator.cxx:314
 TQNFCalculator.cxx:315
 TQNFCalculator.cxx:316
 TQNFCalculator.cxx:317
 TQNFCalculator.cxx:318
 TQNFCalculator.cxx:319
 TQNFCalculator.cxx:320
 TQNFCalculator.cxx:321
 TQNFCalculator.cxx:322
 TQNFCalculator.cxx:323
 TQNFCalculator.cxx:324
 TQNFCalculator.cxx:325
 TQNFCalculator.cxx:326
 TQNFCalculator.cxx:327
 TQNFCalculator.cxx:328
 TQNFCalculator.cxx:329
 TQNFCalculator.cxx:330
 TQNFCalculator.cxx:331
 TQNFCalculator.cxx:332
 TQNFCalculator.cxx:333
 TQNFCalculator.cxx:334
 TQNFCalculator.cxx:335
 TQNFCalculator.cxx:336
 TQNFCalculator.cxx:337
 TQNFCalculator.cxx:338
 TQNFCalculator.cxx:339
 TQNFCalculator.cxx:340
 TQNFCalculator.cxx:341
 TQNFCalculator.cxx:342
 TQNFCalculator.cxx:343
 TQNFCalculator.cxx:344
 TQNFCalculator.cxx:345
 TQNFCalculator.cxx:346
 TQNFCalculator.cxx:347
 TQNFCalculator.cxx:348
 TQNFCalculator.cxx:349
 TQNFCalculator.cxx:350
 TQNFCalculator.cxx:351
 TQNFCalculator.cxx:352
 TQNFCalculator.cxx:353
 TQNFCalculator.cxx:354
 TQNFCalculator.cxx:355
 TQNFCalculator.cxx:356
 TQNFCalculator.cxx:357
 TQNFCalculator.cxx:358
 TQNFCalculator.cxx:359
 TQNFCalculator.cxx:360
 TQNFCalculator.cxx:361
 TQNFCalculator.cxx:362
 TQNFCalculator.cxx:363
 TQNFCalculator.cxx:364
 TQNFCalculator.cxx:365
 TQNFCalculator.cxx:366
 TQNFCalculator.cxx:367
 TQNFCalculator.cxx:368
 TQNFCalculator.cxx:369
 TQNFCalculator.cxx:370
 TQNFCalculator.cxx:371
 TQNFCalculator.cxx:372
 TQNFCalculator.cxx:373
 TQNFCalculator.cxx:374
 TQNFCalculator.cxx:375
 TQNFCalculator.cxx:376
 TQNFCalculator.cxx:377
 TQNFCalculator.cxx:378
 TQNFCalculator.cxx:379
 TQNFCalculator.cxx:380
 TQNFCalculator.cxx:381
 TQNFCalculator.cxx:382
 TQNFCalculator.cxx:383
 TQNFCalculator.cxx:384
 TQNFCalculator.cxx:385
 TQNFCalculator.cxx:386
 TQNFCalculator.cxx:387
 TQNFCalculator.cxx:388
 TQNFCalculator.cxx:389
 TQNFCalculator.cxx:390
 TQNFCalculator.cxx:391
 TQNFCalculator.cxx:392
 TQNFCalculator.cxx:393
 TQNFCalculator.cxx:394
 TQNFCalculator.cxx:395
 TQNFCalculator.cxx:396
 TQNFCalculator.cxx:397
 TQNFCalculator.cxx:398
 TQNFCalculator.cxx:399
 TQNFCalculator.cxx:400
 TQNFCalculator.cxx:401
 TQNFCalculator.cxx:402
 TQNFCalculator.cxx:403
 TQNFCalculator.cxx:404
 TQNFCalculator.cxx:405
 TQNFCalculator.cxx:406
 TQNFCalculator.cxx:407
 TQNFCalculator.cxx:408
 TQNFCalculator.cxx:409
 TQNFCalculator.cxx:410
 TQNFCalculator.cxx:411
 TQNFCalculator.cxx:412
 TQNFCalculator.cxx:413
 TQNFCalculator.cxx:414
 TQNFCalculator.cxx:415
 TQNFCalculator.cxx:416
 TQNFCalculator.cxx:417
 TQNFCalculator.cxx:418
 TQNFCalculator.cxx:419
 TQNFCalculator.cxx:420
 TQNFCalculator.cxx:421
 TQNFCalculator.cxx:422
 TQNFCalculator.cxx:423
 TQNFCalculator.cxx:424
 TQNFCalculator.cxx:425
 TQNFCalculator.cxx:426
 TQNFCalculator.cxx:427
 TQNFCalculator.cxx:428
 TQNFCalculator.cxx:429
 TQNFCalculator.cxx:430
 TQNFCalculator.cxx:431
 TQNFCalculator.cxx:432
 TQNFCalculator.cxx:433
 TQNFCalculator.cxx:434
 TQNFCalculator.cxx:435
 TQNFCalculator.cxx:436
 TQNFCalculator.cxx:437
 TQNFCalculator.cxx:438
 TQNFCalculator.cxx:439
 TQNFCalculator.cxx:440
 TQNFCalculator.cxx:441
 TQNFCalculator.cxx:442
 TQNFCalculator.cxx:443
 TQNFCalculator.cxx:444
 TQNFCalculator.cxx:445
 TQNFCalculator.cxx:446
 TQNFCalculator.cxx:447
 TQNFCalculator.cxx:448
 TQNFCalculator.cxx:449
 TQNFCalculator.cxx:450
 TQNFCalculator.cxx:451
 TQNFCalculator.cxx:452
 TQNFCalculator.cxx:453
 TQNFCalculator.cxx:454
 TQNFCalculator.cxx:455
 TQNFCalculator.cxx:456
 TQNFCalculator.cxx:457
 TQNFCalculator.cxx:458
 TQNFCalculator.cxx:459
 TQNFCalculator.cxx:460
 TQNFCalculator.cxx:461
 TQNFCalculator.cxx:462
 TQNFCalculator.cxx:463
 TQNFCalculator.cxx:464
 TQNFCalculator.cxx:465
 TQNFCalculator.cxx:466
 TQNFCalculator.cxx:467
 TQNFCalculator.cxx:468
 TQNFCalculator.cxx:469
 TQNFCalculator.cxx:470
 TQNFCalculator.cxx:471
 TQNFCalculator.cxx:472
 TQNFCalculator.cxx:473
 TQNFCalculator.cxx:474
 TQNFCalculator.cxx:475
 TQNFCalculator.cxx:476
 TQNFCalculator.cxx:477
 TQNFCalculator.cxx:478
 TQNFCalculator.cxx:479
 TQNFCalculator.cxx:480
 TQNFCalculator.cxx:481
 TQNFCalculator.cxx:482
 TQNFCalculator.cxx:483
 TQNFCalculator.cxx:484
 TQNFCalculator.cxx:485
 TQNFCalculator.cxx:486
 TQNFCalculator.cxx:487
 TQNFCalculator.cxx:488
 TQNFCalculator.cxx:489
 TQNFCalculator.cxx:490
 TQNFCalculator.cxx:491
 TQNFCalculator.cxx:492
 TQNFCalculator.cxx:493
 TQNFCalculator.cxx:494
 TQNFCalculator.cxx:495
 TQNFCalculator.cxx:496
 TQNFCalculator.cxx:497
 TQNFCalculator.cxx:498
 TQNFCalculator.cxx:499
 TQNFCalculator.cxx:500
 TQNFCalculator.cxx:501
 TQNFCalculator.cxx:502
 TQNFCalculator.cxx:503
 TQNFCalculator.cxx:504
 TQNFCalculator.cxx:505
 TQNFCalculator.cxx:506
 TQNFCalculator.cxx:507
 TQNFCalculator.cxx:508
 TQNFCalculator.cxx:509
 TQNFCalculator.cxx:510
 TQNFCalculator.cxx:511
 TQNFCalculator.cxx:512
 TQNFCalculator.cxx:513
 TQNFCalculator.cxx:514
 TQNFCalculator.cxx:515
 TQNFCalculator.cxx:516
 TQNFCalculator.cxx:517
 TQNFCalculator.cxx:518
 TQNFCalculator.cxx:519
 TQNFCalculator.cxx:520
 TQNFCalculator.cxx:521
 TQNFCalculator.cxx:522
 TQNFCalculator.cxx:523
 TQNFCalculator.cxx:524
 TQNFCalculator.cxx:525
 TQNFCalculator.cxx:526
 TQNFCalculator.cxx:527
 TQNFCalculator.cxx:528
 TQNFCalculator.cxx:529
 TQNFCalculator.cxx:530
 TQNFCalculator.cxx:531
 TQNFCalculator.cxx:532
 TQNFCalculator.cxx:533
 TQNFCalculator.cxx:534
 TQNFCalculator.cxx:535
 TQNFCalculator.cxx:536
 TQNFCalculator.cxx:537
 TQNFCalculator.cxx:538
 TQNFCalculator.cxx:539
 TQNFCalculator.cxx:540
 TQNFCalculator.cxx:541
 TQNFCalculator.cxx:542
 TQNFCalculator.cxx:543
 TQNFCalculator.cxx:544
 TQNFCalculator.cxx:545
 TQNFCalculator.cxx:546
 TQNFCalculator.cxx:547
 TQNFCalculator.cxx:548
 TQNFCalculator.cxx:549
 TQNFCalculator.cxx:550
 TQNFCalculator.cxx:551
 TQNFCalculator.cxx:552
 TQNFCalculator.cxx:553
 TQNFCalculator.cxx:554
 TQNFCalculator.cxx:555
 TQNFCalculator.cxx:556
 TQNFCalculator.cxx:557
 TQNFCalculator.cxx:558
 TQNFCalculator.cxx:559
 TQNFCalculator.cxx:560
 TQNFCalculator.cxx:561
 TQNFCalculator.cxx:562
 TQNFCalculator.cxx:563
 TQNFCalculator.cxx:564
 TQNFCalculator.cxx:565
 TQNFCalculator.cxx:566
 TQNFCalculator.cxx:567
 TQNFCalculator.cxx:568
 TQNFCalculator.cxx:569
 TQNFCalculator.cxx:570
 TQNFCalculator.cxx:571
 TQNFCalculator.cxx:572
 TQNFCalculator.cxx:573
 TQNFCalculator.cxx:574
 TQNFCalculator.cxx:575
 TQNFCalculator.cxx:576
 TQNFCalculator.cxx:577
 TQNFCalculator.cxx:578
 TQNFCalculator.cxx:579
 TQNFCalculator.cxx:580
 TQNFCalculator.cxx:581
 TQNFCalculator.cxx:582
 TQNFCalculator.cxx:583
 TQNFCalculator.cxx:584
 TQNFCalculator.cxx:585
 TQNFCalculator.cxx:586
 TQNFCalculator.cxx:587
 TQNFCalculator.cxx:588
 TQNFCalculator.cxx:589
 TQNFCalculator.cxx:590
 TQNFCalculator.cxx:591
 TQNFCalculator.cxx:592
 TQNFCalculator.cxx:593
 TQNFCalculator.cxx:594
 TQNFCalculator.cxx:595
 TQNFCalculator.cxx:596
 TQNFCalculator.cxx:597
 TQNFCalculator.cxx:598
 TQNFCalculator.cxx:599
 TQNFCalculator.cxx:600
 TQNFCalculator.cxx:601
 TQNFCalculator.cxx:602
 TQNFCalculator.cxx:603
 TQNFCalculator.cxx:604
 TQNFCalculator.cxx:605
 TQNFCalculator.cxx:606
 TQNFCalculator.cxx:607
 TQNFCalculator.cxx:608
 TQNFCalculator.cxx:609
 TQNFCalculator.cxx:610
 TQNFCalculator.cxx:611
 TQNFCalculator.cxx:612
 TQNFCalculator.cxx:613
 TQNFCalculator.cxx:614
 TQNFCalculator.cxx:615
 TQNFCalculator.cxx:616
 TQNFCalculator.cxx:617
 TQNFCalculator.cxx:618
 TQNFCalculator.cxx:619
 TQNFCalculator.cxx:620
 TQNFCalculator.cxx:621
 TQNFCalculator.cxx:622
 TQNFCalculator.cxx:623
 TQNFCalculator.cxx:624
 TQNFCalculator.cxx:625
 TQNFCalculator.cxx:626
 TQNFCalculator.cxx:627
 TQNFCalculator.cxx:628
 TQNFCalculator.cxx:629
 TQNFCalculator.cxx:630
 TQNFCalculator.cxx:631
 TQNFCalculator.cxx:632
 TQNFCalculator.cxx:633
 TQNFCalculator.cxx:634
 TQNFCalculator.cxx:635
 TQNFCalculator.cxx:636
 TQNFCalculator.cxx:637
 TQNFCalculator.cxx:638
 TQNFCalculator.cxx:639
 TQNFCalculator.cxx:640
 TQNFCalculator.cxx:641
 TQNFCalculator.cxx:642
 TQNFCalculator.cxx:643
 TQNFCalculator.cxx:644
 TQNFCalculator.cxx:645
 TQNFCalculator.cxx:646
 TQNFCalculator.cxx:647
 TQNFCalculator.cxx:648
 TQNFCalculator.cxx:649
 TQNFCalculator.cxx:650
 TQNFCalculator.cxx:651
 TQNFCalculator.cxx:652
 TQNFCalculator.cxx:653
 TQNFCalculator.cxx:654
 TQNFCalculator.cxx:655
 TQNFCalculator.cxx:656
 TQNFCalculator.cxx:657
 TQNFCalculator.cxx:658
 TQNFCalculator.cxx:659
 TQNFCalculator.cxx:660
 TQNFCalculator.cxx:661
 TQNFCalculator.cxx:662
 TQNFCalculator.cxx:663
 TQNFCalculator.cxx:664
 TQNFCalculator.cxx:665
 TQNFCalculator.cxx:666
 TQNFCalculator.cxx:667
 TQNFCalculator.cxx:668
 TQNFCalculator.cxx:669
 TQNFCalculator.cxx:670
 TQNFCalculator.cxx:671
 TQNFCalculator.cxx:672
 TQNFCalculator.cxx:673
 TQNFCalculator.cxx:674
 TQNFCalculator.cxx:675
 TQNFCalculator.cxx:676
 TQNFCalculator.cxx:677
 TQNFCalculator.cxx:678
 TQNFCalculator.cxx:679
 TQNFCalculator.cxx:680
 TQNFCalculator.cxx:681
 TQNFCalculator.cxx:682
 TQNFCalculator.cxx:683
 TQNFCalculator.cxx:684
 TQNFCalculator.cxx:685
 TQNFCalculator.cxx:686
 TQNFCalculator.cxx:687
 TQNFCalculator.cxx:688
 TQNFCalculator.cxx:689
 TQNFCalculator.cxx:690
 TQNFCalculator.cxx:691
 TQNFCalculator.cxx:692
 TQNFCalculator.cxx:693
 TQNFCalculator.cxx:694
 TQNFCalculator.cxx:695
 TQNFCalculator.cxx:696
 TQNFCalculator.cxx:697
 TQNFCalculator.cxx:698
 TQNFCalculator.cxx:699
 TQNFCalculator.cxx:700
 TQNFCalculator.cxx:701
 TQNFCalculator.cxx:702
 TQNFCalculator.cxx:703
 TQNFCalculator.cxx:704
 TQNFCalculator.cxx:705
 TQNFCalculator.cxx:706
 TQNFCalculator.cxx:707
 TQNFCalculator.cxx:708
 TQNFCalculator.cxx:709
 TQNFCalculator.cxx:710
 TQNFCalculator.cxx:711
 TQNFCalculator.cxx:712
 TQNFCalculator.cxx:713
 TQNFCalculator.cxx:714
 TQNFCalculator.cxx:715
 TQNFCalculator.cxx:716
 TQNFCalculator.cxx:717
 TQNFCalculator.cxx:718
 TQNFCalculator.cxx:719
 TQNFCalculator.cxx:720
 TQNFCalculator.cxx:721
 TQNFCalculator.cxx:722
 TQNFCalculator.cxx:723
 TQNFCalculator.cxx:724
 TQNFCalculator.cxx:725
 TQNFCalculator.cxx:726
 TQNFCalculator.cxx:727
 TQNFCalculator.cxx:728
 TQNFCalculator.cxx:729
 TQNFCalculator.cxx:730
 TQNFCalculator.cxx:731
 TQNFCalculator.cxx:732
 TQNFCalculator.cxx:733
 TQNFCalculator.cxx:734
 TQNFCalculator.cxx:735
 TQNFCalculator.cxx:736
 TQNFCalculator.cxx:737
 TQNFCalculator.cxx:738
 TQNFCalculator.cxx:739
 TQNFCalculator.cxx:740
 TQNFCalculator.cxx:741
 TQNFCalculator.cxx:742
 TQNFCalculator.cxx:743
 TQNFCalculator.cxx:744
 TQNFCalculator.cxx:745
 TQNFCalculator.cxx:746
 TQNFCalculator.cxx:747
 TQNFCalculator.cxx:748
 TQNFCalculator.cxx:749
 TQNFCalculator.cxx:750
 TQNFCalculator.cxx:751
 TQNFCalculator.cxx:752
 TQNFCalculator.cxx:753
 TQNFCalculator.cxx:754
 TQNFCalculator.cxx:755
 TQNFCalculator.cxx:756
 TQNFCalculator.cxx:757
 TQNFCalculator.cxx:758
 TQNFCalculator.cxx:759
 TQNFCalculator.cxx:760
 TQNFCalculator.cxx:761
 TQNFCalculator.cxx:762
 TQNFCalculator.cxx:763
 TQNFCalculator.cxx:764
 TQNFCalculator.cxx:765
 TQNFCalculator.cxx:766
 TQNFCalculator.cxx:767
 TQNFCalculator.cxx:768
 TQNFCalculator.cxx:769
 TQNFCalculator.cxx:770
 TQNFCalculator.cxx:771
 TQNFCalculator.cxx:772
 TQNFCalculator.cxx:773
 TQNFCalculator.cxx:774
 TQNFCalculator.cxx:775
 TQNFCalculator.cxx:776
 TQNFCalculator.cxx:777
 TQNFCalculator.cxx:778
 TQNFCalculator.cxx:779
 TQNFCalculator.cxx:780
 TQNFCalculator.cxx:781
 TQNFCalculator.cxx:782
 TQNFCalculator.cxx:783
 TQNFCalculator.cxx:784
 TQNFCalculator.cxx:785
 TQNFCalculator.cxx:786
 TQNFCalculator.cxx:787
 TQNFCalculator.cxx:788
 TQNFCalculator.cxx:789
 TQNFCalculator.cxx:790
 TQNFCalculator.cxx:791
 TQNFCalculator.cxx:792
 TQNFCalculator.cxx:793
 TQNFCalculator.cxx:794
 TQNFCalculator.cxx:795
 TQNFCalculator.cxx:796
 TQNFCalculator.cxx:797
 TQNFCalculator.cxx:798
 TQNFCalculator.cxx:799
 TQNFCalculator.cxx:800
 TQNFCalculator.cxx:801
 TQNFCalculator.cxx:802
 TQNFCalculator.cxx:803
 TQNFCalculator.cxx:804
 TQNFCalculator.cxx:805
 TQNFCalculator.cxx:806
 TQNFCalculator.cxx:807
 TQNFCalculator.cxx:808
 TQNFCalculator.cxx:809
 TQNFCalculator.cxx:810
 TQNFCalculator.cxx:811
 TQNFCalculator.cxx:812
 TQNFCalculator.cxx:813
 TQNFCalculator.cxx:814
 TQNFCalculator.cxx:815
 TQNFCalculator.cxx:816
 TQNFCalculator.cxx:817
 TQNFCalculator.cxx:818
 TQNFCalculator.cxx:819
 TQNFCalculator.cxx:820
 TQNFCalculator.cxx:821
 TQNFCalculator.cxx:822
 TQNFCalculator.cxx:823
 TQNFCalculator.cxx:824
 TQNFCalculator.cxx:825
 TQNFCalculator.cxx:826
 TQNFCalculator.cxx:827
 TQNFCalculator.cxx:828
 TQNFCalculator.cxx:829
 TQNFCalculator.cxx:830
 TQNFCalculator.cxx:831
 TQNFCalculator.cxx:832
 TQNFCalculator.cxx:833
 TQNFCalculator.cxx:834
 TQNFCalculator.cxx:835
 TQNFCalculator.cxx:836
 TQNFCalculator.cxx:837
 TQNFCalculator.cxx:838
 TQNFCalculator.cxx:839
 TQNFCalculator.cxx:840
 TQNFCalculator.cxx:841
 TQNFCalculator.cxx:842
 TQNFCalculator.cxx:843
 TQNFCalculator.cxx:844
 TQNFCalculator.cxx:845
 TQNFCalculator.cxx:846
 TQNFCalculator.cxx:847
 TQNFCalculator.cxx:848
 TQNFCalculator.cxx:849
 TQNFCalculator.cxx:850
 TQNFCalculator.cxx:851
 TQNFCalculator.cxx:852
 TQNFCalculator.cxx:853
 TQNFCalculator.cxx:854
 TQNFCalculator.cxx:855
 TQNFCalculator.cxx:856
 TQNFCalculator.cxx:857
 TQNFCalculator.cxx:858
 TQNFCalculator.cxx:859
 TQNFCalculator.cxx:860
 TQNFCalculator.cxx:861
 TQNFCalculator.cxx:862
 TQNFCalculator.cxx:863
 TQNFCalculator.cxx:864
 TQNFCalculator.cxx:865
 TQNFCalculator.cxx:866
 TQNFCalculator.cxx:867
 TQNFCalculator.cxx:868
 TQNFCalculator.cxx:869
 TQNFCalculator.cxx:870
 TQNFCalculator.cxx:871
 TQNFCalculator.cxx:872
 TQNFCalculator.cxx:873
 TQNFCalculator.cxx:874
 TQNFCalculator.cxx:875
 TQNFCalculator.cxx:876
 TQNFCalculator.cxx:877
 TQNFCalculator.cxx:878
 TQNFCalculator.cxx:879
 TQNFCalculator.cxx:880
 TQNFCalculator.cxx:881
 TQNFCalculator.cxx:882
 TQNFCalculator.cxx:883
 TQNFCalculator.cxx:884
 TQNFCalculator.cxx:885
 TQNFCalculator.cxx:886
 TQNFCalculator.cxx:887
 TQNFCalculator.cxx:888
 TQNFCalculator.cxx:889
 TQNFCalculator.cxx:890
 TQNFCalculator.cxx:891
 TQNFCalculator.cxx:892
 TQNFCalculator.cxx:893
 TQNFCalculator.cxx:894
 TQNFCalculator.cxx:895
 TQNFCalculator.cxx:896
 TQNFCalculator.cxx:897
 TQNFCalculator.cxx:898
 TQNFCalculator.cxx:899
 TQNFCalculator.cxx:900
 TQNFCalculator.cxx:901
 TQNFCalculator.cxx:902
 TQNFCalculator.cxx:903
 TQNFCalculator.cxx:904
 TQNFCalculator.cxx:905
 TQNFCalculator.cxx:906
 TQNFCalculator.cxx:907
 TQNFCalculator.cxx:908
 TQNFCalculator.cxx:909
 TQNFCalculator.cxx:910
 TQNFCalculator.cxx:911
 TQNFCalculator.cxx:912
 TQNFCalculator.cxx:913
 TQNFCalculator.cxx:914
 TQNFCalculator.cxx:915
 TQNFCalculator.cxx:916
 TQNFCalculator.cxx:917
 TQNFCalculator.cxx:918
 TQNFCalculator.cxx:919
 TQNFCalculator.cxx:920
 TQNFCalculator.cxx:921
 TQNFCalculator.cxx:922
 TQNFCalculator.cxx:923
 TQNFCalculator.cxx:924
 TQNFCalculator.cxx:925
 TQNFCalculator.cxx:926
 TQNFCalculator.cxx:927
 TQNFCalculator.cxx:928
 TQNFCalculator.cxx:929
 TQNFCalculator.cxx:930
 TQNFCalculator.cxx:931
 TQNFCalculator.cxx:932
 TQNFCalculator.cxx:933
 TQNFCalculator.cxx:934
 TQNFCalculator.cxx:935
 TQNFCalculator.cxx:936
 TQNFCalculator.cxx:937
 TQNFCalculator.cxx:938
 TQNFCalculator.cxx:939
 TQNFCalculator.cxx:940
 TQNFCalculator.cxx:941
 TQNFCalculator.cxx:942
 TQNFCalculator.cxx:943
 TQNFCalculator.cxx:944
 TQNFCalculator.cxx:945
 TQNFCalculator.cxx:946
 TQNFCalculator.cxx:947
 TQNFCalculator.cxx:948
 TQNFCalculator.cxx:949
 TQNFCalculator.cxx:950
 TQNFCalculator.cxx:951
 TQNFCalculator.cxx:952
 TQNFCalculator.cxx:953
 TQNFCalculator.cxx:954
 TQNFCalculator.cxx:955
 TQNFCalculator.cxx:956
 TQNFCalculator.cxx:957
 TQNFCalculator.cxx:958
 TQNFCalculator.cxx:959
 TQNFCalculator.cxx:960
 TQNFCalculator.cxx:961
 TQNFCalculator.cxx:962
 TQNFCalculator.cxx:963
 TQNFCalculator.cxx:964
 TQNFCalculator.cxx:965
 TQNFCalculator.cxx:966
 TQNFCalculator.cxx:967
 TQNFCalculator.cxx:968
 TQNFCalculator.cxx:969
 TQNFCalculator.cxx:970
 TQNFCalculator.cxx:971
 TQNFCalculator.cxx:972
 TQNFCalculator.cxx:973
 TQNFCalculator.cxx:974
 TQNFCalculator.cxx:975
 TQNFCalculator.cxx:976
 TQNFCalculator.cxx:977
 TQNFCalculator.cxx:978
 TQNFCalculator.cxx:979
 TQNFCalculator.cxx:980
 TQNFCalculator.cxx:981
 TQNFCalculator.cxx:982
 TQNFCalculator.cxx:983
 TQNFCalculator.cxx:984
 TQNFCalculator.cxx:985
 TQNFCalculator.cxx:986
 TQNFCalculator.cxx:987
 TQNFCalculator.cxx:988
 TQNFCalculator.cxx:989
 TQNFCalculator.cxx:990
 TQNFCalculator.cxx:991
 TQNFCalculator.cxx:992
 TQNFCalculator.cxx:993
 TQNFCalculator.cxx:994
 TQNFCalculator.cxx:995
 TQNFCalculator.cxx:996
 TQNFCalculator.cxx:997
 TQNFCalculator.cxx:998
 TQNFCalculator.cxx:999
 TQNFCalculator.cxx:1000
 TQNFCalculator.cxx:1001
 TQNFCalculator.cxx:1002
 TQNFCalculator.cxx:1003
 TQNFCalculator.cxx:1004
 TQNFCalculator.cxx:1005
 TQNFCalculator.cxx:1006
 TQNFCalculator.cxx:1007
 TQNFCalculator.cxx:1008
 TQNFCalculator.cxx:1009
 TQNFCalculator.cxx:1010
 TQNFCalculator.cxx:1011
 TQNFCalculator.cxx:1012
 TQNFCalculator.cxx:1013
 TQNFCalculator.cxx:1014
 TQNFCalculator.cxx:1015
 TQNFCalculator.cxx:1016
 TQNFCalculator.cxx:1017
 TQNFCalculator.cxx:1018
 TQNFCalculator.cxx:1019
 TQNFCalculator.cxx:1020
 TQNFCalculator.cxx:1021
 TQNFCalculator.cxx:1022
 TQNFCalculator.cxx:1023
 TQNFCalculator.cxx:1024
 TQNFCalculator.cxx:1025
 TQNFCalculator.cxx:1026
 TQNFCalculator.cxx:1027
 TQNFCalculator.cxx:1028
 TQNFCalculator.cxx:1029
 TQNFCalculator.cxx:1030
 TQNFCalculator.cxx:1031
 TQNFCalculator.cxx:1032
 TQNFCalculator.cxx:1033
 TQNFCalculator.cxx:1034
 TQNFCalculator.cxx:1035
 TQNFCalculator.cxx:1036
 TQNFCalculator.cxx:1037
 TQNFCalculator.cxx:1038
 TQNFCalculator.cxx:1039
 TQNFCalculator.cxx:1040
 TQNFCalculator.cxx:1041
 TQNFCalculator.cxx:1042
 TQNFCalculator.cxx:1043
 TQNFCalculator.cxx:1044
 TQNFCalculator.cxx:1045
 TQNFCalculator.cxx:1046
 TQNFCalculator.cxx:1047
 TQNFCalculator.cxx:1048
 TQNFCalculator.cxx:1049
 TQNFCalculator.cxx:1050
 TQNFCalculator.cxx:1051
 TQNFCalculator.cxx:1052
 TQNFCalculator.cxx:1053
 TQNFCalculator.cxx:1054
 TQNFCalculator.cxx:1055
 TQNFCalculator.cxx:1056
 TQNFCalculator.cxx:1057
 TQNFCalculator.cxx:1058
 TQNFCalculator.cxx:1059
 TQNFCalculator.cxx:1060
 TQNFCalculator.cxx:1061
 TQNFCalculator.cxx:1062
 TQNFCalculator.cxx:1063
 TQNFCalculator.cxx:1064
 TQNFCalculator.cxx:1065
 TQNFCalculator.cxx:1066
 TQNFCalculator.cxx:1067
 TQNFCalculator.cxx:1068
 TQNFCalculator.cxx:1069
 TQNFCalculator.cxx:1070
 TQNFCalculator.cxx:1071
 TQNFCalculator.cxx:1072
 TQNFCalculator.cxx:1073
 TQNFCalculator.cxx:1074
 TQNFCalculator.cxx:1075
 TQNFCalculator.cxx:1076
 TQNFCalculator.cxx:1077
 TQNFCalculator.cxx:1078
 TQNFCalculator.cxx:1079
 TQNFCalculator.cxx:1080
 TQNFCalculator.cxx:1081
 TQNFCalculator.cxx:1082
 TQNFCalculator.cxx:1083
 TQNFCalculator.cxx:1084
 TQNFCalculator.cxx:1085
 TQNFCalculator.cxx:1086
 TQNFCalculator.cxx:1087
 TQNFCalculator.cxx:1088
 TQNFCalculator.cxx:1089
 TQNFCalculator.cxx:1090
 TQNFCalculator.cxx:1091
 TQNFCalculator.cxx:1092
 TQNFCalculator.cxx:1093
 TQNFCalculator.cxx:1094
 TQNFCalculator.cxx:1095
 TQNFCalculator.cxx:1096
 TQNFCalculator.cxx:1097
 TQNFCalculator.cxx:1098
 TQNFCalculator.cxx:1099
 TQNFCalculator.cxx:1100
 TQNFCalculator.cxx:1101
 TQNFCalculator.cxx:1102
 TQNFCalculator.cxx:1103
 TQNFCalculator.cxx:1104
 TQNFCalculator.cxx:1105
 TQNFCalculator.cxx:1106
 TQNFCalculator.cxx:1107
 TQNFCalculator.cxx:1108
 TQNFCalculator.cxx:1109
 TQNFCalculator.cxx:1110
 TQNFCalculator.cxx:1111
 TQNFCalculator.cxx:1112
 TQNFCalculator.cxx:1113
 TQNFCalculator.cxx:1114
 TQNFCalculator.cxx:1115
 TQNFCalculator.cxx:1116
 TQNFCalculator.cxx:1117
 TQNFCalculator.cxx:1118
 TQNFCalculator.cxx:1119
 TQNFCalculator.cxx:1120
 TQNFCalculator.cxx:1121
 TQNFCalculator.cxx:1122
 TQNFCalculator.cxx:1123
 TQNFCalculator.cxx:1124
 TQNFCalculator.cxx:1125
 TQNFCalculator.cxx:1126
 TQNFCalculator.cxx:1127
 TQNFCalculator.cxx:1128
 TQNFCalculator.cxx:1129
 TQNFCalculator.cxx:1130
 TQNFCalculator.cxx:1131
 TQNFCalculator.cxx:1132
 TQNFCalculator.cxx:1133
 TQNFCalculator.cxx:1134
 TQNFCalculator.cxx:1135
 TQNFCalculator.cxx:1136
 TQNFCalculator.cxx:1137
 TQNFCalculator.cxx:1138
 TQNFCalculator.cxx:1139
 TQNFCalculator.cxx:1140
 TQNFCalculator.cxx:1141
 TQNFCalculator.cxx:1142
 TQNFCalculator.cxx:1143
 TQNFCalculator.cxx:1144
 TQNFCalculator.cxx:1145
 TQNFCalculator.cxx:1146
 TQNFCalculator.cxx:1147
 TQNFCalculator.cxx:1148
 TQNFCalculator.cxx:1149
 TQNFCalculator.cxx:1150
 TQNFCalculator.cxx:1151
 TQNFCalculator.cxx:1152
 TQNFCalculator.cxx:1153
 TQNFCalculator.cxx:1154
 TQNFCalculator.cxx:1155
 TQNFCalculator.cxx:1156
 TQNFCalculator.cxx:1157
 TQNFCalculator.cxx:1158
 TQNFCalculator.cxx:1159
 TQNFCalculator.cxx:1160
 TQNFCalculator.cxx:1161
 TQNFCalculator.cxx:1162
 TQNFCalculator.cxx:1163
 TQNFCalculator.cxx:1164
 TQNFCalculator.cxx:1165
 TQNFCalculator.cxx:1166
 TQNFCalculator.cxx:1167
 TQNFCalculator.cxx:1168
 TQNFCalculator.cxx:1169
 TQNFCalculator.cxx:1170
 TQNFCalculator.cxx:1171
 TQNFCalculator.cxx:1172
 TQNFCalculator.cxx:1173
 TQNFCalculator.cxx:1174
 TQNFCalculator.cxx:1175
 TQNFCalculator.cxx:1176
 TQNFCalculator.cxx:1177
 TQNFCalculator.cxx:1178
 TQNFCalculator.cxx:1179
 TQNFCalculator.cxx:1180
 TQNFCalculator.cxx:1181
 TQNFCalculator.cxx:1182
 TQNFCalculator.cxx:1183
 TQNFCalculator.cxx:1184
 TQNFCalculator.cxx:1185
 TQNFCalculator.cxx:1186
 TQNFCalculator.cxx:1187
 TQNFCalculator.cxx:1188
 TQNFCalculator.cxx:1189
 TQNFCalculator.cxx:1190
 TQNFCalculator.cxx:1191
 TQNFCalculator.cxx:1192
 TQNFCalculator.cxx:1193
 TQNFCalculator.cxx:1194
 TQNFCalculator.cxx:1195
 TQNFCalculator.cxx:1196
 TQNFCalculator.cxx:1197
 TQNFCalculator.cxx:1198
 TQNFCalculator.cxx:1199
 TQNFCalculator.cxx:1200
 TQNFCalculator.cxx:1201
 TQNFCalculator.cxx:1202
 TQNFCalculator.cxx:1203
 TQNFCalculator.cxx:1204
 TQNFCalculator.cxx:1205
 TQNFCalculator.cxx:1206
 TQNFCalculator.cxx:1207
 TQNFCalculator.cxx:1208
 TQNFCalculator.cxx:1209
 TQNFCalculator.cxx:1210
 TQNFCalculator.cxx:1211
 TQNFCalculator.cxx:1212
 TQNFCalculator.cxx:1213
 TQNFCalculator.cxx:1214
 TQNFCalculator.cxx:1215
 TQNFCalculator.cxx:1216
 TQNFCalculator.cxx:1217
 TQNFCalculator.cxx:1218
 TQNFCalculator.cxx:1219
 TQNFCalculator.cxx:1220
 TQNFCalculator.cxx:1221
 TQNFCalculator.cxx:1222
 TQNFCalculator.cxx:1223
 TQNFCalculator.cxx:1224
 TQNFCalculator.cxx:1225
 TQNFCalculator.cxx:1226
 TQNFCalculator.cxx:1227
 TQNFCalculator.cxx:1228
 TQNFCalculator.cxx:1229
 TQNFCalculator.cxx:1230
 TQNFCalculator.cxx:1231
 TQNFCalculator.cxx:1232
 TQNFCalculator.cxx:1233
 TQNFCalculator.cxx:1234
 TQNFCalculator.cxx:1235
 TQNFCalculator.cxx:1236
 TQNFCalculator.cxx:1237
 TQNFCalculator.cxx:1238
 TQNFCalculator.cxx:1239
 TQNFCalculator.cxx:1240
 TQNFCalculator.cxx:1241
 TQNFCalculator.cxx:1242
 TQNFCalculator.cxx:1243
 TQNFCalculator.cxx:1244
 TQNFCalculator.cxx:1245
 TQNFCalculator.cxx:1246
 TQNFCalculator.cxx:1247
 TQNFCalculator.cxx:1248
 TQNFCalculator.cxx:1249
 TQNFCalculator.cxx:1250
 TQNFCalculator.cxx:1251
 TQNFCalculator.cxx:1252
 TQNFCalculator.cxx:1253
 TQNFCalculator.cxx:1254
 TQNFCalculator.cxx:1255
 TQNFCalculator.cxx:1256
 TQNFCalculator.cxx:1257
 TQNFCalculator.cxx:1258
 TQNFCalculator.cxx:1259
 TQNFCalculator.cxx:1260
 TQNFCalculator.cxx:1261
 TQNFCalculator.cxx:1262
 TQNFCalculator.cxx:1263
 TQNFCalculator.cxx:1264
 TQNFCalculator.cxx:1265
 TQNFCalculator.cxx:1266
 TQNFCalculator.cxx:1267
 TQNFCalculator.cxx:1268
 TQNFCalculator.cxx:1269
 TQNFCalculator.cxx:1270
 TQNFCalculator.cxx:1271
 TQNFCalculator.cxx:1272
 TQNFCalculator.cxx:1273
 TQNFCalculator.cxx:1274
 TQNFCalculator.cxx:1275
 TQNFCalculator.cxx:1276
 TQNFCalculator.cxx:1277
 TQNFCalculator.cxx:1278
 TQNFCalculator.cxx:1279
 TQNFCalculator.cxx:1280
 TQNFCalculator.cxx:1281
 TQNFCalculator.cxx:1282
 TQNFCalculator.cxx:1283
 TQNFCalculator.cxx:1284
 TQNFCalculator.cxx:1285
 TQNFCalculator.cxx:1286
 TQNFCalculator.cxx:1287
 TQNFCalculator.cxx:1288
 TQNFCalculator.cxx:1289
 TQNFCalculator.cxx:1290
 TQNFCalculator.cxx:1291
 TQNFCalculator.cxx:1292
 TQNFCalculator.cxx:1293
 TQNFCalculator.cxx:1294
 TQNFCalculator.cxx:1295
 TQNFCalculator.cxx:1296
 TQNFCalculator.cxx:1297
 TQNFCalculator.cxx:1298
 TQNFCalculator.cxx:1299
 TQNFCalculator.cxx:1300
 TQNFCalculator.cxx:1301
 TQNFCalculator.cxx:1302
 TQNFCalculator.cxx:1303
 TQNFCalculator.cxx:1304
 TQNFCalculator.cxx:1305
 TQNFCalculator.cxx:1306
 TQNFCalculator.cxx:1307
 TQNFCalculator.cxx:1308
 TQNFCalculator.cxx:1309
 TQNFCalculator.cxx:1310
 TQNFCalculator.cxx:1311
 TQNFCalculator.cxx:1312
 TQNFCalculator.cxx:1313
 TQNFCalculator.cxx:1314
 TQNFCalculator.cxx:1315
 TQNFCalculator.cxx:1316
 TQNFCalculator.cxx:1317
 TQNFCalculator.cxx:1318
 TQNFCalculator.cxx:1319
 TQNFCalculator.cxx:1320
 TQNFCalculator.cxx:1321
 TQNFCalculator.cxx:1322
 TQNFCalculator.cxx:1323
 TQNFCalculator.cxx:1324
 TQNFCalculator.cxx:1325
 TQNFCalculator.cxx:1326
 TQNFCalculator.cxx:1327
 TQNFCalculator.cxx:1328
 TQNFCalculator.cxx:1329
 TQNFCalculator.cxx:1330
 TQNFCalculator.cxx:1331
 TQNFCalculator.cxx:1332
 TQNFCalculator.cxx:1333
 TQNFCalculator.cxx:1334
 TQNFCalculator.cxx:1335
 TQNFCalculator.cxx:1336
 TQNFCalculator.cxx:1337
 TQNFCalculator.cxx:1338
 TQNFCalculator.cxx:1339
 TQNFCalculator.cxx:1340
 TQNFCalculator.cxx:1341
 TQNFCalculator.cxx:1342
 TQNFCalculator.cxx:1343
 TQNFCalculator.cxx:1344
 TQNFCalculator.cxx:1345
 TQNFCalculator.cxx:1346
 TQNFCalculator.cxx:1347
 TQNFCalculator.cxx:1348
 TQNFCalculator.cxx:1349
 TQNFCalculator.cxx:1350
 TQNFCalculator.cxx:1351
 TQNFCalculator.cxx:1352
 TQNFCalculator.cxx:1353
 TQNFCalculator.cxx:1354
 TQNFCalculator.cxx:1355
 TQNFCalculator.cxx:1356
 TQNFCalculator.cxx:1357
 TQNFCalculator.cxx:1358
 TQNFCalculator.cxx:1359
 TQNFCalculator.cxx:1360
 TQNFCalculator.cxx:1361
 TQNFCalculator.cxx:1362
 TQNFCalculator.cxx:1363
 TQNFCalculator.cxx:1364
 TQNFCalculator.cxx:1365
 TQNFCalculator.cxx:1366
 TQNFCalculator.cxx:1367
 TQNFCalculator.cxx:1368
 TQNFCalculator.cxx:1369
 TQNFCalculator.cxx:1370
 TQNFCalculator.cxx:1371
 TQNFCalculator.cxx:1372
 TQNFCalculator.cxx:1373
 TQNFCalculator.cxx:1374
 TQNFCalculator.cxx:1375
 TQNFCalculator.cxx:1376
 TQNFCalculator.cxx:1377
 TQNFCalculator.cxx:1378
 TQNFCalculator.cxx:1379
 TQNFCalculator.cxx:1380
 TQNFCalculator.cxx:1381
 TQNFCalculator.cxx:1382
 TQNFCalculator.cxx:1383
 TQNFCalculator.cxx:1384
 TQNFCalculator.cxx:1385
 TQNFCalculator.cxx:1386
 TQNFCalculator.cxx:1387
 TQNFCalculator.cxx:1388
 TQNFCalculator.cxx:1389
 TQNFCalculator.cxx:1390
 TQNFCalculator.cxx:1391
 TQNFCalculator.cxx:1392
 TQNFCalculator.cxx:1393
 TQNFCalculator.cxx:1394
 TQNFCalculator.cxx:1395
 TQNFCalculator.cxx:1396
 TQNFCalculator.cxx:1397
 TQNFCalculator.cxx:1398
 TQNFCalculator.cxx:1399
 TQNFCalculator.cxx:1400
 TQNFCalculator.cxx:1401
 TQNFCalculator.cxx:1402
 TQNFCalculator.cxx:1403
 TQNFCalculator.cxx:1404
 TQNFCalculator.cxx:1405
 TQNFCalculator.cxx:1406
 TQNFCalculator.cxx:1407
 TQNFCalculator.cxx:1408
 TQNFCalculator.cxx:1409
 TQNFCalculator.cxx:1410
 TQNFCalculator.cxx:1411
 TQNFCalculator.cxx:1412
 TQNFCalculator.cxx:1413
 TQNFCalculator.cxx:1414
 TQNFCalculator.cxx:1415
 TQNFCalculator.cxx:1416
 TQNFCalculator.cxx:1417
 TQNFCalculator.cxx:1418
 TQNFCalculator.cxx:1419
 TQNFCalculator.cxx:1420
 TQNFCalculator.cxx:1421
 TQNFCalculator.cxx:1422
 TQNFCalculator.cxx:1423
 TQNFCalculator.cxx:1424
 TQNFCalculator.cxx:1425
 TQNFCalculator.cxx:1426
 TQNFCalculator.cxx:1427
 TQNFCalculator.cxx:1428
 TQNFCalculator.cxx:1429
 TQNFCalculator.cxx:1430
 TQNFCalculator.cxx:1431
 TQNFCalculator.cxx:1432
 TQNFCalculator.cxx:1433
 TQNFCalculator.cxx:1434
 TQNFCalculator.cxx:1435
 TQNFCalculator.cxx:1436
 TQNFCalculator.cxx:1437
 TQNFCalculator.cxx:1438
 TQNFCalculator.cxx:1439
 TQNFCalculator.cxx:1440