Belle II Software  release-08-01-10
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 
20 namespace 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::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...
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.
std::string printMap(const MapType &aMap)
get the contents of the map as string.
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.
Abstract base class for different kinds of events.