//this file looks like plain C, but it's actually -*- c++ -*-
#ifndef __TQUtils__
#define __TQUtils__

#include "QFramework/TQFlags.h"

#include "TObject.h"
#include "QFramework/TQFolder.h"
#include "TString.h"
#include "TDirectory.h"
#include "TClass.h"
#include "TCollection.h"
#include "QFramework/TQTaggable.h"
#include "TTree.h"
#include "TMatrixD.h"
#include "math.h"
#include <sys/stat.h>

#ifdef HAS_XAOD
namespace xAOD { //EXCLUDE
  class TEvent;
}
#endif

namespace TQUtils {
  int getMinIndex(const std::vector<int>& vals, const std::vector<bool>& accepts);
  int getMinIndex(int val0, int val1, int val2, bool accept0, bool accept1, bool accept2);

  TFile * openFile(const TString& filename);
  bool fileExists(const TString& filename);
  bool fileExistsLocal(const TString& filename);
  bool fileExistsEOS(const TString& filename);
  bool directoryExists(const TString& path);
  TList * getListOfFilesMatching(TString pattern);
  bool ensureDirectoryForFile(TString filename);
  bool ensureDirectory(TString path);

  bool areEquivalent(TObject * obj1, TObject * obj2);

  /* to be moved to TQStringUtils */

  inline int sgn(int val){ return (val<0 ? -1 : 1); }
  inline double sgn(double val){ return (val<0 ? -1. : 1.); }

  bool parseAssignment(TString input, TString * dest, TString * source);

  TObjArray * getBranchNames(const TString& input);

  bool isNum(double a);
  bool inRange(double x, double a, double b);

  unsigned long getCurrentTime();
  TString getTimeStamp(const TString& format = "%c", size_t len = 80);
  TString formatTimeDifference(unsigned int time);
  TString getMD5(const TString& filepath);
  TString getMD5Local(const TString& filepath);
  TString getMD5EOS(TString filepath);
  TString getModificationDate(TFile* f);

  unsigned long getFileSize(const TString& path);

  double convertXtoNDC(double x);
  double convertYtoNDC(double y);
  double convertXtoPixels(double x);
  double convertYtoPixels(double y);
  double convertXfromNDC(double x);
  double convertYfromNDC(double y);
  double convertdXtoNDC(double x);
  double convertdYtoNDC(double y);
  double convertdXtoPixels(double x);
  double convertdYtoPixels(double y);
  double convertdXfromNDC(double x);
  double convertdYfromNDC(double y);

  double getAverage(std::vector<double>& vec);
  double getSampleVariance(std::vector<double>& vec);
  double getSampleCovariance(std::vector<double>& vec1, std::vector<double>& vec2, bool verbose=true);
  double getSampleCorrelation(std::vector<double>& vec1, std::vector<double>& vec2, bool verbose=true);

  inline double getOrderOfMagnitude(double value) {return value==0 ? 0. : log10(fabs(value)) ;}
  inline int getOrderOfMagnitudeInt(double value) {return int (value==0 ? 0. : log10(fabs(value))) ;}
  double getAverageOrderOfMagnitude(TMatrixD* mat);
  int getAverageOrderOfMagnitudeInt(TMatrixD* mat);


  char getLastCharacterInFile(const char* filename);
  bool ensureTrailingNewline(const char* filename);

  TString findFile(const TString& basepath, const TString& filename);
  TString findFileLocal(const TString& basepath, const TString& filename);
  TString findFileEOS(const TString& basepath, const TString& filename, const TString& eosprefix);
  TString findFile(TList* basepaths, const TString& filename, int& index);
  TString findFile(TList* basepaths, const TString& filename);
  TList* execute(const TString& cmd, size_t maxOutputLength = 80);

  TList* lsEOS(TString exp, const TString& eosprefix, TString path="");
  TList* lsdCache(const TString& fname, const TString& localGroupDisk, const TString& oldHead, const TString& newHead, const TString& dq2cmd = "dq2");
  TList* lsLocal(const TString& exp);
  TList* ls(TString exp);

  TList* getObjectsFromFile(TString identifier, TClass* objClass = TObject::Class());
  TList* getObjectsFromFile(const TString& filename, const TString& objName, TClass* objClass = TObject::Class());
  TList* getObjects(const TString& objName, TClass* objClass = TObject::Class(), TDirectory* d = gDirectory);

