#include "QFramework/TQVectorAuxObservable.h"
#include <limits>

#include "QFramework/TQSample.h"

// uncomment the following line to enable debug printouts
// #define _DEBUG_
// you can perform debug printouts with statements like this
// DEBUG("error number %d occurred",someInteger);

// be careful to not move the _DEBUG_ flag behind the following line
// otherwise, it will show no effect
#include "QFramework/TQLibrary.h"


////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQVectorAuxObservable
//
// TODO: write documenation
//
////////////////////////////////////////////////////////////////////////////////////////////////

/*@observable: [TQVectorAuxObservable] The TQVectorAuxObservable is a helper/wrapper Observable
    when dealing with VectorObservables (i.e. Observables with a variable number of evaluations
    per event). It is automatically created when encountering expressions of the form
    'VecMODE(subExpression)' where MODE is one of the provided operation modes. The available 
    modes and their operation on the values provided by the observable corresponding to the 
    subExpressio nare: 'AND' (logical 'and' of the values, where 'true' is any non-zero value),
    'OR' (logical 'or'), 'SUM' (sum of the values), 'SUMABS' (sum of the absolute values),
    'AVG' (average of the values), 'AVGABS' (average of absolute values), 'LEN' (number of values/evaluations), 'MAX' (largest value),
    'MIN' (sallest value), 'MAXABS'/'MINABS' (largest/smallest absolute value), 'NORM' (modolus 
    of the vector, i.e.,sqrt(sumOfSquares) ), 'PROD' (product over all values), 'NTRUE' (number
    of non-zero values), 'NFALSE' (number of values equal to zero), 'AT' (requires second, comma
    separated subExpression; provides the values at the index given by the second subExpression).
    Vector valued modes of operation: 'INDICES' (provides a vector of indices 0,1,... with range 
    corresponding to another (vector valued) Observable specified by the argument).
*/

ClassImp(TQVectorAuxObservable)

//______________________________________________________________________________________________

TQVectorAuxObservable::TQVectorAuxObservable(){
  // default constructor
  DEBUGclass("default constructor called");
}

//______________________________________________________________________________________________

TQVectorAuxObservable::~TQVectorAuxObservable(){
  // default destructor
  DEBUGclass("destructor called");
} 



//______________________________________________________________________________________________

double TQVectorAuxObservable::getValueAtINDICES(int index) const {
  //evaluation for mode 'INDICES'
  if (index < this->fSubObservable->getNevaluations() && index >=0) {
    return index;
  }
  throw std::runtime_error(TString::Format( "Caught attempt to perform vector valued evaluation (with index %d , should be less than %d) instance of TQVectorAuxObservable with expression '%s'", index, this->fSubObservable->getNevaluations()-1, this->getExpression().Data() ).Data());
  return std::numeric_limits<double>::quiet_NaN();
}


//______________________________________________________________________________________________

double TQVectorAuxObservable::getValueAt(int index) const {
  
  //redirect scalar evaluation and catch illegal evaluation attempts
  if (this->fObservableType == TQObservable::ObservableType::scalar) {
    if (index == 0) {
      return this->getValue();
    }
    throw std::runtime_error(TString::Format( "Caught attempt to perform vector valued evaluation (with index %d) on scalar valued instance of TQVectorAuxObservable with expression '%s'", index, this->getExpression().Data() ).Data());
    return std::numeric_limits<double>::quiet_NaN();
  }
  
  double retval = std::numeric_limits<double>::quiet_NaN();
  switch (this->fOperation) {
    case INDICES:
      retval = this->getValueAtINDICES(index);
      break;
    default:
      retval = std::numeric_limits<double>::quiet_NaN();
      throw std::runtime_error(TString::Format("Cannot evaluate VectorAux observable with expression '%s': Unknown mode/enum value or mismatch with observable type (scalar/vector)",this->getExpression().Data()).Data());
      break;
  }
  
  return retval;
  
}
 
//______________________________________________________________________________________________

