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

class RooAbsReal;
class TQFolder;
class TGraph;
class RooAbsCollection;
class RooWorkspace;
class RooFitResult;
class RooDataSet;
class RooAbsPdf;
class RooArgSet;
class RooArgList;
class RooAbsArg;
class RooRealVar;
class RooLinkedList;
class PiecewiseInterpolation;
class RooHistFunc;
class RooDataHist;
class RooSimultaneous;
class RooProdPdf;
class RooProduct;
class RooRealSumPdf;
class TH1;
class TH2;
#include <RooListProxy.h>
namespace RooStats {
  class HypoTestInverterResult;
}
namespace ROOT { //EXCLUDE
  namespace Fit { //EXCLUDE
    class FitConfig;
  }
}

// The RooFit legacy iterators are deprecated and will be removed in ROOT 6.34
// Range-based loops do not exist for this library in earlier ROOT versions.
// To keep compatability between versions, we define this preprocessor function.
#if ROOT_VERSION_CODE < ROOT_VERSION(6,16,0)
namespace TSUtils_helpers{
  template<class C> auto mkIterator(const C& list){
    return list.createIterator();
  }
  template<> auto mkIterator<RooLinkedList>(const RooLinkedList& list){
    return list.fwdIterator();
  }
  template<class C> auto next(C& iter){
    return iter->Next();
  }
  template<> auto next<RooFIter>(RooFIter& iter){
    return iter.next();
  }  
}
#define ROOFIT_ITERATE(LIST,TYPE,ELEM) TYPE* ELEM = 0; auto* ELEM ## _iter = TSUtils_helpers::mkIterator(LIST);  while (ELEM = (TYPE*) TSUtils_helpers::next(ELEM ## _iter))
#else
#define ROOFIT_ITERATE(LIST,TYPE,ELEM) for(TYPE* ELEM : (LIST)) 
#endif

#include <RooListProxy.h>
#include <RooAbsCollection.h>
#if ROOT_VERSION_CODE < ROOT_VERSION(6,18,0)
struct RooAbsCollection_IteratorHelper { //EXCLUDE
  RooFIter itr;
  RooAbsArg* nextItem;
  RooAbsCollection_IteratorHelper(const RooAbsCollection& c, bool end);
  RooAbsArg* operator++();
  bool operator!=(const RooAbsCollection_IteratorHelper& other);
  bool operator!=(const RooAbsArg* other);
  RooAbsArg* operator*();
};
RooAbsCollection_IteratorHelper begin(const RooAbsCollection& c);
RooAbsCollection_IteratorHelper end(const RooAbsCollection& c);
#endif
#if ROOT_VERSION_CODE < ROOT_VERSION(6,30,0)
struct RooLinkedList_IteratorHelper { //EXCLUDE
  RooFIter itr;
  RooAbsArg* nextItem;
  RooLinkedList_IteratorHelper(const RooLinkedList& c, bool end);
  RooAbsArg* operator++();
  bool operator!=(const RooLinkedList_IteratorHelper& other);
  bool operator!=(const RooAbsArg* other);
  RooAbsArg* operator*();
};
RooLinkedList_IteratorHelper begin(const RooLinkedList& c);
RooLinkedList_IteratorHelper end(const RooLinkedList& c);
struct RooFIter_IteratorHelper { //EXCLUDE
  RooFIter* itr;
  RooAbsArg* nextItem;
  RooFIter_IteratorHelper(RooFIter& it, bool end);
  RooAbsArg* operator++();
  bool operator!=(const RooFIter_IteratorHelper& other);
  bool operator!=(const RooAbsArg* other);
  RooAbsArg* operator*();
};
RooFIter_IteratorHelper begin(RooFIter& it);
RooFIter_IteratorHelper end(RooFIter& it);
struct TIterator_IteratorHelper { //EXCLUDE
  TIterator* itr;
  TObject* nextItem;
  TIterator_IteratorHelper(TIterator* it, bool end);
  TObject* operator++();
  bool operator!=(const TIterator_IteratorHelper& other);
  bool operator!=(const TObject* other);
  TObject* operator*();
};
TIterator_IteratorHelper begin(TObject* it);
TIterator_IteratorHelper end(TObject* it);
#endif


#include <RooMinimizer.h>

class TQTaggable;
class TSStatisticsManager;

#include "TMatrixDSym.h"
namespace RooStats { //EXCLUDE
  class ModelConfig;
}
#include "RooStats/HistFactory/FlexibleInterpVar.h" //forward declaration of the class doesN't quite work here as Cling / Root's dict generation doesn't cope well with nested namespaces...

