UFO
IodaGroupIndices.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2021 UCAR
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  */
7 
9 
10 #include "eckit/exception/Exceptions.h"
11 #include "ioda/ObsGroup.h"
12 #include "oops/base/Variables.h"
13 
14 namespace ufo {
15 
16 // -----------------------------------------------------------------------------
17 /// Returns indices of all elements in the range
18 /// [\p elements_to_look_for_begin, \p elements_to_look_for_end) in the \p all_elements vector,
19 /// in the same order that the former are in.
20 /// Throws an exception if at least one of elements looked for is missing
21 /// from \p all_elements.
22 template<typename T>
23 std::vector<int> getAllIndices(const std::vector<T> & all_elements,
24  typename std::vector<T>::const_iterator elements_to_look_for_begin,
25  typename std::vector<T>::const_iterator elements_to_look_for_end) {
26  std::vector<int> result;
27  for (typename std::vector<T>::const_iterator sought_it = elements_to_look_for_begin;
28  sought_it != elements_to_look_for_end; ++sought_it) {
29  const T &sought = *sought_it;
30  const auto found_it = std::find(all_elements.begin(), all_elements.end(), sought);
31  if (found_it != all_elements.end()) {
32  result.push_back(std::distance(all_elements.begin(), found_it));
33  } else {
34  const std::string errormsg = "getAllIndices: Can't find element in the vector";
35  throw eckit::BadParameter(errormsg, Here());
36  }
37  }
38  return result;
39 }
40 
41 // -----------------------------------------------------------------------------
42 /// Returns indices of all elements in \p elements_to_look_for in the \p all_elements vector,
43 /// in the same order that \p elements_to_look_for are in.
44 /// Throws an exception if at least one of elements looked for is missing
45 /// from \p all_elements.
46 template<typename T>
47 std::vector<int> getAllIndices(const std::vector<T> & all_elements,
48  const std::vector<T> & elements_to_look_for) {
49  return getAllIndices(all_elements, elements_to_look_for.begin(), elements_to_look_for.end());
50 }
51 
52 // -----------------------------------------------------------------------------
53 std::vector<int> getRequiredVariableIndices(const ioda::ObsGroup &obsgroup,
54  const std::string &varname,
55  typename std::vector<std::string>::const_iterator elements_to_look_for_begin,
56  typename std::vector<std::string>::const_iterator elements_to_look_for_end) {
57  ioda::Variable var = obsgroup.vars.open(varname);
58  std::vector<std::string> elements_in_group;
59  var.read<std::string>(elements_in_group);
60  return getAllIndices(elements_in_group, elements_to_look_for_begin, elements_to_look_for_end);
61 }
62 
63 // -----------------------------------------------------------------------------
64 
65 std::vector<int> getRequiredVarOrChannelIndices(const ioda::ObsGroup &obsgroup,
66  const oops::Variables &vars_to_look_for) {
67  if (vars_to_look_for.channels().empty()) {
68  // Read all variables from the file into std vector
69  ioda::Variable variablesvar = obsgroup.vars.open("variables");
70  std::vector<std::string> variables;
71  variablesvar.read<std::string>(variables);
72 
73  // Find the indices of the ones we need
74  return getAllIndices(variables, vars_to_look_for.variables());
75  } else {
76  // At present this function can search either for channel numbers or variable names,
77  // but not both. So make sure there's only one multi-channel variable.
78  ASSERT(vars_to_look_for.variables().size() == vars_to_look_for.channels().size());
79 
80  // Read all channels from the file into std vector
81  ioda::Variable channelsvar = obsgroup.vars.open("channels");
82  std::vector<int> channels;
83  channelsvar.read<int>(channels);
84 
85  // Find the indices of the ones we need
86  return getAllIndices(channels, vars_to_look_for.channels());
87  }
88 }
89 
90 // -----------------------------------------------------------------------------
91 
92 } // namespace ufo
float distance(const Point &a, const Point &b)
Returns the distance between the two cartesian-mapped Point arguments
Definition: RunCRTM.h:27
std::vector< int > getRequiredVariableIndices(const ioda::ObsGroup &obsgroup, const std::string &varname, typename std::vector< std::string >::const_iterator elements_to_look_for_begin, typename std::vector< std::string >::const_iterator elements_to_look_for_end)
std::vector< int > getAllIndices(const std::vector< T > &all_elements, typename std::vector< T >::const_iterator elements_to_look_for_begin, typename std::vector< T >::const_iterator elements_to_look_for_end)
std::vector< int > getRequiredVarOrChannelIndices(const ioda::ObsGroup &obsgroup, const oops::Variables &vars_to_look_for)