int TQVectorAuxObservable::getNevaluations() const {
  int result = 1;
  switch (this->fOperation) {
    //for vector valued evaluations make sure to add relevant code here!
    case INDICES:
      result = this->fSubObservable->getNevaluations();
      break;
    default: //any non-vector valued modes
      result = 1;
      break;
  }
  return result;
}

//______________________________________________________________________________________________

double TQVectorAuxObservable::getValue() const {
  // value retrieval function, called on every event for every cut and histogram this observable is used in
  DEBUGclass("entering function");
  
  if (this->fObservableType == TQObservable::ObservableType::vector) {
    throw std::runtime_error(TString::Format( "Caught attempt to perform scalar evaluation on vector valued instance of TQVectorAuxObservable with expression '%s'",this->getExpression().Data() ).Data());
  }
  
  if (!this->fSubObservable) {throw std::runtime_error("Cannot retrieve value without valid sub observable"); return -99999.;}
  
  if ( !(this->getCurrentEntry() < 0) && this->getCurrentEntry() == this->fCachedEntry) {
    //we can simply use the cached value
    return this->fCachedValue;
  }
  double retval;
  int nEntries = this->fSubObservable->getNevaluations();
  if (nEntries < 1) {
    this->fCachedValue = 0.;
    this->fCachedEntry = this->getCurrentEntry();
    return this->fCachedValue;
  }
  
  int at = -1; //only used for 'AT' mode
  switch (this->fOperation) {
    case AND: 
      retval = 1.;
      for (int i=0; i<nEntries; i++) {
        if (std::fabs(this->fSubObservable->getValueAt(i)) < 2* std::numeric_limits<double>::epsilon()) {retval = 0.; break;}
      }
      break;
    case OR: 
      retval = 0.;
      for (int i=0; i<nEntries; i++) {
        if (std::fabs(this->fSubObservable->getValueAt(i)) > 2* std::numeric_limits<double>::epsilon()) {retval = 1.; break;}
      }
      break;
    case SUM: 
      retval = 0.;
      for (int i=0; i<nEntries; i++) {
        retval += this->fSubObservable->getValueAt(i);
      }
      break;
    case SUMABS: 
      retval = 0.;
      for (int i=0; i<nEntries; i++) {
        retval += std::fabs(this->fSubObservable->getValueAt(i));
      }
      break;
    case AVG: 
      retval = 0.;
      for (int i=0; i<nEntries; i++) {
        retval += this->fSubObservable->getValueAt(i);
      }
      retval /= nEntries;
      break;
    case AVGABS: 
      retval = 0.;
      for (int i=0; i<nEntries; i++) {
        retval += std::fabs(this->fSubObservable->getValueAt(i));
      }
      retval /= nEntries;
      break;
    case LEN: 
      retval = nEntries;
      break;
    case MAX: 
      retval = std::numeric_limits<double>::min();
      for (int i=0; i<nEntries; i++) {
        retval = std::max(this->fSubObservable->getValueAt(i),retval);
      }
      break;
    case MIN: 
      retval = std::numeric_limits<double>::max();
      for (int i=0; i<nEntries; i++) {
        retval = std::min(this->fSubObservable->getValueAt(i),retval);
      }
      break;
    case MAXABS: 
      retval = std::numeric_limits<double>::min();
      for (int i=0; i<nEntries; i++) {
        retval = std::max(std::fabs(this->fSubObservable->getValueAt(i)),retval);
      }
      break;
    case MINABS: 
      retval = std::numeric_limits<double>::max();
      for (int i=0; i<nEntries; i++) {
        retval = std::min(std::fabs(this->fSubObservable->getValueAt(i)),retval);
      }
      break;
    case NORM: 
      retval = 0;
      for (int i=0; i<nEntries; i++) {
        retval += pow(this->fSubObservable->getValueAt(i),2.);
      }
      retval = sqrt(retval);
      break;
    case PROD: 
      retval = 1.;
      for (int i=0; i<nEntries; i++) {
        retval *= this->fSubObservable->getValueAt(i);
      }
      break;
    case NTRUE: 
      retval = 0;
      for (int i=0; i<nEntries; i++) {
        retval += (std::fabs(this->fSubObservable->getValueAt(i)) > 2* std::numeric_limits<double>::epsilon());
      }
      break;
    case NFALSE: 
      retval = 0;
      for (int i=0; i<nEntries; i++) {
        retval += (std::fabs(this->fSubObservable->getValueAt(i)) < 2* std::numeric_limits<double>::epsilon());
      }
      break;
    case AT:
      at = int(this->fIndexObservable->getValue()); //index observable must be scalar!
      if (at<nEntries && at>=0) {
        retval = this->fSubObservable->getValueAt(at);
      } else {
        throw std::runtime_error(TString::Format("Caught attempt to evaluate the vector observable with expression '%s' out of bounds (requested index: %d, max index: %d)",this->fSubObservable->getExpression().Data(),at,nEntries-1).Data());
        retval = std::numeric_limits<double>::quiet_NaN();
      }
      break;
    default:
      retval = std::numeric_limits<double>::quiet_NaN();
      throw std::runtime_error(TString::Format("Cannot evaluate VectorAux observable with expression '%s': Unknown mode/enum value or mismatch with observable type (scalar/vector)",this->getExpression().Data()).Data());
  };
  
  this->fCachedValue = retval;
  this->fCachedEntry = this->getCurrentEntry();
  return fCachedValue;
}

