ARTS  2.0.49
m_abs.cc
Go to the documentation of this file.
1 /* Copyright (C) 2000-2008
2  Stefan Buehler <sbuehler@ltu.se>
3  Patrick Eriksson <patrick.eriksson@chalmers.se>
4  Axel von Engeln <engeln@uni-bremen.de>
5  Thomas Kuhn <tkuhn@uni-bremen.de>
6 
7  This program is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2, or (at your option) any
10  later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20  USA. */
21 
22 //
23 
33 #include <cmath>
34 #include <algorithm>
35 #include "arts.h"
36 #include "matpackI.h"
37 #include "array.h"
38 #include "messages.h"
39 #include "file.h"
40 #include "absorption.h"
41 #include "auto_md.h"
42 #include "math_funcs.h"
43 #include "make_array.h"
44 #include "physics_funcs.h"
45 #include "continua.h"
46 #include "make_vector.h"
47 #include "check_input.h"
48 #include "xml_io.h"
49 
50 #ifdef ENABLE_NETCDF
51 #include <netcdf.h>
52 #include "nc_io.h"
53 #endif
54 
55 extern const Numeric SPEED_OF_LIGHT;
56 
57 /* Workspace method: Doxygen documentation will be auto-generated */
58 void AbsInputFromRteScalars(// WS Output:
59  Vector& abs_p,
60  Vector& abs_t,
61  Matrix& abs_vmrs,
62  // WS Input:
63  const Numeric& rte_pressure,
64  const Numeric& rte_temperature,
65  const Vector& rte_vmr_list,
66  const Verbosity&)
67 {
68  // Prepare abs_p:
69  abs_p.resize(1);
70  abs_p = rte_pressure;
71 
72  // Prepare abs_t:
73  abs_t.resize(1);
74  abs_t = rte_temperature;
75 
76  // Prepare abs_vmrs:
77  abs_vmrs.resize(rte_vmr_list.nelem(),1);
78  abs_vmrs = rte_vmr_list;
79 }
80 
81 
82 /* Workspace method: Doxygen documentation will be auto-generated */
84  ArrayOfArrayOfLineRecord& abs_lines_per_species,
85  // WS Input:
86  const ArrayOfArrayOfSpeciesTag& tgs,
87  const Verbosity&)
88 {
89  // Make abs_lines_per_species the right size:
90  abs_lines_per_species.resize( tgs.nelem() );
91 
92  for (Index i=0; i<tgs.nelem(); ++i)
93  {
94  abs_lines_per_species[i].resize(0);
95  }
96 }
97 
98 
99 /* Workspace method: Doxygen documentation will be auto-generated */
100 void abs_linesReadFromHitran(// WS Output:
101  ArrayOfLineRecord& abs_lines,
102  // Control Parameters:
103  const String& filename,
104  const Numeric& fmin,
105  const Numeric& fmax,
106  const Verbosity& verbosity)
107 {
109 
110  ifstream is;
111 
112  // Reset lines in case it already existed:
113  abs_lines.resize(0);
114 
115  out2 << " Reading file: " << filename << "\n";
116  open_input_file(is, filename);
117 
118  bool go_on = true;
119  while ( go_on )
120  {
121  LineRecord lr;
122  if ( lr.ReadFromHitranStream(is, verbosity) )
123  {
124  // If we are here the read function has reached eof and has
125  // returned no data.
126  go_on = false;
127  }
128  else
129  {
130  if ( fmin <= lr.F() )
131  {
132  if ( lr.F() <= fmax )
133  abs_lines.push_back(lr);
134  else
135  go_on = false;
136  }
137  }
138  }
139  out2 << " Read " << abs_lines.nelem() << " lines.\n";
140 }
141 
142 
143 /* Workspace method: Doxygen documentation will be auto-generated */
144 void abs_linesReadFromHitran2004(// WS Output:
145  ArrayOfLineRecord& abs_lines,
146  // Control Parameters:
147  const String& filename,
148  const Numeric& fmin,
149  const Numeric& fmax,
150  const Verbosity& verbosity)
151 {
153 
154  ifstream is;
155 
156  // Reset lines in case it already existed:
157  abs_lines.resize(0);
158 
159  out2 << " Reading file: " << filename << "\n";
160  open_input_file(is, filename);
161 
162  bool go_on = true;
163  while ( go_on )
164  {
165  LineRecord lr;
166  if ( lr.ReadFromHitran2004Stream(is, verbosity) )
167  {
168  // If we are here the read function has reached eof and has
169  // returned no data.
170  go_on = false;
171  }
172  else
173  {
174  if ( fmin <= lr.F() )
175  {
176  if ( lr.F() <= fmax )
177  abs_lines.push_back(lr);
178  else
179  go_on = false;
180  }
181  }
182  }
183  out2 << " Read " << abs_lines.nelem() << " lines.\n";
184 }
185 
186 
187 /* Workspace method: Doxygen documentation will be auto-generated */
188 void abs_linesReadFromMytran2(// WS Output:
189  ArrayOfLineRecord& abs_lines,
190  // Control Parameters:
191  const String& filename,
192  const Numeric& fmin,
193  const Numeric& fmax,
194  const Verbosity& verbosity)
195 {
197 
198  ifstream is;
199 
200  // Reset lines in case it already existed:
201  abs_lines.resize(0);
202 
203  out2 << " Reading file: " << filename << "\n";
204  open_input_file(is, filename);
205 
206  bool go_on = true;
207  while ( go_on )
208  {
209  LineRecord lr;
210  if ( lr.ReadFromMytran2Stream(is, verbosity) )
211  {
212  // If we are here the read function has reached eof and has
213  // returned no data.
214  go_on = false;
215  }
216  else
217  {
218  // lines are not necessarily frequency sorted
219  if ( fmin <= lr.F() )
220  if ( lr.F() <= fmax )
221  abs_lines.push_back(lr);
222  }
223  }
224  out2 << " Read " << abs_lines.nelem() << " lines.\n";
225 }
226 
227 
228 /* Workspace method: Doxygen documentation will be auto-generated */
229 void abs_linesReadFromJpl(// WS Output:
230  ArrayOfLineRecord& abs_lines,
231  // Control Parameters:
232  const String& filename,
233  const Numeric& fmin,
234  const Numeric& fmax,
235  const Verbosity& verbosity)
236 {
238 
239  ifstream is;
240 
241  // Reset lines in case it already existed:
242  abs_lines.resize(0);
243 
244  out2 << " Reading file: " << filename << "\n";
245  open_input_file(is, filename);
246 
247  bool go_on = true;
248  while ( go_on )
249  {
250  LineRecord lr;
251  if ( lr.ReadFromJplStream(is, verbosity) )
252  {
253  // If we are here the read function has reached eof and has
254  // returned no data.
255  go_on = false;
256  }
257  else
258  {
259  // we expect lines to be sorted
260  if ( fmin <= lr.F() )
261  {
262  if ( lr.F() <= fmax )
263  abs_lines.push_back(lr);
264  else
265  go_on = false;
266  }
267  }
268  }
269  out2 << " Read " << abs_lines.nelem() << " lines.\n";
270 }
271 
272 
273 /* Workspace method: Doxygen documentation will be auto-generated */
274 void abs_linesReadFromArts(// WS Output:
275  ArrayOfLineRecord& abs_lines,
276  // Control Parameters:
277  const String& filename,
278  const Numeric& fmin,
279  const Numeric& fmax,
280  const Verbosity& verbosity)
281 {
283 
284  xml_read_arts_catalogue_from_file (filename, abs_lines, fmin, fmax, verbosity);
285 
286  out2 << " Read " << abs_lines.nelem() << " lines from " << filename << ".\n";
287 }
288 
289 
290 /* Workspace method: Doxygen documentation will be auto-generated */
292  ArrayOfLineRecord& abs_lines,
293  const ArrayOfArrayOfSpeciesTag& abs_species,
294  // Control Parameters:
295  const String& basename,
296  const Numeric& fmin,
297  const Numeric& fmax,
298  const Verbosity& verbosity)
299 {
301  extern const Array<SpeciesRecord> species_data;
302 
303  // Build a set of species indices. Duplicates are ignored.
304  set<Index> unique_species;
305  for (ArrayOfArrayOfSpeciesTag::const_iterator asp = abs_species.begin();
306  asp != abs_species.end(); asp++)
307  for (ArrayOfSpeciesTag::const_iterator sp = asp->begin();
308  sp != asp->end(); sp++)
309  {
310  // If the Isotope number is equal to the number of Isotopes for that species,
311  // it means 'all isotopes', in which case we have to read a catalog.
312  // Species with isotopic ratio -1 don't need a catalog.
313  if (sp->Isotope() == species_data[sp->Species()].Isotope().nelem()
314  || species_data[sp->Species()].Isotope()[sp->Isotope()].Abundance() != -1)
315  {
316  unique_species.insert(sp->Species());
317  }
318  }
319 
320  // Read catalogs for each identified species and put them all into
321  // abs_lines.
322  abs_lines.resize(0);
323  for (set<Index>::const_iterator it = unique_species.begin();
324  it != unique_species.end(); it++)
325  {
326  ArrayOfLineRecord more_abs_lines;
327  abs_linesReadFromArts(more_abs_lines, basename + "." + (species_data[*it].Name()) + ".xml",
328  fmin, fmax, verbosity);
329  abs_lines.insert(abs_lines.end(), more_abs_lines.begin(), more_abs_lines.end());
330  }
331 
332  out2 << " Read " << abs_lines.nelem() << " lines in total.\n";
333 }
334 
335 
337 
348  ArrayOfLineRecord& abs_lines,
349  // Control Parameters:
350  const String& filename,
351  const Numeric& fmin,
352  const Numeric& fmax,
353  const Verbosity& verbosity)
354 {
356 
357  // The input stream:
358  ifstream is;
359 
360  // We will use this line record to read in the line records in the
361  // file one after another:
362  LineRecord lr;
363 
364  // Reset lines in case it already existed:
365  abs_lines.resize(0);
366 
367  out2 << " Reading file: " << filename << "\n";
368  open_input_file(is, filename);
369 
370  // Get version tag and check that it corresponds to the current version.
371  {
372  String v;
373  is >> v;
374  if ( v!=lr.VersionString() )
375  {
376  ostringstream os;
377 
378  // If what we read is the version String, it should have at elast 9 characters.
379  if ( 9 <= v.nelem() )
380  {
381  if ( "ARTSCAT" == v.substr(0,7) )
382  {
383  os << "The ARTS line file you are trying contains a version tag "
384  << "different from the current version.\n"
385  << "Tag in file: " << v << "\n"
386  << "Current version: " << lr.Version();
387  throw runtime_error(os.str());
388  }
389  }
390 
391  os << "The ARTS line file you are trying to read does not contain a valid version tag.\n"
392  << "Probably it was created with an older version of ARTS that used different units.";
393  throw runtime_error(os.str());
394  }
395  }
396 
397  bool go_on = true;
398  while ( go_on )
399  {
400  if ( lr.ReadFromArtscat3Stream(is, verbosity) )
401  {
402  // If we are here the read function has reached eof and has
403  // returned no data.
404  go_on = false;
405  }
406  else
407  {
408  // lines are not necessarily frequency sorted
409  if ( fmin <= lr.F() && lr.F() <= fmax )
410  {
411  abs_lines.push_back(lr);
412  }
413  }
414  }
415  out2 << " Read " << abs_lines.nelem() << " lines.\n";
416 }
417 
418 
419 /* FIXME OLE: Do we need this function? */
420 void linesElowToJoule(// WS Output:
421  ArrayOfLineRecord& abs_lines )
422 {
423  for ( Index i=0; i<abs_lines.nelem(); ++i )
424  abs_lines[i].melow = wavenumber_to_joule(abs_lines[i].melow);
425 }
426 
427 
428 /* Workspace method: Doxygen documentation will be auto-generated */
430  ArrayOfArrayOfLineRecord& abs_lines_per_species,
431  // WS Input:
432  const ArrayOfArrayOfSpeciesTag& tgs,
433  // Control Parameters:
434  const ArrayOfString& filenames,
435  const ArrayOfString& formats,
436  const Vector& fmin,
437  const Vector& fmax,
438  const Verbosity& verbosity)
439 {
441 
442  const Index n_tg = tgs.nelem(); // # tag groups
443  const Index n_cat = filenames.nelem(); // # tag Catalogues
444 
445  // Check that dimensions of the keyword parameters are consistent
446  // (must all be the same).
447 
448  if ( n_cat != formats.nelem() ||
449  n_cat != fmin.nelem() ||
450  n_cat != fmax.nelem() )
451  {
452  ostringstream os;
453  os << "abs_lines_per_speciesReadFromCatalogues: All keyword\n"
454  << "parameters must get the same number of arguments.\n"
455  << "You specified:\n"
456  << "filenames: " << n_cat << "\n"
457  << "formats: " << formats.nelem() << "\n"
458  << "fmin: " << fmin.nelem() << "\n"
459  << "fmax: " << fmax.nelem();
460  throw runtime_error(os.str());
461  }
462 
463  // Furthermore, the dimension must be
464  // smaller than or equal to the number of tag groups.
465 
466  if ( n_cat > n_tg )
467  {
468  ostringstream os;
469  os << "abs_lines_per_speciesReadFromCatalogues: You specified more\n"
470  << "catalugues than you have tag groups.\n"
471  << "You specified:\n"
472  << "Catalogues: " << n_cat << "\n"
473  << "tgs: " << n_tg;
474  throw runtime_error(os.str());
475  }
476 
477  // There must be at least one tag group and at least one catalogue:
478 
479  if ( n_cat < 1 ||
480  n_tg < 1 )
481  {
482  ostringstream os;
483  os << "abs_lines_per_speciesReadFromCatalogues: You must have at\n"
484  << "least one catalogue and at least one tag group.\n"
485  << "You specified:\n"
486  << "Catalogues: " << n_cat << "\n"
487  << "tgs: " << n_tg;
488  throw runtime_error(os.str());
489  }
490 
491  // There can be repetitions in the keyword paramters. We want to read
492  // and process each catalogue only once, so we'll compile a set of
493  // real catalogues, along with a data structure that tells us which
494  // tag groups should use this catalogue.
495 
496  MakeArray<String> real_filenames ( filenames[0] );
497  MakeArray<String> real_formats ( formats[0] );
498  MakeArray<Numeric> real_fmin ( fmin[0] );
499  MakeArray<Numeric> real_fmax ( fmax[0] );
500 
501  Array< ArrayOfIndex > real_tgs(1);
502  real_tgs[0].resize(1);
503  real_tgs[0][0] = 0;
504 
505  // The last specified catalogue, to which we should assign all
506  // remaining lines. Index of this one in real_ arrays.
507  Index last_cat = 0;
508 
509  for ( Index i=1; i<n_tg; ++i )
510  {
511  // Is there a catalogue specified?
512  if ( n_cat > i )
513  {
514  // Yes, there is a catalogue.
515 
516  // Has this been specified before?
517  // We use the STL find algorithm to look for the catalogue
518  // name in the real_catalogues. Find returns an iterator, so
519  // to get an index we have to take the difference to
520  // .begin().
521  const Index that_cat = find( real_filenames.begin(),
522  real_filenames.end(),
523  filenames[i] ) - real_filenames.begin();
524  if ( that_cat < real_filenames.nelem() )
525  {
526  // Yes, it has been specified before
527  // ==> Assign to that catalogue
528  real_tgs[that_cat].push_back(i);
529 
530  // Verify, that format, fmin, and fmax are consistent:
531  if ( formats[i] != real_formats[that_cat] ||
532  fmin[i] != real_fmin[that_cat] ||
533  fmax[i] != real_fmax[that_cat] )
534  {
535  ostringstream os;
536  os << "abs_lines_per_speciesReadFromCatalogues: If you specify the\n"
537  << "same catalogue repeatedly, format, fmin, and fmax must be\n"
538  << "consistent. There is an inconsistency between\n"
539  << "catalogue " << that_cat << " and " << i << ".";
540  throw runtime_error(os.str());
541  }
542  }
543  else
544  {
545  // No, it has not been specified before.
546  // ==> Add an entry to real_tgs and the other real_ variables:
547  real_tgs.push_back( MakeArray<Index>(i) );
548 
549  real_filenames.push_back( filenames[i] );
550  real_formats.push_back ( formats[i] );
551  real_fmin.push_back ( fmin[i] );
552  real_fmax.push_back ( fmax[i] );
553 
554  last_cat = i; // assign remainder of lines to this
555  // catalogue, if there is no other catalogue.
556  }
557  }
558  else
559  {
560  // No, there is no catalogue.
561  // ==> Assign to the last catalogue
562  real_tgs[last_cat].push_back(i);
563  }
564  }
565 
566  Index n_real_cat = real_filenames.nelem(); // # real catalogues to read
567 
568  // Some output to low priority stream:
569  out3 << " Catalogues to read and tgs for which these will be used:\n";
570  for ( Index i=0; i<n_real_cat; ++i )
571  {
572  out3 << " " << real_filenames[i] << ":";
573  for ( Index s=0; s<real_tgs[i].nelem(); ++s )
574  out3 << " " << real_tgs[i][s];
575  out3 << "\n";
576  }
577 
578  // Make abs_lines_per_species the right size:
579  abs_lines_per_species.resize( tgs.nelem() );
580 
581  // Loop through the catalogues to read:
582  for ( Index i=0; i<n_real_cat; ++i )
583  {
584  ArrayOfLineRecord abs_lines;
585 
586  // Read catalogue:
587 
588  if ( "HITRAN96"==real_formats[i] )
589  {
590  abs_linesReadFromHitran( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i], verbosity );
591  }
592  else if ( "HITRAN04"==real_formats[i] )
593  {
594  abs_linesReadFromHitran2004( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i], verbosity );
595  }
596  else if ( "MYTRAN2"==real_formats[i] )
597  {
598  abs_linesReadFromMytran2( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i], verbosity );
599  }
600  else if ( "JPL"==real_formats[i] )
601  {
602  abs_linesReadFromJpl( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i], verbosity );
603  }
604  else if ( "ARTS"==real_formats[i] )
605  {
606  abs_linesReadFromArts( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i], verbosity );
607  }
608  else
609  {
610  ostringstream os;
611  os << "abs_lines_per_speciesReadFromCatalogues: You specified the\n"
612  << "format `" << real_formats[i] << "', which is unknown.\n"
613  << "Allowd formats are: HITRAN96, HITRAN04, MYTRAN2, JPL, ARTS.";
614  throw runtime_error(os.str());
615  }
616 
617  // We need to make subset tgs for the groups that should
618  // be read from this catalogue.
619  ArrayOfArrayOfSpeciesTag these_tgs(real_tgs[i].nelem());
620  for ( Index s=0; s<real_tgs[i].nelem(); ++s )
621  {
622  these_tgs[s] = tgs[real_tgs[i][s]];
623  }
624 
625  // Create these_abs_lines_per_species:
626  ArrayOfArrayOfLineRecord these_abs_lines_per_species;
627  abs_lines_per_speciesCreateFromLines( these_abs_lines_per_species, abs_lines, these_tgs, verbosity );
628 
629  // Put these lines in the right place in abs_lines_per_species:
630  for ( Index s=0; s<real_tgs[i].nelem(); ++s )
631  {
632  abs_lines_per_species[real_tgs[i][s]] = these_abs_lines_per_species[s];
633  }
634  }
635 }
636 
637 
638 /* Workspace method: Doxygen documentation will be auto-generated */
640  ArrayOfArrayOfLineRecord& abs_lines_per_species,
641  // WS Input:
642  const ArrayOfLineRecord& abs_lines,
643  const ArrayOfArrayOfSpeciesTag& tgs,
644  const Verbosity& verbosity)
645 {
647 
648  // The species lookup data:
649  extern const Array<SpeciesRecord> species_data;
650 
651  // As a safety feature, we will watch out for the case that a
652  // species is included in the calculation, but not all lines are
653  // used. For this we need an array to flag the used species:
654 
655  // For some weird reason, Arrays of bool do not work, although all
656  // other types seem to work fine. So in this single case, I'll use
657  // the stl vector directly. The other place where this is done is in
658  // the function executor in main.cc.
659  // FIXME: Fix this when Array<bool> works.
660  std::vector<bool> species_used (species_data.nelem(),false);
661 
662  // Make abs_lines_per_species the right size:
663  abs_lines_per_species = ArrayOfArrayOfLineRecord(tgs.nelem());
664 
665  // Unfortunately, MTL conatains a bug that leads to all elements of
666  // the outer Array of an Array<Array>> pointing to the same data
667  // after creation. So we need to fix this explicitly:
668  for ( Index i=0; i<abs_lines_per_species.nelem(); ++i )
669  abs_lines_per_species[i] = ArrayOfLineRecord();
670 
671  // Loop all lines in the input line list:
672  for ( Index i=0; i<abs_lines.nelem(); ++i )
673  {
674  // Get a convenient reference to the current line:
675  const LineRecord& this_line = abs_lines[i];
676 
677  // We have to test each tag group in turn (in the order in which
678  // they appear in the controlfile). The line is assigned to the
679  // first tag group that fits.
680 
681  // The flag found is used to break the for loops when the right
682  bool found = false;
683 
684  // We need to define j here, since we need the value outside the
685  // for loop:
686  Index j;
687 
688  // Loop the tag groups:
689  for ( j=0; j<tgs.nelem() && !found ; ++j )
690  {
691  // A tag group can contain several tags:
692  for ( Index k=0; k<tgs[j].nelem() && !found; ++k )
693  {
694  // Get a reference to the current tag (not really
695  // necessary, but makes for nicer notation below):
696  const SpeciesTag& this_tag = tgs[j][k];
697 
698  // Now we will test different attributes of the line
699  // against matching attributes of the tag. If any
700  // attribute does not match, we continue with the next tag
701  // in the tag group. (Exception: Species, see just below.)
702 
703  // Test species. If this attribute does not match we don`t
704  // have to test the other tags in this group, since all
705  // tags must belong to the same species.
706  if ( this_tag.Species() != this_line.Species() ) break;
707 
708  // Test isotope. The isotope can either match directly, or
709  // the Isotope of the tag can be one larger than the
710  // number of isotopes, which means `all'. Test the second
711  // condition first, since this will probably be more often
712  // used.
713  if ( this_tag.Isotope() != this_line.SpeciesData().Isotope().nelem() )
714  if ( this_tag.Isotope() != this_line.Isotope() )
715  continue;
716 
717  // Test frequncy range we take both the lower (Lf) and the
718  // upper (Uf) border frequency to include the `equal' case.
719  // Both Lf and Uf can also be negative, which means `no limit'
720 
721  // Take the lower limit first:
722  if ( this_tag.Lf() >= 0 )
723  if ( this_tag.Lf() > this_line.F() )
724  continue;
725 
726  // Then the upper limit:
727  if ( this_tag.Uf() >= 0 )
728  if ( this_tag.Uf() < this_line.F() )
729  continue;
730 
731  // When we get here, this_tag has survived all tests. That
732  // means it matches the line perfectly!
733  found = true;
734  }
735  }
736 
737  // If a matching tag was found, this line can be used in the
738  // calculation. Add it to the line list for this tag group.
739  if (found)
740  {
741  // We have to use j-1 here, since j was still increased by
742  // one after the matching tag has been found.
743  abs_lines_per_species[j-1].push_back(this_line);
744 
745  // Flag this species as used, if not already done:
746  if ( !species_used[this_line.Species()] )
747  species_used[this_line.Species()] = true;
748  }
749  else
750  {
751  // Safety feature: Issue a warning messages if the lines for a
752  // species are only partly covered by tags.
753  if ( species_used[this_line.Species()] )
754  {
756  out2 << " Your tags include other lines of species "
757  << this_line.SpeciesData().Name()
758  << ",\n"
759  << "why do you not include line "
760  << i
761  << " (at "
762  << this_line.F()
763  << " Hz)?\n";
764  }
765  }
766  }
767 
768  // Write some information to the lowest priority output stream.
769  for (Index i=0; i<tgs.nelem(); ++i)
770  {
771  out3 << " " << i << ":";
772 
773  for (Index s=0; s<tgs[i].nelem(); ++s)
774  out3 << " " << tgs[i][s].Name();
775 
776  out3 << ": " << abs_lines_per_species[i].nelem() << " lines\n";
777  }
778 
779 }
780 
781 
782 /* Workspace method: Doxygen documentation will be auto-generated */
784  ArrayOfArrayOfLineRecord& abs_lines_per_species,
785  const Verbosity&)
786 {
787  // We will simply append the mirror lines after the original
788  // lines. This way we don't have to make a backup copy of the
789  // original lines.
790 
791  for ( Index i=0; i<abs_lines_per_species.nelem(); ++i )
792  {
793  // Get a reference to the current list of lines to save typing:
794  ArrayOfLineRecord& ll = abs_lines_per_species[i];
795 
796  // For increased efficiency, reserve the necessary space:
797  ll.reserve(2*ll.nelem());
798 
799  // Loop through all lines of this tag group:
800  {
801  // It is important that we determine the size of ll *before*
802  // we start the loop. After all, we are adding elements. And
803  // we cerainly don't want to continue looping the newly added
804  // elements, we want to loop only the original elements.
805  Index n=ll.nelem();
806  for ( Index j=0; j<n; ++j )
807  {
808  LineRecord dummy = ll[j];
809  dummy.setF( -dummy.F() );
810  // cout << "Adding ML at f = " << dummy.F() << "\n";
811  ll.push_back(dummy);
812  }
813  }
814  }
815 
816 }
817 
818 
819 /* Workspace method: Doxygen documentation will be auto-generated */
821  ArrayOfArrayOfLineRecord& abs_lines_per_species,
822  // WS Input:
823  const ArrayOfLineshapeSpec& abs_lineshape,
824  const Vector& f_grid,
825  const Verbosity&)
826 {
827  // Make sure abs_lines_per_species and abs_lineshape have the same
828  // dimension. As a special case, abs_lineshape can have length 1, in
829  // which case it is valid for all species.
830  if ( (abs_lines_per_species.nelem() != abs_lineshape.nelem()) &&
831  (abs_lineshape.nelem() != 1) )
832  {
833  ostringstream os;
834  os << "Dimension of abs_lines_per_species does\n"
835  << "not match that of abs_lineshape.\n"
836  << "(Dimension of abs_lineshape must be 1 or\n"
837  << "equal to abs_lines_per_species.)";
838  throw runtime_error(os.str());
839  }
840 
841  // Make sure that the frequency grid is properly sorted:
842  for ( Index s=0; s<f_grid.nelem()-1; ++s )
843  {
844  if ( f_grid[s+1] <= f_grid[s] )
845  {
846  ostringstream os;
847  os << "The frequency grid f_grid is not properly sorted.\n"
848  << "f_grid[" << s << "] = " << f_grid[s] << "\n"
849  << "f_grid[" << s+1 << "] = " << f_grid[s+1];
850  throw runtime_error(os.str());
851  }
852  }
853 
854  // Cycle through all tag groups:
855  for ( Index i=0; i<abs_lines_per_species.nelem(); ++i )
856  {
857  // Get cutoff frequency of this tag group.
858  // We have to also handle the special case that there is only
859  // one lineshape for all species.
860  Numeric cutoff;
861  if (1==abs_lineshape.nelem())
862  cutoff = abs_lineshape[0].Cutoff();
863  else
864  cutoff = abs_lineshape[i].Cutoff();
865 
866  // Check whether cutoff is defined:
867  if ( cutoff != -1)
868  {
869  // Get a reference to the current list of lines to save typing:
870  ArrayOfLineRecord& ll = abs_lines_per_species[i];
871 
872  // Calculate the borders:
873  Numeric upp = f_grid[f_grid.nelem()-1] + cutoff;
874  Numeric low = f_grid[0] - cutoff;
875 
876  // Cycle through all lines within this tag group.
878  for ( ArrayOfLineRecord::iterator j=ll.begin(); j<ll.end(); ++j )
879  {
880  // Center frequency:
881  const Numeric F0 = j->F();
882 
883  if ( ( F0 >= low) && ( F0 <= upp) )
884  {
885  // Build list of elements which should be kept
886  keep.push_back (j);
887  // The original implementation just erased the non-wanted
888  // elements from the array. Problem: On every erase the
889  // whole array will be copied which actually kills
890  // performance.
891  }
892  }
893 
894  // If next comparison is false, some elements have to be removed
895  if (keep.nelem () != ll.nelem ())
896  {
897  ArrayOfLineRecord nll;
898  // Copy all elements that should be kept to a new Array
900  = keep.begin(); j != keep.end(); j++)
901  {
902  nll.push_back (**j);
903  }
904  // Overwrite the old array with the new one
905  ll.resize (nll.nelem ());
906  ll = nll;
907  }
908  }
909  }
910 }
911 
912 
913 /* Workspace method: Doxygen documentation will be auto-generated */
916  // Control Parameters:
917  const String& basename,
918  const Verbosity& verbosity)
919 {
921 
922  // Species lookup data:
923  extern const Array<SpeciesRecord> species_data;
924 
925  // We want to make lists of included and excluded species:
926  ArrayOfString included(0), excluded(0);
927 
928  tgs.resize(0);
929 
930  for ( Index i=0; i<species_data.nelem(); ++i )
931  {
932  const String specname = species_data[i].Name();
933  const String filename = basename + "." + specname + ".xml";
934 
935  // Try to open VMR file:
936  try
937  {
938  ifstream file;
939  open_input_file(file, filename);
940 
941  // Ok, if we get here the file was found.
942 
943  // Add to included list:
944  included.push_back(specname);
945 
946  // Convert name of species to a SpeciesTag object:
947  SpeciesTag this_tag(specname);
948 
949  // Create Array of SpeciesTags with length 1
950  // (our tag group has only one tag):
951  ArrayOfSpeciesTag this_group(1);
952  this_group[0] = this_tag;
953 
954  // Add this tag group to tgs:
955  tgs.push_back(this_group);
956  }
957  catch (runtime_error)
958  {
959  // Ok, the file for the species could not be found.
960  excluded.push_back(specname);
961  }
962  }
963 
964  // Some nice output:
965  out2 << " Included Species (" << included.nelem() << "):\n";
966  for ( Index i=0; i<included.nelem(); ++i )
967  out2 << " " << included[i] << "\n";
968 
969  out2 << " Excluded Species (" << excluded.nelem() << "):\n";
970  for ( Index i=0; i<excluded.nelem(); ++i )
971  out2 << " " << excluded[i] << "\n";
972 }
973 
974 
975 /* Workspace method: Doxygen documentation will be auto-generated */
976 void abs_lineshapeDefine(// WS Output:
977  ArrayOfLineshapeSpec& abs_lineshape,
978  // WS Input:
979  const String& shape,
980  const String& normalizationfactor,
981  const Numeric& cutoff,
982  const Verbosity& verbosity)
983 {
985 
986  // Make lineshape and normalization factor data visible:
989 
990 
991  // generate the right number of elements
992  // Index tag_sz = tgs.nelem();
993  // We generate only 1 copy of the lineshape settings. Absorption
994  // routines check for this case and use it for all species.
995  Index tag_sz = 1;
996  abs_lineshape.resize(tag_sz);
997 
998  // Is this lineshape available?
999  Index found0=-1;
1000  for ( Index i=0; i<lineshape_data.nelem() && (found0 == -1) ; ++i )
1001  {
1002  const String& str = lineshape_data[i].Name();
1003  if (str == shape)
1004  {
1005  out2 << " Selected lineshape: " << str << "\n";
1006  found0=i;
1007  }
1008  }
1009 
1010  // Is this normalization to the lineshape available?
1011  Index found1=-1;
1012  for ( Index i=0; i<lineshape_norm_data.nelem() && (found1 == -1); ++i )
1013  {
1014  const String& str = lineshape_norm_data[i].Name();
1015  if (str == normalizationfactor)
1016  {
1017  out2 << " Selected normalization factor : " << normalizationfactor << "\n";
1018 
1019  if ( (cutoff != -1) && (cutoff < 0.0) )
1020  throw runtime_error(" Cutoff must be -1 or positive.");
1021  out2 << " Selected cutoff frequency [Hz] : " << cutoff << "\n";
1022  found1=i;
1023  }
1024  }
1025 
1026 
1027  // did we find the lineshape and normalization factor?
1028  if (found0 == -1)
1029  throw runtime_error("Selected lineshape not available.");
1030  if (found1 == -1)
1031  throw runtime_error("Selected normalization to lineshape not available.");
1032 
1033 
1034  // now set the lineshape
1035  for (Index i=0; i<tag_sz; i++)
1036  {
1037  abs_lineshape[i].SetInd_ls( found0 );
1038  abs_lineshape[i].SetInd_lsn( found1 );
1039  abs_lineshape[i].SetCutoff( cutoff );
1040  }
1041 }
1042 
1043 
1044 /* Workspace method: Doxygen documentation will be auto-generated */
1045 void abs_lineshape_per_tgDefine(// WS Output:
1046  ArrayOfLineshapeSpec& abs_lineshape,
1047  // WS Input:
1048  const ArrayOfArrayOfSpeciesTag& tgs,
1049  const ArrayOfString& shape,
1050  const ArrayOfString& normalizationfactor,
1051  const Vector& cutoff,
1052  const Verbosity& verbosity)
1053 {
1054  CREATE_OUT2
1055 
1056  // Make lineshape and normalization factor data visible:
1059 
1060  // check that the number of elements are equal
1061  Index tg_sz = tgs.nelem();
1062  if ( (tg_sz != shape.nelem()) ||
1063  (tg_sz != normalizationfactor.nelem()) ||
1064  (tg_sz != cutoff.nelem()) )
1065  {
1066  ostringstream os;
1067  os << "abs_lineshape_per_tgDefine: number of elements does\n"
1068  << "not match the number of tag groups defined.";
1069  throw runtime_error(os.str());
1070  }
1071 
1072 
1073  // generate the right number of elements
1074  abs_lineshape.resize(tg_sz);
1075 
1076  // Is this lineshape available?
1077  for (Index k=0; k<tg_sz; ++k)
1078  {
1079  Index found0=-1;
1080  for ( Index i=0; i<lineshape_data.nelem() && (found0 == -1); ++i )
1081  {
1082  const String& str = lineshape_data[i].Name();
1083  if (str == shape[k])
1084  {
1085  out2 << " Tag Group: [";
1086  for (Index s=0; s<tgs[k].nelem()-1; ++s)
1087  out2 << tgs[k][s].Name() << ", ";
1088  out2 << tgs[k][tgs[k].nelem()-1].Name() << "]\n";
1089  out2 << " Selected lineshape: " << str << "\n";
1090  found0=i;
1091  }
1092  }
1093 
1094  // Is this normalization to the lineshape available?
1095  Index found1=-1;
1096  for ( Index i=0; i<lineshape_norm_data.nelem() && (found1 == -1); ++i )
1097  {
1098  const String& str = lineshape_norm_data[i].Name();
1099  if (str == normalizationfactor[k])
1100  {
1101  out2 << " Selected normalization factor: " << normalizationfactor[k] << "\n";
1102  if ( (cutoff[k] != -1) && (cutoff[k] < 0.0) )
1103  throw runtime_error(" Cutoff must be -1 or positive.");
1104  out2 << " Selected cutoff frequency : " << cutoff[k] << "\n";
1105  found1=i;
1106  }
1107  }
1108 
1109 
1110  // did we find the lineshape and normalization factor?
1111  if (found0 == -1)
1112  {
1113  ostringstream os;
1114  os << "Selected lineshape not available: "<< shape[k] <<"\n";
1115  throw runtime_error(os.str());
1116  }
1117  if (found1 == -1)
1118  {
1119  ostringstream os;
1120  os << "Selected normalization to lineshape not available: "<<
1121  normalizationfactor[k] <<"\n";
1122  throw runtime_error(os.str());
1123  }
1124 
1125  // now set the lineshape variables
1126  abs_lineshape[k].SetInd_ls( found0 );
1127  abs_lineshape[k].SetInd_lsn( found1 );
1128  abs_lineshape[k].SetCutoff( cutoff[k] );
1129  }
1130 }
1131 
1132 
1133 /* Workspace method: Doxygen documentation will be auto-generated */
1134 void abs_h2oSet(Vector& abs_h2o,
1135  const ArrayOfArrayOfSpeciesTag& abs_species,
1136  const Matrix& abs_vmrs,
1137  const Verbosity&)
1138 {
1139  const Index h2o_index
1140  = find_first_species_tg( abs_species,
1142 
1143  if ( h2o_index < 0 )
1144  throw runtime_error("No tag group contains water!");
1145 
1146  abs_h2o.resize( abs_vmrs.ncols() );
1147  abs_h2o = abs_vmrs(h2o_index,Range(joker));
1148 }
1149 
1150 
1151 /* Workspace method: Doxygen documentation will be auto-generated */
1152 void abs_n2Set(Vector& abs_n2,
1153  const ArrayOfArrayOfSpeciesTag& abs_species,
1154  const Matrix& abs_vmrs,
1155  const Verbosity&)
1156 {
1157  const Index n2_index
1158  = find_first_species_tg( abs_species,
1160 
1161  if ( n2_index < 0 )
1162  throw runtime_error("No tag group contains nitrogen!");
1163 
1164  abs_n2.resize( abs_vmrs.ncols() );
1165  abs_n2 = abs_vmrs(n2_index,Range(joker));
1166 }
1167 
1168 
1169 /* Workspace method: Doxygen documentation will be auto-generated */
1170 void AbsInputFromAtmFields (// WS Output:
1171  Vector& abs_p,
1172  Vector& abs_t,
1173  Matrix& abs_vmrs,
1174  // WS Input:
1175  const Index& atmosphere_dim,
1176  const Vector& p_grid,
1177  const Tensor3& t_field,
1178  const Tensor4& vmr_field,
1179  const Verbosity&
1180  )
1181 {
1182  // First, make sure that we really have a 1D atmosphere:
1183  if ( 1 != atmosphere_dim )
1184  {
1185  ostringstream os;
1186  os << "Atmospheric dimension must be 1D, but atmosphere_dim is "
1187  << atmosphere_dim << ".";
1188  throw runtime_error(os.str());
1189  }
1190 
1191  abs_p = p_grid;
1192  abs_t = t_field (joker, 0, 0);
1193  abs_vmrs = vmr_field (joker, joker, 0, 0);
1194 }
1195 
1196 
1197 /* Workspace method: Doxygen documentation will be auto-generated */
1198 void abs_coefCalc(// WS Output:
1199  Matrix& abs_coef,
1200  ArrayOfMatrix& abs_coef_per_species,
1201  // WS Input:
1202  const ArrayOfArrayOfSpeciesTag& tgs,
1203  const Vector& f_grid,
1204  const Vector& abs_p,
1205  const Vector& abs_t,
1206  const Vector& abs_n2,
1207  const Vector& abs_h2o,
1208  const Matrix& abs_vmrs,
1209  const ArrayOfArrayOfLineRecord& abs_lines_per_species,
1210  const ArrayOfLineshapeSpec& abs_lineshape,
1211  const ArrayOfString& abs_cont_names,
1212  const ArrayOfString& abs_cont_models,
1213  const ArrayOfVector& abs_cont_parameters,
1214  const Verbosity& verbosity)
1215 {
1216  // Dimension checks are performed in the executed functions
1217 
1218  // allocate local variable to hold the cross sections per tag group
1219  ArrayOfMatrix abs_xsec_per_species;
1220 
1221  abs_xsec_per_speciesInit(abs_xsec_per_species, tgs, f_grid, abs_p, verbosity);
1222 
1223  abs_xsec_per_speciesAddLines(abs_xsec_per_species,
1224  tgs,
1225  f_grid,
1226  abs_p,
1227  abs_t,
1228  abs_h2o,
1229  abs_vmrs,
1230  abs_lines_per_species,
1231  abs_lineshape,
1232  verbosity);
1233 
1234  abs_xsec_per_speciesAddConts(abs_xsec_per_species,
1235  tgs,
1236  f_grid,
1237  abs_p,
1238  abs_t,
1239  abs_n2,
1240  abs_h2o,
1241  abs_vmrs,
1242  abs_cont_names,
1243  abs_cont_parameters,
1244  abs_cont_models,
1245  verbosity);
1246 
1247  abs_coefCalcFromXsec(abs_coef,
1248  abs_coef_per_species,
1249  abs_xsec_per_species,
1250  abs_vmrs,
1251  abs_p,
1252  abs_t,
1253  verbosity);
1254 
1255 }
1256 
1257 
1258 /* Workspace method: Doxygen documentation will be auto-generated */
1259 void abs_coefCalcSaveMemory(// WS Output:
1260  Matrix& abs_coef,
1261  // WS Input:
1262  const ArrayOfArrayOfSpeciesTag& tgs,
1263  const Vector& f_grid,
1264  const Vector& abs_p,
1265  const Vector& abs_t,
1266  const Vector& abs_n2,
1267  const Vector& abs_h2o,
1268  const Matrix& abs_vmrs,
1269  const ArrayOfArrayOfLineRecord& abs_lines_per_species,
1270  const ArrayOfLineshapeSpec& abs_lineshape,
1271  const ArrayOfString& abs_cont_names,
1272  const ArrayOfString& abs_cont_models,
1273  const ArrayOfVector& abs_cont_parameters,
1274  const Verbosity& verbosity)
1275 {
1276  CREATE_OUT3
1277 
1278  // Dimension checks are performed in the executed functions
1279 
1280  // Allocate local variable to hold the cross sections per tag group:
1281  ArrayOfMatrix abs_xsec_per_species;
1282 
1283  // Allocate local variable to hold the absorption for each tag group:
1284  Matrix this_abs;
1285 
1286  // Allocate local variable to hold abs_coef_per_species for each tag
1287  // group. This is just a dummy, we need it, since it is a formal
1288  // argument of abs_coefCalcFromXsec.
1289  ArrayOfMatrix this_abs_coef_per_species;
1290 
1291  // Define variable to hold a dummy list of tag groups with only 1 element:
1292  ArrayOfArrayOfSpeciesTag this_tg(1);
1293 
1294  // Local list of VMRs, only 1 element:
1295  Matrix this_vmr(1,abs_p.nelem());
1296 
1297  // Local abs_lines_per_species, only 1 element:
1298  ArrayOfArrayOfLineRecord these_lines(1);
1299 
1300  // Local lineshape list, only 1 element:
1301  ArrayOfLineshapeSpec this_lineshape(1);
1302 
1303  // Initialize the output variable abs_coef:
1304  abs_coef.resize( f_grid.nelem(), abs_p.nelem() );
1305  abs_coef = 0; // Matpack can set all elements like this.
1306 
1307  out3 << " Number of tag groups to do: " << tgs.nelem() << "\n";
1308 
1309  // Loop over all species:
1310  for ( Index i=0; i<tgs.nelem(); ++i )
1311  {
1312  out3 << " Doing tag group " << i << ".\n";
1313 
1314  // Get a dummy list of tag groups with only the current element:
1315  this_tg[0].resize(tgs[i].nelem());
1316  this_tg[0] = tgs[i];
1317 
1318  // VMR for this species:
1319  this_vmr(0,joker) = abs_vmrs(i,joker);
1320 
1321  // List of lines:
1322  these_lines[0].resize(abs_lines_per_species[i].nelem());
1323  these_lines[0] = abs_lines_per_species[i];
1324 
1325  // List of lineshapes:
1326  this_lineshape[0] = abs_lineshape[i];
1327 
1328  abs_xsec_per_speciesInit(abs_xsec_per_species, this_tg, f_grid, abs_p, verbosity);
1329 
1330  abs_xsec_per_speciesAddLines(abs_xsec_per_species,
1331  this_tg,
1332  f_grid,
1333  abs_p,
1334  abs_t,
1335  abs_h2o,
1336  this_vmr,
1337  these_lines,
1338  this_lineshape,
1339  verbosity);
1340 
1341  abs_xsec_per_speciesAddConts(abs_xsec_per_species,
1342  this_tg,
1343  f_grid,
1344  abs_p,
1345  abs_t,
1346  abs_n2,
1347  abs_h2o,
1348  this_vmr,
1349  abs_cont_names,
1350  abs_cont_parameters,
1351  abs_cont_models,
1352  verbosity);
1353 
1354  abs_coefCalcFromXsec(this_abs,
1355  this_abs_coef_per_species,
1356  abs_xsec_per_species,
1357  this_vmr,
1358  abs_p,
1359  abs_t,
1360  verbosity);
1361 
1362  // Add absorption of this species to total absorption:
1363  assert(abs_coef.nrows()==this_abs.nrows());
1364  assert(abs_coef.ncols()==this_abs.ncols());
1365  abs_coef += this_abs;
1366  }
1367 }
1368 
1369 
1370 /* Workspace method: Doxygen documentation will be auto-generated */
1371 void abs_coefCalcFromXsec(// WS Output:
1372  Matrix& abs_coef,
1373  ArrayOfMatrix& abs_coef_per_species,
1374  // WS Input:
1375  const ArrayOfMatrix& abs_xsec_per_species,
1376  const Matrix& abs_vmrs,
1377  const Vector& abs_p,
1378  const Vector& abs_t,
1379  const Verbosity& verbosity)
1380 {
1381  CREATE_OUT3
1382 
1383  // Check that abs_vmrs and abs_xsec_per_species really have compatible
1384  // dimensions. In abs_vmrs there should be one row for each tg:
1385  if ( abs_vmrs.nrows() != abs_xsec_per_species.nelem() )
1386  {
1387  ostringstream os;
1388  os << "Variable abs_vmrs must have compatible dimension to abs_xsec_per_species.\n"
1389  << "abs_vmrs.nrows() = " << abs_vmrs.nrows() << "\n"
1390  << "abs_xsec_per_species.nelem() = " << abs_xsec_per_species.nelem();
1391  throw runtime_error(os.str());
1392  }
1393 
1394  // Check that number of altitudes are compatible. We only check the
1395  // first element, this is possilble because within arts all elements
1396  // are on the same altitude grid.
1397  if ( abs_vmrs.ncols() != abs_xsec_per_species[0].ncols() )
1398  {
1399  ostringstream os;
1400  os << "Variable abs_vmrs must have same numbers of altitudes as abs_xsec_per_species.\n"
1401  << "abs_vmrs.ncols() = " << abs_vmrs.ncols() << "\n"
1402  << "abs_xsec_per_species[0].ncols() = " << abs_xsec_per_species[0].ncols();
1403  throw runtime_error(os.str());
1404  }
1405 
1406  // Check dimensions of abs_p and abs_t:
1407  chk_size("abs_p", abs_p, abs_vmrs.ncols());
1408  chk_size("abs_t", abs_t, abs_vmrs.ncols());
1409 
1410 
1411  // Initialize abs_coef and abs_coef_per_species. The array dimension of abs_coef_per_species
1412  // is the same as that of abs_xsec_per_species. The dimension of abs_coef should
1413  // be equal to one of the abs_xsec_per_species enries.
1414  abs_coef.resize( abs_xsec_per_species[0].nrows(), abs_xsec_per_species[0].ncols() );
1415  abs_coef = 0; // Matpack can set all elements like this.
1416 
1417  abs_coef_per_species.resize( abs_xsec_per_species.nelem() );
1418 
1419  out3 << " Computing abs_coef and abs_coef_per_species from abs_xsec_per_species.\n";
1420 
1421  // Loop through all tag groups
1422  for ( Index i=0; i<abs_xsec_per_species.nelem(); ++i )
1423  {
1424  out3 << " Tag group " << i << "\n";
1425 
1426  // Make this element of abs_xsec_per_species the right size:
1427  abs_coef_per_species[i].resize( abs_xsec_per_species[i].nrows(), abs_xsec_per_species[i].ncols() );
1428  abs_coef_per_species[i] = 0; // Initialize all elements to 0.
1429 
1430  // Loop through all altitudes
1431  for ( Index j=0; j<abs_xsec_per_species[i].ncols(); j++)
1432  {
1433  // Calculate total number density from pressure and temperature.
1434  const Numeric n = number_density(abs_p[j],abs_t[j]);
1435 
1436  // Loop through all frequencies
1437  for ( Index k=0; k<abs_xsec_per_species[i].nrows(); k++)
1438  {
1439  abs_coef_per_species[i](k,j) = abs_xsec_per_species[i](k,j) * n * abs_vmrs(i,j);
1440  }
1441  }
1442 
1443  // Add up to the total absorption:
1444  abs_coef += abs_coef_per_species[i]; // In Matpack you can use the +=
1445  // operator to do elementwise addition.
1446  }
1447 }
1448 
1449 
1450 /* Workspace method: Doxygen documentation will be auto-generated */
1451 void abs_xsec_per_speciesInit(// WS Output:
1452  ArrayOfMatrix& abs_xsec_per_species,
1453  // WS Input:
1454  const ArrayOfArrayOfSpeciesTag& tgs,
1455  const Vector& f_grid,
1456  const Vector& abs_p,
1457  const Verbosity& verbosity
1458  )
1459 {
1460  CREATE_OUT3
1461 
1462  // Initialize abs_xsec_per_species. The array dimension of abs_xsec_per_species
1463  // is the same as that of abs_lines_per_species.
1464  abs_xsec_per_species.resize( tgs.nelem() );
1465 
1466  // Loop abs_xsec_per_species and make each matrix the right size,
1467  // initializing to zero:
1468  for ( Index i=0; i<tgs.nelem(); ++i )
1469  {
1470  // Make this element of abs_coef_per_species the right size:
1471  abs_xsec_per_species[i].resize( f_grid.nelem(), abs_p.nelem() );
1472  abs_xsec_per_species[i] = 0; // Matpack can set all elements like this.
1473  }
1474 
1475  ostringstream os;
1476  os << " Initialized abs_xsec_per_species.\n"
1477  << " Number of frequencies : " << f_grid.nelem() << "\n"
1478  << " Number of pressure levels : " << abs_p.nelem() << "\n";
1479  out3 << os.str();
1480 }
1481 
1482 
1483 /* Workspace method: Doxygen documentation will be auto-generated */
1485  ArrayOfMatrix& abs_xsec_per_species,
1486  // WS Input:
1487  const ArrayOfArrayOfSpeciesTag& tgs,
1488  const Vector& f_grid,
1489  const Vector& abs_p,
1490  const Vector& abs_t,
1491  const Vector& abs_h2o,
1492  const Matrix& abs_vmrs,
1493  const ArrayOfArrayOfLineRecord& abs_lines_per_species,
1494  const ArrayOfLineshapeSpec& abs_lineshape,
1495  const Verbosity& verbosity)
1496 {
1497  CREATE_OUT3
1498 
1499  // Check that all temperatures are at least 0 K. (Negative Kelvin
1500  // temperatures are unphysical.)
1501  if ( min(abs_t) < 0 )
1502  {
1503  ostringstream os;
1504  os << "Temperature must be at least 0 K. But you request an absorption\n"
1505  << "calculation at " << min(abs_t) << " K!";
1506  throw runtime_error(os.str());
1507  }
1508 
1509  // Check that all paramters that should have the number of tag
1510  // groups as a dimension are consistent.
1511  {
1512  const Index n_tgs = tgs.nelem();
1513  const Index n_xsec = abs_xsec_per_species.nelem();
1514  const Index n_vmrs = abs_vmrs.nrows();
1515  const Index n_lines = abs_lines_per_species.nelem();
1516  const Index n_shapes = abs_lineshape.nelem();
1517 
1518  if ( n_tgs != n_xsec ||
1519  n_tgs != n_vmrs ||
1520  n_tgs != n_lines ||
1521  ( n_tgs != n_shapes &&
1522  1 != n_shapes ) )
1523  {
1524  ostringstream os;
1525  os << "The following variables must all have the same dimension:\n"
1526  << "tgs: " << tgs.nelem() << "\n"
1527  << "abs_xsec_per_species: " << abs_xsec_per_species.nelem() << "\n"
1528  << "abs_vmrs: " << abs_vmrs.nrows() << "\n"
1529  << "abs_lines_per_species: " << abs_lines_per_species.nelem() << "\n"
1530  << "abs_lineshape: " << abs_lineshape.nelem() << "\n"
1531  << "(As a special case, abs_lineshape is allowed to have only one element.)";
1532  throw runtime_error(os.str());
1533  }
1534  }
1535 
1536  // Print information:
1537  //
1538  out3 << " Calculating line spectra.\n";
1539  //
1540  // Uncomment the part below if you temporarily want detailed info about
1541  // transitions to be done
1542 
1543  // The variables defined here (in particular the frequency
1544  // conversion) are just to make the output nice. They are not used
1545  // in subsequent calculations.
1546  // cout << " Transitions to do: \n";
1547  // Index nlines = 0;
1548  // String funit;
1549  // Numeric ffac;
1550  // if ( f_grid[0] < 3e12 )
1551  // {
1552  // funit = "GHz"; ffac = 1e9;
1553  // }
1554  // else
1555  // {
1556  // extern const Numeric SPEED_OF_LIGHT;
1557  // funit = "cm-1"; ffac = SPEED_OF_LIGHT*100;
1558  // }
1559  // for ( Index i=0; i<abs_lines_per_species.nelem(); ++i )
1560  // {
1561  // for ( Index l=0; l<abs_lines_per_species[i].nelem(); ++l )
1562  // {
1563  // cout << " " << abs_lines_per_species[i][l].Name() << " @ "
1564  // << abs_lines_per_species[i][l].F()/ffac << " " << funit << " ("
1565  // << abs_lines_per_species[i][l].I0() << " "
1566  // << abs_lines_per_species[i][l].Agam() << ")\n";
1567  // nlines++;
1568  // }
1569  // }
1570  // out2 << " Total number of transistions : " << nlines << "\n";
1571 
1572  // Call xsec_species for each tag group.
1573  for ( Index i=0; i<tgs.nelem(); ++i )
1574  {
1575  // Get a pointer to the line list for the current species. This
1576  // is just so that we don't have to type abs_lines_per_species[i] over
1577  // and over again.
1578  const ArrayOfLineRecord& ll = abs_lines_per_species[i];
1579 
1580  // Also get a pointer to the lineshape specification. This
1581  // requires special treatment: If there is only 1 lineshape
1582  // given, the same line shape should be used for all species.
1583  LineshapeSpec ls;
1584  if (1==abs_lineshape.nelem())
1585  ls = abs_lineshape[0];
1586  else
1587  ls = abs_lineshape[i];
1588 
1589  // Skip the call to abs_xsec_per_species if the line list is empty.
1590  if ( 0 < ll.nelem() )
1591  {
1592  // As a safety check, check that the species of the first
1593  // line matches the species we should have according to
1594  // tgs. (This in case the order in tgs has been changed and
1595  // abs_lines_per_species has not been changed consistently.)
1596  if (ll[0].Species() != tgs[i][0].Species() )
1597  {
1598  ostringstream os;
1599  os << "The species in the line list does not match the species\n"
1600  << "for which you want to calculate absorption:\n"
1601  << "abs_species: " << get_tag_group_name(tgs[i]) << "\n"
1602  << "abs_lines_per_species: " << ll[0].Name();
1603  throw runtime_error(os.str());
1604  }
1605 
1606  // Get the name of the species. The member function name of a
1607  // LineRecord returns the full name (species + isotope). So
1608  // it is for us more convenient to get the species index
1609  // from the LineRecord member function Species(), and then
1610  // use this to look up the species name in species_data.
1611  extern const Array<SpeciesRecord> species_data;
1612  String species_name = species_data[ll[0].Species()].Name();
1613 
1614  // Get the name of the lineshape. For that we use the member
1615  // function Ind_ls() to the lineshape data ls, which returns
1616  // an index. With that index we can go into lineshape_data
1617  // to get the name.
1618  // We will need this for safety checks later on.
1620  String lineshape_name = lineshape_data[ls.Ind_ls()].Name();
1621 
1622 
1623  // The use of overlap parameters for oxygen lines only makes
1624  // sense if the special Rosenkranz lineshape is used
1625  // (Rosenkranz_Voigt_Drayson or Rosenkranz_Voigt_Kuntz6).
1626  // Likewise, the use of these lineshapes only makes sense if
1627  // overlap parameters are available. We will test both these
1628  // conditions.
1629 
1630  // First of all, let's find out if the species we are
1631  // dealing with is oxygen.
1632  if ( "O2" == species_name )
1633  {
1634  // Do we have overlap parameters in the aux fields of
1635  // the LineRecord?
1636  if ( 0 != ll[0].Naux() )
1637  {
1638  // Yes. So let's make sure that the lineshape is one
1639  // that can use these parameters.
1640  if ( "Rosenkranz_Voigt_Drayson" != lineshape_name &&
1641  "Rosenkranz_Voigt_Kuntz6" != lineshape_name )
1642  {
1643  ostringstream os;
1644  os
1645  << "You are using a line catalogue that contains auxiliary parameters to\n"
1646  << "take care of overlap for oxygen lines. But you are not using a\n"
1647  << "lineshape that uses these parameters. Use Rosenkranz_Voigt_Drayson or\n"
1648  << "Rosenkranz_Voigt_Kuntz6.";
1649  throw runtime_error(os.str());
1650  }
1651  }
1652  }
1653 
1654  // Now we go the opposite way. Let's see if the Rosenkranz
1655  // lineshapes are used.
1656  if ( "Rosenkranz_Voigt_Drayson" == lineshape_name ||
1657  "Rosenkranz_Voigt_Kuntz6" == lineshape_name )
1658  {
1659  // Is the species oxygen, as it should be?
1660  if ( "O2" != species_name )
1661  {
1662  ostringstream os;
1663  os
1664  << "You are trying to use one of the special Rosenkranz lineshapes with\n"
1665  << "overlap correction for a species other than oxygen. Your species is\n"
1666  << species_name << ".\n"
1667  << "Select another lineshape for this species.";
1668  throw runtime_error(os.str());
1669  }
1670  else
1671  {
1672  // Do we have overlap parameters in the aux fields of
1673  // the LineRecord?
1674  if ( 0 == ll[0].Naux() )
1675  {
1676  ostringstream os;
1677  os
1678  << "You are trying to use one of the special Rosenkranz lineshapes with\n"
1679  << "overlap correction. But your line file does not contain aux\n"
1680  << "parameters. (I've checked only the first LineRecord). Use a line file\n"
1681  << "with overlap parameters.";
1682  throw runtime_error(os.str());
1683  }
1684  }
1685  }
1686 
1687  xsec_species( abs_xsec_per_species[i],
1688  f_grid,
1689  abs_p,
1690  abs_t,
1691  abs_h2o,
1692  abs_vmrs(i,Range(joker)),
1693  ll,
1694  ls.Ind_ls(),
1695  ls.Ind_lsn(),
1696  ls.Cutoff(),
1697  verbosity );
1698  // Note that we call xsec_species with a row of abs_vmrs,
1699  // selected by the above Matpack expression. This is
1700  // possible, because xsec_species is using Views.
1701  }
1702 
1703  {
1704  ostringstream os;
1705  os << " Tag group " << i
1706  << " (" << get_tag_group_name(tgs[i]) << "): "
1707  << ll.nelem() << " transitions\n";
1708  out3 << os.str();
1709  }
1710 
1711  } // End of species for loop.
1712 }
1713 
1714 /* Workspace method: Doxygen documentation will be auto-generated */
1716  ArrayOfMatrix& abs_xsec_per_species,
1717  // WS Input:
1718  const ArrayOfArrayOfSpeciesTag& tgs,
1719  const Vector& f_grid,
1720  const Vector& abs_p,
1721  const Vector& abs_t,
1722  const Vector& abs_n2,
1723  const Vector& abs_h2o,
1724  const Matrix& abs_vmrs,
1725  const ArrayOfString& abs_cont_names,
1726  const ArrayOfVector& abs_cont_parameters,
1727  const ArrayOfString& abs_cont_models,
1728  const Verbosity& verbosity)
1729 {
1730  CREATE_OUT3
1731 
1732  // Check that all paramters that should have the number of tag
1733  // groups as a dimension are consistent.
1734  {
1735  const Index n_tgs = tgs.nelem();
1736  const Index n_xsec = abs_xsec_per_species.nelem();
1737  const Index n_vmrs = abs_vmrs.nrows();
1738 
1739  if ( n_tgs != n_xsec || n_tgs != n_vmrs )
1740  {
1741  ostringstream os;
1742  os << "The following variables must all have the same dimension:\n"
1743  << "tgs: " << tgs.nelem() << "\n"
1744  << "abs_xsec_per_species: " << abs_xsec_per_species.nelem() << "\n"
1745  << "abs_vmrs.nrows(): " << abs_vmrs.nrows();
1746  throw runtime_error(os.str());
1747  }
1748  }
1749 
1750  // Check, that dimensions of abs_cont_names and
1751  // abs_cont_parameters are consistent...
1752  if ( abs_cont_names.nelem() !=
1753  abs_cont_parameters.nelem() )
1754  {
1755  ostringstream os;
1756 
1757  for (Index i=0; i < abs_cont_names.nelem(); ++i)
1758  os << "abs_xsec_per_speciesAddConts: " << i << " name : " << abs_cont_names[i] << "\n";
1759 
1760  for (Index i=0; i < abs_cont_parameters.nelem(); ++i)
1761  os << "abs_xsec_per_speciesAddConts: " << i << " param: " << abs_cont_parameters[i] << "\n";
1762 
1763  for (Index i=0; i < abs_cont_models.nelem(); ++i)
1764  os << "abs_xsec_per_speciesAddConts: " << i << " option: " << abs_cont_models[i] << "\n";
1765 
1766  os << "The following variables must have the same dimension:\n"
1767  << "abs_cont_names: " << abs_cont_names.nelem() << "\n"
1768  << "abs_cont_parameters: " << abs_cont_parameters.nelem();
1769 
1770  throw runtime_error(os.str());
1771  }
1772 
1773  // ...and that indeed the names match valid continuum models:
1774  for ( Index i=0; i<abs_cont_names.nelem(); ++i )
1775  {
1776  check_continuum_model(abs_cont_names[i]);
1777  }
1778 
1779 
1780  // Check that abs_p, abs_t, and abs_vmrs have the same
1781  // dimension. This could be a user error, so we throw a
1782  // runtime_error.
1783 
1784  if ( abs_t.nelem() != abs_p.nelem() )
1785  {
1786  ostringstream os;
1787  os << "Variable abs_t must have the same dimension as abs_p.\n"
1788  << "abs_t.nelem() = " << abs_t.nelem() << '\n'
1789  << "abs_p.nelem() = " << abs_p.nelem();
1790  throw runtime_error(os.str());
1791  }
1792 
1793  if ( abs_vmrs.ncols() != abs_p.nelem() )
1794  {
1795  ostringstream os;
1796  os << "Variable dimension abs_vmrs.ncols() must\n"
1797  << "be the same as abs_p.nelem().\n"
1798  << "abs_vmrs.ncols() = " << abs_vmrs.ncols() << '\n'
1799  << "abs_p.nelem() = " << abs_p.nelem();
1800  throw runtime_error(os.str());
1801  }
1802 
1803  // We do checks on abs_h2o and abs_n2 later, because we only want to
1804  // do the check if the parameter are really needed.
1805 
1806 
1807  out3 << " Calculating continuum spectra.\n";
1808 
1809  // Loop tag groups:
1810  for ( Index i=0; i<tgs.nelem(); ++i )
1811  {
1812  extern const Array<SpeciesRecord> species_data;
1813 
1814  // Go through the tags in the current tag group to see if they
1815  // are continuum tags:
1816  for ( Index s=0; s<tgs[i].nelem(); ++s )
1817  {
1818  // First of all, we have to make sure that this is not a
1819  // tag that means `all isotopes', because this should not
1820  // include continuum. For such tags, tag.Isotope() will
1821  // return the number of isotopes (i.e., one more than the
1822  // allowed index range).
1823  if ( tgs[i][s].Isotope() <
1824  species_data[tgs[i][s].Species()].Isotope().nelem() )
1825  {
1826  // If we get here, it means that the tag describes a
1827  // specific isotope. Could be a continuum tag!
1828 
1829  // The if clause below checks whether the abundance of this tag
1830  // is negative. (Negative abundance marks continuum tags.)
1831  // It does the following:
1832  //
1833  // 1. species_data contains the lookup table of species
1834  // specific data. We need the right entry in this
1835  // table. The index of this is obtained by calling member function
1836  // Species() on the tag. Thus we have:
1837  // species_data[tgs[i][s].Species()].
1838  //
1839  // 2. Member function Isotope() on the above biest gives
1840  // us the array of isotope specific data. This we have
1841  // to subscribe with the right isotope index, which we
1842  // get by calling member function Isotope on the
1843  // tag. Thus we have:
1844  // Isotope()[tgs[i][s].Isotope()]
1845  //
1846  // 3. Finally, from the isotope data we need to get the mixing
1847  // ratio by calling the member function Abundance().
1848  if ( 0 >
1849  species_data[tgs[i][s].Species()].Isotope()[tgs[i][s].Isotope()].Abundance() )
1850  {
1851  // We have identified a continuum tag!
1852 
1853  // Get only the continuum name. The full tag name is something like:
1854  // H2O-HITRAN96Self-*-*. We want only the `H2O-HITRAN96Self' part:
1855  const String name =
1856  species_data[tgs[i][s].Species()].Name() + "-"
1857  + species_data[tgs[i][s].Species()].Isotope()[tgs[i][s].Isotope()].Name();
1858 
1859  // Check that this corresponds to a valid continuum
1860  // model:
1861  check_continuum_model(name);
1862 
1863  // Check, if we have parameters for this model. For
1864  // this, the model name must be listed in
1865  // abs_cont_names.
1866  const Index n =
1867  find( abs_cont_names.begin(),
1868  abs_cont_names.end(),
1869  name ) - abs_cont_names.begin();
1870 
1871  // n==abs_cont_names.nelem() indicates that
1872  // the name was not found.
1873  if ( n==abs_cont_names.nelem() )
1874  {
1875  ostringstream os;
1876  os << "Cannot find model " << name
1877  << " in abs_cont_names.";
1878  throw runtime_error(os.str());
1879  }
1880 
1881  // Ok, the tag specifies a valid continuum model and
1882  // we have continuum parameters.
1883 
1884  {
1885  ostringstream os;
1886  os << " Adding " << name
1887  << " to tag group " << i << ".\n";
1888  out3 << os.str();
1889  }
1890 
1891  // find the options for this continuum tag from the input array
1892  // of options. The actual field of the array is n:
1893  const String ContOption = abs_cont_models[n];
1894 
1895 
1896  // ------------------------------------------------------------------
1897  // Now is the time to check whether abs_h2o and
1898  // abs_n2 are ok!
1899 
1900  // abs_h2o has a global scalar default value of -1. We throw an
1901  // appropriate error message here if we find this, since most
1902  // continuum models require it. (abs_h2o is the H2O VMR to be used
1903  // for the continua of other species, such as O2.)
1904 
1905  if ( -.99 > abs_h2o[0] )
1906  {
1907  ostringstream os;
1908  os << "The variable abs_h2o seems to be set to its global default\n"
1909  << "value of -1. You have to set this to a H2O VMR profile if\n"
1910  << "you want to use absorption contiua. If you are calling\n"
1911  << "absorption routines directly, or on the fly, you could\n"
1912  << "use for example the method *abs_h2oSet*.\n"
1913  << "If you are generating an absorption lookup table with\n"
1914  << "abs_lookupCreate, it should be enough to add a H2O species\n"
1915  << "to your calculation to fix this problem.";
1916  throw runtime_error(os.str());
1917  }
1918 
1919  // If h2o_abs is not set to the default value, it
1920  // must have the same size as the pressure grid:
1921  if ( abs_h2o.nelem() != abs_p.nelem() )
1922  {
1923  ostringstream os;
1924  os << "Variable abs_h2o must have the same dimension as abs_p.\n"
1925  << "abs_h2o.nelem() = " << abs_h2o.nelem() << '\n'
1926  << "abs_p.nelem() = " << abs_p.nelem();
1927  throw runtime_error(os.str());
1928  }
1929 
1930  // For abs_n2 the situation is slightly
1931  // different. The global scalar default value is a
1932  // reasonable estimate for the N2 profile, so we
1933  // just have to expand it to a vector here. Because
1934  // we cannot modify abs_n2, we have to make a local
1935  // copy in any case.
1936 
1937  Vector n2_prof(abs_p.nelem());
1938  if ( abs_n2.nelem() == abs_p.nelem() )
1939  {
1940  n2_prof = abs_n2;
1941  }
1942  else
1943  {
1944  if (1==abs_n2.nelem())
1945  {
1946  // We seem to have found the global
1947  // default value. Expand this to a vector
1948  // with the right length, by copying it to
1949  // all elements of n2_prof.
1950  n2_prof = abs_n2[0];
1951  }
1952  else
1953  {
1954  ostringstream os;
1955  os << "Variable abs_n2 must have dimension 1, or\n"
1956  << "the same dimension as abs_p.\n"
1957  << "abs_n2.nelem() = " << abs_n2.nelem() << '\n'
1958  << "abs_p.nelem() = " << abs_p.nelem();
1959  throw runtime_error(os.str());
1960  }
1961  }
1962 
1963  // ------------------------------------------------------------------
1964 
1965 
1966  // Add the continuum for this tag. The parameters in
1967  // this call should be clear. The vmr is in
1968  // abs_vmrs(i,Range(joker)). The other vmr variable, `abs_h2o'
1969  // contains the real H2O vmr, which is needed for
1970  // the oxygen continuum.
1971  xsec_continuum_tag( abs_xsec_per_species[i],
1972  name,
1973  abs_cont_parameters[n],
1974  abs_cont_models[n],
1975  f_grid,
1976  abs_p,
1977  abs_t,
1978  n2_prof,
1979  abs_h2o,
1980  abs_vmrs(i,Range(joker)),
1981  verbosity );
1982  // Calling this function with a row of Matrix abs_vmrs
1983  // is possible because it uses Views.
1984  }
1985  }
1986  }
1987  }
1988 
1989 }
1990 
1991 
1992 
1993 //======================================================================
1994 // Methods related to continua
1995 //======================================================================
1996 
1997 /* Workspace method: Doxygen documentation will be auto-generated */
1998 void abs_cont_descriptionInit(// WS Output:
1999  ArrayOfString& names,
2000  ArrayOfString& options,
2002  const Verbosity& verbosity)
2003 {
2004  CREATE_OUT2
2005 
2006  names.resize(0);
2007  options.resize(0);
2008  parameters.resize(0);
2009  out2 << " Initialized abs_cont_names \n"
2010  " abs_cont_models\n"
2011  " abs_cont_parameters.\n";
2012 }
2013 
2014 
2015 /* Workspace method: Doxygen documentation will be auto-generated */
2016 void abs_cont_descriptionAppend(// WS Output:
2017  ArrayOfString& abs_cont_names,
2018  ArrayOfString& abs_cont_models,
2019  ArrayOfVector& abs_cont_parameters,
2020  // Control Parameters:
2021  const String& tagname,
2022  const String& model,
2023  const Vector& userparameters,
2024  const Verbosity&)
2025 {
2026  // First we have to check that name matches a continuum species tag.
2027  check_continuum_model(tagname);
2028 
2029  //cout << " + tagname: " << tagname << "\n";
2030  //cout << " + model: " << model << "\n";
2031  //cout << " + parameters: " << userparameters << "\n";
2032 
2033  // Add name and parameters to the apropriate variables:
2034  abs_cont_names.push_back(tagname);
2035  abs_cont_models.push_back(model);
2036  abs_cont_parameters.push_back(userparameters);
2037 }
2038 
2039 
2040 /* Workspace method: Doxygen documentation will be auto-generated */
2041 void abs_scalar_gasFromAbsCoef(// WS Output:
2042  Matrix& abs_scalar_gas,
2043  // WS Input:
2044  const ArrayOfMatrix& abs_coef_per_species,
2045  const Verbosity&)
2046 {
2047  // abs_scalar_gas has format [f_grid, abs_species].
2048  // abs_coef_per_species has format ArrayOfMatrix (over species),
2049  // where for each species the matrix has format [f_grid, abs_p].
2050 
2051  Index n_species = abs_coef_per_species.nelem(); // # species
2052 
2053  if (0==n_species)
2054  {
2055  ostringstream os;
2056  os << "Must have at least one species.";
2057  throw runtime_error(os.str());
2058  }
2059 
2060  Index n_f = abs_coef_per_species[0].nrows(); // # frequencies
2061 
2062  // # pressures must be 1:
2063  if (1!=abs_coef_per_species[0].ncols())
2064  {
2065  ostringstream os;
2066  os << "Must have exactly one pressure.";
2067  throw runtime_error(os.str());
2068  }
2069 
2070  abs_scalar_gas.resize(n_f,n_species);
2071 
2072  // Loop species:
2073  for ( Index si=0; si<n_species; ++si )
2074  abs_scalar_gas(Range(joker),si) = abs_coef_per_species[si](Range(joker),0);
2075 
2076 }
2077 
2078 
2079 /* Workspace method: Doxygen documentation will be auto-generated */
2080 void abs_scalar_gasCalcLBL(// WS Output:
2081  Matrix& abs_scalar_gas,
2082  // WS Input:
2083  const Vector& f_grid,
2084  const ArrayOfArrayOfSpeciesTag& abs_species,
2085  const Vector& abs_n2,
2086  const ArrayOfArrayOfLineRecord& abs_lines_per_species,
2087  const ArrayOfLineshapeSpec& abs_lineshape,
2088  const ArrayOfString& abs_cont_names,
2089  const ArrayOfString& abs_cont_models,
2090  const ArrayOfVector& abs_cont_parameters,
2091  const Index& f_index,
2092  const Numeric& rte_pressure,
2093  const Numeric& rte_temperature,
2094  const Vector& rte_vmr_list,
2095  const Numeric& rte_doppler,
2096  const Verbosity& verbosity)
2097 {
2098  CREATE_OUT3
2099 
2100  // Output of AbsInputFromRteScalars:
2101  Vector abs_p;
2102  Vector abs_t;
2103  Matrix abs_vmrs;
2104  // Output of abs_h2oSet:
2105  Vector abs_h2o;
2106  // Output of abs_coefCalc:
2107  Matrix abs_coef;
2108  ArrayOfMatrix abs_coef_per_species;
2109 
2110  // If f_index>=0, we need to make a local copy of f_grid, because
2111  // f_gridSelectFIndex will destroy f_grid. In any case, we assign
2112  // f_grid_pointer so that it points to the valid f_grid (either
2113  // original or copy).
2114  // (This is also need for the Doppler treatment,
2115  // since that also modifies the local frequency grid.)
2116  Vector local_f_grid;
2117  const Vector* f_grid_pointer;
2118  if (f_index>=0)
2119  {
2120  // Make copy:
2121  local_f_grid = f_grid;
2122 
2123  // Select the right frequency:
2124  f_gridSelectFIndex(local_f_grid, f_index, verbosity);
2125 
2126  // Make pointer point to copy:
2127  f_grid_pointer = &local_f_grid;
2128  }
2129  else
2130  {
2131  // Make pointer point to original.
2132  f_grid_pointer = &f_grid;
2133  }
2134 
2135  // Doppler treatment, do this only if there is a non-zero Doppler
2136  // shift. We do this after the frequency selection, so in the case
2137  // that we have only a single frequency, we have to shift only that!
2138 
2139  // Unfortunately, we need yet another local copy of f_grid. In
2140  // constrast to the frequency selection, we here want to modify the
2141  // actual frequency values inside!
2142  Vector local_doppler_f_grid;
2143  if (0==rte_doppler)
2144  {
2145  out3 << " Doppler shift: None\n";
2146  }
2147  else
2148  {
2149  ostringstream os;
2150  os << " Doppler shift: " << rte_doppler << " Hz\n";
2151  out3 << os.str();
2152 
2153  Numeric local_doppler;
2154  NumericScale( local_doppler, rte_doppler, -1, verbosity );
2155  // I could just have multiplied by -1 directly, but I like using
2156  // the WSM here.
2157 
2158  VectorAddScalar( local_doppler_f_grid, *f_grid_pointer, local_doppler, verbosity );
2159 
2160  // Make pointer point to the doppler shifted frequency grid.
2161  f_grid_pointer = &local_doppler_f_grid;
2162  }
2163 
2164  AbsInputFromRteScalars(abs_p,
2165  abs_t,
2166  abs_vmrs,
2167  rte_pressure,
2168  rte_temperature,
2169  rte_vmr_list,
2170  verbosity);
2171 
2172  abs_h2oSet(abs_h2o, abs_species, abs_vmrs, verbosity);
2173 
2174  abs_coefCalc(abs_coef,
2175  abs_coef_per_species,
2176  abs_species,
2177  *f_grid_pointer,
2178  abs_p,
2179  abs_t,
2180  abs_n2,
2181  abs_h2o,
2182  abs_vmrs,
2183  abs_lines_per_species,
2184  abs_lineshape,
2185  abs_cont_names,
2186  abs_cont_models,
2187  abs_cont_parameters,
2188  verbosity);
2189 
2190  abs_scalar_gasFromAbsCoef(abs_scalar_gas,
2191  abs_coef_per_species,
2192  verbosity);
2193 }
2194 
2195 
2196 /* Workspace method: Doxygen documentation will be auto-generated */
2197 void f_gridSelectFIndex(// WS Output:
2198  Vector& f_grid,
2199  // WS Input:
2200  const Index& f_index,
2201  const Verbosity&)
2202 {
2203  // Prepare f_grid. f_index < 0 means retain all frequencies, but
2204  // f_index >= 0 means to retain only that frequency.
2205  if ( f_index >= 0 )
2206  {
2207  // Check that f_index is inside f_grid:
2208  if ( f_index >= f_grid.nelem() )
2209  {
2210  ostringstream os;
2211  os << "The frequency index you want is outside f_grid.\n"
2212  << "You have " << f_index
2213  << ", the largest allowed value is " << f_grid.nelem()-1 << ".";
2214  throw runtime_error( os.str() );
2215  }
2216 
2217  Numeric this_f = f_grid[f_index];
2218  f_grid.resize(1);
2219  f_grid = this_f;
2220  }
2221 }
2222 
2223 
2224 #ifdef ENABLE_NETCDF
2225 /* Workspace method: Doxygen documentation will be auto-generated */
2226 /* Included by Claudia Emde, 20100707 */
2227 void WriteMolTau(//WS Input
2228  const Vector& f_grid,
2229  const Tensor3& z_field,
2230  const Tensor5& abs_field,
2231  const Index& atmosphere_dim,
2232  //Keyword
2233  const String& filename,
2234  const Verbosity&)
2235 {
2236 
2237  int retval, ncid;
2238  int nlev_dimid, nlyr_dimid, nwvl_dimid, none_dimid;
2239  int dimids[2];
2240  int wvlmin_varid, wvlmax_varid, z_varid, wvl_varid, tau_varid;
2241 
2242  if (atmosphere_dim != 1)
2243  throw runtime_error("WriteMolTau can only be used for atmsophere_dim=1");
2244 
2245  // Open file
2246  if ((retval = nc_create(filename.c_str(), NC_CLOBBER, &ncid)))
2247  ncerror (retval, "nc_create");
2248 
2249  // Define dimensions
2250  if ((retval = nc_def_dim(ncid, "nlev", (int) z_field.npages(), &nlev_dimid)))
2251  ncerror (retval, "nc_def_dim");
2252 
2253  if ((retval = nc_def_dim(ncid, "nlyr", (int) z_field.npages() - 1, &nlyr_dimid)))
2254  ncerror (retval, "nc_def_dim");
2255 
2256  if ((retval = nc_def_dim(ncid, "nwvl", (int) f_grid.nelem(), &nwvl_dimid)))
2257  ncerror (retval, "nc_def_dim");
2258 
2259  if ((retval = nc_def_dim(ncid, "none", 1, &none_dimid)))
2260  ncerror (retval, "nc_def_dim");
2261 
2262  // Define variables
2263  if ((retval = nc_def_var(ncid, "wvlmin", NC_DOUBLE, 1, &none_dimid, &wvlmin_varid)))
2264  ncerror (retval, "nc_def_var wvlmin");
2265 
2266  if ((retval = nc_def_var(ncid, "wvlmax", NC_DOUBLE, 1, &none_dimid, &wvlmax_varid)))
2267  ncerror (retval, "nc_def_var wvlmax");
2268 
2269  if ((retval = nc_def_var(ncid, "z", NC_DOUBLE, 1, &nlev_dimid, &z_varid)))
2270  ncerror (retval, "nc_def_var z");
2271 
2272  if ((retval = nc_def_var(ncid, "wvl", NC_DOUBLE, 1, &nwvl_dimid, &wvl_varid)))
2273  ncerror (retval, "nc_def_var wvl");
2274 
2275  dimids[0]=nlyr_dimid;
2276  dimids[1]=nwvl_dimid;
2277 
2278  if ((retval = nc_def_var(ncid, "tau", NC_DOUBLE, 2, &dimids[0], &tau_varid)))
2279  ncerror (retval, "nc_def_var tau");
2280 
2281  // Units
2282  if ((retval = nc_put_att_text(ncid, wvlmin_varid, "units", 2, "nm")))
2283  ncerror (retval, "nc_put_att_text");
2284 
2285  if ((retval = nc_put_att_text(ncid, wvlmax_varid, "units", 2, "nm")))
2286  ncerror (retval, "nc_put_att_text");
2287 
2288  if ((retval = nc_put_att_text(ncid, z_varid, "units", 2, "km")))
2289  ncerror (retval, "nc_put_att_text");
2290 
2291  if ((retval = nc_put_att_text(ncid, wvl_varid, "units", 2, "nm")))
2292  ncerror (retval, "nc_put_att_text");
2293 
2294  if ((retval = nc_put_att_text(ncid, tau_varid, "units", 1, "-")))
2295  ncerror (retval, "nc_put_att_text");
2296 
2297  // End define mode. This tells netCDF we are done defining
2298  // metadata.
2299  if ((retval = nc_enddef(ncid)))
2300  ncerror (retval, "nc_enddef");
2301 
2302  // Assign data
2303  double wvlmin[1];
2304  wvlmin[0]= SPEED_OF_LIGHT/f_grid[f_grid.nelem()-1]*1e9;
2305  if ((retval = nc_put_var_double (ncid, wvlmin_varid, &wvlmin[0])))
2306  ncerror (retval, "nc_put_var");
2307 
2308  double wvlmax[1];
2309  wvlmax[0]= SPEED_OF_LIGHT/f_grid[0]*1e9;
2310  if ((retval = nc_put_var_double (ncid, wvlmax_varid, &wvlmax[0])))
2311  ncerror (retval, "nc_put_var");
2312 
2313  double z[z_field.npages()];
2314  for (int iz=0; iz<z_field.npages(); iz++)
2315  z[iz]=z_field(z_field.npages()-1-iz, 0, 0)*1e-3;
2316 
2317  if ((retval = nc_put_var_double (ncid, z_varid, &z[0])))
2318  ncerror (retval, "nc_put_var");
2319 
2320  double wvl[f_grid.nelem()];
2321  for (int iv=0; iv<f_grid.nelem(); iv++)
2322  wvl[iv]=SPEED_OF_LIGHT/f_grid[f_grid.nelem()-1-iv]*1e9;
2323 
2324  if ((retval = nc_put_var_double (ncid, wvl_varid, &wvl[0])))
2325  ncerror (retval, "nc_put_var");
2326 
2327  Matrix tau(z_field.npages()-1, f_grid.nelem(), 0.);
2328 
2329  // Calculate average tau for layers
2330  for (int is=0; is<abs_field.nshelves(); is++)
2331  for (int iz=0; iz<z_field.npages()-1; iz++)
2332  for (int iv=0; iv<f_grid.nelem(); iv++)
2333  // sum up all species
2334  tau(iz, iv) += 0.5 * (abs_field(is,f_grid.nelem()-1-iv,z_field.npages()-1-iz,0,0)+
2335  abs_field(is,f_grid.nelem()-1-iv,z_field.npages()-2-iz,0,0))
2336  *(z_field(z_field.npages()-1-iz,0,0)-z_field(z_field.npages()-2-iz,0,0));
2337 
2338 
2339  if ((retval = nc_put_var_double (ncid, tau_varid, tau.get_c_array())))
2340  ncerror (retval, "nc_put_var");
2341 
2342  // Close the file
2343  if ((retval = nc_close(ncid)))
2344  ncerror (retval, "nc_close");
2345 
2346 }
2347 
2348 #else
2349 
2350 void WriteMolTau(//WS Input
2351  const Vector& f_grid _U_,
2352  const Tensor3& z_field _U_,
2353  const Tensor5& abs_field _U_,
2354  const Index& atmosphere_dim _U_,
2355  //Keyword
2356  const String& filename _U_,
2357  const Verbosity&)
2358 {
2359  throw runtime_error("The workspace method WriteMolTau is not available"
2360  "because ARTS was compiled without NetCDF support.");
2361 }
2362 
2363 #endif /* ENABLE_NETCDF */
2364 
abs_lines_per_speciesCompact
void abs_lines_per_speciesCompact(ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfLineshapeSpec &abs_lineshape, const Vector &f_grid, const Verbosity &)
WORKSPACE METHOD: abs_lines_per_speciesCompact.
Definition: m_abs.cc:820
Matrix
The Matrix class.
Definition: matpackI.h:767
species_index_from_species_name
Index species_index_from_species_name(String name)
Return species index for given species name.
Definition: abs_species_tags.cc:452
f_gridSelectFIndex
void f_gridSelectFIndex(Vector &f_grid, const Index &f_index, const Verbosity &)
WORKSPACE METHOD: f_gridSelectFIndex.
Definition: m_abs.cc:2197
NumericScale
void NumericScale(Numeric &out, const Numeric &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericScale.
Definition: m_basic_types.cc:369
LineRecord::ReadFromArtscat3Stream
bool ReadFromArtscat3Stream(istream &is, const Verbosity &verbosity)
Read one line from a stream associated with an ARTSCAT-3 file.
Definition: absorption.cc:1825
abs_lines_per_speciesSetEmpty
void abs_lines_per_speciesSetEmpty(ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfArrayOfSpeciesTag &tgs, const Verbosity &)
WORKSPACE METHOD: abs_lines_per_speciesSetEmpty.
Definition: m_abs.cc:83
abs_linesReadFromHitran
void abs_linesReadFromHitran(ArrayOfLineRecord &abs_lines, const String &filename, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
WORKSPACE METHOD: abs_linesReadFromHitran.
Definition: m_abs.cc:100
abs_xsec_per_speciesAddLines
void abs_xsec_per_speciesAddLines(ArrayOfMatrix &abs_xsec_per_species, const ArrayOfArrayOfSpeciesTag &tgs, const Vector &f_grid, const Vector &abs_p, const Vector &abs_t, const Vector &abs_h2o, const Matrix &abs_vmrs, const ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfLineshapeSpec &abs_lineshape, const Verbosity &verbosity)
WORKSPACE METHOD: abs_xsec_per_speciesAddLines.
Definition: m_abs.cc:1484
auto_md.h
VectorAddScalar
void VectorAddScalar(Vector &out, const Vector &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: VectorAddScalar.
Definition: m_basic_types.cc:673
absorption.h
Declarations required for the calculation of absorption coefficients.
Tensor3
The Tensor3 class.
Definition: matpackIII.h:340
ArrayOfLineRecord
Array< LineRecord > ArrayOfLineRecord
Holds a list of spectral line data.
Definition: absorption.h:1191
WriteMolTau
void WriteMolTau(const Vector &f_grid, const Tensor3 &z_field, const Tensor5 &abs_field, const Index &atmosphere_dim, const String &filename, const Verbosity &)
WORKSPACE METHOD: WriteMolTau.
Definition: m_abs.cc:2350
abs_cont_descriptionInit
void abs_cont_descriptionInit(ArrayOfString &names, ArrayOfString &options, ArrayOfVector &parameters, const Verbosity &verbosity)
WORKSPACE METHOD: abs_cont_descriptionInit.
Definition: m_abs.cc:1998
LineshapeSpec::Ind_ls
const Index & Ind_ls() const
Return the index of this lineshape.
Definition: absorption.h:150
joker
const Joker joker
nc_io.h
This file contains basic functions to handle NetCDF data files.
abs_lines_per_speciesReadFromCatalogues
void abs_lines_per_speciesReadFromCatalogues(ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfArrayOfSpeciesTag &tgs, const ArrayOfString &filenames, const ArrayOfString &formats, const Vector &fmin, const Vector &fmax, const Verbosity &verbosity)
WORKSPACE METHOD: abs_lines_per_speciesReadFromCatalogues.
Definition: m_abs.cc:429
abs_coefCalc
void abs_coefCalc(Matrix &abs_coef, ArrayOfMatrix &abs_coef_per_species, const ArrayOfArrayOfSpeciesTag &tgs, const Vector &f_grid, const Vector &abs_p, const Vector &abs_t, const Vector &abs_n2, const Vector &abs_h2o, const Matrix &abs_vmrs, const ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfLineshapeSpec &abs_lineshape, const ArrayOfString &abs_cont_names, const ArrayOfString &abs_cont_models, const ArrayOfVector &abs_cont_parameters, const Verbosity &verbosity)
WORKSPACE METHOD: abs_coefCalc.
Definition: m_abs.cc:1198
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:771
open_input_file
void open_input_file(ifstream &file, const String &name)
Open a file for reading.
Definition: file.cc:160
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
xsec_continuum_tag
void xsec_continuum_tag(MatrixView xsec, const String &name, ConstVectorView parameters, const String &model, ConstVectorView f_grid, ConstVectorView abs_p, ConstVectorView abs_t, ConstVectorView abs_n2, ConstVectorView abs_h2o, ConstVectorView vmr, const Verbosity &verbosity)
Calculates model absorption for one continuum or full model tag.
Definition: continua.cc:9495
get_tag_group_name
String get_tag_group_name(const ArrayOfSpeciesTag &tg)
Return the name of a tag group as a string.
Definition: abs_species_tags.cc:314
abs_coefCalcSaveMemory
void abs_coefCalcSaveMemory(Matrix &abs_coef, const ArrayOfArrayOfSpeciesTag &tgs, const Vector &f_grid, const Vector &abs_p, const Vector &abs_t, const Vector &abs_n2, const Vector &abs_h2o, const Matrix &abs_vmrs, const ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfLineshapeSpec &abs_lineshape, const ArrayOfString &abs_cont_names, const ArrayOfString &abs_cont_models, const ArrayOfVector &abs_cont_parameters, const Verbosity &verbosity)
WORKSPACE METHOD: abs_coefCalcSaveMemory.
Definition: m_abs.cc:1259
CREATE_OUT2
#define CREATE_OUT2
Definition: messages.h:207
Tensor4
The Tensor4 class.
Definition: matpackIV.h:375
array.h
This file contains the definition of Array.
SpeciesTag::Isotope
Index Isotope() const
Isotopic species index.
Definition: abs_species_tags.h:66
LineshapeSpec::Cutoff
const Numeric & Cutoff() const
Return the cutoff frequency (in Hz).
Definition: absorption.h:162
abs_linesReadFromArts
void abs_linesReadFromArts(ArrayOfLineRecord &abs_lines, const String &filename, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
WORKSPACE METHOD: abs_linesReadFromArts.
Definition: m_abs.cc:274
continua.h
This header file contains all the declarations of the implemented continua and full absorption (lines...
ConstTensor3View::npages
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:151
xsec_species
void xsec_species(MatrixView xsec, ConstVectorView f_grid, ConstVectorView abs_p, ConstVectorView abs_t, ConstVectorView abs_h2o_orig, ConstVectorView vmr, const ArrayOfLineRecord &abs_lines, const Index ind_ls, const Index ind_lsn, const Numeric cutoff, const Verbosity &verbosity)
Calculate line absorption cross sections for one tag group.
Definition: absorption.cc:2240
abs_coefCalcFromXsec
void abs_coefCalcFromXsec(Matrix &abs_coef, ArrayOfMatrix &abs_coef_per_species, const ArrayOfMatrix &abs_xsec_per_species, const Matrix &abs_vmrs, const Vector &abs_p, const Vector &abs_t, const Verbosity &verbosity)
WORKSPACE METHOD: abs_coefCalcFromXsec.
Definition: m_abs.cc:1371
matpackI.h
LineshapeSpec::Ind_lsn
const Index & Ind_lsn() const
Return the index of the normalization factor.
Definition: absorption.h:155
abs_lines_per_speciesCreateFromLines
void abs_lines_per_speciesCreateFromLines(ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfLineRecord &abs_lines, const ArrayOfArrayOfSpeciesTag &tgs, const Verbosity &verbosity)
WORKSPACE METHOD: abs_lines_per_speciesCreateFromLines.
Definition: m_abs.cc:639
Array
This can be used to make arrays out of anything.
Definition: array.h:103
SpeciesTag
A tag group can consist of the sum of several of these.
Definition: abs_species_tags.h:45
LineRecord::ReadFromHitranStream
bool ReadFromHitranStream(istream &is, const Verbosity &verbosity)
Read one line from a stream associated with a HITRAN 1986-2001 file.
Definition: absorption.cc:255
number_density
Numeric number_density(const Numeric &p, const Numeric &t)
number_density
Definition: physics_funcs.cc:195
LineRecord::SpeciesData
const SpeciesRecord & SpeciesData() const
The matching SpeciesRecord from species_data.
Definition: absorption.cc:224
check_continuum_model
void check_continuum_model(const String &name)
An auxiliary functions that checks if a given continuum model is listed in species_data....
Definition: continua.cc:12872
SPEED_OF_LIGHT
const Numeric SPEED_OF_LIGHT
CREATE_OUT3
#define CREATE_OUT3
Definition: messages.h:208
abs_xsec_per_speciesAddConts
void abs_xsec_per_speciesAddConts(ArrayOfMatrix &abs_xsec_per_species, const ArrayOfArrayOfSpeciesTag &tgs, const Vector &f_grid, const Vector &abs_p, const Vector &abs_t, const Vector &abs_n2, const Vector &abs_h2o, const Matrix &abs_vmrs, const ArrayOfString &abs_cont_names, const ArrayOfVector &abs_cont_parameters, const ArrayOfString &abs_cont_models, const Verbosity &verbosity)
WORKSPACE METHOD: abs_xsec_per_speciesAddConts.
Definition: m_abs.cc:1715
abs_linesReadFromArtsObsolete
void abs_linesReadFromArtsObsolete(ArrayOfLineRecord &abs_lines, const String &filename, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
Obsolete old ARTS catalogue reading function.
Definition: m_abs.cc:347
species_data
Array< SpeciesRecord > species_data
Definition: species_data.cc:40
messages.h
Declarations having to do with the four output streams.
linesElowToJoule
void linesElowToJoule(ArrayOfLineRecord &abs_lines)
Definition: m_abs.cc:420
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
_U_
#define _U_
Definition: config.h:158
my_basic_string
The implementation for String, the ARTS string class.
Definition: mystring.h:62
SpeciesTag::Uf
Numeric Uf() const
The upper line center frequency in Hz: If this is <0 it means no upper limit.
Definition: abs_species_tags.h:74
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:175
LineRecord::ReadFromJplStream
bool ReadFromJplStream(istream &is, const Verbosity &verbosity)
Read one line from a stream associated with a JPL file.
Definition: absorption.cc:1579
find_first_species_tg
Index find_first_species_tg(const ArrayOfArrayOfSpeciesTag &tgs, const Index &spec)
Find first occurrence of species in tag groups.
Definition: abs_species_tags.cc:393
physics_funcs.h
LineRecord::Isotope
Index Isotope() const
The index of the isotopic species that this line belongs to.
Definition: absorption.h:590
ArrayOfArrayOfLineRecord
Array< Array< LineRecord > > ArrayOfArrayOfLineRecord
Holds a lists of spectral line data for each tag group.
Definition: absorption.h:1196
SpeciesRecord::Isotope
const Array< IsotopeRecord > & Isotope() const
Definition: absorption.h:364
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Verbosity
Definition: messages.h:50
abs_lines_per_speciesAddMirrorLines
void abs_lines_per_speciesAddMirrorLines(ArrayOfArrayOfLineRecord &abs_lines_per_species, const Verbosity &)
WORKSPACE METHOD: abs_lines_per_speciesAddMirrorLines.
Definition: m_abs.cc:783
abs_lineshape_per_tgDefine
void abs_lineshape_per_tgDefine(ArrayOfLineshapeSpec &abs_lineshape, const ArrayOfArrayOfSpeciesTag &tgs, const ArrayOfString &shape, const ArrayOfString &normalizationfactor, const Vector &cutoff, const Verbosity &verbosity)
WORKSPACE METHOD: abs_lineshape_per_tgDefine.
Definition: m_abs.cc:1045
make_array.h
Implements the class MakeArray, which is a derived class of Array, allowing explicit initialization.
math_funcs.h
LineRecord::VersionString
String VersionString() const
Return the version String.
Definition: absorption.h:573
LineRecord
Spectral line catalog data.
Definition: absorption.h:481
xml_read_arts_catalogue_from_file
void xml_read_arts_catalogue_from_file(const String &filename, ArrayOfLineRecord &type, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
Definition: xml_io.cc:928
make_vector.h
The class MakeVector is a special kind of Vector that can be initialized explicitly from one or more ...
abs_linesReadFromSplitArtscat
void abs_linesReadFromSplitArtscat(ArrayOfLineRecord &abs_lines, const ArrayOfArrayOfSpeciesTag &abs_species, const String &basename, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
WORKSPACE METHOD: abs_linesReadFromSplitArtscat.
Definition: m_abs.cc:291
LineRecord::setF
void setF(Numeric new_mf)
Set the line center frequency in Hz.
Definition: absorption.h:602
Matrix::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1549
LineRecord::Species
Index Species() const
The index of the molecular species that this line belongs to.
Definition: absorption.h:585
AbsInputFromAtmFields
void AbsInputFromAtmFields(Vector &abs_p, Vector &abs_t, Matrix &abs_vmrs, const Index &atmosphere_dim, const Vector &p_grid, const Tensor3 &t_field, const Tensor4 &vmr_field, const Verbosity &)
WORKSPACE METHOD: AbsInputFromAtmFields.
Definition: m_abs.cc:1170
LineshapeSpec
Lineshape related specification like which lineshape to use, the normalizationfactor,...
Definition: absorption.h:131
abs_linesReadFromHitran2004
void abs_linesReadFromHitran2004(ArrayOfLineRecord &abs_lines, const String &filename, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
WORKSPACE METHOD: abs_linesReadFromHitran2004.
Definition: m_abs.cc:144
AbsInputFromRteScalars
void AbsInputFromRteScalars(Vector &abs_p, Vector &abs_t, Matrix &abs_vmrs, const Numeric &rte_pressure, const Numeric &rte_temperature, const Vector &rte_vmr_list, const Verbosity &)
WORKSPACE METHOD: AbsInputFromRteScalars.
Definition: m_abs.cc:58
Tensor5
The Tensor5 class.
Definition: matpackV.h:443
abs_cont_descriptionAppend
void abs_cont_descriptionAppend(ArrayOfString &abs_cont_names, ArrayOfString &abs_cont_models, ArrayOfVector &abs_cont_parameters, const String &tagname, const String &model, const Vector &userparameters, const Verbosity &)
WORKSPACE METHOD: abs_cont_descriptionAppend.
Definition: m_abs.cc:2016
abs_n2Set
void abs_n2Set(Vector &abs_n2, const ArrayOfArrayOfSpeciesTag &abs_species, const Matrix &abs_vmrs, const Verbosity &)
WORKSPACE METHOD: abs_n2Set.
Definition: m_abs.cc:1152
SpeciesTag::Lf
Numeric Lf() const
The lower line center frequency in Hz.
Definition: abs_species_tags.h:70
Range
The range class.
Definition: matpackI.h:148
abs_speciesDefineAllInScenario
void abs_speciesDefineAllInScenario(ArrayOfArrayOfSpeciesTag &tgs, const String &basename, const Verbosity &verbosity)
WORKSPACE METHOD: abs_speciesDefineAllInScenario.
Definition: m_abs.cc:914
wavenumber_to_joule
Numeric wavenumber_to_joule(Numeric e)
A little helper function to convert energy from units of wavenumber (cm^-1) to Joule (J).
Definition: absorption.cc:2845
abs_lineshapeDefine
void abs_lineshapeDefine(ArrayOfLineshapeSpec &abs_lineshape, const String &shape, const String &normalizationfactor, const Numeric &cutoff, const Verbosity &verbosity)
WORKSPACE METHOD: abs_lineshapeDefine.
Definition: m_abs.cc:976
SpeciesRecord::Name
const String & Name() const
Definition: absorption.h:362
ConstTensor5View::nshelves
Index nshelves() const
Returns the number of shelves.
Definition: matpackV.cc:32
parameters
Parameters parameters
Holds the command line parameters.
Definition: parameters.cc:40
abs_h2oSet
void abs_h2oSet(Vector &abs_h2o, const ArrayOfArrayOfSpeciesTag &abs_species, const Matrix &abs_vmrs, const Verbosity &)
WORKSPACE METHOD: abs_h2oSet.
Definition: m_abs.cc:1134
min
#define min(a, b)
Definition: continua.cc:13096
LineRecord::Version
Index Version() const
Return the version number.
Definition: absorption.h:581
lineshape_data
Array< LineshapeRecord > lineshape_data
Definition: lineshapes.cc:2090
abs_linesReadFromMytran2
void abs_linesReadFromMytran2(ArrayOfLineRecord &abs_lines, const String &filename, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
WORKSPACE METHOD: abs_linesReadFromMytran2.
Definition: m_abs.cc:188
file.h
This file contains basic functions to handle ASCII files.
MakeArray
Explicit construction of Arrays.
Definition: make_array.h:52
chk_size
void chk_size(const String &x_name, ConstVectorView x, const Index &c)
Runtime check for size of Vector.
Definition: check_input.cc:911
lineshape_norm_data
Array< LineshapeNormRecord > lineshape_norm_data
Definition: lineshapes.cc:2187
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
check_input.h
Vector
The Vector class.
Definition: matpackI.h:555
LineRecord::F
Numeric F() const
The line center frequency in Hz.
Definition: absorption.h:599
LineRecord::ReadFromHitran2004Stream
bool ReadFromHitran2004Stream(istream &is, const Verbosity &verbosity)
Read one line from a stream associated with a HITRAN 2004 file.
Definition: absorption.cc:708
SpeciesTag::Species
Index Species() const
Molecular species index.
Definition: abs_species_tags.h:61
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
abs_linesReadFromJpl
void abs_linesReadFromJpl(ArrayOfLineRecord &abs_lines, const String &filename, const Numeric &fmin, const Numeric &fmax, const Verbosity &verbosity)
WORKSPACE METHOD: abs_linesReadFromJpl.
Definition: m_abs.cc:229
abs_xsec_per_speciesInit
void abs_xsec_per_speciesInit(ArrayOfMatrix &abs_xsec_per_species, const ArrayOfArrayOfSpeciesTag &tgs, const Vector &f_grid, const Vector &abs_p, const Verbosity &verbosity)
WORKSPACE METHOD: abs_xsec_per_speciesInit.
Definition: m_abs.cc:1451
LineRecord::ReadFromMytran2Stream
bool ReadFromMytran2Stream(istream &is, const Verbosity &verbosity)
Read one line from a stream associated with a MYTRAN2 file.
Definition: absorption.cc:1177
abs_scalar_gasCalcLBL
void abs_scalar_gasCalcLBL(Matrix &abs_scalar_gas, const Vector &f_grid, const ArrayOfArrayOfSpeciesTag &abs_species, const Vector &abs_n2, const ArrayOfArrayOfLineRecord &abs_lines_per_species, const ArrayOfLineshapeSpec &abs_lineshape, const ArrayOfString &abs_cont_names, const ArrayOfString &abs_cont_models, const ArrayOfVector &abs_cont_parameters, const Index &f_index, const Numeric &rte_pressure, const Numeric &rte_temperature, const Vector &rte_vmr_list, const Numeric &rte_doppler, const Verbosity &verbosity)
WORKSPACE METHOD: abs_scalar_gasCalcLBL.
Definition: m_abs.cc:2080
arts.h
The global header file for ARTS.
ll
#define ll
Definition: continua.cc:14339
xml_io.h
This file contains basic functions to handle XML data files.
abs_scalar_gasFromAbsCoef
void abs_scalar_gasFromAbsCoef(Matrix &abs_scalar_gas, const ArrayOfMatrix &abs_coef_per_species, const Verbosity &)
WORKSPACE METHOD: abs_scalar_gasFromAbsCoef.
Definition: m_abs.cc:2041