LCOV - code coverage report
Current view: top level - variable/include/scipp/variable - structure_array_model.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 35 47 74.5 %
Date: 2024-04-28 01:25:40 Functions: 77 156 49.4 %

          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             : #include "scipp/core/dimensions.h"
       7             : #include "scipp/core/element_array_view.h"
       8             : #include "scipp/core/except.h"
       9             : #include "scipp/units/unit.h"
      10             : #include "scipp/variable/element_array_model.h"
      11             : #include "scipp/variable/except.h"
      12             : #include "scipp/variable/transform.h"
      13             : #include "scipp/variable/variable_concept.h"
      14             : 
      15             : namespace scipp::variable {
      16             : 
      17             : /// Implementation of VariableConcept that represents an array with structured
      18             : /// elements of type T.
      19             : ///
      20             : /// The difference to ElementArrayModel is that this class allows for creating
      21             : /// variables that share ownership of the underlying structure elements, e.g.,
      22             : /// to provide access to an array of vector elements from an array of vectors.
      23             : template <class T, class Elem>
      24             : class StructureArrayModel : public VariableConcept {
      25             : public:
      26             :   using value_type = T;
      27             :   using element_type = Elem;
      28             :   static constexpr scipp::index element_count = sizeof(T) / sizeof(Elem);
      29             :   static_assert(sizeof(Elem) * element_count == sizeof(T));
      30             : 
      31      327092 :   StructureArrayModel(const scipp::index size, const units::Unit &unit,
      32             :                       element_array<Elem> model)
      33             :       : VariableConcept(units::one), // unit ignored
      34      327092 :         m_elements(std::make_shared<ElementArrayModel<Elem>>(
      35      654184 :             size * element_count, unit, std::move(model))) {}
      36             : 
      37           1 :   StructureArrayModel(VariableConceptHandle &&elements)
      38             :       : VariableConcept(units::one), // unit ignored
      39           1 :         m_elements(std::move(elements)) {}
      40             : 
      41             :   ~StructureArrayModel() override;
      42             : 
      43           0 :   static DType static_dtype() noexcept { return scipp::dtype<T>; }
      44     5956918 :   DType dtype() const noexcept override { return scipp::dtype<T>; }
      45      318442 :   scipp::index size() const override {
      46      318442 :     return m_elements->size() / element_count;
      47             :   }
      48             : 
      49      652193 :   const units::Unit &unit() const override { return m_elements->unit(); }
      50       56731 :   void setUnit(const units::Unit &unit) override { m_elements->setUnit(unit); }
      51             : 
      52             :   VariableConceptHandle
      53             :   makeDefaultFromParent(const scipp::index size) const override;
      54             : 
      55             :   VariableConceptHandle
      56           0 :   makeDefaultFromParent(const Variable &shape) const override {
      57           0 :     return makeDefaultFromParent(shape.dims().volume());
      58             :   }
      59             : 
      60             :   [[nodiscard]] bool equals(const Variable &a,
      61             :                             const Variable &b) const override;
      62             :   [[nodiscard]] bool equals_nan(const Variable &a,
      63             :                                 const Variable &b) const override;
      64             :   void copy(const Variable &src, Variable &dest) const override;
      65             :   void copy(const Variable &src, Variable &&dest) const override;
      66             :   void assign(const VariableConcept &other) override;
      67             : 
      68     1098092 :   bool has_variances() const noexcept override { return false; }
      69           0 :   void setVariances(const Variable &) override {
      70           0 :     except::throw_cannot_have_variances(core::dtype<T>);
      71             :   }
      72             : 
      73           1 :   VariableConceptHandle clone() const override {
      74           1 :     return std::make_shared<StructureArrayModel<T, Elem>>(m_elements->clone());
      75             :   }
      76             : 
      77      681875 :   auto values(const core::ElementArrayViewParams &base) const {
      78      681875 :     return ElementArrayView(base, get_values());
      79             :   }
      80      419253 :   auto values(const core::ElementArrayViewParams &base) {
      81      419253 :     return ElementArrayView(base, get_values());
      82             :   }
      83             : 
      84       49181 :   VariableConceptHandle elements() const { return m_elements; }
      85             : 
      86           4 :   scipp::index dtype_size() const override { return sizeof(T); }
      87           4 :   scipp::index object_size() const override {
      88           4 :     return sizeof(*this) + m_elements->object_size();
      89             :   }
      90           0 :   const VariableConceptHandle &bin_indices() const override {
      91           0 :     throw except::TypeError("This data type does not have bin indices.");
      92             :   }
      93             : 
      94          14 :   scipp::span<const T> values() const {
      95          14 :     return {get_values(), static_cast<size_t>(size())};
      96             :   }
      97           0 :   scipp::span<T> values() {
      98           0 :     return {get_values(), static_cast<size_t>(size())};
      99             :   }
     100             : 
     101             : private:
     102             :   const T *get_values() const;
     103             :   T *get_values();
     104             :   VariableConceptHandle m_elements;
     105             : };
     106             : 
     107             : template <class T, class Elem>
     108       15429 : VariableConceptHandle StructureArrayModel<T, Elem>::makeDefaultFromParent(
     109             :     const scipp::index size) const {
     110             :   return std::make_shared<StructureArrayModel<T, Elem>>(
     111       15429 :       size, unit(), element_array<Elem>(size * element_count));
     112             : }
     113             : 
     114             : template <class T, class Elem>
     115        4016 : bool StructureArrayModel<T, Elem>::equals(const Variable &a,
     116             :                                           const Variable &b) const {
     117        8032 :   return a.dtype() == dtype() && b.dtype() == dtype() &&
     118        8032 :          a.elements<T>() == b.elements<T>();
     119             : }
     120             : 
     121             : template <class T, class Elem>
     122           1 : bool StructureArrayModel<T, Elem>::equals_nan(const Variable &a,
     123             :                                               const Variable &b) const {
     124           2 :   return a.dtype() == dtype() && b.dtype() == dtype() &&
     125           2 :          variable::equals_nan(a.elements<T>(), b.elements<T>());
     126             : }
     127             : 
     128             : template <class T, class Elem>
     129       56697 : void StructureArrayModel<T, Elem>::copy(const Variable &src,
     130             :                                         Variable &dest) const {
     131       56697 :   transform_in_place<T>(
     132    11887605 :       dest, src, [](auto &a, const auto &b) { a = b; }, "copy");
     133       56696 : }
     134             : template <class T, class Elem>
     135           0 : void StructureArrayModel<T, Elem>::copy(const Variable &src,
     136             :                                         Variable &&dest) const {
     137           0 :   copy(src, dest);
     138           0 : }
     139             : 
     140             : } // namespace scipp::variable

Generated by: LCOV version 1.14