ARTS  2.2.66
m_cia.cc
Go to the documentation of this file.
1 /* Copyright (C) 2012 Oliver Lemke <olemke@core-dump.info> and Stefan
2  Buehler <sbuehler@ltu.se>.
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 "arts.h"
30 #include "absorption.h"
31 #include "file.h"
32 #include "cia.h"
33 #include "messages.h"
34 #include "physics_funcs.h"
35 #include "auto_md.h"
36 #include "xml_io.h"
37 
38 
39 extern const Numeric SPEED_OF_LIGHT;
40 
41 /* Workspace method: Doxygen documentation will be auto-generated */
42 void abs_xsec_per_speciesAddCIA(// WS Output:
43  ArrayOfMatrix& abs_xsec_per_species,
44  // WS Input:
45  const ArrayOfArrayOfSpeciesTag& abs_species,
46  const ArrayOfIndex& abs_species_active,
47  const Vector& f_grid,
48  const Vector& abs_p,
49  const Vector& abs_t,
50  const Matrix& abs_vmrs,
51  const ArrayOfCIARecord& abs_cia_data,
52  // WS Generic Input:
53  const Numeric& T_extrapolfac,
54  const Index& robust,
55  // Verbosity object:
56  const Verbosity& verbosity)
57 {
59 
60  {
61  // Check that all parameters that should have the number of tag
62  // groups as a dimension are consistent:
63  const Index n_tgs = abs_species.nelem();
64  const Index n_xsec = abs_xsec_per_species.nelem();
65  const Index nr_vmrs = abs_vmrs.nrows();
66 // const Index n_cia = abs_cia_data.nelem();
67 
68  if (n_tgs != n_xsec ||
69  n_tgs != nr_vmrs) // ||
70 // n_tgs != n_cia)
71  {
72  ostringstream os;
73  os << "The following variables must all have the same dimension:\n"
74  << "abs_species: " << n_tgs << "\n"
75  << "abs_xsec_per_species: " << n_xsec << "\n"
76  << "abs_vmrs.nrows: " << nr_vmrs << "\n";
77 // << "abs_cia_data: " << n_cia;
78  throw runtime_error(os.str());
79  }
80  }
81 
82  {
83  // Check that all parameters that should have the the dimension of p_grid
84  // are consistent:
85  const Index n_p = abs_p.nelem();
86  const Index n_t = abs_t.nelem();
87  const Index nc_vmrs = abs_vmrs.ncols();
88 
89  if (n_p != n_t ||
90  n_p != nc_vmrs)
91  {
92  ostringstream os;
93  os << "The following variables must all have the same dimension:\n"
94  << "abs_p: " << n_p << "\n"
95  << "abs_t: " << n_t << "\n"
96  << "abs_vmrs.ncols: " << nc_vmrs;
97  throw runtime_error(os.str());
98  }
99  }
100 
101  // Allocate a vector with dimension frequencies for constructing our
102  // cross-sections before adding them (more efficient to allocate this here
103  // outside of the loops)
104  Vector xsec_temp(f_grid.nelem());
105 
106  // Loop over CIA data sets.
107  // Index i loops through the outer array (different tag groups),
108  // index s through the inner array (different tags within each goup).
109  for (Index ii = 0; ii < abs_species_active.nelem(); ii++)
110  {
111  const Index i = abs_species_active[ii];
112 
113  for (Index s = 0; s < abs_species[i].nelem(); s++)
114  {
115  const SpeciesTag& this_species = abs_species[i][s];
116 
117  // Check if this is a CIA tag
118  if (this_species.Type() != SpeciesTag::TYPE_CIA)
119  continue;
120 
121  // Get convenient references of this CIA data record and this
122  // absorption cross-section record:
123  Index this_cia_index = cia_get_index(abs_cia_data,
124  this_species.Species(),
125  this_species.CIASecond());
126 
127  assert(this_cia_index != -1);
128 
129  const CIARecord& this_cia = abs_cia_data[this_cia_index];
130  Matrix& this_xsec = abs_xsec_per_species[i];
131 
132  if (out2.sufficient_priority())
133  {
134  // Some nice output to out2:
135  out2 << " CIA Species found: " + this_species.Name() + "\n";
136  }
137 
138  // Check that the dimension of this_xsec is
139  // consistent with abs_p and f_grid.
140  if (this_xsec.nrows()!=f_grid.nelem()) {
141  ostringstream os;
142  os << "Wrong dimension of abs_xsec_per_species.nrows for species "
143  << i << ":\n"
144  << "should match f_grid (" << f_grid.nelem() << ") but is "
145  << this_xsec.nrows() << ".";
146  throw runtime_error(os.str());
147  }
148  if (this_xsec.ncols()!=abs_p.nelem()) {
149  ostringstream os;
150  os << "Wrong dimension of abs_xsec_per_species.ncols for species "
151  << i << ":\n"
152  << "should match abs_p (" << abs_p.nelem() << ") but is "
153  << this_xsec.ncols() << ".";
154  throw runtime_error(os.str());
155  }
156 
157  // Find out index of VMR for the second CIA species.
158  // (The index for the first species is simply i.)
159  Index i_sec = find_first_species_tg(abs_species, this_cia.Species(1));
160 
161  // Catch the case that the VMR for the second species does not exist:
162  if (i_sec < 0) {
163  ostringstream os;
164  os << "VMR profile for second species in CIA species pair does not exist.\n"
165  << "Tag " << this_species.Name() << " needs a VMR profile of "
166  << this_cia.MoleculeName(1) << "!" ;
167  throw runtime_error(os.str());
168  }
169 
170  // Loop over pressure:
171  for (Index ip = 0; ip < abs_p.nelem(); ip++)
172  {
173  // Get the binary absorption cross sections from the CIA data:
174  try {
175  this_cia.Extract(xsec_temp, f_grid, abs_t[ip],
176  this_species.CIADataset(),
177  T_extrapolfac, robust, verbosity);
178  } catch (runtime_error e) {
179  ostringstream os;
180  os << "Problem with CIA species " << this_species.Name() << ":\n"
181  << e.what();
182  throw runtime_error(os.str());
183  }
184 
185  // We have to multiply with the number density of the second CIA species.
186  // We do not have to multiply with the first, since we still
187  // want to return a (unary) absorption cross-section, not an
188  // absorption coefficient.
189 
190  // Calculate number density from pressure and temperature.
191  const Numeric n = abs_vmrs(i_sec,ip) * number_density(abs_p[ip],abs_t[ip]);
192  xsec_temp *= n;
193 
194  // Add to result variable:
195  this_xsec(joker,ip) += xsec_temp;
196  }
197 
198  }
199  }
200 }
201 
202 
203 /* Workspace method: Doxygen documentation will be auto-generated */
204 void abs_cia_dataReadFromCIA(// WS Output:
205  ArrayOfCIARecord& abs_cia_data,
206  // WS Input:
207  const ArrayOfArrayOfSpeciesTag& abs_species,
208  const String& catalogpath,
209  const Verbosity& verbosity)
210 {
211  ArrayOfString subfolders;
212  subfolders.push_back("Main-Folder/");
213  subfolders.push_back("Alternate-Folder/");
214 
215  abs_cia_data.resize(0);
216 
217  // Loop species tag groups to find CIA tags.
218  // Index sp loops through the tag groups, index iso through the tags within
219  // each group. Despite the name, iso does not denote the isotope!
220  for (Index sp = 0; sp < abs_species.nelem(); sp++)
221  {
222  for (Index iso = 0; iso < abs_species[sp].nelem(); iso++)
223  {
224  if (abs_species[sp][iso].Type() != SpeciesTag::TYPE_CIA)
225  continue;
226 
227  ArrayOfString cia_names;
228 
229  Index cia_index = cia_get_index(abs_cia_data,
230  abs_species[sp][iso].Species(),
231  abs_species[sp][iso].CIASecond());
232 
233  // If cia_index is not -1, we have already read this datafile earlier
234  if (cia_index != -1)
235  continue;
236 
237  cia_names.push_back(species_name_from_species_index(abs_species[sp][iso].Species())
238  + "-" + species_name_from_species_index(abs_species[sp][iso].CIASecond()));
239 
240  cia_names.push_back(species_name_from_species_index(abs_species[sp][iso].CIASecond())
241  + "-" + species_name_from_species_index(abs_species[sp][iso].Species()));
242 
243  ArrayOfString checked_dirs;
244 
245  bool found = false;
246  for (Index fname = 0; !found && fname < cia_names.nelem(); fname++)
247  {
248  String cia_name = cia_names[fname];
249 
250  for (Index dir = 0; !found && dir < subfolders.nelem(); dir++)
251  {
252  ArrayOfString files;
253  checked_dirs.push_back(catalogpath + "/"
254  + subfolders[dir]
255  + cia_name + "/");
256  try {
257  list_directory(files, *(checked_dirs.end()-1));
258  }
259  catch (runtime_error e) {
260  continue;
261  }
262 
263  for (Index i = files.nelem()-1; i >= 0; i--)
264  {
265  if (files[i].find(cia_name) != 0
266  || files[i].rfind(".cia") != files[i].length() - 4)
267  {
268  files.erase(files.begin() + i);
269  }
270  }
271  if (files.nelem())
272  {
273  CIARecord ciar;
274 
275  found = true;
276  String catfile = *(checked_dirs.end()-1) + files[0];
277 
278  ciar.SetSpecies(abs_species[sp][iso].Species(),
279  abs_species[sp][iso].CIASecond());
280  ciar.ReadFromCIA(catfile, verbosity);
281 
282  abs_cia_data.push_back(ciar);
283  }
284  }
285  }
286 
287  if (!found)
288  {
289  ostringstream os;
290  os << "Error: No data file found for CIA species "
291  << cia_names[0] << endl
292  << "Looked in directories: " << checked_dirs;
293 
294  throw runtime_error(os.str());
295  }
296  }
297  }
298 }
299 
300 
301 /* Workspace method: Doxygen documentation will be auto-generated */
302 void abs_cia_dataReadFromXML(// WS Output:
303  ArrayOfCIARecord& abs_cia_data,
304  // WS Input:
305  const ArrayOfArrayOfSpeciesTag& abs_species,
306  const String& filename,
307  const Verbosity& verbosity)
308 {
309  xml_read_from_file(filename, abs_cia_data, verbosity);
310 
311  // Check that all CIA tags from abs_species are present in the
312  // XML file
313 
314  vector<String> missing_tags;
315 
316  // Loop species tag groups to find CIA tags.
317  // Index sp loops through the tag groups, index iso through the tags within
318  // each group. Despite the name, iso does not denote the isotope!
319  for (Index sp = 0; sp < abs_species.nelem(); sp++)
320  {
321  for (Index iso = 0; iso < abs_species[sp].nelem(); iso++)
322  {
323  if (abs_species[sp][iso].Type() != SpeciesTag::TYPE_CIA)
324  continue;
325 
326  Index cia_index = cia_get_index(abs_cia_data,
327  abs_species[sp][iso].Species(),
328  abs_species[sp][iso].CIASecond());
329 
330  // If cia_index is -1, this CIA tag was not present in the input file
331  if (cia_index == -1)
332  {
333  missing_tags.push_back(species_name_from_species_index(abs_species[sp][iso].Species())
334  + "-"
335  + species_name_from_species_index(abs_species[sp][iso].CIASecond()));
336  }
337  }
338  }
339 
340  if (missing_tags.size())
341  {
342  ostringstream os;
343  bool first = true;
344 
345  os
346  << "Error: The following CIA tag(s) are missing in input file: ";
347  for (size_t i = 0; i < missing_tags.size(); i++)
348  {
349  if (!first) os << ", ";
350  else first = false;
351  os << missing_tags[i];
352  }
353  throw runtime_error(os.str());
354  }
355 }
356 
357 
358 /* Workspace method: Doxygen documentation will be auto-generated */
359 void CIAInfo(// Generic Input:
360  const String& catalogpath,
361  const ArrayOfString& cia_tags,
362  const Verbosity& verbosity)
363 {
364  CREATE_OUT1;
365 
366  ArrayOfArrayOfSpeciesTag species_tags;
367 
368  for (Index i = 0; i < cia_tags.nelem(); i++)
369  {
370  ArrayOfSpeciesTag this_species_tag;
371 
372  ArrayOfString species_names;
373 
374  cia_tags[i].split(species_names, "-");
375 
376  if (species_names.nelem() != 2)
377  {
378  ostringstream os;
379  os << "ERROR: Cannot parse CIA tag: " << cia_tags[i];
380  throw runtime_error(os.str());
381  }
382 
383  this_species_tag.push_back(SpeciesTag(species_names[0]
384  + "-CIA-"
385  + species_names[1]
386  + "-0"));
387 
388  species_tags.push_back(this_species_tag);
389  }
390 
391  ArrayOfCIARecord cia_data;
392 
393  abs_cia_dataReadFromCIA(cia_data, species_tags, catalogpath, verbosity);
394 
395  Print(cia_data, 1, verbosity);
396 }
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:35
Header file for work with HITRAN collision induced absorption (CIA).
void Print(Workspace &ws, const Agenda &x, const Index &level, const Verbosity &verbosity)
Definition: m_general.cc:81
Index nelem() const
Number of elements.
Definition: array.h:176
Index CIADataset() const
CIA dataset index inside this CIA file.
Index CIASecond() const
Species index of the 2nd CIA species.
String Name() const
Return the full name of the tag.
Declarations having to do with the four output streams.
void abs_cia_dataReadFromXML(ArrayOfCIARecord &abs_cia_data, const ArrayOfArrayOfSpeciesTag &abs_species, const String &filename, const Verbosity &verbosity)
WORKSPACE METHOD: abs_cia_dataReadFromXML.
Definition: m_cia.cc:302
The Vector class.
Definition: matpackI.h:556
Index Species() const
Molecular species index.
void CIAInfo(const String &catalogpath, const ArrayOfString &cia_tags, const Verbosity &verbosity)
WORKSPACE METHOD: CIAInfo.
Definition: m_cia.cc:359
Index Type() const
Return the type of this tag.
void ReadFromCIA(const String &filename, const Verbosity &verbosity)
Read CIA catalog file.
Definition: cia.cc:345
const Numeric SPEED_OF_LIGHT
This file contains basic functions to handle XML data files.
This file contains basic functions to handle ASCII files.
void iso(Array< IsotopologueRecord >::iterator &ii, String name, const ArrayOfNumeric &coeff, const Index &coefftype)
void abs_xsec_per_speciesAddCIA(ArrayOfMatrix &abs_xsec_per_species, const ArrayOfArrayOfSpeciesTag &abs_species, const ArrayOfIndex &abs_species_active, const Vector &f_grid, const Vector &abs_p, const Vector &abs_t, const Matrix &abs_vmrs, const ArrayOfCIARecord &abs_cia_data, const Numeric &T_extrapolfac, const Index &robust, const Verbosity &verbosity)
WORKSPACE METHOD: abs_xsec_per_speciesAddCIA.
Definition: m_cia.cc:42
Numeric number_density(const Numeric &p, const Numeric &t)
number_density
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:180
String species_name_from_species_index(const Index spec_ind)
Return species name for given species index.
Definition: absorption.cc:1301
void Extract(VectorView result, ConstVectorView f_grid, const Numeric &temperature, const Index &dataset, const Numeric &T_extrapolfac, const Index &robust, const Verbosity &verbosity) const
Vector version of extract.
Definition: cia.cc:265
The implementation for String, the ARTS string class.
Definition: mystring.h:63
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:838
The global header file for ARTS.
void list_directory(ArrayOfString &files, String dirname)
Return list of files in directory.
Definition: file.cc:581
#define CREATE_OUTS
Definition: messages.h:216
A tag group can consist of the sum of several of these.
#define CREATE_OUT1
Definition: messages.h:212
Index find_first_species_tg(const ArrayOfArrayOfSpeciesTag &tgs, const Index &spec)
Find first occurrence of species in tag groups.
void xml_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads data from XML file.
Definition: xml_io.cc:831
const Joker joker
void abs_cia_dataReadFromCIA(ArrayOfCIARecord &abs_cia_data, const ArrayOfArrayOfSpeciesTag &abs_species, const String &catalogpath, const Verbosity &verbosity)
WORKSPACE METHOD: abs_cia_dataReadFromCIA.
Definition: m_cia.cc:204
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:29
The Matrix class.
Definition: matpackI.h:788
Declarations required for the calculation of absorption coefficients.
This can be used to make arrays out of anything.
Definition: array.h:40
void SetSpecies(const Index first, const Index second)
Set CIA species.
Definition: cia.h:161
String MoleculeName(const Index i) const
Return each molecule name (as a string) that is associated with this CIARecord.
Definition: cia.cc:301
CIA data for a single pair of molecules.
Definition: cia.h:68
Index cia_get_index(const ArrayOfCIARecord &cia_data, const Index sp1, const Index sp2)
Get the index in cia_data for the two given species.
Definition: cia.cc:252
Index Species(const Index i) const
Return CIA species index.
Definition: cia.h:101
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:832