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

#include "TString.h"

#include "RooAbsPdf.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooArgSet.h"
#include "RooArgList.h"
#include "RooCategory.h"
#include "RooDataSet.h"
#include "RooRealSumPdf.h"
#include "RooSimultaneous.h"
#include "RooFitResult.h"


#include "RooAbsOptTestStatistic.h"

#include "QFramework/TQFolder.h"
#include "QFramework/TQNamedTaggable.h"

#include "TMatrixDSym.h"
#include "TVectorD.h"

#include <list>
#include <map>
#include <vector>

class RooExpectedEvents : public RooAbsReal {
  RooAbsPdf& _pdf;
  const RooArgSet& _normSet;
public:
  RooExpectedEvents(const char* name, const char* title, RooAbsPdf& pdf, const RooArgSet& normSet);
  virtual ~RooExpectedEvents();
  virtual double evaluate() const override;
  virtual TObject* clone(const char*) const override;

  ClassDef(RooExpectedEvents,1)
};

class RooPdfEvaluator : public RooAbsTestStatistic { //nested
  RooAbsPdf* _hesse;
  RooArgSet* nset;
  RooArgList* params;
  TMatrixDSym covMat;
  TMatrixDSym corrMat;
  double threshold;
  double ccheck;
public:
  enum ErrorCalculation {
    NoErrors=0,
    LinearErrors=1,
    SamplingErrors=2
  };

#if ROOT_VERSION_CODE >= ROOT_VERSION(6,25,0) 
  virtual RooAbsTestStatistic* create(const char * /*name*/, 
                                      const char * /*title*/, 
                                      RooAbsReal& /*real*/, 
                                      RooAbsData& /*data*/, 
                                      const RooArgSet& /*projDeps*/, 
                                      Configuration const& /*cfg*/) override { return NULL; }
#else
  RooAbsTestStatistic* create(const char *, const char *, RooAbsReal&, RooAbsData&,
                              const RooArgSet&, const char*, const char*,
                              Int_t, RooFit::MPSplit, Bool_t, Bool_t, Bool_t) override {  return NULL; }
#endif
  virtual Double_t combinedValue(RooAbsReal** /*gofArray*/, Int_t /*nVal*/) const override { return 0.; }
  
  RooPdfEvaluator(RooAbsReal* func, const RooFitResult* result, double threshold, double ccheck = 0.05);
  RooPdfEvaluator(const RooPdfEvaluator& other);
  virtual ~RooPdfEvaluator();
  virtual TObject* clone(const char*) const override;
  virtual Double_t evaluatePartition(
#if ROOT_VERSION_CODE >= ROOT_VERSION(6,20,00)
                                     size_t /*firstEvent*/, size_t /*lastEvent*/, size_t /*stepSize*/
#else
                                     Int_t /*firstEvent*/, Int_t /*lastEvent*/, Int_t /*stepSize*/
#endif
                                     ) const ;

  RooAbsReal* getFunc();
  void fillHistogram(TH1 *hist,const RooArgList& plotVars, ErrorCalculation mode = RooPdfEvaluator::LinearErrors);
  double getValue() const;
  double getError(ErrorCalculation mode = RooPdfEvaluator::LinearErrors);
  void setDirty();

  int getParameterIndex(const char* pname) const;
  void setCorrelation(const char* p1, const char* p2, double val);
  double getCorrelation(const char* p1, const char* p2) const;

protected:
  TVectorD getVariations();
  bool allEntriesZero(const TVectorD& v) const;
};

class TSHistogramExporter : public TQNamedTaggable {
  std::list<RooAbsData*> allData;
  TQFolder* styleModel;
  RooFitResult* fitResult;

public:
  TString nfPattern;

protected:
  RooDataSet* getDataRegion(RooDataSet* ds, const TString& catname) const;
public:

  TSHistogramExporter(TQFolder* style = NULL, RooFitResult* fr = NULL);
  virtual ~TSHistogramExporter();

  class Region { //nested
  protected:
    TString name;
    RooAbsPdf* func;
    RooArgSet observables;
    std::map<RooAbsReal*,std::vector<int>> removedBins;
    RooSimultaneous* simPdf;
    bool combined = false;
    std::map<TString,RooRealVar*> selectionVars;
    std::map<TString,std::vector<RooAbsReal*> > samples;
    std::map<TString,std::vector<RooDataSet*> >datasets;
  public:
    void collectSelectionVars(const TString& nfPattern);
    void select();
    bool isCombined() const;
    const RooArgSet& getObservables() const;
    void removeBins(RooAbsReal* obs, const std::vector<int> bins);
    std::vector<int> getRemovedBins(RooAbsReal* obs) const;
    bool isRemovedBin(RooAbsReal* obs, int idx) const;    
    const TString& getName() const;
    RooCategory* getChannelCategory();
    Region(const TString& n, RooAbsPdf* p, RooArgSet* obs, bool combined=false);
    Region(const TString& n, RooSimultaneous* sim, RooRealSumPdf* p, RooArgSet* obs,bool combined=false);
    virtual ~Region();
    std::vector<TString> allData() const;
    std::vector<TString> allSamples() const;
    RooDataSet* getData(const TString& name, int index) const ;
    int nData(const TString& name) const;
    void print() const;
    RooAbsPdf* getPdf() const;
    void addData(const TString& name, RooDataSet* ds);
    void addSample(const TString& name, RooAbsReal* obj);
    void addSamples(const Region* other);
    void addSamples(RooRealSumPdf* sumPdf);
    RooAbsReal* createIntegral(const TString& nameAppend, const RooArgSet& normSet, const RooArgSet& projectedVars) const;
    RooAbsReal* createIntegral() const;
    double expectedEvents() const;
    TH1* makeHistogram(const TString& n, RooArgList& x) const;
    void selectComponents  (const std::vector<TString>& keys) const;
    void selectComponentsLegacy  (const std::vector<TString>& keys) const;
    void unselectComponentsLegacy() const;
    void unselectComponents() const;
    TString getComponentNames(const std::vector<TString>& keys) const;
    TString getSelectionVariableNames(const std::vector<TString>& keys) const;
  };

  static RooArgSet* selectBranchNodes(RooAbsReal* func, const TString& compNames);
  static void selectComponents  (RooAbsReal* func, const TString& compNames);
  static void unselectComponents(RooAbsReal* func);

  static std::vector<TSHistogramExporter::Region*> makeRegions(RooSimultaneous* pdf, const RooArgSet* observables, const std::list<RooAbsData*>& datasets);
  static std::map<TString,RooRealSumPdf*> getComponents(RooSimultaneous* pdf);
  static RooCategory* getCategories(RooSimultaneous* simPdf);


  static int addCombinedRegions(TCollection* input, std::vector<TSHistogramExporter::Region*>& regions, const std::vector<TSHistogramExporter::Region*>& origregions);
  static int addCombinedSamples(TCollection* input,std::map< const TString, std::vector<TString> >& samples, const std::vector<TString>& allSamples);

  bool getMC(TDirectory* dir, Region* region, std::map< const TString, std::vector<TString> > samples, int calculateErrors=1, double checkThreshold=0.05);
  int getData(TDirectory* dir, const TString& selector, const TString& histname, const Region* region);

  ClassDef(TSHistogramExporter,0)
};


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