namespace TSUtils {
  template<class T, class LIST>
  std::vector<T> toVector(LIST& c){
    std::vector<T> v;
    ROOFIT_ITERATE(c,RooAbsArg,arg){
      T elem = dynamic_cast<T>(arg);
      v.push_back(elem);
    }
    return v;
  }
  
  void getPlotRange(RooAbsReal* rv, double& min, double& max, int& nbins);
  const RooArgSet& getVariables(const RooAbsData* _ds);
  const TMatrixDSym* getCovarianceMatrix(const RooFitResult* fitResult);

  bool checkCovarianceHist(TH2* hCovariance, const RooArgSet& parameters, const RooFitResult* fitResult = 0, TQTaggable* options = 0);
  TMatrixDSym retrieveCovariances(RooArgList* parameters, const RooFitResult* fitResult);
  bool checkCovarianceMatrix(const RooFitResult* fitResult, double ccheck);  
  
  TVectorD getErrors(const TMatrixD& covariance);
  TVectorD getErrors(const RooAbsCollection* parameters);  
  TMatrixDSym makeCovarianceMatrix(const TMatrixD& correlation, const TVectorD& errors);
  TMatrixDSym makeCovarianceMatrix(const TMatrixD& correlation, const std::vector<double>& errors);  
  TMatrixDSym makeCorrelationMatrix(const TMatrixD& covariance);  
  const TMatrixDSym* getCorrelationMatrix(const RooFitResult* fitResult);
  TQFolder* convertGraph(TGraph* g);
  TQFolder* makeGraphFolder(const char* name,const std::map<double,double>& values);

  void applySettings(TQTaggable* config, const RooArgSet& allVars, RooStats::ModelConfig* mc);
  TQFolder* applyFitResult(RooAbsCollection* vars, TQFolder* fitResult);

  
  double diffParameterSets(TQFolder* p1, TQFolder* p2, bool verbose);

  RooLinkedList& getListOfSnapshots(RooWorkspace* ws);
  std::vector<TString> getListOfSnapshotNames(RooWorkspace* ws);
  
  bool takeSnapshot(RooWorkspace* workspace, const TString& name, TQTaggable* config = nullptr, TSStatisticsManager* manager = nullptr);
  
  void expandKeys(const RooAbsCollection* nuis, TQFolder * options);
  std::vector<TString> expandNames(const RooAbsCollection* nuis, const TString& filter, const TString& exceptions);
  
  int countConstParameters(const RooAbsCollection* params);
  int countFloatParameters(const RooAbsCollection* params);
  int countConstParameters(const RooAbsCollection& params);
  int countFloatParameters(const RooAbsCollection& params);

  RooAbsPdf* stripConstraints(RooProdPdf* product, const RooArgSet& observables, RooArgSet& constraints);  

  TH2* makeValidMatrix(TH2* orig, bool up, bool isCovariance, bool makeCorrelation, bool verbose);
  
  std::map<TString,double> getParameterValues(const RooAbsCollection& parameters);
  std::map<TString,double> getParameterValues(const RooAbsCollection* parameters);

  void setParametersConstant(const RooAbsCollection* params, bool constVal = true);
  void setParameterValues(const RooAbsCollection* parameters, const std::map<TString,double>& values);
  void setParameterValues(const RooAbsCollection& parameters, const std::map<TString,double>& values);
  void setParameterValues(const RooAbsCollection* parameters, double val);
  void setParameterValues(const RooAbsCollection* parameters, const RooAbsCollection* values);
  void setParameterValues(const RooAbsCollection& parameters, const RooAbsCollection* values);
  void setParameterValues(const RooAbsCollection* parameters, const RooAbsCollection& values);
  void setParameterValues(const RooAbsCollection& parameters, const RooAbsCollection& values);
  void setParametersConstFloat(const RooAbsCollection* parameters, const RooAbsCollection* values);
  void setParametersConstFloat(const RooAbsCollection& parameters, const RooAbsCollection* values);
  void setParametersConstFloat(const RooAbsCollection* parameters, const RooAbsCollection& values);
  void setParametersConstFloat(const RooAbsCollection& parameters, const RooAbsCollection& values);
  void setParameterValues(const RooAbsCollection* parameters, TQTaggable* options, const TString& prefix, bool forceSetConst = false);
  void setParameterValues(const RooAbsCollection& parameters, TQFolder* fitResult);
  void setParametersConstant(const RooAbsCollection* parameters, const std::vector<TString>& parnames, bool constval);

