#include "QFramework/TQMVAObservable.h"
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQNamedTaggable.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQPathManager.h"
#include "QFramework/TQUtils.h"

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

#include "TMVA/IMethod.h"


////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQMVAObservable
//
// The TQMVAObservable is a variant of TQObservable that is able to
// take the location of an MVA XML file and instantiate a TMVA::Reader
// base on its settings. The result of the observable will be the
// evaluation of the classifier defined by the XML file.
//
////////////////////////////////////////////////////////////////////////////////////////////////

/*@observable: [TQMVAObservable] The TQMVAObservable provides a way to evaluate TMVA classifiers.
    Similar to the TQMultiObservable it relies fully on its subObservables which it evaluates in 
    order to forward their values to the (trained) MVA. It then provides the reponse of the MVA.
    It is automatically instantiated when encountering an expression either matching '*weights.xml*'
    or starting with 'MVA:'. In the latter case the 'MVA:' part is removed and in either case
    the remaining expression is interpreted as the path to the MVA weights file which is then 
    passed to TMVA (after passing it through the TQPathManager, i.e., in CAFExample based analysis 
    packages, paths can simply be provided relative to (typically) the 'share' directory just like
    non-absolute paths to configuration files. 
    Additionally, this observable requires the weights xml file to be slightly
    modified compared to those produced by default by TMVA: the 'Label' attribute of each variable
    in the xml must contain the Observable expression corresponding to the variable. The 
    subObservables of the TQMVAObservable are then automatically retrieved using these expressions.
    

*/

ClassImp(TQMVAObservable)

#ifndef NO_LIBXML2
#include <libxml/tree.h>
#include <libxml/parserInternals.h>
#endif
TQTaggable TQMVAObservable::globalAliases = TQTaggable();

//______________________________________________________________________________________________

TQMVAObservable::TQMVAObservable(){
  // default constructor
  this->SetName("TQMVAObservable");
}

//______________________________________________________________________________________________

TQMVAObservable::TQMVAObservable(const TString& expression){
  // constructor with an expression
  DEBUGclass("constructor called with expression '%s'",expression.Data());
  this->setExpression(expression);
  TString expr(expression);
  this->SetName(TQFolder::getPathTail(expr));
}

//______________________________________________________________________________________________

TQMVAObservable::~TQMVAObservable(){
  // destructor
}

//______________________________________________________________________________________________

void TQMVAObservable::setExpression(const TString& expr){
  // set the expression to a given string
  this->fExpression = TQStringUtils::compactify(expr);
}

//______________________________________________________________________________________________

#ifndef NO_LIBXML2
namespace{
  xmlNodePtr findNodeByName(xmlNodePtr rootnode, const char * nodename){
    xmlNodePtr node = rootnode;
    if(node == NULL){
      TQLibrary::ERRORfunc("unable to retrieve node '%s' - document empty!", nodename);
      return NULL;
    }
    while(node != NULL){
      if(!xmlStrcmp(node->name, (const xmlChar*)(nodename))){
        return node; 
      } else if(node->children){
        xmlNodePtr intNode = findNodeByName(node->children, nodename); 
        if(intNode) return intNode;
      }
      node = node->next;
    }
    return NULL;
  }

  //______________________________________________________________________________________________

  bool findAttributeValue(xmlNodePtr node, const char* attrname, TString& val){
    if(node == NULL) return false;
    xmlAttr* attribute = node->properties;
    while(attribute && attribute->name && attribute->children){
      if(!xmlStrcmp(attribute->name, (const xmlChar*)(attrname))){
        xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1);
        val = TString((const char*)value);
        free(value); 
        return true;
      }
      attribute = attribute->next;
    }
    return false;
  }

  //______________________________________________________________________________________________

  bool findNodeAttributeMatch(xmlNodePtr node, const char* attrname, const TString& attrval){
    if(node == NULL) return false;
    xmlNodePtr child = node->children;
    TString val;
    while(child != NULL){
      if(findAttributeValue(child,attrname,val)){
        if(TQStringUtils::matches(val,attrval))
          return true;
      }
      child = child->next;
    }
    return false;
  }

  //______________________________________________________________________________________________

  xmlNodePtr findNodeByNameAndAttribute(xmlNodePtr rootnode, const char* nodename, const TString& attrname, const TString& attrval){
    xmlNodePtr node = rootnode;
    if(node == NULL){
      TQLibrary::ERRORfunc("unable to retrieve node '%s' - document empty!", nodename);
      return NULL;
    }
 
    while(node != NULL){
      if(!xmlStrcmp(node->name, (const xmlChar*)(nodename))){
        return node; 
      } else if(node->children){
        xmlNodePtr intNode = findNodeByNameAndAttribute(node->children, nodename,attrname,attrval); 
        if(findNodeAttributeMatch(intNode,attrname,attrval)) return intNode;
      }
      node = node->next;
    }
    return NULL;
  }
}
#endif

