LCOV - code coverage report
Current view: top level - core/include/scipp/core/element - event_operations.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 33 35 94.3 %
Date: 2024-04-28 01:25:40 Functions: 27 330 8.2 %

          Line data    Source code
       1             : // SPDX-License-Identifier: BSD-3-Clause
       2             : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
       3             : /// @file
       4             : /// @author Simon Heybrock
       5             : #pragma once
       6             : 
       7             : #include "scipp/common/numeric.h"
       8             : #include "scipp/common/overloaded.h"
       9             : 
      10             : #include "scipp/units/unit.h"
      11             : 
      12             : #include "scipp/core/element/arg_list.h"
      13             : #include "scipp/core/histogram.h"
      14             : #include "scipp/core/time_point.h"
      15             : #include "scipp/core/transform_common.h"
      16             : #include "scipp/core/value_and_variance.h"
      17             : 
      18             : namespace scipp::core::element::event {
      19             : 
      20         829 : constexpr auto get = [](const auto &x, const scipp::index i) {
      21             :   if constexpr (is_ValueAndVariance_v<std::decay_t<decltype(x)>>)
      22           0 :     return ValueAndVariance{x.value[i], x.variance[i]};
      23             :   else
      24         829 :     return x[i];
      25             : };
      26             : 
      27             : namespace map_detail {
      28             : template <class Coord, class Edge, class Weight>
      29             : using args = std::tuple<Coord, scipp::span<const Edge>,
      30             :                         scipp::span<const Weight>, Weight>;
      31             : } // namespace map_detail
      32             : 
      33             : constexpr auto map = overloaded{
      34             :     element::arg_list<map_detail::args<int64_t, int64_t, double>,
      35             :                       map_detail::args<int64_t, int64_t, float>,
      36             :                       map_detail::args<int64_t, int64_t, int64_t>,
      37             :                       map_detail::args<int64_t, int64_t, int32_t>,
      38             :                       map_detail::args<int64_t, int64_t, bool>,
      39             :                       map_detail::args<int32_t, int32_t, double>,
      40             :                       map_detail::args<int32_t, int32_t, float>,
      41             :                       map_detail::args<int32_t, int32_t, int64_t>,
      42             :                       map_detail::args<int32_t, int32_t, int32_t>,
      43             :                       map_detail::args<int32_t, int32_t, bool>,
      44             :                       map_detail::args<int64_t, double, double>,
      45             :                       map_detail::args<int64_t, double, float>,
      46             :                       map_detail::args<int64_t, double, int64_t>,
      47             :                       map_detail::args<int64_t, double, int32_t>,
      48             :                       map_detail::args<int64_t, double, bool>,
      49             :                       map_detail::args<int32_t, double, double>,
      50             :                       map_detail::args<int32_t, double, float>,
      51             :                       map_detail::args<int32_t, double, int64_t>,
      52             :                       map_detail::args<int32_t, double, int32_t>,
      53             :                       map_detail::args<int32_t, double, bool>,
      54             :                       map_detail::args<time_point, time_point, double>,
      55             :                       map_detail::args<time_point, time_point, float>,
      56             :                       map_detail::args<time_point, time_point, int64_t>,
      57             :                       map_detail::args<time_point, time_point, int32_t>,
      58             :                       map_detail::args<time_point, time_point, bool>,
      59             :                       map_detail::args<double, double, double>,
      60             :                       map_detail::args<double, double, float>,
      61             :                       map_detail::args<double, double, int64_t>,
      62             :                       map_detail::args<double, double, int32_t>,
      63             :                       map_detail::args<double, double, bool>,
      64             :                       map_detail::args<float, double, double>,
      65             :                       map_detail::args<float, double, float>,
      66             :                       map_detail::args<float, double, int64_t>,
      67             :                       map_detail::args<float, double, int32_t>,
      68             :                       map_detail::args<float, double, bool>,
      69             :                       map_detail::args<float, float, float>,
      70             :                       map_detail::args<float, float, int64_t>,
      71             :                       map_detail::args<float, float, int32_t>,
      72             :                       map_detail::args<float, float, bool>,
      73             :                       map_detail::args<double, float, double>,
      74             :                       map_detail::args<double, float, float>,
      75             :                       map_detail::args<double, float, int64_t>,
      76             :                       map_detail::args<double, float, int32_t>,
      77             :                       map_detail::args<double, float, bool>>,
      78             :     transform_flags::expect_no_variance_arg<0>,
      79             :     transform_flags::expect_no_variance_arg<1>,
      80         164 :     [](const units::Unit &x, const units::Unit &edges,
      81             :        const units::Unit &weights, const units::Unit &fill) {
      82         164 :       expect::equals(x, edges);
      83         164 :       expect::equals(weights, fill);
      84         164 :       return weights;
      85             :     }};
      86             : 
      87             : constexpr auto map_linspace =
      88         244 :     overloaded{map, [](const auto &coord, const auto &edges,
      89             :                        const auto &weights, const auto &fill) {
      90         244 :                  const auto params = linear_edge_params(edges);
      91         244 :                  const auto bin = get_bin<scipp::index>(coord, edges, params);
      92         244 :                  return bin < 0 ? fill : get(weights, bin);
      93             :                }};
      94             : 
      95             : constexpr auto map_sorted_edges =
      96          88 :     overloaded{map, [](const auto &coord, const auto &edges,
      97             :                        const auto &weights, const auto &fill) {
      98          88 :                  auto it = std::upper_bound(edges.begin(), edges.end(), coord);
      99         173 :                  return (it == edges.end() || it == edges.begin())
     100          88 :                             ? fill
     101          88 :                             : get(weights, --it - edges.begin());
     102             :                }};
     103             : 
     104             : constexpr auto lookup_previous =
     105         210 :     overloaded{map, [](const auto &point, const auto &x, const auto &weights,
     106             :                        const auto &fill) {
     107         210 :                  auto it = std::upper_bound(x.begin(), x.end(), point);
     108         210 :                  return it == x.begin() ? fill : get(weights, --it - x.begin());
     109             :                }};
     110             : 
     111             : namespace map_and_mul_detail {
     112             : template <class Data, class Coord, class Edge, class Weight>
     113             : using args =
     114             :     std::tuple<Data, Coord, scipp::span<const Edge>, scipp::span<const Weight>>;
     115             : } // namespace map_and_mul_detail
     116             : 
     117             : constexpr auto map_and_mul = overloaded{
     118             :     element::arg_list<
     119             :         map_and_mul_detail::args<double, double, double, double>,
     120             :         map_and_mul_detail::args<double, double, double, float>,
     121             :         map_and_mul_detail::args<float, double, double, double>,
     122             :         map_and_mul_detail::args<float, double, double, float>,
     123             :         map_and_mul_detail::args<double, float, float, double>,
     124             :         map_and_mul_detail::args<double, time_point, time_point, double>,
     125             :         map_and_mul_detail::args<double, time_point, time_point, float>,
     126             :         map_and_mul_detail::args<float, time_point, time_point, double>,
     127             :         map_and_mul_detail::args<float, time_point, time_point, float>>,
     128             :     transform_flags::expect_no_variance_arg<1>,
     129             :     transform_flags::expect_no_variance_arg<2>,
     130             :     transform_flags::expect_no_variance_arg<3>, // caught in transform anyway,
     131             :                                                 // but adding this should save
     132             :                                                 // binary size and compile time
     133         117 :     [](units::Unit &data, const units::Unit &x, const units::Unit &edges,
     134             :        const units::Unit &weights) {
     135         117 :       expect::equals(x, edges);
     136         117 :       data *= weights;
     137         117 :     }};
     138             : 
     139             : constexpr auto map_and_mul_linspace = overloaded{
     140             :     map_and_mul,
     141         325 :     [](auto &data, const auto x, const auto &edges, const auto &weights) {
     142         325 :       const auto params = linear_edge_params(edges);
     143         325 :       if (const auto bin = get_bin<scipp::index>(x, edges, params); bin < 0)
     144           7 :         data *= 0.0;
     145             :       else
     146         318 :         data *= get(weights, bin);
     147         325 :     }};
     148             : 
     149             : constexpr auto map_and_mul_sorted_edges =
     150          12 :     overloaded{map_and_mul, [](auto &data, const auto x, const auto &edges,
     151             :                                const auto &weights) {
     152          12 :                  auto it = std::upper_bound(edges.begin(), edges.end(), x);
     153          12 :                  if (it == edges.end() || it == edges.begin())
     154           0 :                    data *= 0.0;
     155             :                  else
     156          12 :                    data *= get(weights, --it - edges.begin());
     157          12 :                }};
     158             : 
     159             : } // namespace scipp::core::element::event

Generated by: LCOV version 1.14