Belle II Software development
MapHelperFunctions.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9# pragma once
10
11#include <string>
12#include <iterator>
13#include <sstream>
14#include <algorithm>
15#include <vector>
16#include <utility>
17#include <tuple>
18#include <numeric>
19
20namespace Belle2 {
31 template <typename MapType>
32 std::vector<typename MapType::key_type> getUniqueKeys(const MapType& aMap)
33 {
34 std::vector<typename MapType::key_type> allKeys; // collect all keys of the map -> then sort & unique (+resize)
35 if (aMap.empty()) { return allKeys; }
36
37 typedef typename MapType::const_iterator mapIter;
38 for (mapIter it = aMap.begin(); it != aMap.end(); ++it) { allKeys.push_back(it->first); }
39 std::sort(allKeys.begin(), allKeys.end());
40 auto newEnd = std::unique(allKeys.begin(), allKeys.end());
41 allKeys.resize(std::distance(allKeys.begin(), newEnd));
42
43 return allKeys;
44 }
45
50 template <typename MapType>
51 unsigned int getUniqueSize(const MapType& aMap) { return getUniqueKeys<MapType>(aMap).size(); }
52
57 template <typename MapType>
58 std::vector<std::pair<typename MapType::key_type, unsigned int> > getNValuesPerKey(const MapType& aMap)
59 {
60 typedef typename MapType::key_type keyT;
61 typedef typename MapType::const_iterator mapIter;
62
63 std::vector<std::pair<keyT, unsigned int> > valuesPerKey;
64 if (aMap.empty()) return valuesPerKey; // return empty vector if map is empty
65
66 std::vector<keyT> uniqueKeys = getUniqueKeys<MapType>(aMap);
67
68 for (keyT key : uniqueKeys) {
69 std::pair<mapIter, mapIter> keyRange = aMap.equal_range(key);
70 valuesPerKey.push_back(std::make_pair(key, std::distance(keyRange.first, keyRange.second)));
71 }
72 return valuesPerKey;
73 }
74
78 template <typename MapType>
79 std::vector<typename MapType::mapped_type> getValuesToKey(const MapType& aMap, typename MapType::key_type aKey)
80 {
81 typedef typename MapType::const_iterator mapIter;
82
83 std::vector<typename MapType::mapped_type> values;
84 if (aMap.empty()) return values;
85
86 std::pair<mapIter, mapIter> keyRange = aMap.equal_range(aKey);
87 for (mapIter it = keyRange.first; it != keyRange.second; ++it) { values.push_back(it->second); }
88
89 return values;
90 }
91
100 template <typename MapType>
101 std::vector<std::tuple<typename MapType::key_type, typename MapType::mapped_type, unsigned int> >
102 getSortedKeyValueTuples(const MapType& aMap)
103 {
104 typedef typename MapType::key_type keyT;
105 typedef typename MapType::mapped_type mapT;
106
107 std::vector<std::tuple<keyT, mapT, unsigned int> > keyValuePairs;
108 if (aMap.empty()) return keyValuePairs; // return empty vector if nothing is stored in map
109
110 std::vector<std::pair<keyT, unsigned int> > nValuesPerKey = getNValuesPerKey(aMap);
111
112 for (std::pair<keyT, unsigned int> keyValues : nValuesPerKey) {
113 std::vector<mapT> valuesToKey = getValuesToKey(aMap, keyValues.first);
114
115 mapT valueSum = std::accumulate(valuesToKey.begin(), valuesToKey.end(), 0.0);
116 keyValuePairs.push_back(std::make_tuple(keyValues.first, valueSum, keyValues.second));
117 }
118
119 // sort using a lambda function (using std::tie as std::tuple has a defined operator < that ensures strict weak ordering)
120 std::sort(keyValuePairs.begin(), keyValuePairs.end(),
121 [](const std::tuple<keyT, mapT, unsigned int>& lTuple, const std::tuple<keyT, mapT, unsigned int>& rTuple)
122 { return std::tie(std::get<2>(rTuple), std::get<1>(rTuple)) < std::tie(std::get<2>(lTuple), std::get<1>(lTuple)); }
123 );
124
125 return keyValuePairs;
126 }
127
132 template<typename MapType>
133 std::vector<typename MapType::mapped_type> getAllValues(const MapType& aMap)
134 {
135 typedef typename MapType::key_type keyT;
136 std::vector<keyT> allKeys = getUniqueKeys(aMap);
137
138 typedef typename MapType::mapped_type valueT;
139 std::vector<valueT> allValues;
140 for (const keyT& key : allKeys) {
141 std::vector<valueT> keyValues = getValuesToKey(aMap, key);
142 for (const valueT& value : keyValues) {
143 allValues.push_back(value);
144 }
145 }
146
147 return allValues;
148 }
149
153 template <typename MapType>
154 std::string printMap(const MapType& aMap)
155 {
156 if (aMap.empty()) return std::string("passed map is empty!");
157
158 typedef typename MapType::key_type keyT;
159 typedef typename MapType::mapped_type mapT;
160
161 std::stringstream mapContent;
162 mapContent << "content of map:\n";
163 for (keyT key : getUniqueKeys(aMap)) {
164 mapContent << "key: " << key << " -> value(s):";
165 for (mapT value : getValuesToKey(aMap, key)) { mapContent << " " << value; }
166 mapContent << "\n";
167 }
168
169 return mapContent.str() + "\n"; // terminate with endline
170 }
171
173}
std::vector< std::pair< typename MapType::key_type, unsigned int > > getNValuesPerKey(const MapType &aMap)
get the unique keys of a map together with the number of values associated to each key.
std::vector< typename MapType::key_type > getUniqueKeys(const MapType &aMap)
get the unique keys of a map (i.e.
unsigned int getUniqueSize(const MapType &aMap)
get the number of unique keys inside the map NOTE: for non-multimap this is the same as ....
std::vector< typename MapType::mapped_type > getValuesToKey(const MapType &aMap, typename MapType::key_type aKey)
get all values stored in the map for a given key
std::vector< typename MapType::mapped_type > getAllValues(const MapType &aMap)
get all values in the map (i.e.
std::string printMap(const MapType &aMap)
get the contents of the map as string.
std::vector< std::tuple< typename MapType::key_type, typename MapType::mapped_type, unsigned int > > getSortedKeyValueTuples(const MapType &aMap)
get the (key, value, number of values) tuples stored in the map, sorted after the following scheme (d...
Abstract base class for different kinds of events.