32#include "fastjet/tools/BackgroundEstimatorBase.hh"
36FASTJET_BEGIN_NAMESPACE
38LimitedWarning BackgroundEstimatorBase::_warnings_empty_area;
40#ifdef FASTJET_HAVE_THREAD_SAFETY
41BackgroundEstimatorBase::BackgroundEstimatorBase(
const BackgroundEstimatorBase &other_bge){
42 _rescaling_class = other_bge._rescaling_class;
43 _cached_estimate = other_bge._cached_estimate;
44 _cache_available = other_bge._cache_available;
45 _writing_to_cache.store(other_bge._writing_to_cache.load());;
57void BackgroundEstimatorBase::_median_and_stddev(
const vector<double> & quantity_vector,
60 double & stand_dev_if_gaussian,
61 bool do_fj2_calculation)
const {
66 if (quantity_vector.size() == 0) {
68 stand_dev_if_gaussian = 0;
72 vector<double> sorted_quantity_vector = quantity_vector;
73 sort(sorted_quantity_vector.begin(), sorted_quantity_vector.end());
77 int n_jets_used = sorted_quantity_vector.size();
78 if (n_empty_jets < -n_jets_used/4.0) {
79 _warnings_empty_area.warn(
"BackgroundEstimatorBase::_median_and_stddev(...): the estimated empty area is suspiciously large and negative and may lead to an over-estimation of rho. This may be due to (i) a rare statistical fluctuation or (ii) too small a range used to estimate the background properties.");
84 double posn[2] = {0.5, (1.0-0.6827)/2.0};
86 for (
int i = 0; i < 2; i++) {
87 res[i] = _percentile(sorted_quantity_vector, posn[i], n_empty_jets,
92 stand_dev_if_gaussian = res[0] - res[1];
105double BackgroundEstimatorBase::_percentile(
const vector<double> & sorted_quantities,
106 const double percentile,
108 const bool do_fj2_calculation
110 assert(percentile >= 0.0 && percentile <= 1.0);
112 int quantities_size = sorted_quantities.size();
113 if (quantities_size == 0)
return 0;
115 double total_njets = quantities_size + nempty;
116 double percentile_pos;
117 if (do_fj2_calculation) {
118 percentile_pos = (total_njets-1)*percentile - nempty;
120 percentile_pos = (total_njets)*percentile - nempty - 0.5;
124 if (percentile_pos >= 0 && quantities_size > 1) {
125 int int_percentile_pos = int(percentile_pos);
128 if (int_percentile_pos+1 > quantities_size-1){
129 int_percentile_pos = quantities_size-2;
130 percentile_pos = quantities_size-1;
134 sorted_quantities[int_percentile_pos] * (int_percentile_pos+1-percentile_pos)
135 + sorted_quantities[int_percentile_pos+1] * (percentile_pos - int_percentile_pos);
138 }
else if (percentile_pos > -0.5 && quantities_size >= 1
139 && !do_fj2_calculation) {
143 result = sorted_quantities[0];
152void BackgroundEstimatorBase::_lock_if_needed()
const{
153#ifdef FASTJET_HAVE_THREAD_SAFETY
158 }
while (!_writing_to_cache.compare_exchange_strong(expected,
true,
159 memory_order_seq_cst,
160 memory_order_relaxed));
164void BackgroundEstimatorBase::_unlock_if_needed()
const{
165#ifdef FASTJET_HAVE_THREAD_SAFETY
167 _writing_to_cache =
false;