  void setParameterErrors(const RooAbsCollection* parameters, TQTaggable* options, const TString& prefix, bool forceSetConst = false);
  void setParameterRanges(const RooAbsCollection* parameters, TQTaggable* options, const TString& prefix);  
  void addParameters(const RooAbsCollection* parameters, const std::vector<TString>& parnames, RooAbsCollection& pars);
  std::vector<TString> getParameterKeys(TQTaggable* tags, const TString& prefix);  
  
  template<class stringT> void getParameterNames(const RooAbsCollection* l,std::vector<stringT>& names);
  template<class stringT> void getParameterNames(const RooAbsCollection& l,std::vector<stringT>& names);  
  RooWorkspace* makeCleanWorkspace(RooWorkspace* oldWS, const char* newName, const char* mcname = "ModelConfig", bool copySnapshots=true, bool catchUnaccountedParameters=true);

  TQFolder * convertFitResults(RooFitResult * fitResult, TQTaggable* options = NULL, ROOT::Fit::FitConfig* fitConfig=NULL);
  TQFolder * convertParameterList(const RooAbsCollection * list, const TString& filter = "*");
  int convertParameterList(const RooAbsCollection * list, TQFolder* result_list, const TString& filter = "*");

  RooFitResult * prefitResults(RooAbsCollection* params);
  RooFitResult * convertFitResults(TQFolder* fitResult, RooAbsCollection * params = NULL);
  template<class T> RooFitResult * convertFitResults(TQFolder* fitResult, const std::vector<T>& params);  
  RooArgList* convertParameterList(TQFolder* folder, RooAbsCollection * params);

  void removeFloatingParameters(RooAbsCollection& set);
  void removeConstantParameters(RooAbsCollection& set);  
  
  TQFolder* modifyFitResults(TQFolder* fitResults, TQFolder* changes);
  RooAbsPdf * createHessePdf(const RooFitResult* fr, const RooAbsCollection* params);

  RooDataSet* getDataHistogram(RooAbsPdf* pdf, RooArgSet* observables, RooRealVar* weightVar = NULL, RooAbsArg* moreArgs = NULL);
  TH1* getHistogram(RooAbsPdf* pdf, RooArgSet* observables);

  std::vector<double> getBinning(RooAbsPdf* pdf, RooRealVar* obs);

  int nParameters(RooAbsReal* func);
  int nParameters(const RooMinimizer& minimizer);

#if ROOT_VERSION_CODE < ROOT_VERSION(6,25,0)  
  RooMinimizerFcn*    getFunction(RooMinimizer& minimizer);  
#else
  RooAbsMinimizerFcn* getFunction(RooMinimizer& minimizer);
#endif
  
  double  getPropagatedError(RooAbsReal* var, const RooFitResult* fr, const double threshold = 0);

  TMatrixDSym getCorrelationMatrix(const TMatrixDSym& V);
  
  //moderatly hacky helpers to modify workspaces inplace
  std::vector<const RooAbsArg*>* getConstituents(const RooAbsArg* parent);
  std::set<const RooAbsArg*>* getContributionsRecursive(const RooAbsArg* rootNode, TClass* cl = nullptr, bool recurseMatching=false, std::set<const RooAbsArg*>* elements = nullptr);
  
  //helper classes to access some protected members of certain RooFit classes
 
  void printInfo(const PiecewiseInterpolation* _interp);
  RooAbsArg* getNominalMember(const PiecewiseInterpolation* _interp);
  RooListProxy* getParamSetMember(const PiecewiseInterpolation* _interp);
  RooListProxy* getHighSetMember(const PiecewiseInterpolation* _interp);
  RooListProxy* getLowSetMember(const PiecewiseInterpolation* _interp);

  //RooStats::HistFactory::FlexibleInterpVar
  Double_t* getNominalMemberPtr(const RooStats::HistFactory::FlexibleInterpVar* interp);
  Double_t getNominalMember(const RooStats::HistFactory::FlexibleInterpVar* interp);
  std::vector<double>* getHighMember(const RooStats::HistFactory::FlexibleInterpVar* interp);
  std::vector<double>* getLowMember(const RooStats::HistFactory::FlexibleInterpVar* interp);
  RooListProxy* getParamListMember(const RooStats::HistFactory::FlexibleInterpVar* interp);

  void printInfo(RooDataSet* _ds);

  void printBins(RooDataHist* _dh);
  void scaleHist(RooDataHist* _dh, double scale);
  void scaleDifferenceToNominal(RooDataHist* _var, const RooDataHist* _nom, double scale);

