LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
orderedProcessNamesCollection.cc
Go to the documentation of this file.
2 #include "boost/algorithm/string.hpp"
5 #include "cetlib/container_algorithms.h"
6 #include "range/v3/view.hpp"
7 
8 #include <cassert>
9 #include <numeric>
10 
11 namespace {
12  auto
13  stringified_process_names(art::ProcessHistory const& history)
14  {
15  assert(not history.empty());
16  return std::accumulate(
17  history.begin() + 1,
18  history.end(),
19  history.begin()->processName(),
20  [](std::string result, art::ProcessConfiguration const& config) {
21  result += '\n';
22  result += config.processName();
23  return result;
24  });
25  }
26 
27  // Collapsed histories are histories that do not overlap with any
28  // others. For example, of the following process histories:
29  //
30  // 1: [A]
31  // 2: [A,B]
32  // 3: [A,B,C]
33  // 4: [A,D]
34  //
35  // The collapsed histories are 3 and 4 since 1 and 2 are subsets of
36  // 3. In otherwords, 3 and 4 are the only histories that do not
37  // have descendants.
38  //
39  // For simplicity, we create a list of all process names,
40  // concatenated according to each history. Although it is possible
41  // for two non-overlapping histories to have the same process names,
42  // we do not make such a distinction here.
43  auto
44  collapsed_histories(std::vector<std::string> const& all_process_names)
45  {
46  assert(not empty(all_process_names));
47 
48  std::vector<std::string> result;
49  auto candidate = cbegin(all_process_names);
50  auto const end = cend(all_process_names);
51  for (auto test = candidate + 1; test != end; ++test, ++candidate) {
52  if (test->find(*candidate) != 0) {
53  result.push_back(*candidate);
54  }
55  }
56  result.push_back(*candidate);
57  return result;
58  }
59 
60  auto
61  transform_to_final_result(std::vector<std::string> const& collapsed)
62  {
63  std::vector<std::vector<std::string>> result;
64  for (auto const& process_names_str : collapsed) {
65  std::vector<std::string> process_names;
66  boost::split(process_names, process_names_str, boost::is_any_of("\n"));
67  result.push_back(std::move(process_names));
68  }
69  return result;
70  }
71 }
72 
73 std::vector<std::vector<std::string>>
75 {
76  std::vector<std::string> all_process_names;
77  all_process_names.reserve(histories.size());
78  for (auto const& history : histories | ::ranges::views::values) {
79  all_process_names.push_back(stringified_process_names(history));
80  }
81  cet::sort_all(all_process_names);
82 
83  // It is possible for two non-overlapping histories to have the same
84  // process name. We thus need to erase duplicate names.
85  auto const e = end(all_process_names);
86  auto const new_end = std::unique(begin(all_process_names), e);
87  all_process_names.erase(new_end, e);
88 
89  auto const collapsed = collapsed_histories(all_process_names);
90  return transform_to_final_result(collapsed);
91 }
const_iterator end() const
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
bool empty() const
const_iterator begin() const
std::vector< std::vector< std::string > > orderedProcessNamesCollection(ProcessHistoryMap const &pHistMap)
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:85
std::map< ProcessHistoryID const, ProcessHistory > ProcessHistoryMap
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
Float_t e
Definition: plot.C:35
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109