//______________________________________________________________________________________________



//______________________________________________________________________________________________


//______________________________________________________________________________________________

Long64_t TQVectorAuxObservable::getCurrentEntry() const {
  // retrieve the current entry from the sub observable

  return this->fSubObservable? this->fSubObservable->getCurrentEntry() : (this->fIndexObservable? this->fIndexObservable->getCurrentEntry() : -1);
}

//______________________________________________________________________________________________

TObjArray* TQVectorAuxObservable::getBranchNames() const {
  // retrieve the list of branch names for this observable
  // ownership of the list belongs to the caller of the function
  DEBUGclass("retrieving branch names");
  TObjArray* subNames = this->fSubObservable? this->fSubObservable->getBranchNames() : nullptr;
  TObjArray* indexNames = this->fIndexObservable? this->fIndexObservable->getBranchNames() : nullptr;
  if (subNames && indexNames) {
    indexNames->SetOwner(false);
    subNames -> AddAll(indexNames);
    delete indexNames;
  } else if (indexNames) {
    //if subNames is a nullptr but indexNames isn't, just use the latter
    subNames = indexNames;
  }
  //now either subNames is a valid list of none is.
  return subNames;
}
//______________________________________________________________________________________________

TQVectorAuxObservable::TQVectorAuxObservable(const TString& expression):
TQObservable(expression)
{
  // constructor with expression argument
  DEBUGclass("constructor called with '%s'",expression.Data());
  // the predefined string member "expression" allows your observable to store an expression of your choice
  // this string will be the verbatim argument you passed to the constructor of your observable
  // you can use it to choose between different modes or pass configuration options to your observable
  this->SetName(TQObservable::makeObservableName(expression));
  this->setExpression(expression);
}

//______________________________________________________________________________________________

const TString& TQVectorAuxObservable::getExpression() const {
  // retrieve the expression associated with this observable
  this->fFullExpression = this->fSubObservable? this->fSubObservable->getExpression() : (this->fVecExpression.IsNull()? this->fExpression : this->fVecExpression);
  DEBUGclass("Prepending prefix");
  this->fFullExpression.Prepend("Vec"+TQVectorAuxObservable::getOperationName(this->fOperation) + "(");
  if (this->fIndexObservable) this->fFullExpression.Append(","+this->fIndexObservable->getExpression()); //for 'AT' mode we need a second observable determining the index to retrieve
  else if (!this->fIndexExpression.IsNull()) fFullExpression.Append(","+this->fIndexExpression);
  this->fFullExpression.Append(")");
  DEBUGclass("Returning full expression");
  return this->fFullExpression;
}

//______________________________________________________________________________________________

bool TQVectorAuxObservable::hasExpression() const {
  // check if this observable type knows expressions
  return true;
}

