ARTS  2.3.1285(git:92a29ea9-dirty)
m_hitran_xsec.cc
Go to the documentation of this file.
1 /* Copyright (C) 2017 Oliver Lemke <oliver.lemke@uni-hamburg.de> and
2  Stefan Buehler <stefan.buehler@uni-hamburg.de>.
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 
29 #include "absorption.h"
30 #include "arts.h"
31 #include "messages.h"
32 
33 #include "auto_md.h"
34 #include "hitran_xsec.h"
35 #include "physics_funcs.h"
36 #include "xml_io.h"
37 
38 extern const Numeric SPEED_OF_LIGHT;
39 
40 /* Workspace method: Doxygen documentation will be auto-generated */
42  ArrayOfMatrix& abs_xsec_per_species,
43  ArrayOfArrayOfMatrix& dabs_xsec_per_species_dx,
44  // WS Input:
45  const ArrayOfArrayOfSpeciesTag& abs_species,
46  const ArrayOfRetrievalQuantity& jacobian_quantities,
47  const ArrayOfIndex& abs_species_active,
48  const Vector& f_grid,
49  const Vector& abs_p,
50  const Vector& abs_t,
51  const ArrayOfXsecRecord& hitran_xsec_data,
52  const Index& apply_tfit,
53  const Numeric& force_p,
54  const Numeric& force_t,
55  // Verbosity object:
56  const Verbosity& verbosity) {
58 
59  {
60  // Check that all parameters that should have the number of tag
61  // groups as a dimension are consistent:
62  const Index n_tgs = abs_species.nelem();
63  const Index n_xsec = abs_xsec_per_species.nelem();
64 
65  if (n_tgs != n_xsec) {
66  ostringstream os;
67  os << "The following variables must all have the same dimension:\n"
68  << "abs_species: " << n_tgs << "\n"
69  << "abs_xsec_per_species: " << n_xsec;
70  throw runtime_error(os.str());
71  }
72  }
73 
74  // Jacobian overhead START
75  /* NOTE: The calculations below are inefficient and could
76  be made much better by using interp in Extract to
77  return the derivatives as well. */
78  const bool do_jac = supports_hitran_xsec(jacobian_quantities);
79  const bool do_freq_jac = do_frequency_jacobian(jacobian_quantities);
80  // const bool do_temp_jac = ppd.do_temperature();
81  Vector dfreq, dabs_t;
82  const Numeric df = frequency_perturbation(jacobian_quantities);
83  // const Numeric dt = ppd.Temperature_Perturbation();
84  const ArrayOfIndex jac_pos =
85  equivalent_propmattype_indexes(jacobian_quantities);
86  if (do_freq_jac) {
87  dfreq.resize(f_grid.nelem());
88  dfreq = f_grid;
89  dfreq += df;
90  }
91  // if (do_temp_jac)
92  // {
93  // dabs_t.resize(abs_t.nelem());
94  // dabs_t = abs_t;
95  // dabs_t += dt;
96  // }
97  // Jacobian overhead END
98 
99  // Useful if there is no Jacobian to calculate
100  ArrayOfMatrix empty;
101 
102  {
103  // Check that all parameters that should have the the dimension of p_grid
104  // are consistent:
105  const Index n_p = abs_p.nelem();
106  const Index n_t = abs_t.nelem();
107 
108  if (n_p != n_t) {
109  ostringstream os;
110  os << "The following variables must all have the same dimension:\n"
111  << "abs_p: " << n_p << "\n"
112  << "abs_t: " << n_t;
113  throw runtime_error(os.str());
114  }
115  }
116 
117  // Allocate a vector with dimension frequencies for constructing our
118  // cross-sections before adding them (more efficient to allocate this here
119  // outside of the loops)
120  Vector xsec_temp(f_grid.nelem(), 0.);
121 
122  // Jacobian vectors START
123  // Vector dxsec_temp_dT;
124  Vector dxsec_temp_dF;
125  if (do_freq_jac) dxsec_temp_dF.resize(f_grid.nelem());
126  // if (do_temp_jac)
127  // dxsec_temp_dT.resize(f_grid.nelem());
128  // Jacobian vectors END
129 
130  ArrayOfString fail_msg;
131  bool do_abort = false;
132 
133  // Loop over Xsec data sets.
134  // Index ii loops through the outer array (different tag groups),
135  // index s through the inner array (different tags within each goup).
136  for (Index ii = 0; ii < abs_species_active.nelem(); ii++) {
137  const Index i = abs_species_active[ii];
138 
139  for (Index s = 0; s < abs_species[i].nelem(); s++) {
140  const SpeciesTag& this_species = abs_species[i][s];
141 
142  // Check if this is a HITRAN cross section tag
143  if (this_species.Type() != SpeciesTag::TYPE_HITRAN_XSEC) continue;
144 
145 #ifndef ENABLE_FFTW
146  out0 << "HITRAN XSEC Warning: No FFTW library support enabled, "
147  << "convolution will be extremely slow\n";
148 #endif
149 
150  Index this_xdata_index =
151  hitran_xsec_get_index(hitran_xsec_data, this_species.Species());
152  if (this_xdata_index < 0) {
153  ostringstream os;
154  os << "Cross-section species " << this_species.Name()
155  << " not found in *hitran_xsec_data*.";
156  throw std::runtime_error(os.str());
157  }
158  const XsecRecord& this_xdata = hitran_xsec_data[this_xdata_index];
159  Matrix& this_xsec = abs_xsec_per_species[i];
160  ArrayOfMatrix& this_dxsec = do_jac ? dabs_xsec_per_species_dx[i] : empty;
161 
162  // Loop over pressure:
163 #pragma omp parallel for if (!arts_omp_in_parallel() && abs_p.nelem() >= 1) \
164  firstprivate(xsec_temp, dxsec_temp_dF)
165  for (Index ip = 0; ip < abs_p.nelem(); ip++) {
166  if (do_abort) continue;
167  const Numeric current_p = force_p < 0 ? abs_p[ip] : force_p;
168  const Numeric current_t = force_t < 0 ? abs_t[ip] : force_t;
169 
170  // Get the absorption cross sections from the HITRAN data:
171  try {
172  this_xdata.Extract(
173  xsec_temp, f_grid, current_p, current_t, apply_tfit, verbosity);
174  if (do_freq_jac)
175  this_xdata.Extract(dxsec_temp_dF,
176  dfreq,
177  current_p,
178  current_t,
179  apply_tfit,
180  verbosity);
181  // FIXME: Temperature is not yet taken into account
182  // if(do_temp_jac)
183  // this_xdata.Extract(dxsec_temp_dT, f_grid, dabs_t[ip],
184  // verbosity);
185  } catch (runtime_error& e) {
186  ostringstream os;
187  os << "Problem with HITRAN cross section species "
188  << this_species.Name() << " at pressure level " << ip << " ("
189  << abs_p[ip] / 100. << " hPa):\n"
190  << e.what();
191 #pragma omp critical(abs_xsec_per_speciesAddHitranXsec)
192  {
193  do_abort = true;
194  fail_msg.push_back(os.str());
195  }
196  }
197 
198  if (!do_jac) {
199  // Add to result variable:
200  this_xsec(joker, ip) += xsec_temp;
201  } else {
202  for (Index iv = 0; iv < xsec_temp.nelem(); iv++) {
203  this_xsec(iv, ip) += xsec_temp[iv];
204  for (Index iq = 0; iq < jac_pos.nelem(); iq++) {
205  if (is_frequency_parameter(jacobian_quantities[jac_pos[iq]]))
206  this_dxsec[iq](iv, ip) +=
207  (dxsec_temp_dF[iv] - xsec_temp[iv]) / df;
208  // else if (ppd(iq) == JQT_temperature)
209  // this_dxsec[iq](iv, ip) += (dxsec_temp_dT[iv] -
210  // xsec_temp[iv]) / dt;
211  else if (jacobian_quantities[jac_pos[iq]] ==
213  if (species_match(jacobian_quantities[jac_pos[iq]],
214  abs_species[i])) {
215  this_dxsec[iq](iv, ip) += xsec_temp[iv];
216  }
217  }
218  // Note for coef that d/dt(a*n*n) = da/dt * n1*n2 + a * dn1/dt * n2 + a * n1 * dn2/dt,
219  // we now output da/dt*n2 + a*dn2/dt and coef conversion then have to do
220  // dxsec*n1 + xsec*dn1/dt, which is what it has to do anyways, so no problems!
221  // Also note that d/dvmr gives a factor for other species absorption.
222  // even if own absorption is zero...
223  }
224  }
225  }
226  }
227  }
228  }
229 
230  if (do_abort) {
232  os << "Error messages from failures:\n";
233  for (const auto& msg : fail_msg) {
234  os << msg << '\n';
235  }
236  throw std::runtime_error(os.str());
237  }
238 }
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
ArrayOfIndex equivalent_propmattype_indexes(const ArrayOfRetrievalQuantity &js)
Returns a list of positions for the derivatives in Propagation Matrix calculations.
Definition: jacobian.cc:1099
Index nelem() const
Number of elements.
Definition: array.h:195
String Name() const
Return the full name of the tag.
Declarations having to do with the four output streams.
The Vector class.
Definition: matpackI.h:860
Index Species() const
Molecular species index.
Index Type() const
Return the type of this tag.
Numeric frequency_perturbation(const ArrayOfRetrievalQuantity &js) noexcept
Returns the frequency perturbation if it exists.
Definition: jacobian.cc:1312
This file contains basic functions to handle XML data files.
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
bool is_frequency_parameter(const RetrievalQuantity &t) noexcept
Returns if the Retrieval quantity is a frequency parameter in propagation matrix calculations.
Definition: jacobian.cc:1120
The global header file for ARTS.
bool supports_hitran_xsec(const ArrayOfRetrievalQuantity &js)
Returns if the array supports HITRAN cross-section derivatives.
Definition: jacobian.cc:1204
_CS_string_type str() const
Definition: sstream.h:491
#define CREATE_OUTS
Definition: messages.h:209
Methods and classes for HITRAN absorption cross section data.
A tag group can consist of the sum of several of these.
const Joker joker
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
The Matrix class.
Definition: matpackI.h:1193
Declarations required for the calculation of absorption coefficients.
bool species_match(const RetrievalQuantity &rq, const ArrayOfSpeciesTag &ast)
Returns if the Retrieval quantity is VMR derivative for all the species in the species tags...
Definition: jacobian.cc:1244
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
Definition: sstream.h:204
This can be used to make arrays out of anything.
Definition: array.h:40
void resize(Index n)
Resize function.
Definition: matpackI.cc:404
Index hitran_xsec_get_index(const ArrayOfXsecRecord &xsec_data, const Index species)
Get the index in hitran_xsec_data for the given species.
Definition: hitran_xsec.cc:342
void abs_xsec_per_speciesAddHitranXsec(ArrayOfMatrix &abs_xsec_per_species, ArrayOfArrayOfMatrix &dabs_xsec_per_species_dx, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfIndex &abs_species_active, const Vector &f_grid, const Vector &abs_p, const Vector &abs_t, const ArrayOfXsecRecord &hitran_xsec_data, const Index &apply_tfit, const Numeric &force_p, const Numeric &force_t, const Verbosity &verbosity)
WORKSPACE METHOD: abs_xsec_per_speciesAddHitranXsec.
const Numeric SPEED_OF_LIGHT
bool do_frequency_jacobian(const ArrayOfRetrievalQuantity &js) noexcept
Returns if the array wants a frequency derivative.
Definition: jacobian.cc:1296
This file contains declerations of functions of physical character.