// -*- C++ -*-
//
// This file is part of YODA -- Yet more Objects for Data Analysis
// Copyright (C) 2008-2025 The YODA collaboration (see AUTHORS for details)
//
#include "YODA/Counter.h"

#include <cmath>
#include <iostream>
#include <iomanip>

using namespace std;

namespace YODA {


  // Divide two counters
  /// @todo Add skipnullpts extra optional arg
  Estimate0D divide(const Counter& numer, const Counter& denom) {
    Estimate0D rtn;
    if (numer.path() == denom.path())  rtn.setPath(numer.path());
    if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
    if (denom.val() != 0) {
      const double val = numer.val() / denom.val();
      const double err = val * add_quad(numer.relErr(), denom.relErr());
      rtn.set(val, {-err, err});
    }
    return rtn;
  }


  // Calculate a histogrammed efficiency ratio of two histograms
  /// @todo Add skipnullpts extra optional arg
  Estimate0D efficiency(const Counter& accepted, const Counter& total) {
    Estimate0D tmp = divide(accepted, total);

    // Check that the numerator is consistent with being a subset of the denominator (NOT effNumEntries here!)
    if (accepted.numEntries() > total.numEntries() || accepted.sumW() > total.sumW())
      throw UserError("Attempt to calculate an efficiency when the numerator is not a subset of the denominator");

    // If no entries on the denominator, set eff = err = 0 and move to the next bin
    /// @todo Provide optional alt behaviours to fill with NaN or remove the invalid point, or...
    /// @todo Or throw a LowStatsError exception if h.effNumEntries() (or sumW()?) == 0?
    double eff = std::numeric_limits<double>::quiet_NaN();
    double err = std::numeric_limits<double>::quiet_NaN();
    if (total.sumW() != 0) {
      eff = accepted.sumW() / total.sumW(); //< Actually this is already calculated by the division...
      err = sqrt(abs( ((1-2*eff)*accepted.sumW2() + sqr(eff)*total.sumW2()) / sqr(total.sumW()) ));
    }

    tmp.set(eff, {-err, err});
    return tmp;
  }


}