  //std::vector<const RooAbsArg*>* getConstituents(const RooSimultaneous* sim);
  void removeConstituentsFromRooSimultaneous(RooSimultaneous* sim, const TString& filter);
  void removeConstituentsFromRooRealSumPdf(RooRealSumPdf* pdf, const TString& filter);
  void removeConstituentsFromRooProdPdf(RooProdPdf* pdf, const TString& filter);
  void removeConstituentsFromRooProduct(RooProduct* prod, const TString& filter);
  void removeConstituentsFromPiecewiseInterpolation(PiecewiseInterpolation* interp, const TString& filter);
  void removeConstituentsFromFlexibleInterpVar(RooStats::HistFactory::FlexibleInterpVar* interp, const TString& filter);
  
  RooDataHist* getDataHist(const RooHistFunc* h);
  
  std::map<std::string,RooArgSet>* getNamedSets(RooWorkspace* ws);

  bool importObjectToWorkspace(RooWorkspace* ws, RooAbsArg* obj);
  bool importObjectToWorkspace(RooWorkspace* ws, RooAbsData* obj);

  RooStats::HypoTestInverterResult* collectToyLimits(const std::vector<std::string>& filenames,const char* limitname = "Limits", const char* resultname = "HypoTestInverterResult");
  int fixToys(RooStats::HypoTestInverterResult* r);

  std::string lookupName(const RooAbsCategory* cat, int i);

  std::map<std::vector<double> ,RooAbsReal*> slice(RooAbsReal* func, const std::vector<RooRealVar*>& observables, const RooArgList& nps, double relThreshold = 0);
}