//______________________________________________________________________________________________

bool TQMVAObservable::Reader::getExpression(TQTaggable* var, TString& result) {
  if(!var) return false;
  TString expr = var->getTagStringDefault("Expression","");
  TString name = var->getTagStringDefault("Internal","");
  TString label = var->getTagStringDefault("Label","");
  if(label.IsNull()) return false;
  if(expr.IsNull()) return false;
  if(name.IsNull()) return false;
  if(expr == name && label == name){ result = name; return true; }
  else if (expr == name){ result = label; return true; }
  else if (label == name){ result = expr; return true; }
  return false;
}

//______________________________________________________________________________________________

TQMVAObservable::Reader::Reader(const char* filename, const char* methodname) : 
  fFileName(filename),
  fMethodName(methodname),
  fVariables(new TObjArray())
{
  // perform the entire setup from the given file name
  this->fMVAReader = new TMVA::Reader("Silent",false);
  this->clearVariables();
  if(this->parseVariables() > 0){
    this->assignVariables();
    this->fMVAMethod = this->fMVAReader->BookMVA(this->fMethodName, this->fFileName);
    if(!this->fMVAMethod){
      throw std::runtime_error(TString::Format("unable to book method '%s' in MVA::Reader from file '%s'",this->fMethodName.Data(),this->fFileName.Data()).Data());
    }
  } else {
    throw std::runtime_error(TString::Format("no variables found in file '%s'",this->fFileName.Data()).Data());
  }
}

//______________________________________________________________________________________________

void TQMVAObservable::Reader::printVariables() const {
  // print the variables of this observable
  TQTaggableIterator itr(fVariables);
  std::cout << TQStringUtils::makeBoldWhite("Variables") << " of " << TQStringUtils::makeBoldWhite(this->fMethodName) << " as read from " << TQStringUtils::makeBoldWhite(this->fFileName) << std::endl;
  while(itr.hasNext()){
    TQTaggable* var = itr.readNext();
    if(!var) continue;
    std::cout << var->exportTagsAsString() << std::endl;
  }
}

//______________________________________________________________________________________________

void TQMVAObservable::Reader::clearVariables(){
  // clear the variables of this observable
  this->fVariables->Clear();
  this->fValues.clear();
}

//______________________________________________________________________________________________

