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 : #include "scipp/variable/bin_array_variable.tcc" 6 : #include "scipp/variable/bins.h" 7 : 8 : #include "operations_common.h" 9 : 10 : namespace scipp::variable { 11 : 12 : template <> 13 27 : std::string Formatter<core::bin<Variable>>::format(const Variable &var) const { 14 27 : const auto &[indices, dim, content] = var.constituents<Variable>(); 15 54 : return "binned data: dim='" + to_string(dim) + "', content=Variable" + 16 108 : format_variable_like(content); 17 27 : } 18 : 19 : INSTANTIATE_BIN_ARRAY_VARIABLE(VariableView, Variable) 20 : 21 : template <class T> class BinVariableMakerVariable : public BinVariableMaker<T> { 22 : private: 23 15385 : Variable call_make_bins(const Variable &, const Variable &indices, 24 : const Dim dim, const DType type, 25 : const Dimensions &dims, const units::Unit &unit, 26 : const bool variances) const override { 27 : // Buffer contains only variable, which is created with new dtype, no 28 : // information to copy from parent. 29 : return make_bins_no_validate( 30 15385 : indices, dim, variableFactory().create(type, dims, unit, variances)); 31 : } 32 80428 : const Variable &data(const Variable &var) const override { 33 80428 : return this->buffer(var); 34 : } 35 88092 : Variable data(Variable &var) const override { return this->buffer(var); } 36 : }; 37 : 38 41355 : void expect_valid_bin_indices(const Variable &indices, const Dim dim, 39 : const Sizes &buffer_sizes) { 40 41355 : core::expect::equals(units::none, indices.unit()); 41 41355 : auto var = copy(indices); 42 41355 : const auto vals = var.values<scipp::index_pair>().as_span(); 43 41355 : std::sort(vals.begin(), vals.end()); 44 82708 : if ((!vals.empty() && (vals.begin()->first < 0)) || 45 41354 : (!vals.empty() && ((vals.end() - 1)->second > buffer_sizes[dim]))) 46 2 : throw except::SliceError("Bin indices out of range"); 47 41352 : if (std::adjacent_find(vals.begin(), vals.end(), 48 11928879 : [](const auto a, const auto b) { 49 11928879 : return a.second > b.first; 50 41352 : }) != vals.end()) 51 1 : throw except::SliceError("Overlapping bin indices are not allowed."); 52 41351 : if (std::find_if(vals.begin(), vals.end(), [](const auto x) { 53 11968171 : return x.first > x.second; 54 41351 : }) != vals.end()) 55 2 : throw except::SliceError( 56 4 : "Bin begin index must be less or equal to its end index."); 57 41355 : } 58 : 59 : REGISTER_FORMATTER(bin_Variable, core::bin<Variable>) 60 : 61 : namespace { 62 : auto register_variable_maker_bucket_Variable( 63 : (variableFactory().emplace( 64 : dtype<bucket<Variable>>, 65 : std::make_unique<BinVariableMakerVariable<Variable>>()), 66 : 0)); 67 : } 68 : 69 : } // namespace scipp::variable