LCOV - code coverage report
Current view: top level - variable/include/scipp/variable - transform_subspan.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 21 21 100.0 %
Date: 2024-04-28 01:25:40 Functions: 8 8 100.0 %

          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/variable/arithmetic.h"
       8             : #include "scipp/variable/subspan_view.h"
       9             : #include "scipp/variable/transform.h"
      10             : #include "scipp/variable/variable_factory.h"
      11             : 
      12             : namespace scipp::variable {
      13             : 
      14             : namespace transform_subspan_detail {
      15       47723 : static constexpr auto erase = [](Dimensions dims, const Dim dim) {
      16       47723 :   dims.erase(dim);
      17       47723 :   return dims;
      18             : };
      19             : 
      20      142827 : static constexpr auto maybe_subspan = [](const Variable &var, const Dim dim) {
      21      142827 :   if (var.dims().contains(dim))
      22       47723 :     return subspan_view(var, dim);
      23       95104 :   return var;
      24             : };
      25             : } // namespace transform_subspan_detail
      26             : 
      27             : template <class... Types, class Op, class... Var>
      28             : [[nodiscard]] Variable
      29       47609 : transform_subspan_impl(const DType type, const Dim dim, const scipp::index size,
      30             :                        Op op, const std::string_view &name, Var... var) {
      31             :   using namespace transform_subspan_detail;
      32             : 
      33       47609 :   auto dims =
      34       95332 :       merge(var.dims().contains(dim) ? erase(var.dims(), dim) : var.dims()...);
      35       47609 :   dims.addInner(dim, size);
      36       47609 :   const bool variance =
      37             :       std::is_base_of_v<core::transform_flags::expect_variance_arg_t<0>, Op> ||
      38             :       (std::is_base_of_v<
      39       47609 :            core::transform_flags::expect_in_variance_if_out_variance_t, Op> &&
      40       47609 :        (var.has_variances() || ...));
      41       47609 :   Variable out =
      42       47609 :       variableFactory().create(type, dims, op(var.unit()...), variance);
      43             : 
      44       47613 :   in_place<false>::transform_data(type_tuples<Types...>(op), op, name,
      45             :                                   subspan_view(out, dim),
      46             :                                   maybe_subspan(var, dim)...);
      47       95216 :   return out;
      48       47610 : }
      49             : 
      50             : /// Non-element-wise transform.
      51             : ///
      52             : /// This is a specialized version of transform, handling the case of inputs (and
      53             : /// output) that differ along one of their dimensions. Applications are mixing
      54             : /// of events and dense data, as well as operations that change the length of a
      55             : /// dimension (such as rebin). The syntax for the user-provided operator is
      56             : /// special and differs from that of `transform` and `transform_in_place`, and
      57             : /// also the tuple of supported type combinations is special:
      58             : /// 1. The overload for the transform of the unit is as for `transform`, i.e.,
      59             : ///    returns the new unit.
      60             : /// 2. The overload handling the data has one extra argument. This additional
      61             : ///    (first) argument is the "out" argument, as used in `transform_in_place`.
      62             : /// 3. The tuple of supported type combinations must include the type of the out
      63             : ///    argument as the first type in the inner tuples. The output type must be
      64             : ///    passed at runtime as the first argument. `transform_subspan` DOES NOT
      65             : ///    INITIALIZE the output array, i.e., `Op` must take care of initializing
      66             : ///    the respective subspans. This is done for improved performance, avoiding
      67             : ///    streaming/writing to memory twice. Optionally, initialization can be
      68             : ///    requested by passing an operator inheriting
      69             : ///    core::transform_flags::zero_output_t.
      70             : /// 4. The output type and the type of non-events inputs that depend on `dim`
      71             : ///    must be specified as `span<T>`. The user-provided lambda is called with a
      72             : ///    span of values for these arguments.
      73             : /// 5. Use the flag transform_flags::expect_variance_arg<0> to control whether
      74             : ///    the output should have variances or not.
      75             : template <class... Types, class Op>
      76             : [[nodiscard]] Variable
      77             : transform_subspan(const DType type, const Dim dim, const scipp::index size,
      78             :                   const Variable &var1, const Variable &var2, Op op,
      79             :                   const std::string_view &name = "operation") {
      80             :   return transform_subspan_impl<Types...>(type, dim, size, op, name, var1,
      81             :                                           var2);
      82             : }
      83             : 
      84             : template <class... Types, class Op>
      85             : [[nodiscard]] Variable
      86       47609 : transform_subspan(const DType type, const Dim dim, const scipp::index size,
      87             :                   const Variable &var1, const Variable &var2,
      88             :                   const Variable &var3, Op op,
      89             :                   const std::string_view &name = "operation") {
      90             :   return transform_subspan_impl<Types...>(type, dim, size, op, name, var1, var2,
      91       47611 :                                           var3);
      92             : }
      93             : 
      94             : } // namespace scipp::variable

Generated by: LCOV version 1.14