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

#include <iostream>
#include "TH1.h"
#include "TString.h"

class TQGridScanNormalObservable;
class TQGridScanSplitObservable;


// This class holds significance data for a given set of cuts
// It holds the bin numbers corresponding to these cut values
// When the cut values themselves are requested, they are lazily evaluated from the 
// corresponding hist of the grid scan results and stored in memory. The results can then be
// re-written to disc to store the cut values permanently.
class TQGridScanPoint : public TObject {
public:
  using NormalBounds = std::vector<std::pair<int, int>>; // bin numbers
  using SplitBounds = std::vector<int>;
  using NormalVals = std::vector<std::pair<double, double>>; // values of bin edges
  using SplitVals = std::vector<double>;
  constexpr static double kValNotSet = std::numeric_limits<double>::quiet_NaN();
  //using NormalObsVec = std::vector<TQGridScanNormalObservable*>;
  //using SplitObsVec = std::vector<TQGridScanSplitObservable*>;

  TQGridScanPoint() = default;

  TQGridScanPoint(
      NormalBounds normalBounds,
      SplitBounds splitBounds,
      double significance,
      TString info
  );
  TQGridScanPoint(
      NormalBounds normalBounds,
      double significance,
      TString info
  );
  TQGridScanPoint(
      NormalBounds normalBounds,
      SplitBounds splitBounds,
      std::vector<double> foms, // figure of merits
      TString info
  );
TQGridScanPoint(
    NormalBounds normalBounds,
    std::vector<double> foms,
    TString info
);

  double significance() const { return m_significance; }
  // std::vector<double> foms() const { return m_foms; }
  // temporary hack:
  std::vector<double> foms() const {
    if (!m_foms.empty()) {return m_foms;}
    else {return {m_significance};}
  }

  const NormalBounds& normalBounds() const { return m_normalBounds; }
  const SplitBounds& splitBounds() const { return m_splitBounds; }
  const NormalVals& normalVals(const std::vector<TQGridScanNormalObservable*>& obsVec);
  const SplitVals& splitVals(const std::vector<TQGridScanSplitObservable*>& obsVec);
  
  void print();

  const TString& info() const { return m_info; }

  // Pointers to the normal and split scan observables are stored to access bin edge values
  //static void setNormalObs(NormalObsVec* obsVec) { normalObs = obsVec; }
  //static void setSplitObs(SplitObsVec* obsVec) { splitObs = obsVec; }
  
  //static NormalObsVec* normalObs;
  //static SplitObsVec* splitObs;

  friend bool operator < (const TQGridScanPoint& lhs, const TQGridScanPoint& rhs) { return lhs.significance() < rhs.significance(); }
  friend bool operator > (const TQGridScanPoint& lhs, const TQGridScanPoint& rhs) { return lhs.significance() > rhs.significance(); }

  ClassDefOverride(TQGridScanPoint,2)  // auxiliary class for the TQGridScanner

protected:
  double m_significance = 0.0;
  std::vector<double> m_foms;
  TString m_info;
  
  NormalBounds m_normalBounds;
  SplitBounds m_splitBounds;
  NormalVals m_normalVals;
  SplitVals m_splitVals;
};

//bool operator < (const TQGridScanPoint& first, const TQGridScanPoint& second) {
//  return (first.significance() < second.significance());
//}
//bool operator > (const TQGridScanPoint& first, const TQGridScanPoint& second) {
//  return (first.significance() > second.significance());
//}

#endif

 TQGridScanPoint.h:1
 TQGridScanPoint.h:2
 TQGridScanPoint.h:3
 TQGridScanPoint.h:4
 TQGridScanPoint.h:5
 TQGridScanPoint.h:6
 TQGridScanPoint.h:7
 TQGridScanPoint.h:8
 TQGridScanPoint.h:9
 TQGridScanPoint.h:10
 TQGridScanPoint.h:11
 TQGridScanPoint.h:12
 TQGridScanPoint.h:13
 TQGridScanPoint.h:14
 TQGridScanPoint.h:15
 TQGridScanPoint.h:16
 TQGridScanPoint.h:17
 TQGridScanPoint.h:18
 TQGridScanPoint.h:19
 TQGridScanPoint.h:20
 TQGridScanPoint.h:21
 TQGridScanPoint.h:22
 TQGridScanPoint.h:23
 TQGridScanPoint.h:24
 TQGridScanPoint.h:25
 TQGridScanPoint.h:26
 TQGridScanPoint.h:27
 TQGridScanPoint.h:28
 TQGridScanPoint.h:29
 TQGridScanPoint.h:30
 TQGridScanPoint.h:31
 TQGridScanPoint.h:32
 TQGridScanPoint.h:33
 TQGridScanPoint.h:34
 TQGridScanPoint.h:35
 TQGridScanPoint.h:36
 TQGridScanPoint.h:37
 TQGridScanPoint.h:38
 TQGridScanPoint.h:39
 TQGridScanPoint.h:40
 TQGridScanPoint.h:41
 TQGridScanPoint.h:42
 TQGridScanPoint.h:43
 TQGridScanPoint.h:44
 TQGridScanPoint.h:45
 TQGridScanPoint.h:46
 TQGridScanPoint.h:47
 TQGridScanPoint.h:48
 TQGridScanPoint.h:49
 TQGridScanPoint.h:50
 TQGridScanPoint.h:51
 TQGridScanPoint.h:52
 TQGridScanPoint.h:53
 TQGridScanPoint.h:54
 TQGridScanPoint.h:55
 TQGridScanPoint.h:56
 TQGridScanPoint.h:57
 TQGridScanPoint.h:58
 TQGridScanPoint.h:59
 TQGridScanPoint.h:60
 TQGridScanPoint.h:61
 TQGridScanPoint.h:62
 TQGridScanPoint.h:63
 TQGridScanPoint.h:64
 TQGridScanPoint.h:65
 TQGridScanPoint.h:66
 TQGridScanPoint.h:67
 TQGridScanPoint.h:68
 TQGridScanPoint.h:69
 TQGridScanPoint.h:70
 TQGridScanPoint.h:71
 TQGridScanPoint.h:72
 TQGridScanPoint.h:73
 TQGridScanPoint.h:74
 TQGridScanPoint.h:75
 TQGridScanPoint.h:76
 TQGridScanPoint.h:77
 TQGridScanPoint.h:78
 TQGridScanPoint.h:79
 TQGridScanPoint.h:80
 TQGridScanPoint.h:81
 TQGridScanPoint.h:82
 TQGridScanPoint.h:83
 TQGridScanPoint.h:84
 TQGridScanPoint.h:85
 TQGridScanPoint.h:86
 TQGridScanPoint.h:87
 TQGridScanPoint.h:88
 TQGridScanPoint.h:89
 TQGridScanPoint.h:90
 TQGridScanPoint.h:91
 TQGridScanPoint.h:92
 TQGridScanPoint.h:93
 TQGridScanPoint.h:94
 TQGridScanPoint.h:95
 TQGridScanPoint.h:96
 TQGridScanPoint.h:97
 TQGridScanPoint.h:98
 TQGridScanPoint.h:99
 TQGridScanPoint.h:100
 TQGridScanPoint.h:101