Canoe
Comprehensive Atmosphere N' Ocean Engine
spectral_grid.cpp
Go to the documentation of this file.
1 // external
2 #include <yaml-cpp/yaml.h>
3 
4 // athena
5 #include <athena/athena.hpp>
6 
7 // application
8 #include <application/exceptions.hpp>
9 
10 // harp
11 #include "spectral_grid.hpp"
12 
13 std::pair<Real, Real> SpectralGridBase::ReadRangeFrom(YAML::Node const& my) {
14  std::string units = my["units"] ? my["units"].as<std::string>() : "cm-1";
15 
16  if (units == "cm-1") {
17  unit_type = "wavenumber";
18  } else if (units == "um") {
19  unit_type = "wavelength";
20  } else if (units == "GHz") {
21  unit_type = "frequency";
22  } else {
23  throw RuntimeError("SpectralGridBase", "unknown spectral unit type");
24  }
25 
26  char str[80];
27  snprintf(str, sizeof(str), "%s-%s", unit_type.c_str(), "range");
28 
29  if (!my[str]) {
30  throw NotFoundError("SpectralGridBase", str);
31  }
32 
34  Real wmin = my[str][0].as<Real>();
35  Real wmax = my[str][1].as<Real>();
36  if (wmin > wmax) {
37  throw RuntimeError("SpectralGridBase", "wmin > wmax");
38  }
39 
40  return std::make_pair(wmin, wmax);
41 }
42 
44  auto&& wpair = ReadRangeFrom(my);
45  Real wmin = wpair.first;
46  Real wmax = wpair.second;
47 
48  int num_bins;
49 
50  if (wmin == wmax) {
51  num_bins = 1;
52  spec.resize(num_bins);
53  spec[0].wav1 = spec[0].wav2 = wmin;
54  spec[0].wght = 1.;
55  } else if (my["resolution"]) {
56  Real dwave = my["resolution"].as<Real>();
57  num_bins = static_cast<int>((wmax - wmin) / dwave) + 1;
58  spec.resize(num_bins);
59  for (int i = 0; i < num_bins; ++i) {
60  spec[i].wav1 = spec[i].wav2 = wmin + dwave * i;
61  spec[i].wght = (i == 0) || (i == num_bins - 1) ? 0.5 * dwave : dwave;
62  }
63  } else if (my["num-bins"]) {
64  Real dwave = static_cast<Real>(1. * (wmax - wmin) / num_bins);
65  num_bins = my["num-bins"].as<int>();
66  spec.resize(num_bins);
67  for (int i = 0; i < num_bins; ++i) {
68  spec[i].wav1 = wmin + dwave * i;
69  spec[i].wav2 = spec[i].wav1 + dwave;
70  spec[i].wght = 1.;
71  }
72  } else {
73  throw NotFoundError("RegularSpacingSpectralGrid",
74  "either 'resolution' or 'num-bins' must be defined");
75  }
76 }
77 
79  auto&& wpair = ReadRangeFrom(my);
80 
81  char str[80];
82  snprintf(str, sizeof(str), "%s-points", unit_type.c_str());
83 
84  if (!my[str]) {
85  throw NotFoundError("CustomSpacingSpectralGrid", str);
86  }
87 
88  std::vector<Real> wavs = my[str].as<std::vector<Real>>();
89  std::sort(wavs.begin(), wavs.end());
90 
91  Real wmin = wavs.front();
92  Real wmax = wavs.back();
93  int num_bins = wavs.size();
94 
95  if (wmin > wmax) {
96  throw RuntimeError("CustomSpacingSpectralGrid", "wmin > wmax");
97  }
98 
99  spec.resize(num_bins);
100  for (int i = 0; i < num_bins; ++i) {
101  spec[i].wav1 = wavs[i];
102  spec[i].wav2 = wavs[i];
103  spec[i].wght = 1.;
104  }
105 }
106 
108  YAML::Node const& my) {
109  auto&& wpair = ReadRangeFrom(my);
110  Real wmin = wpair.first;
111  Real wmax = wpair.second;
112 
113  if (my["g-points"]) {
114  int num_bins = my["g-points"].size();
115  spec.resize(num_bins);
116  for (int i = 0; i < num_bins; ++i) {
117  spec[i].wav1 = wmin;
118  spec[i].wav2 = wmax;
119  spec[i].wght = my["g-points"][i].as<Real>();
120  }
121  } else {
122  throw NotFoundError("CorrelatedKTableSpectralGrid",
123  "'g-points' must be defined");
124  }
125 }
126 
128  if (!my["grid-type"]) {
129  throw NotFoundError("SpectralGridFactory", "grid-type");
130  }
131 
132  std::string grid_type = my["grid-type"].as<std::string>();
133 
134  SpectralGridPtr pgrid;
135 
136  if (grid_type == "regular") {
137  pgrid = std::make_shared<RegularSpacingSpectralGrid>(my);
138  } else if (grid_type == "custom") {
139  pgrid = std::make_shared<CustomSpacingSpectralGrid>(my);
140  } else if (grid_type == "correlated-k-table") {
141  pgrid = std::make_shared<CorrelatedKTableSpectralGrid>(my);
142  } else {
143  throw RuntimeError("SpectralGridFactory", "unknown grid type");
144  }
145 
146  return pgrid;
147 }
CorrelatedKTableSpectralGrid(YAML::Node const &my)
CustomSpacingSpectralGrid(YAML::Node const &my)
RegularSpacingSpectralGrid(YAML::Node const &my)
std::string unit_type
defines the unit of the spectral grid
std::pair< Real, Real > ReadRangeFrom(YAML::Node const &my)
Read the spectral range from a YAML node.
std::vector< SpectralBin > spec
spectral grids
static SpectralGridPtr CreateFrom(YAML::Node const &my)
std::shared_ptr< SpectralGridBase > SpectralGridPtr