ARTS 2.5.10 (git: 2f1c442c)
energylevelmap.cc
Go to the documentation of this file.
1/* Copyright (C) 2019
2 Richard Larsson <ric.larsson@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA. */
18
27#include "energylevelmap.h"
28#include "special_interp.h"
29
30
32 if (not (value.nbooks() == levels.nelem() and
33 (vib_energy.nelem() == levels.nelem() or vib_energy.nelem() == 0))) {
34 return false; // Bad dimensions, vibrational energies and IDs and data of strange size
35 }
36
37 if (type == EnergyLevelMapType::Tensor3_t) {
38 } else if (type == EnergyLevelMapType::Vector_t) {
39 if (value.npages() not_eq 1 or value.nrows() not_eq 1) {
40 return false; // Bad dimensions for vector type
41 }
42 } else if (type == EnergyLevelMapType::Numeric_t) {
43 if (value.npages() not_eq 1 or value.nrows() not_eq 1 or value.ncols() not_eq 1) {
44 return false; // Bad dimensions for numeric type
45 }
46 } else if (type == EnergyLevelMapType::None_t) {
47 if (value.npages() not_eq 0 or value.nrows() not_eq 0 or value.ncols() not_eq 0) {
48 return false; // Bad dimensions for none type
49 }
50 }
51
52 return std::all_of(vib_energy.begin(),
54 [](const auto& val) { return val >= 0; });
55}
56
57
59 const AbsorptionLines& band,
60 const Index& line_index) const
61{
62 ARTS_USER_ERROR_IF (type not_eq EnergyLevelMapType::Numeric_t,
63 "Must have Numeric_t, input type is bad");
64
65 Output2 x{/*.r_low=*/0, /*.r_upp=*/0};
66
67 bool found1=false;
68 bool found2=false;
69 for (size_t i=0; i<levels.size(); i++) {
70 const Quantum::Number::StateMatch lt(levels[i], band.lines[line_index].localquanta, band.quantumidentity);
71
72 if (lt == Quantum::Number::StateMatchType::Level and lt.low) {
73 found1 = true;
74 x.r_low = value(i, 0, 0, 0);
75 }
76
77 if (lt == Quantum::Number::StateMatchType::Level and lt.upp) {
78 found2 = true;
79 x.r_upp = value(i, 0, 0, 0);
80 }
81
82 if (found1 and found2)
83 break;
84 }
85
86 return x;
87}
88
90 const AbsorptionLines& band,
91 const Numeric T) const
92{
93 ARTS_USER_ERROR_IF (type not_eq EnergyLevelMapType::Numeric_t,
94 "Must have Numeric_t, input type is bad");
95
96 Output4 x{/*.E_low=*/0, /*.E_upp=*/0, /*.T_low=*/T, /*.T_upp=*/T};
97
98 bool found1=false;
99 bool found2=false;
100 for (Index i=0; i<levels.nelem(); i++) {
102
103 if (lt == Quantum::Number::StateMatchType::Level and lt.low) {
104 found1 = true;
105 x.T_low = value(i, 0, 0, 0);
106 x.E_low = vib_energy[i];
107 }
108
109 if (lt == Quantum::Number::StateMatchType::Level and lt.upp) {
110 found2 = true;
111 x.T_upp = value(i, 0, 0, 0);
112 x.E_upp = vib_energy[i];
113 }
114
115 if (found1 and found2) {
116 break;
117 }
118 }
119 return x;
120}
121
124 levels(std::move(levels_)),
125 vib_energy(std::move(energies)),
126 value(std::move(data))
127{
128 ThrowIfNotOK();
129}
130
133 levels(std::move(levels_)),
134 vib_energy(std::move(energies)),
135 value(data.nrows(), 1, 1, data.ncols())
136{
137 value(joker, 0, 0, joker) = data;
138 ThrowIfNotOK();
139}
140
143 levels(std::move(levels_)),
144 vib_energy(std::move(energies)),
145 value(data.nelem(), 1, 1, 1)
146{
147 value(joker, 0, 0, 0) = data;
148 ThrowIfNotOK();
149}
150
152{
153 if (type == EnergyLevelMapType::None_t) return EnergyLevelMap{};
154 ARTS_USER_ERROR_IF (type not_eq EnergyLevelMapType::Tensor3_t,
155 "Must have Tensor3_t, input type is bad");
156
157 EnergyLevelMap elm(EnergyLevelMapType::Vector_t, 1, 1, p.nelem(), *this);
158
159 Matrix itw_field;
160 interp_atmfield_gp2itw(itw_field, atmosphere_dim, p, lat, lon);
161
162 const Index nnlte = levels.nelem();
163 for (Index itnlte = 0; itnlte < nnlte; itnlte++)
164 interp_atmfield_by_itw(elm.value(itnlte, 0, 0, joker), atmosphere_dim,
165 value(itnlte, joker, joker, joker),
166 p, lat, lon, itw_field);
167 return elm;
168}
169
171{
172 if (type == EnergyLevelMapType::None_t) return EnergyLevelMap{};
173 if (type == EnergyLevelMapType::Numeric_t)
174 return *this;
175 ARTS_USER_ERROR_IF (type not_eq EnergyLevelMapType::Vector_t
176 ,"Must have Vector_t, input type is bad");
177
178 ARTS_USER_ERROR_IF (ip >= value.ncols() or ip < 0,
179 "Bad dims for data:\n\tThe pressure dim of data contains: ",
180 value.ncols(), " values and you are requesting element index ", ip, "\n")
181
182 EnergyLevelMap elm(EnergyLevelMapType::Numeric_t, 1, 1, 1, *this);
183 elm.value(joker, 0, 0, 0) = value(joker, 0, 0, ip);
184 return elm;
185}
186
187std::ostream& operator<<(std::ostream& os, const EnergyLevelMap& elm) {
188 return os << elm.type << '\n'
189 << elm.levels << '\n'
190 << elm.value << '\n'
191 << elm.vib_energy << '\n';
192}
193
195{
196 if (type == EnergyLevelMapType::None_t or type == EnergyLevelMapType::Numeric_t)
197 return *this;
198 ARTS_USER_ERROR_IF (type not_eq EnergyLevelMapType::Tensor3_t,
199 "Must have Tensor3_t, input type is bad");
200
201 auto elm = EnergyLevelMap(EnergyLevelMapType::Numeric_t, 1, 1, 1, *this);
202 elm.value(joker, 0, 0, 0) = value(joker, ip, ilat, ilon);
203 return elm;
204}
205
207 auto out = toEnergyLevelMapType(s);
210 "Only \"None\", \"Numeric\", \"Vector\", and \"Tensor3\" types accepted\n"
211 "You request to have an EnergyLevelMap of type: ",
212 s,
213 '\n')
214 return out;
215}
216
217std::ostream& operator<<(std::ostream& os, EnergyLevelMapType x) {return os << toString(x);}
Index nelem() const ARTS_NOEXCEPT
Definition: array.h:92
Index ncols() const noexcept
Definition: matpackIV.h:146
Index nrows() const noexcept
Definition: matpackIV.h:145
Index nbooks() const noexcept
Definition: matpackIV.h:143
Index npages() const noexcept
Definition: matpackIV.h:144
Index nelem() const noexcept
Returns the number of elements.
Definition: matpackI.h:547
The Matrix class.
Definition: matpackI.h:1285
The Tensor4 class.
Definition: matpackIV.h:435
Iterator1D begin() ARTS_NOEXCEPT
Return iterator to first element.
Definition: matpackI.cc:144
Iterator1D end() ARTS_NOEXCEPT
Return iterator behind last element.
Definition: matpackI.cc:148
The Vector class.
Definition: matpackI.h:910
#define ARTS_NOEXCEPT
Definition: debug.h:99
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:153
EnergyLevelMapType toEnergyLevelMapTypeOrThrow(std::string_view s)
std::ostream & operator<<(std::ostream &os, const EnergyLevelMap &elm)
Class to map energy levels.
EnergyLevelMapType
constexpr EnergyLevelMapType toEnergyLevelMapType(std::string_view s) noexcept
constexpr std::string_view toString(EnergyLevelMapType x) noexcept
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
const Joker joker
void interp_atmfield_gp2itw(Matrix &itw, const Index &atmosphere_dim, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon)
Converts atmospheric grid positions to weights for interpolation of an atmospheric field.
void interp_atmfield_by_itw(VectorView x, const Index &atmosphere_dim, ConstTensor3View x_field, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon, ConstMatrixView itw)
Interpolates an atmospheric field with pre-calculated weights by interp_atmfield_gp2itw.
Header file for special_interp.cc.
Array< SingleLine > lines
A list of individual lines.
QuantumIdentifier quantumidentity
Catalog ID.
bool OK() const ARTS_NOEXCEPT
EnergyLevelMap operator[](Index ip) const
Output2 get_ratio_params(const AbsorptionLines &band, const Index &line_index) const
Get the output required for Population::NLTE.
Output4 get_vibtemp_params(const AbsorptionLines &band, const Numeric T) const
Get the output required for Population::NLTE-VibrationalTemperatures.
EnergyLevelMap InterpToGridPos(Index atmosphere_dim, const ArrayOfGridPos &p, const ArrayOfGridPos &lat, const ArrayOfGridPos &lon) const
ArrayOfQuantumIdentifier levels
EnergyLevelMapType type
void ThrowIfNotOK() const ARTS_NOEXCEPT
EnergyLevelMap operator()(Index ip, Index ilat, Index ilon) const
StateMatchType operates so that a check less than a level should be 'better', bar None.