  std::vector<TQTaggable*>* getListOfTagsFromFile(const TString& filename);
  std::vector<TQTaggable*>* getListOfTagsFromFile(const TString& filename, TQTaggable& dictTags);

  void printBranches(TTree* t);
  void printActiveBranches(TTree* t);
  double getValue(TTree* t, const TString& bname, Long64_t iEvent = 0);
  double getSum(TTree* t, const TString& bname);

  #ifdef HAS_XAOD
  double xAODMetaDataGetSumWeightsInitialFromEventBookkeeper(TTree* MetaData);
  double xAODMetaDataGetSumWeightsInitialFromCutBookkeeper(TTree* tree, const char* container = "StreamAOD", const char* bookkeeper = "AllExecutedEvents");
  double xAODMetaDataGetSumWeightsInitialFromCutBookkeeper(xAOD::TEvent& event, const char* container = "StreamAOD", const char* bookkeeper = "AllExecutedEvents");
  double xAODMetaDataGetNEventsInitialFromCutBookkeeper(TTree* tree, const char* container = "StreamAOD", const char* bookkeeper = "AllExecutedEvents");
  double xAODMetaDataGetNEventsInitialFromCutBookkeeper(xAOD::TEvent& event, const char* container = "StreamAOD", const char* bookkeeper = "AllExecutedEvents");
  #endif

  TList* getListOfFoldersInFile(const TString& filename, TClass* type = TQFolder::Class());
  int appendToListOfFolders(const TString& filename, TList* list, TClass* type = TQFolder::Class());
  TList* getListOfFolderNamesInFile(const TString& filename, TClass* type = TQFolder::Class());
  int appendToListOfFolderNames(const TString& filename, TList* list, TClass* type = TQFolder::Class(), const TString& prefix="");

  double roundAuto(double d, int nSig=1);
  double roundAutoUp(double d, int nSig=1);
  double roundAutoDown(double d, int nSig=1);

  double round (double d, int nDigits=0);
  double roundUp (double d, int nDigits=0);
  double roundDown(double d, int nDigits=0);

  void printParticles(TTree* t, Long64_t evt, int id, const TString& bName = "TruthParticles");
  void printParticle(TTree* t, Long64_t evt, int index, const TString& bName = "TruthParticles");
  void printProductionChain(TTree* t, Long64_t evt = 0, int ptcl = 0, const TString& bName = "TruthParticles");
  void printDecayChain(TTree* t, Long64_t evt = 0, int ptcl = 0, const TString& bName = "TruthParticles");

  void dumpTop(TString folder, TString prefix = "qframework", TString message = "");

   // Takes an environment variable and returns its value (returns empty string
  // in case it does not exist).
  std::string readEnvVarValue(const std::string& envVar);

  // Takes an environment variable and returns its value iterpreted as a boolean
  // (returns value of fallback argument in case it does not exist).
  // The interpretation as a bool is done via TQStringUtils::getBoolFromString
  bool readEnvVarValueBool(const std::string& envVar, bool fallback = true);

  size_t getPeakRSS();
  size_t getCurrentRSS();
  
  template<class T, class U> void append(std::vector<T>& target, const std::vector<U>& source){
    for(const auto& it:source) { target.push_back(it); }
  } 

  void printHEPdataInfo(TQFolder* config, const TString& title, const TString& description, const TString& filename);  
  void writeHEPdataHeader(std::ostream& out, const TString& vartype, const TString name, const TString& unit = "");
  void writeHEPdataValue(std::ostream& out, const TString& s);
  void writeHEPdataValue(std::ostream& out, double d);
  void writeHEPdataValueAndError(std::ostream& out, double d, double e, std::string elbl);
  void writeHEPdataValueWithErrors(std::ostream& out, double d);
  void writeHEPdataError(std::ostream& out, double eup, double edn, std::string elbl);  
}

