File indexing completed on 2026-09-28 09:10:37
0001
0002
0003 #ifndef EDM4EIC_TensorCollection_H
0004 #define EDM4EIC_TensorCollection_H
0005
0006
0007 #include "edm4eic/Tensor.h"
0008 #include "edm4eic/MutableTensor.h"
0009 #include "edm4eic/TensorObj.h"
0010 #include "edm4eic/TensorCollectionData.h"
0011
0012
0013 #include "podio/ICollectionProvider.h"
0014 #include "podio/CollectionBase.h"
0015 #include "podio/detail/Pythonizations.h"
0016 #include "podio/utilities/TypeHelpers.h"
0017
0018 #if defined(PODIO_JSON_OUTPUT) && !defined(__CLING__)
0019 #include "nlohmann/json_fwd.hpp"
0020 #endif
0021
0022 #include <string_view>
0023 #include <vector>
0024 #include <algorithm>
0025 #include <ostream>
0026 #include <mutex>
0027 #include <memory>
0028 #include <cstddef>
0029
0030 namespace podio {
0031 struct RelationNames;
0032 }
0033
0034 namespace edm4eic {
0035
0036
0037
0038 class TensorCollectionIterator {
0039 public:
0040 using value_type = Tensor;
0041 using difference_type = ptrdiff_t;
0042 using reference = Tensor;
0043 using pointer = Tensor*;
0044 using iterator_category = std::input_iterator_tag;
0045
0046
0047 using iterator_concept = std::random_access_iterator_tag;
0048
0049 TensorCollectionIterator(size_t index, const TensorObjPointerContainer* collection) : m_index(index), m_object(podio::utils::MaybeSharedPtr<TensorObj>{nullptr}), m_collection(collection) {}
0050 TensorCollectionIterator() = default;
0051
0052 TensorCollectionIterator(const TensorCollectionIterator&) = default;
0053 TensorCollectionIterator(TensorCollectionIterator&&) = default;
0054 TensorCollectionIterator& operator=(const TensorCollectionIterator&) = default;
0055 TensorCollectionIterator& operator=(TensorCollectionIterator&&) = default;
0056 ~TensorCollectionIterator() = default;
0057
0058 constexpr auto operator<=>(const TensorCollectionIterator& other) const {
0059 return m_index <=> other.m_index;
0060 }
0061
0062 constexpr bool operator==(const TensorCollectionIterator& x) const {
0063 return m_index == x.m_index;
0064 }
0065
0066 reference operator*() const;
0067 pointer operator->();
0068 TensorCollectionIterator& operator++();
0069 TensorCollectionIterator operator++(int);
0070 TensorCollectionIterator& operator--();
0071 TensorCollectionIterator operator--(int);
0072 TensorCollectionIterator& operator+=(difference_type n);
0073 TensorCollectionIterator operator+(difference_type n) const;
0074 friend TensorCollectionIterator operator+(difference_type n, const TensorCollectionIterator& it);
0075 TensorCollectionIterator& operator-=(difference_type n);
0076 TensorCollectionIterator operator-(difference_type n) const;
0077 reference operator[](difference_type n) const;
0078 difference_type operator-(const TensorCollectionIterator& other) const;
0079
0080 private:
0081 size_t m_index{0};
0082 Tensor m_object { podio::utils::MaybeSharedPtr<TensorObj>{nullptr} };
0083 const TensorObjPointerContainer* m_collection{nullptr};
0084 };
0085
0086
0087 class TensorMutableCollectionIterator {
0088 public:
0089 using value_type = Tensor;
0090 using difference_type = ptrdiff_t;
0091 using reference = MutableTensor;
0092 using pointer = MutableTensor*;
0093 using iterator_category = std::input_iterator_tag;
0094
0095
0096 using iterator_concept = std::random_access_iterator_tag;
0097
0098 TensorMutableCollectionIterator(size_t index, const TensorObjPointerContainer* collection) : m_index(index), m_object(podio::utils::MaybeSharedPtr<TensorObj>{nullptr}), m_collection(collection) {}
0099 TensorMutableCollectionIterator() = default;
0100
0101 TensorMutableCollectionIterator(const TensorMutableCollectionIterator&) = default;
0102 TensorMutableCollectionIterator(TensorMutableCollectionIterator&&) = default;
0103 TensorMutableCollectionIterator& operator=(const TensorMutableCollectionIterator&) = default;
0104 TensorMutableCollectionIterator& operator=(TensorMutableCollectionIterator&&) = default;
0105 ~TensorMutableCollectionIterator() = default;
0106
0107 constexpr auto operator<=>(const TensorMutableCollectionIterator& other) const {
0108 return m_index <=> other.m_index;
0109 }
0110
0111 constexpr bool operator==(const TensorMutableCollectionIterator& x) const {
0112 return m_index == x.m_index;
0113 }
0114
0115 reference operator*() const;
0116 pointer operator->();
0117 TensorMutableCollectionIterator& operator++();
0118 TensorMutableCollectionIterator operator++(int);
0119 TensorMutableCollectionIterator& operator--();
0120 TensorMutableCollectionIterator operator--(int);
0121 TensorMutableCollectionIterator& operator+=(difference_type n);
0122 TensorMutableCollectionIterator operator+(difference_type n) const;
0123 friend TensorMutableCollectionIterator operator+(difference_type n, const TensorMutableCollectionIterator& it);
0124 TensorMutableCollectionIterator& operator-=(difference_type n);
0125 TensorMutableCollectionIterator operator-(difference_type n) const;
0126 reference operator[](difference_type n) const;
0127 difference_type operator-(const TensorMutableCollectionIterator& other) const;
0128
0129 private:
0130 size_t m_index{0};
0131 MutableTensor m_object { podio::utils::MaybeSharedPtr<TensorObj>{nullptr} };
0132 const TensorObjPointerContainer* m_collection{nullptr};
0133 };
0134
0135
0136
0137
0138
0139 class TensorCollection : public podio::CollectionBase {
0140 public:
0141 using value_type = Tensor;
0142 using mutable_type = MutableTensor;
0143 using const_iterator = TensorCollectionIterator;
0144 using iterator = TensorMutableCollectionIterator;
0145 using difference_type = ptrdiff_t;
0146 using size_type = size_t;
0147 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0148 using reverse_iterator = std::reverse_iterator<iterator>;
0149
0150 TensorCollection() = default;
0151 TensorCollection(TensorCollectionData&& data, bool isSubsetColl);
0152
0153 TensorCollection(const TensorCollection& ) = delete;
0154 TensorCollection& operator=(const TensorCollection& ) = delete;
0155 TensorCollection(TensorCollection&&) = default;
0156 TensorCollection& operator=(TensorCollection&&) = default;
0157
0158 ~TensorCollection() override;
0159 #if defined(__cpp_lib_containers_ranges)
0160 template<podio::detail::RangeConvertibleTo<value_type> R>
0161 TensorCollection(std::from_range_t, R&& range);
0162 #endif
0163
0164
0165
0166 template<podio::detail::RangeConvertibleTo<value_type> R>
0167 static TensorCollection from(R&& range);
0168
0169 constexpr static std::string_view typeName = "edm4eic::TensorCollection";
0170 constexpr static std::string_view valueTypeName = "edm4eic::Tensor";
0171 constexpr static std::string_view dataTypeName = "edm4eic::TensorData";
0172
0173 void clear() final;
0174
0175
0176 static void __cppyy_pythonize__(PyObject* klass, const std::string& name){
0177 podio::detail::pythonizations::pythonize_subscript(klass, name);
0178 }
0179
0180
0181 void print(std::ostream& os=std::cout, bool flush=true) const final;
0182
0183
0184 MutableTensor create();
0185
0186
0187
0188 template<typename... Args>
0189 MutableTensor create(Args&&... args);
0190
0191
0192 std::size_t size() const final;
0193
0194
0195 std::size_t max_size() const final;
0196
0197
0198 bool empty() const final;
0199
0200
0201 const std::string_view getTypeName() const final { return typeName; }
0202
0203 const std::string_view getValueTypeName() const final { return valueTypeName; }
0204
0205 const std::string_view getDataTypeName() const final { return dataTypeName; }
0206
0207 podio::SchemaVersionT getSchemaVersion() const final;
0208
0209 bool isSubsetCollection() const final {
0210 return m_isSubsetColl;
0211 }
0212
0213 void setSubsetCollection(bool setSubset=true) final;
0214
0215
0216 Tensor operator[](std::size_t index) const;
0217
0218 MutableTensor operator[](std::size_t index);
0219
0220 Tensor at(std::size_t index) const;
0221
0222 MutableTensor at(std::size_t index);
0223
0224
0225
0226 void push_back(const MutableTensor& object);
0227
0228 void push_back(const Tensor& object);
0229
0230 void prepareForWrite() const final;
0231 void prepareAfterRead() final;
0232 bool setReferences(const podio::ICollectionProvider* collectionProvider) final;
0233
0234
0235 podio::CollectionWriteBuffers getBuffers() final;
0236
0237 void setID(uint32_t ID) final {
0238 m_collectionID = ID;
0239 if (!m_isSubsetColl) {
0240 std::for_each(m_storage.entries.begin(), m_storage.entries.end(),
0241 [ID] (TensorObj* obj) { obj->id = {obj->id.index, static_cast<uint32_t>(ID)}; }
0242 );
0243 }
0244 }
0245
0246 uint32_t getID() const final {
0247 return m_collectionID;
0248 }
0249
0250
0251 bool hasID() const final {
0252 return getID() != static_cast<uint32_t>(podio::ObjectID::untracked) &&
0253 getID() != static_cast<uint32_t>(podio::ObjectID::invalid);
0254 }
0255
0256 [[deprecated("isValid will be removed, use hasID() if you want to check if it has an ID, otherwise assume the "
0257 "collection is valid")]]
0258 bool isValid() const final {
0259 return hasID();
0260 }
0261
0262 size_t getDatamodelRegistryIndex() const final;
0263
0264
0265 iterator begin() {
0266 return iterator(0, &m_storage.entries);
0267 }
0268 const_iterator begin() const {
0269 return const_iterator(0, &m_storage.entries);
0270 }
0271 const_iterator cbegin() const {
0272 return begin();
0273 }
0274 iterator end() {
0275 return iterator(m_storage.entries.size(), &m_storage.entries);
0276 }
0277 const_iterator end() const {
0278 return const_iterator(m_storage.entries.size(), &m_storage.entries);
0279 }
0280 const_iterator cend() const {
0281 return end();
0282 }
0283
0284 reverse_iterator rbegin() {
0285 return reverse_iterator(end());
0286 }
0287 const_reverse_iterator rbegin() const {
0288 return const_reverse_iterator(end());
0289 }
0290 const_reverse_iterator crbegin() const {
0291 return rbegin();
0292 }
0293 reverse_iterator rend() {
0294 return reverse_iterator(begin());
0295 }
0296 const_reverse_iterator rend() const {
0297 return const_reverse_iterator(begin());
0298 }
0299 const_reverse_iterator crend() const {
0300 return rend();
0301 }
0302
0303
0304 std::vector<std::int32_t> elementType(const size_t nElem = 0) const;
0305
0306 private:
0307
0308
0309
0310 friend class TensorCollectionData;
0311
0312 mutable bool m_isPrepared{false};
0313 bool m_isSubsetColl{false};
0314 uint32_t m_collectionID{static_cast<uint32_t>(podio::ObjectID::untracked)};
0315 mutable std::unique_ptr<std::mutex> m_storageMtx{std::make_unique<std::mutex>()};
0316 mutable TensorCollectionData m_storage{};
0317 };
0318
0319 std::ostream& operator<<(std::ostream& o, const TensorCollection& v);
0320
0321 template<typename... Args>
0322 MutableTensor TensorCollection::create(Args&&... args) {
0323 if (m_isSubsetColl) {
0324 throw std::logic_error("Cannot create new elements on a subset collection");
0325 }
0326 auto obj = new TensorObj({static_cast<int>(m_storage.entries.size()), m_collectionID}, {std::forward<Args>(args)...});
0327 m_storage.entries.push_back(obj);
0328
0329
0330 obj->m_shape = new std::vector<std::int64_t>();
0331 obj->m_floatData = new std::vector<float>();
0332 obj->m_int64Data = new std::vector<std::int64_t>();
0333 m_storage.createRelations(obj);
0334 return MutableTensor(podio::utils::MaybeSharedPtr(obj));
0335 }
0336
0337
0338 #if defined(__cpp_lib_containers_ranges)
0339 template<podio::detail::RangeConvertibleTo<TensorCollection::value_type> R>
0340 TensorCollection::TensorCollection(std::from_range_t, R&& range)
0341 : TensorCollection() {
0342 setSubsetCollection(podio::detail::RangeOf<R, value_type>);
0343
0344 for (auto&& elem : range) {
0345 push_back(std::forward<decltype(elem)>(elem));
0346 }
0347 }
0348 #endif
0349
0350 template<podio::detail::RangeConvertibleTo<TensorCollection::value_type> R>
0351 TensorCollection TensorCollection::from(R&& range) {
0352 TensorCollection coll;
0353 if constexpr (podio::detail::RangeOf<R, value_type>) {
0354 coll.setSubsetCollection();
0355 }
0356
0357 for (auto&& elem : range) {
0358 coll.push_back(std::forward<decltype(elem)>(elem));
0359 }
0360
0361 return coll;
0362 }
0363
0364
0365 #if defined(PODIO_JSON_OUTPUT) && !defined(__CLING__)
0366 void to_json(nlohmann::json& j, const TensorCollection& collection);
0367 #endif
0368
0369 }
0370
0371
0372
0373
0374
0375 #if defined(__clang__)
0376 #pragma clang diagnostic push
0377 #pragma clang diagnostic ignored "-Wunknown-warning-option"
0378 #pragma clang diagnostic ignored "-Wdeprecated-redundant-constexpr-static-def"
0379 #pragma clang diagnostic ignored "-Wdeprecated"
0380 constexpr std::string_view edm4eic::TensorCollection::typeName;
0381 constexpr std::string_view edm4eic::TensorCollection::valueTypeName;
0382 constexpr std::string_view edm4eic::TensorCollection::dataTypeName;
0383 #pragma clang diagnostic pop
0384 #elif defined(__GNUC__)
0385 #pragma GCC diagnostic push
0386 #pragma GCC diagnostic ignored "-Wdeprecated"
0387 constexpr std::string_view edm4eic::TensorCollection::typeName;
0388 constexpr std::string_view edm4eic::TensorCollection::valueTypeName;
0389 constexpr std::string_view edm4eic::TensorCollection::dataTypeName;
0390 #pragma GCC diagnostic pop
0391 #endif
0392
0393
0394 #endif