//______________________________________________________________________________________________

void TQVectorAuxObservable::setExpression(const TString& expr){
  // set the expression to a given string
  DEBUGclass("Setting expression for VectorAuxObservable based on specified expression '%s'",expr.Data());
  TString myExpr = expr;
  TQVectorAuxObservable::Operation op = TQVectorAuxObservable::readPrefix(myExpr);
  if (op != TQVectorAuxObservable::Operation::invalid) this->setOperation(op);
  this->fExpression = myExpr;
  DEBUGclass("Set expression for VectorAuxObservable to '%s'",this->fExpression.Data());
}
//______________________________________________________________________________________________

void TQVectorAuxObservable::setOperation(TQVectorAuxObservable::Operation op) {
  this->fOperation = op; 
  //determine if selected mode should yield vector valued results
  switch (this->fOperation) {
    //list vector valued modes of operation here!
    case INDICES:
      this->fObservableType = TQObservable::ObservableType::vector;
      break;
    default:
      this->fObservableType = TQObservable::ObservableType::scalar;
      break;
  }
  
  return;
  }

//______________________________________________________________________________________________

TString TQVectorAuxObservable::getActiveExpression() const {
  // retrieve the expression associated with this incarnation
  DEBUGclass("Creating active expression");
  TString aExpr = this->fSubObservable? this->fSubObservable->getActiveExpression() : (this->fVecExpression.IsNull() ? this->fVecExpression : this->fVecExpression);
  aExpr.Prepend(TQVectorAuxObservable::getPrefix(this->fOperation)+"(");
  if (this->fIndexObservable) aExpr.Append(","+this->fIndexObservable->getActiveExpression()); //for 'AT' mode we need a second observable determining the index to retrieve
  else if (!this->fIndexExpression.IsNull()) aExpr.Append(","+this->fIndexExpression);
  aExpr.Append(")");
  DEBUGclass("returning active expression");
  return aExpr;
}

//______________________________________________________________________________________________

bool TQVectorAuxObservable::initializeSelf(){
  // initialize self - compile container name, construct accessor
  DEBUGclass("Initializing VectorAuxObservable with expression '%s'",this->fExpression.Data());
  //the following block should only be relevant for the 'AT' mode:
  if (this->fOperation == AT) {
    std::vector<TString> expressions = TQStringUtils::tokenizeVector(this->fExpression, ",", true, "()[]{}", "\"\"''"); //split the expression for the index observable from the rest of the expression
    if (expressions.size()<1) {
      ERRORclass("Failed to parse (split) expression '%s'",this->fExpression.Data());
      throw std::runtime_error("This should never happen, even if there's no separator in the expression TQStringUtils::split should not return an empty vector! Please report this to qframework-users@cern.ch!");
      return false;
    }
    if (expressions.size()==2) {
      this->fVecExpression = expressions[0];
      this->fIndexExpression = expressions[1];
    } else {
      ERRORclass("Illegal number of sub-expressions (%d) for TQVectorAuxObservable with expression '%s', must be 2 for mode 'AT'!",expressions.size(),this->fExpression.Data());
      throw std::runtime_error("Failed to parse expression in TQVectorAuxObservable::initializeSelf for 'AT' mode."); 
    }
    this->fIndexObservable = TQObservable::getObservable(this->fIndexExpression,this->fSample);
    if (!this->fIndexObservable) {
      ERRORclass("Failed to obtain index-observable!");
      throw std::runtime_error(TString::Format("Failed to obtain observable from expression '%s'",this->fIndexExpression.Data()).Data());
    }
    DEBUGclass("Going to initialize index-observable");
    if (!this->fIndexObservable->initialize(this->fSample)) {
      throw std::runtime_error(TString::Format("Failed to initialize observable with name '%s' created from expression '%s' for sample '%s'",this->fIndexObservable->GetName(), this->fIndexExpression.Data(), this->fSample->getPath().Data()).Data());
    }
      
  } else {
    this->fVecExpression = this->fExpression; //just use the full expression as the vector (sub) observable expression
  }
    
  this->fSubObservable = TQObservable::getObservable(this->fVecExpression,this->fSample);
  if (!this->fSubObservable) {
    ERRORclass("Failed to obtain sub-observable!");
    throw std::runtime_error(TString::Format("Failed to obtain observable from expression '%s'",this->fVecExpression.Data()).Data());
  }
  DEBUGclass("Going to initialize sub-observable");
  if (!this->fSubObservable->initialize(this->fSample)) {
    throw std::runtime_error(TString::Format("Failed to initialize observable with name '%s' created from expression '%s' for sample '%s'",this->fSubObservable->GetName(), this->fVecExpression.Data(), this->fSample->getPath().Data()).Data());
  }
  this->fCachedEntry = -999;
  DEBUGclass("Done initializing instance with expression '%s'",this->getExpression().Data());
  return true;
}
 
