IODA Bundle
CategorySplit.cpp
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020 NOAA/NWS/NCEP/EMC
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 
8 #include "CategorySplit.h"
9 
10 #include <ostream>
11 
12 #include "eckit/exception/Exceptions.h"
13 
14 #include "../RowSlice.h"
15 
16 
17 namespace Ingester
18 {
19  CategorySplit::CategorySplit(const std::string& mnemonic, const NameMap& nameMap) :
20  nameMap_(nameMap),
21  mnemonic_(mnemonic)
22  {
23  }
24 
25  std::vector<std::string> CategorySplit::subCategories(const BufrDataMap& dataMap)
26  {
27  updateNameMap(dataMap);
28 
29  std::vector<std::string> categories;
30  for (const auto& name : nameMap_)
31  {
32  categories.push_back(name.second);
33  }
34 
35  return categories;
36  }
37 
38  std::map<std::string, BufrDataMap> CategorySplit::split(const BufrDataMap &dataMap)
39  {
40  updateNameMap(dataMap);
41 
42  std::map<std::string, BufrDataMap> dataMaps;
43 
44  const IngesterArray& mnemonicArr = dataMap.at(mnemonic_);
45 
46  for (const auto& mapPair : nameMap_)
47  {
48  // Find matching rows
49  std::vector<size_t> indexVec;
50  for (int rowIdx = 0;
51  rowIdx < static_cast<int>(dataMap.at(mnemonic_).rows());
52  rowIdx++)
53  {
54  if (mnemonicArr.row(rowIdx)[0] == mapPair.first)
55  {
56  indexVec.push_back(rowIdx);
57  }
58  }
59 
60  // Make new data map
61  BufrDataMap newDataMap;
62  for (const auto& dataPair : dataMap)
63  {
64  const auto newArr = rowSlice(dataPair.second, indexVec);
65  newDataMap.insert({dataPair.first, newArr});
66  }
67 
68  dataMaps.insert({mapPair.second, newDataMap});
69  }
70 
71  return dataMaps;
72  }
73 
75  {
76  if (nameMap_.empty())
77  {
78  auto& array = dataMap.at(mnemonic_);
79  for (auto rowIdx = 0; rowIdx < array.rows(); rowIdx++)
80  {
81  auto itemVal = array.row(rowIdx)[0];
82  if (trunc(itemVal) == itemVal)
83  {
84  nameMap_.insert({static_cast<int> (itemVal),
85  std::to_string(static_cast<int> (itemVal))});
86  }
87  else
88  {
89  std::stringstream errStr;
90  errStr << "Can't turn " << mnemonic_ << " into a category as it contains ";
91  errStr << "non-integer values.";
92  throw eckit::BadParameter(errStr.str());
93  }
94  }
95  }
96 
97  if (nameMap_.empty())
98  {
99  std::stringstream errStr;
100  errStr << "No categories could be identified for " << mnemonic_ << ".";
101  throw eckit::BadParameter(errStr.str());
102  }
103  }
104 } // namespace Ingester
EigenType rowSlice(const EigenType &arr, const EigenIdxType &idxVec)
Collection of template methods that are used to slice array and vector data.
Definition: RowSlice.h:19
std::map< int, std::string > NameMap
Map of integers to strings where the key represents the split mnemonics integer value and the value i...
Definition: CategorySplit.h:40
CategorySplit(const std::string &mnemonic, const NameMap &map)
constructor
std::map< std::string, BufrDataMap > split(const BufrDataMap &dataMap) final
Split the data according to internal rules.
std::vector< std::string > subCategories(const BufrDataMap &dataMap) final
Get list of sub categories this split will create.
const std::string mnemonic_
Definition: CategorySplit.h:63
void updateNameMap(const BufrDataMap &dataMap)
Adds values to nameMap_ using the data if nameMap_ is empty.
Eigen::Array< FloatType, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > IngesterArray
Definition: IngesterTypes.h:19
IngesterArrayMap BufrDataMap
Definition: BufrTypes.h:21