#endif
 TQUtils.h:1
 TQUtils.h:2
 TQUtils.h:3
 TQUtils.h:4
 TQUtils.h:5
 TQUtils.h:6
 TQUtils.h:7
 TQUtils.h:8
 TQUtils.h:9
 TQUtils.h:10
 TQUtils.h:11
 TQUtils.h:12
 TQUtils.h:13
 TQUtils.h:14
 TQUtils.h:15
 TQUtils.h:16
 TQUtils.h:17
 TQUtils.h:18
 TQUtils.h:19
 TQUtils.h:20
 TQUtils.h:21
 TQUtils.h:22
 TQUtils.h:23
 TQUtils.h:24
 TQUtils.h:25
 TQUtils.h:26
 TQUtils.h:27
 TQUtils.h:28
 TQUtils.h:29
 TQUtils.h:30
 TQUtils.h:31
 TQUtils.h:32
 TQUtils.h:33
 TQUtils.h:34
 TQUtils.h:35
 TQUtils.h:36
 TQUtils.h:37
 TQUtils.h:38
 TQUtils.h:39
 TQUtils.h:40
 TQUtils.h:41
 TQUtils.h:42
 TQUtils.h:43
 TQUtils.h:44
 TQUtils.h:45
 TQUtils.h:46
 TQUtils.h:47
 TQUtils.h:48
 TQUtils.h:49
 TQUtils.h:50
 TQUtils.h:51
 TQUtils.h:52
 TQUtils.h:53
 TQUtils.h:54
 TQUtils.h:55
 TQUtils.h:56
 TQUtils.h:57
 TQUtils.h:58
 TQUtils.h:59
 TQUtils.h:60
 TQUtils.h:61
 TQUtils.h:62
 TQUtils.h:63
 TQUtils.h:64
 TQUtils.h:65
 TQUtils.h:66
 TQUtils.h:67
 TQUtils.h:68
 TQUtils.h:69
 TQUtils.h:70
 TQUtils.h:71
 TQUtils.h:72
 TQUtils.h:73
 TQUtils.h:74
 TQUtils.h:75
 TQUtils.h:76
 TQUtils.h:77
 TQUtils.h:78
 TQUtils.h:79
 TQUtils.h:80
 TQUtils.h:81
 TQUtils.h:82
 TQUtils.h:83
 TQUtils.h:84
 TQUtils.h:85
 TQUtils.h:86
 TQUtils.h:87
 TQUtils.h:88
 TQUtils.h:89
 TQUtils.h:90
 TQUtils.h:91
 TQUtils.h:92
 TQUtils.h:93
 TQUtils.h:94
 TQUtils.h:95
 TQUtils.h:96
 TQUtils.h:97
 TQUtils.h:98
 TQUtils.h:99
 TQUtils.h:100
 TQUtils.h:101
 TQUtils.h:102
 TQUtils.h:103
 TQUtils.h:104
 TQUtils.h:105
 TQUtils.h:106
 TQUtils.h:107
 TQUtils.h:108
 TQUtils.h:109
 TQUtils.h:110
 TQUtils.h:111
 TQUtils.h:112
 TQUtils.h:113
 TQUtils.h:114
 TQUtils.h:115
 TQUtils.h:116
 TQUtils.h:117
 TQUtils.h:118
 TQUtils.h:119
 TQUtils.h:120
 TQUtils.h:121
 TQUtils.h:122
 TQUtils.h:123
 TQUtils.h:124
 TQUtils.h:125
 TQUtils.h:126
 TQUtils.h:127
 TQUtils.h:128
 TQUtils.h:129
 TQUtils.h:130
 TQUtils.h:131
 TQUtils.h:132
 TQUtils.h:133
 TQUtils.h:134
 TQUtils.h:135
 TQUtils.h:136
 TQUtils.h:137
 TQUtils.h:138
 TQUtils.h:139
 TQUtils.h:140
 TQUtils.h:141
 TQUtils.h:142
 TQUtils.h:143
 TQUtils.h:144
 TQUtils.h:145
 TQUtils.h:146
 TQUtils.h:147
 TQUtils.h:148
 TQUtils.h:149
 TQUtils.h:150
 TQUtils.h:151
 TQUtils.h:152
 TQUtils.h:153
 TQUtils.h:154
 TQUtils.h:155
 TQUtils.h:156
 TQUtils.h:157
 TQUtils.h:158
 TQUtils.h:159
 TQUtils.h:160
 TQUtils.h:161
 TQUtils.h:162
 TQUtils.h:163
 TQUtils.h:164
 TQUtils.h:165
 TQUtils.h:166