//______________________________________________________________________________________________

bool TQVectorAuxObservable::finalizeSelf(){
  // finalize self - delete accessor
  this->fVecExpression = ""; this->fIndexExpression = "";
  return this->fSubObservable ? this->fSubObservable->finalize() : true;
  
}

//______________________________________________________________________________________________

TString TQVectorAuxObservable::getOperationName(TQVectorAuxObservable::Operation op) {
  switch(op) {
    //returning the prefix for a certain operation type without the preceeding 'Vec' and the following ':'
    case AND: return TString("AND"); break;
    case OR: return TString("OR"); break;
    case SUM: return TString("SUM"); break;
    case SUMABS: return TString("SUMABS"); break;
    case AVG: return TString("AVG"); break;
    case AVGABS: return TString("AVGABS"); break;
    case LEN: return TString("LEN"); break;
    case MAX: return TString("MAX"); break;
    case MIN: return TString("MIN"); break;
    case MAXABS: return TString("MAXABS"); break;
    case MINABS: return TString("MINABS"); break;
    case NORM: return TString("NORM"); break;
    case PROD: return TString("PROD"); break;
    case NTRUE: return TString("NTRUE"); break;
    case NFALSE: return TString("NFALSE"); break;
    case AT: return TString("AT"); break;
    case INDICES: return TString("INDICES"); break;
    case invalid: return TString("invalid"); break;
  };
  return TString("nonExistingEnum"); 
}

TString TQVectorAuxObservable::getPrefix(TQVectorAuxObservable::Operation op) {
  return TString("Vec"+TQVectorAuxObservable::getOperationName(op));
}