int TQMVAObservable::Reader::parseVariables(){
#ifdef NO_LIBXML2
  ERRORclass("libxml2 support is disabled - unable to parse variables!");
#warning "compiling without libxml2 support!"
  return 0;
#else
  // parse the variables from this input file
  DEBUG("parsing variables from file '%s'",this->fFileName.Data());
  TString it=TQStringUtils::readFile(this->fFileName);
  if(it.IsNull()){
    ERRORclass("unable to open file '%s'",this->fFileName.Data());
    return -1;
  }
  xmlDocPtr xmldoc_ptr;
  xmlParserCtxtPtr ctxt_ptr = xmlNewParserCtxt();
  if(ctxt_ptr == NULL) return -1;
  xmldoc_ptr = xmlCtxtReadMemory( ctxt_ptr, it.Data(), it.Length(), this->fFileName.Data(), "ISO-8859-1", 0);
  if(xmldoc_ptr == NULL) return -1;
  xmlNodePtr root_element_ptr = xmlDocGetRootElement(xmldoc_ptr);
  xmlNodePtr basenode = root_element_ptr;
  if(this->fMethodName.IsNull()){
    basenode = findNodeByName(root_element_ptr,"MethodSetup");
    TString buffer;
    findAttributeValue(basenode,"Method",fMethodName);
    TQStringUtils::readUpToText(fMethodName,buffer,"::");
    TQStringUtils::removeLeadingText(fMethodName,"::");
  } else {
    TString methodname(fMethodName);
    basenode = findNodeByNameAndAttribute(root_element_ptr,"MethodSetup","Method",methodname);
  }
 
  xmlNodePtr variables = findNodeByName(basenode,"Variables");
  xmlNodePtr node = variables->children;
  while(node != NULL){
    if(!xmlStrcmp(node->name, (const xmlChar*)("Variable"))){
      DEBUG("looking at variable");
      TQNamedTaggable* var = new TQNamedTaggable("variable");
      xmlAttr* attribute = node->properties;
      while(attribute && attribute->name && attribute->children){
        xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1);
        var->setTagString((const char*)attribute->name,(const char*)value);
        free(value); 
        attribute = attribute->next;
      }
      DEBUG("finished variable '%s'",var->getTagStringDefault("Internal","").Data());
      TString expression;
      if(this->getExpression(var,expression)){
        this->fVariables->Add(var);
        this->fValues.push_back(0.);
        TString expr = var->getTagStringDefault("Label",expression);
        this->fExpressions.push_back(TQMVAObservable::globalAliases.replaceInTextRecursive(expr));
      } else {
        WARNclass("unable to parse variable from XML: %s",var->exportTagsAsString().Data());
        delete var;
      }
    }
    node = node->next;
  }
  return fValues.size();
#endif
}

//______________________________________________________________________________________________

void TQMVAObservable::Reader::print() const {
  // print a general overview over the current configuration
  std::cout << TQStringUtils::makeBoldBlue("TQMVAObservable::Reader");
  std::cout << "\t" << TQStringUtils::fixedWidth("fMethodName",20,"l") << " = " << this->fMethodName << std::endl;
  std::cout << "\t" << TQStringUtils::fixedWidth("fFileName",20,"l") << " = " << this->fFileName << std::endl;
  this->printVariables();
}

//______________________________________________________________________________________________

void TQMVAObservable::Reader::assignVariables(){
  // assign the variables of this observable to the internal MVA reader
  TQTaggableIterator itr(fVariables);
  while(itr.hasNext()){
    TQTaggable* var = itr.readNext();
    if(!var) continue;
    TString varname;
    if(var->getTagString("Internal",varname)){
      fMVAReader->AddVariable(varname, &(this->fValues[itr.getLastIndex()]));
    }
  }
}



size_t TQMVAObservable::Reader::size() const {
  return this->fValues.size();
}
const TString& TQMVAObservable::Reader::getExpression(size_t i) const {
  return this->fExpressions[i];
}
double TQMVAObservable::Reader::getValue() const {
  DEBUGclass("calculated weight for reader %s: %g",this->fFileName.Data(),this->fMVAMethod->GetMvaValue( 0,0));
  return this->fMVAMethod->GetMvaValue( 0,0);
}
void TQMVAObservable::Reader::fillValue(size_t i,double val) const {
  this->fValues[i]=val;
}


//______________________________________________________________________________________________

double TQMVAObservable::getValue() const {
  // retrieve the value of this observable
  #ifdef _DEBUG_
  if(!this->fReader){
    throw std::runtime_error("Reader is NULL");
  }
  #endif
  if(this->getCurrentEntry() != this->fCachedEntry){
    DEBUGclass("this event '%d'",this->getCurrentEntry());
    for(size_t i=0; i<this->fReader->size(); ++i){
      const double value = this->fObservables[i]->getValue();
      this->fReader->fillValue(i,value);
      DEBUGclass("filling value[%d]=%g (from '%s')",(int)(i),value,this->fObservables[i]->getActiveExpression().Data());
    }
    this->fCachedValue = this->fReader->getValue();
    this->fCachedEntry = this->getCurrentEntry();
  } else {
    DEBUGclass("re-using cached value from event '%d'",this->fCachedEntry);
  }
  return this->fCachedValue;
}