#endif
 TSUtils.h:1
 TSUtils.h:2
 TSUtils.h:3
 TSUtils.h:4
 TSUtils.h:5
 TSUtils.h:6
 TSUtils.h:7
 TSUtils.h:8
 TSUtils.h:9
 TSUtils.h:10
 TSUtils.h:11
 TSUtils.h:12
 TSUtils.h:13
 TSUtils.h:14
 TSUtils.h:15
 TSUtils.h:16
 TSUtils.h:17
 TSUtils.h:18
 TSUtils.h:19
 TSUtils.h:20
 TSUtils.h:21
 TSUtils.h:22
 TSUtils.h:23
 TSUtils.h:24
 TSUtils.h:25
 TSUtils.h:26
 TSUtils.h:27
 TSUtils.h:28
 TSUtils.h:29
 TSUtils.h:30
 TSUtils.h:31
 TSUtils.h:32
 TSUtils.h:33
 TSUtils.h:34
 TSUtils.h:35
 TSUtils.h:36
 TSUtils.h:37
 TSUtils.h:38
 TSUtils.h:39
 TSUtils.h:40
 TSUtils.h:41
 TSUtils.h:42
 TSUtils.h:43
 TSUtils.h:44
 TSUtils.h:45
 TSUtils.h:46
 TSUtils.h:47
 TSUtils.h:48
 TSUtils.h:49
 TSUtils.h:50
 TSUtils.h:51
 TSUtils.h:52
 TSUtils.h:53
 TSUtils.h:54
 TSUtils.h:55
 TSUtils.h:56
 TSUtils.h:57
 TSUtils.h:58
 TSUtils.h:59
 TSUtils.h:60
 TSUtils.h:61
 TSUtils.h:62
 TSUtils.h:63
 TSUtils.h:64
 TSUtils.h:65
 TSUtils.h:66
 TSUtils.h:67
 TSUtils.h:68
 TSUtils.h:69
 TSUtils.h:70
 TSUtils.h:71
 TSUtils.h:72
 TSUtils.h:73
 TSUtils.h:74
 TSUtils.h:75
 TSUtils.h:76
 TSUtils.h:77
 TSUtils.h:78
 TSUtils.h:79
 TSUtils.h:80
 TSUtils.h:81
 TSUtils.h:82
 TSUtils.h:83
 TSUtils.h:84
 TSUtils.h:85
 TSUtils.h:86
 TSUtils.h:87
 TSUtils.h:88
 TSUtils.h:89
 TSUtils.h:90
 TSUtils.h:91
 TSUtils.h:92
 TSUtils.h:93
 TSUtils.h:94
 TSUtils.h:95
 TSUtils.h:96
 TSUtils.h:97
 TSUtils.h:98
 TSUtils.h:99
 TSUtils.h:100
 TSUtils.h:101
 TSUtils.h:102
 TSUtils.h:103
 TSUtils.h:104
 TSUtils.h:105
 TSUtils.h:106
 TSUtils.h:107
 TSUtils.h:108
 TSUtils.h:109
 TSUtils.h:110
 TSUtils.h:111
 TSUtils.h:112
 TSUtils.h:113
 TSUtils.h:114
 TSUtils.h:115
 TSUtils.h:116
 TSUtils.h:117
 TSUtils.h:118
 TSUtils.h:119
 TSUtils.h:120
 TSUtils.h:121
 TSUtils.h:122
 TSUtils.h:123
 TSUtils.h:124
 TSUtils.h:125
 TSUtils.h:126
 TSUtils.h:127
 TSUtils.h:128
 TSUtils.h:129
 TSUtils.h:130
 TSUtils.h:131
 TSUtils.h:132
 TSUtils.h:133
 TSUtils.h:134
 TSUtils.h:135
 TSUtils.h:136
 TSUtils.h:137
 TSUtils.h:138
 TSUtils.h:139
 TSUtils.h:140
 TSUtils.h:141
 TSUtils.h:142
 TSUtils.h:143
 TSUtils.h:144
 TSUtils.h:145
 TSUtils.h:146
 TSUtils.h:147
 TSUtils.h:148
 TSUtils.h:149
 TSUtils.h:150
 TSUtils.h:151
 TSUtils.h:152
 TSUtils.h:153
 TSUtils.h:154
 TSUtils.h:155
 TSUtils.h:156
 TSUtils.h:157
 TSUtils.h:158
 TSUtils.h:159
 TSUtils.h:160
 TSUtils.h:161
 TSUtils.h:162
 TSUtils.h:163
 TSUtils.h:164
 TSUtils.h:165
 TSUtils.h:166
 TSUtils.h:167
 TSUtils.h:168
 TSUtils.h:169
 TSUtils.h:170
 TSUtils.h:171
 TSUtils.h:172
 TSUtils.h:173
 TSUtils.h:174
 TSUtils.h:175
 TSUtils.h:176
 TSUtils.h:177
 TSUtils.h:178
 TSUtils.h:179
 TSUtils.h:180
 TSUtils.h:181
 TSUtils.h:182
 TSUtils.h:183
 TSUtils.h:184
 TSUtils.h:185
 TSUtils.h:186
 TSUtils.h:187
 TSUtils.h:188
 TSUtils.h:189
 TSUtils.h:190
 TSUtils.h:191
 TSUtils.h:192
 TSUtils.h:193
 TSUtils.h:194
 TSUtils.h:195
 TSUtils.h:196
 TSUtils.h:197
 TSUtils.h:198
 TSUtils.h:199
 TSUtils.h:200
 TSUtils.h:201
 TSUtils.h:202
 TSUtils.h:203
 TSUtils.h:204
 TSUtils.h:205
 TSUtils.h:206
 TSUtils.h:207
 TSUtils.h:208
 TSUtils.h:209
 TSUtils.h:210
 TSUtils.h:211
 TSUtils.h:212
 TSUtils.h:213
 TSUtils.h:214
 TSUtils.h:215
 TSUtils.h:216
 TSUtils.h:217
 TSUtils.h:218
 TSUtils.h:219
 TSUtils.h:220
 TSUtils.h:221
 TSUtils.h:222
 TSUtils.h:223
 TSUtils.h:224
 TSUtils.h:225
 TSUtils.h:226
 TSUtils.h:227
 TSUtils.h:228
 TSUtils.h:229
 TSUtils.h:230
 TSUtils.h:231
 TSUtils.h:232
 TSUtils.h:233
 TSUtils.h:234
 TSUtils.h:235
 TSUtils.h:236
 TSUtils.h:237
 TSUtils.h:238
 TSUtils.h:239
 TSUtils.h:240
 TSUtils.h:241
 TSUtils.h:242
 TSUtils.h:243
 TSUtils.h:244
 TSUtils.h:245
 TSUtils.h:246
 TSUtils.h:247
 TSUtils.h:248
 TSUtils.h:249
 TSUtils.h:250
 TSUtils.h:251
 TSUtils.h:252
 TSUtils.h:253
 TSUtils.h:254
 TSUtils.h:255
 TSUtils.h:256
 TSUtils.h:257
 TSUtils.h:258
 TSUtils.h:259
 TSUtils.h:260
 TSUtils.h:261
 TSUtils.h:262
 TSUtils.h:263
 TSUtils.h:264
 TSUtils.h:265
 TSUtils.h:266
 TSUtils.h:267
 TSUtils.h:268
 TSUtils.h:269
 TSUtils.h:270
 TSUtils.h:271
 TSUtils.h:272
 TSUtils.h:273
 TSUtils.h:274
 TSUtils.h:275
 TSUtils.h:276
 TSUtils.h:277
 TSUtils.h:278
 TSUtils.h:279
 TSUtils.h:280
 TSUtils.h:281
 TSUtils.h:282
 TSUtils.h:283