TQVectorAuxObservable::Operation TQVectorAuxObservable::readPrefix(TString& expr) {
  // try to read a matching prefix and return a corresponding enum.
  // If found, the prefix is removed from expression.
  DEBUGclass("Trying to read prefix from expression '%s'",expr.Data());
  TString copyExpr = expr;
  TQVectorAuxObservable::Operation op = TQVectorAuxObservable::Operation::invalid;
  if(TQStringUtils::removeLeadingText(expr,"Vec")){
    if (TQStringUtils::removeLeadingText(expr,"AND")) {
      op = TQVectorAuxObservable::Operation::AND;
    } else if (TQStringUtils::removeLeadingText(expr,"OR")) {
      op = TQVectorAuxObservable::Operation::OR;
    } else if (TQStringUtils::removeLeadingText(expr,"SUMABS")) {
      op = TQVectorAuxObservable::Operation::SUMABS;
    } else if (TQStringUtils::removeLeadingText(expr,"SUM")) {
      op = TQVectorAuxObservable::Operation::SUM;
    } else if (TQStringUtils::removeLeadingText(expr,"AVG")) {
      op = TQVectorAuxObservable::Operation::AVG;
    } else if (TQStringUtils::removeLeadingText(expr,"AVGABS")) {
      op = TQVectorAuxObservable::Operation::AVGABS;
    } else if (TQStringUtils::removeLeadingText(expr,"LEN")) {
      op = TQVectorAuxObservable::Operation::LEN;
    } else if (TQStringUtils::removeLeadingText(expr,"MIN")) {
      op = TQVectorAuxObservable::Operation::MIN;
    } else if (TQStringUtils::removeLeadingText(expr,"MAX")) {
      op = TQVectorAuxObservable::Operation::MAX;
    } else if (TQStringUtils::removeLeadingText(expr,"MINABS")) {
      op = TQVectorAuxObservable::Operation::MINABS;
    } else if (TQStringUtils::removeLeadingText(expr,"MAXABS")) {
      op = TQVectorAuxObservable::Operation::MAXABS;
    } else if (TQStringUtils::removeLeadingText(expr,"NORM")) {
      op = TQVectorAuxObservable::Operation::NORM;
    } else if (TQStringUtils::removeLeadingText(expr,"PROD")) {
      op = TQVectorAuxObservable::Operation::PROD;
    } else if (TQStringUtils::removeLeadingText(expr,"NTRUE")) {
      op = TQVectorAuxObservable::Operation::NTRUE;
    } else if (TQStringUtils::removeLeadingText(expr,"NFALSE")) {
      op = TQVectorAuxObservable::Operation::NFALSE;
    } else if (TQStringUtils::removeLeadingText(expr,"AT")) {
      op = TQVectorAuxObservable::Operation::AT;
    } else if (TQStringUtils::removeLeadingText(expr,"INDICES")) {
      op = TQVectorAuxObservable::Operation::INDICES;
    }
    if (op != TQVectorAuxObservable::Operation::invalid) {
      TQStringUtils::readBlanksAndNewlines(expr);
      TString subExpr;
      if (TQStringUtils::readBlock(expr,subExpr,"()[]{}","\"\"''")>0) {
        //check if remaining subExpr is empty (up to whitespaces), otherwise there is likely an error and we need to throw! (unless we find a clean way to automatically fix the expression and re-inject it.
        if (!TQStringUtils::isEmpty(expr,true/*ignore blanks*/)) {
          //print an error to inform the user
          ERRORfunc("A known prefix for the VectorAux observable has been found in the expression '%s'. However, there seems to be a remainder after its expression block: '%s'. Did you forget to encapsulate the VecAux expression in square brackets '[...]'?",copyExpr.Data(),expr.Data());
        } else {
          expr=subExpr; //copy the now reduced expression back
          return op;
        }
      }
      
    }
    
    
    expr = copyExpr; //in case nothing matched, restore the original state
  }
  DEBUGclass("No valid TQVectorAuxObservable prefix found!");
  //fallback if no known operation matches:
  return TQVectorAuxObservable::Operation::invalid;
}
//______________________________________________________________________________________________

// the following preprocessor macro defines an "observable factory"
// that is supposed to create instances of your class based on input
// expressions.

// it should receive an expression as an input and decide whether this
// expression should be used to construct an instance of your class,
// in which case it should take care of this, or return NULL.

// in addition to defining your observable factory here, you need to
// register it with the TQObservable manager. This can either be done
// from C++ code, using the line
//   TQObservable::manager.registerFactory(TQVectorAuxObservable::getFactory(),true);
// or from python code, using the line
//   TQObservable.manager.registerFactory(TQVectorAuxObservable.getFactory(),True)
// Either of these lines need to be put in a location where they are
// executed before observables are retrieved. You might want to 'grep'
// for 'registerFactory' in the package you are adding your observable
// to in order to get some ideas on where to put these!

DEFINE_OBSERVABLE_FACTORY(TQVectorAuxObservable,TString expr){
  // try to create an instance of this observable from the given expression
  // return the newly created observable upon success
  // or NULL upon failure
  //std::cout<<"Trying to match prefix of '"<<expr.Data() <<"'"<<std::endl;
  TQVectorAuxObservable::Operation op = TQVectorAuxObservable::readPrefix(expr);
  if (op != TQVectorAuxObservable::Operation::invalid ) {
    //std::cout<<"Found match!"<<std::endl;
    TQVectorAuxObservable* obs = new TQVectorAuxObservable(expr);
    obs->setOperation(op);
    return obs;    
  }
  // check if the expression fits your observable type
  //std::cout<<"Failed to find a match!"<<std::endl;
  return NULL;
}

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