//______________________________________________________________________________________________

TString TQMVAObservable::getActiveExpression() const {
  // return the currently active expression
  return this->fExpression;
}

//______________________________________________________________________________________________

TObjArray* TQMVAObservable::getBranchNames() const {
  // retrieve the branch names associated to this observable
  TObjArray* arr = new TObjArray();
  for(size_t i=0; i<this->fObservables.size(); ++i){
    TQObservable* obs = this->fObservables[i];
    if(!obs) continue;
    TCollection* branches = this->fObservables[i]->getBranchNames();
    if(branches){
      arr->AddAll(branches);
      delete branches;
    }
  }
  return arr;
}

//______________________________________________________________________________________________

TQMVAObservable::Reader* TQMVAObservable::getReader(const TString& expression){
  static std::map<const TString, TQMVAObservable::Reader*> sReaders;
  auto it = sReaders.find(expression);
  if(it == sReaders.end()){
    TString filename,methodname;
    TQFolder::parseLocation(expression,filename,methodname);
    filename = TQPathManager::findFileFromEnvVar(filename, "CAFANALYSISSHARE");
    DEBUG("creating new TQMVAObservable::Reader from '%s' with '%s':'%s'",expression.Data(),filename.Data(),methodname.Data());
    TQMVAObservable::Reader* rd = new TQMVAObservable::Reader(filename,methodname);
    sReaders[expression] = rd;
    return rd;
  } else {
    DEBUG("reusing TQMVAObservable::Reader with expression '%s'",expression.Data());
    return it->second;
  }
}

//______________________________________________________________________________________________

bool TQMVAObservable::initializeSelf(){
  // initialize this observable on the current sample
  if(this->fReader) return true;
  bool retval = true;

  TString filename, methodname;
  this->fReader = this->getReader(this->fExpression);
  if(!fReader) throw std::runtime_error(TString::Format("in TQMVAObservable: unable to obtain reader for expression '%s'",this->fExpression.Data()).Data());

  this->fCachedEntry = -1;
  this->fCachedValue = std::numeric_limits<double>::infinity();
  for(size_t i=0; i<this->fReader->size(); ++i){
    TString expression(this->fReader->getExpression(i));
    TQObservable* obs = TQObservable::getObservable(expression,this->fSample);
    this->fObservables.push_back(obs);
    if(!obs->initialize(this->fSample)) {
      retval = false;
      ERRORclass("Failed to initialize sub-observable obtained from expression '%s' in TQMVAObservable for sample '%s'",this->fReader->getExpression(i).Data(),this->fSample->getPath().Data());
    }
  }
  return retval;
}

//______________________________________________________________________________________________

bool TQMVAObservable::finalizeSelf(){
  // finalize this observable on the current sample
  bool retval = true;
  for(size_t i=0; i<this->fObservables.size(); i++){
    if(!this->fObservables[i]->finalize()) retval = false;
  }
  this->fReader = NULL;
  this->fObservables.clear();
  return retval;
}

//______________________________________________________________________________________________

Long64_t TQMVAObservable::getCurrentEntry() const {
  // retrieve the current entry from the tree
  if(this->fObservables.size() == 0) return -1;
  for (size_t i = 0; i<this->fObservables.size(); i++) {
    if (this->fObservables[i]->getCurrentEntry() >= 0) return this->fObservables[i]->getCurrentEntry();
  }
  return -1;
}

//______________________________________________________________________________________________

const TString& TQMVAObservable::getExpression() const {
  // retrieve the expression associated with this observable
  return this->fExpression;
}

//______________________________________________________________________________________________

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

//______________________________________________________________________________________________

DEFINE_OBSERVABLE_FACTORY(TQMVAObservable,TString expression){
  // try to create an instance of this observable from the given expression
  if(TQStringUtils::removeLeadingText(expression,"MVA:") || TQStringUtils::matches(expression,"*weights.xml*")){
    return new TQMVAObservable(expression);
  }
  return NULL;
}


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