File indexing completed on 2026-08-18 08:30:24
0001
0002
0003
0004 #pragma once
0005
0006 #include <algorithms/algorithm.h>
0007 #include <algorithm>
0008 #include <functional>
0009 #include <numeric>
0010 #include <podio/ObjectID.h>
0011 #include <string_view>
0012 #include <type_traits>
0013 #include <utility>
0014 #include <vector>
0015
0016 #include "algorithms/interfaces/WithPodConfig.h"
0017 #include "services/log/Log_service.h"
0018
0019 namespace eicrecon {
0020
0021 template <class T>
0022 using SortSubsetCollectionAlgorithm =
0023 algorithms::Algorithm<typename algorithms::Input<const typename T::collection_type>,
0024 typename algorithms::Output<typename T::collection_type>>;
0025
0026 template <class T, class AccessorFunctionT>
0027 class SortSubsetCollection : public SortSubsetCollectionAlgorithm<T>,
0028 public WithPodConfig<NoConfig> {
0029
0030 public:
0031 SortSubsetCollection(std::string_view name, AccessorFunctionT accessor)
0032 : SortSubsetCollectionAlgorithm<T>{name,
0033 {"inputCollection"},
0034 {"outputCollection"},
0035 "Sort collection into a subset output collection"}
0036 , m_accessor(std::move(accessor)) {}
0037
0038 void init() final {};
0039
0040 void process(const typename SortSubsetCollectionAlgorithm<T>::Input& input,
0041 const typename SortSubsetCollectionAlgorithm<T>::Output& output) const final {
0042 const auto [input_collection] = input;
0043 auto [output_collection] = output;
0044
0045 output_collection->setSubsetCollection();
0046
0047 const std::size_t n = input_collection->size();
0048
0049
0050 using KeyT = std::decay_t<std::invoke_result_t<AccessorFunctionT, T>>;
0051 std::vector<KeyT> keys;
0052 keys.reserve(n);
0053 for (std::size_t i = 0; i < n; ++i) {
0054 keys.push_back(std::invoke(m_accessor, (*input_collection)[i]));
0055 }
0056
0057
0058 std::vector<std::size_t> indices(n);
0059 std::iota(indices.begin(), indices.end(), 0);
0060 std::sort(indices.begin(), indices.end(), [&](std::size_t i, std::size_t j) {
0061 if (keys[i] < keys[j]) {
0062 return true;
0063 }
0064 if (keys[j] < keys[i]) {
0065 return false;
0066 }
0067 const auto id_i = (*input_collection)[i].getObjectID();
0068 const auto id_j = (*input_collection)[j].getObjectID();
0069 if (id_i.collectionID < id_j.collectionID) {
0070 return true;
0071 }
0072 if (id_j.collectionID < id_i.collectionID) {
0073 return false;
0074 }
0075 return id_i.index < id_j.index;
0076 });
0077
0078 for (std::size_t i : indices) {
0079 output_collection->push_back((*input_collection)[i]);
0080 }
0081 };
0082
0083 private:
0084 AccessorFunctionT m_accessor;
0085 };
0086
0087 }