@@ -210,31 +210,41 @@ Histogram1D::Histogram1D(double _initial_begin, double _bin_width, bool _is_log,
210
210
m_out_of_range_count(0.0 ) {}
211
211
212
212
// / \brief Insert a value into the histogram, with an optional weight
213
+ // /
214
+ // / Notes:
215
+ // / - This function takes the "real value" being inserted into the histogram,
216
+ // / whether the histogram is in linear or log space.
217
+ // /
218
+ // / \param log_value The "real value" being inserted into the histogram. If the
219
+ // / histogram is in log space, then the logarithm (std::log10) of `value` is
220
+ // / evaluated and inserted.
221
+ // / \param weight The weight to assign to the value
222
+
213
223
void Histogram1D::insert (double value, double weight) {
214
224
if (m_is_log) {
215
- value = std::log10 (value);
216
- }
217
- if (value < m_begin || m_count.empty ()) {
218
- _reset_bins (value);
219
- }
220
- if (value < m_begin && m_max_size_exceeded) {
221
- m_out_of_range_count += weight;
222
- return ;
225
+ this ->_insert (std::log10 (value), weight);
226
+ } else {
227
+ this ->_insert (value, weight);
223
228
}
229
+ }
224
230
225
- double _tol = 1e-10 ;
226
- int bin = std::floor ((value - m_begin) / m_bin_width + _tol);
227
-
228
- while (bin >= m_count.size ()) {
229
- if (m_count.size () == m_max_size) {
230
- m_max_size_exceeded = true ;
231
- m_out_of_range_count += weight;
232
- return ;
233
- }
234
- m_count.push_back (0 );
231
+ // / \brief Insert the log of a value into a log space histogram directly,
232
+ // / with an optional weight.
233
+ // /
234
+ // / Notes:
235
+ // / - This function is used to update the histogram when the logarithm
236
+ // / (std::log10) of the "real value" has already been evaluated.
237
+ // / - This function throws if the histogram is not in log space.
238
+ // /
239
+ // / \param log_value The logarithm (std::log10) of the "real value"
240
+ // / \param weight The weight to assign to the value
241
+ void Histogram1D::insert_log_value (double log_value, double weight) {
242
+ if (!m_is_log) {
243
+ throw std::runtime_error (
244
+ " Error in Histogram1D::insert_log_value: histogram is not in log "
245
+ " space" );
235
246
}
236
-
237
- m_count[bin] += weight;
247
+ this ->_insert (log_value, weight);
238
248
}
239
249
240
250
// / \brief Return the coordinates of the beginning of each bin range
@@ -293,17 +303,56 @@ void Histogram1D::merge(Histogram1D const &other) {
293
303
// Merge the counts
294
304
std::vector<double > other_bin_coords = other.bin_coords ();
295
305
for (Index i = 0 ; i < other.m_count .size (); ++i) {
296
- this ->insert (other_bin_coords[i], other.m_count [i]);
306
+ if (m_is_log) {
307
+ this ->insert_log_value (other_bin_coords[i], other.m_count [i]);
308
+ } else {
309
+ this ->insert (other_bin_coords[i], other.m_count [i]);
310
+ }
297
311
}
298
312
this ->m_out_of_range_count += other.m_out_of_range_count ;
299
313
}
300
314
315
+ // / \brief Insert a value into the histogram, with an optional weight
316
+ // /
317
+ // / \param value The value to add to the histogram. If `is_log` is true,
318
+ // / the value should already be in log space.
319
+ // / \param weight The weight to assign to the value
320
+ void Histogram1D::_insert (double value, double weight) {
321
+ if (value < m_begin || m_count.empty ()) {
322
+ _reset_bins (value);
323
+ }
324
+ if (value < m_begin && m_max_size_exceeded) {
325
+ m_out_of_range_count += weight;
326
+ return ;
327
+ }
328
+
329
+ double _tol = 1e-10 ;
330
+ int bin = std::floor ((value - m_begin) / m_bin_width + _tol);
331
+
332
+ while (bin >= m_count.size ()) {
333
+ if (m_count.size () == m_max_size) {
334
+ m_max_size_exceeded = true ;
335
+ m_out_of_range_count += weight;
336
+ return ;
337
+ }
338
+ m_count.push_back (0 );
339
+ }
340
+
341
+ m_count[bin] += weight;
342
+ }
343
+
301
344
// / \brief Reset histogram bins if this is the first value being added,
302
345
// / or if `value` is less than `begin`
303
346
// /
304
347
// / \param value The value to add to the histogram. If `is_log` is true,
305
348
// / the value should already be in log space.
306
349
void Histogram1D::_reset_bins (double value) {
350
+ if (!std::isfinite (value)) {
351
+ std::stringstream msg;
352
+ msg << " Error in Histogram1D::_reset_bins: value (=" << value
353
+ << " ) is not finite." ;
354
+ throw std::runtime_error (msg.str ());
355
+ }
307
356
if (m_count.empty ()) {
308
357
while (value < m_begin) {
309
358
m_begin -= m_bin_width;
@@ -356,6 +405,37 @@ Histogram1D combine(std::vector<Histogram1D> const &histograms) {
356
405
return combined;
357
406
}
358
407
408
+ // -- PartitionedHistogram1D --
409
+
410
+ PartitionedHistogram1D::PartitionedHistogram1D (
411
+ std::vector<std::string> const &_partion_names, double _initial_begin,
412
+ double _bin_width, bool _is_log, Index _max_size)
413
+ : m_partition_names(_partion_names),
414
+ m_histograms(_partion_names.size(),
415
+ Histogram1D(_initial_begin, _bin_width, _is_log, _max_size)),
416
+ m_up_to_date(false ) {}
417
+
418
+ // / \brief Make the combined histogram from the partitioned histograms
419
+ void PartitionedHistogram1D::_make_combined_histogram () const {
420
+ m_combined_histogram = combine (m_histograms);
421
+ std::vector<double > bin_coords = m_combined_histogram->bin_coords ();
422
+ if (!bin_coords.empty ()) {
423
+ auto &hist = const_cast <std::vector<Histogram1D> &>(m_histograms);
424
+ for (Index i = 0 ; i < hist.size (); ++i) {
425
+ if (m_combined_histogram->is_log ()) {
426
+ hist[i].insert_log_value (bin_coords.front (), 0.0 );
427
+ hist[i].insert_log_value (bin_coords.back (), 0.0 );
428
+ } else {
429
+ hist[i].insert (bin_coords.front (), 0.0 );
430
+ hist[i].insert (bin_coords.back (), 0.0 );
431
+ }
432
+ }
433
+ }
434
+ m_up_to_date = true ;
435
+ }
436
+
437
+ // -- GenericSelectedEventFunction --
438
+
359
439
// / \brief Constructor - default component names
360
440
GenericSelectedEventFunction::GenericSelectedEventFunction (
361
441
std::string _name, std::string _description, bool _requires_event_state,
0 commit comments