00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00033 #include <cmath>
00034 #include <algorithm>
00035 #include "arts.h"
00036 #include "matpackI.h"
00037 #include "array.h"
00038 #include "messages.h"
00039 #include "file.h"
00040 #include "absorption.h"
00041 #include "auto_md.h"
00042 #include "math_funcs.h"
00043 #include "make_array.h"
00044 #include "physics_funcs.h"
00045 #include "continua.h"
00046 #include "make_vector.h"
00047 #include "check_input.h"
00048 #include "xml_io.h"
00049
00050
00051
00052 void AbsInputFromRteScalars(
00053 Vector& abs_p,
00054 Vector& abs_t,
00055 Matrix& abs_vmrs,
00056
00057 const Numeric& rte_pressure,
00058 const Numeric& rte_temperature,
00059 const Vector& rte_vmr_list)
00060 {
00061
00062 abs_p.resize(1);
00063 abs_p = rte_pressure;
00064
00065
00066 abs_t.resize(1);
00067 abs_t = rte_temperature;
00068
00069
00070 abs_vmrs.resize(rte_vmr_list.nelem(),1);
00071 abs_vmrs = rte_vmr_list;
00072 }
00073
00074
00075
00076 void abs_lines_per_speciesSetEmpty(
00077 ArrayOfArrayOfLineRecord& abs_lines_per_species,
00078
00079 const ArrayOfArrayOfSpeciesTag& tgs)
00080 {
00081
00082 abs_lines_per_species.resize( tgs.nelem() );
00083
00084 for (Index i=0; i<tgs.nelem(); ++i)
00085 {
00086 abs_lines_per_species[i].resize(0);
00087 }
00088 }
00089
00090
00091
00092 void abs_linesReadFromHitran(
00093 ArrayOfLineRecord& abs_lines,
00094
00095 const String& filename,
00096 const Numeric& fmin,
00097 const Numeric& fmax)
00098 {
00099 ifstream is;
00100
00101
00102 abs_lines.resize(0);
00103
00104 out2 << " Reading file: " << filename << "\n";
00105 open_input_file(is, filename);
00106
00107 bool go_on = true;
00108 while ( go_on )
00109 {
00110 LineRecord lr;
00111 if ( lr.ReadFromHitranStream(is) )
00112 {
00113
00114
00115 go_on = false;
00116 }
00117 else
00118 {
00119 if ( fmin <= lr.F() )
00120 {
00121 if ( lr.F() <= fmax )
00122 abs_lines.push_back(lr);
00123 else
00124 go_on = false;
00125 }
00126 }
00127 }
00128 out2 << " Read " << abs_lines.nelem() << " lines.\n";
00129 }
00130
00131
00132
00133 void abs_linesReadFromHitran2004(
00134 ArrayOfLineRecord& abs_lines,
00135
00136 const String& filename,
00137 const Numeric& fmin,
00138 const Numeric& fmax)
00139 {
00140 ifstream is;
00141
00142
00143 abs_lines.resize(0);
00144
00145 out2 << " Reading file: " << filename << "\n";
00146 open_input_file(is, filename);
00147
00148 bool go_on = true;
00149 while ( go_on )
00150 {
00151 LineRecord lr;
00152 if ( lr.ReadFromHitran2004Stream(is) )
00153 {
00154
00155
00156 go_on = false;
00157 }
00158 else
00159 {
00160 if ( fmin <= lr.F() )
00161 {
00162 if ( lr.F() <= fmax )
00163 abs_lines.push_back(lr);
00164 else
00165 go_on = false;
00166 }
00167 }
00168 }
00169 out2 << " Read " << abs_lines.nelem() << " lines.\n";
00170 }
00171
00172
00173
00174 void abs_linesReadFromMytran2(
00175 ArrayOfLineRecord& abs_lines,
00176
00177 const String& filename,
00178 const Numeric& fmin,
00179 const Numeric& fmax)
00180 {
00181 ifstream is;
00182
00183
00184 abs_lines.resize(0);
00185
00186 out2 << " Reading file: " << filename << "\n";
00187 open_input_file(is, filename);
00188
00189 bool go_on = true;
00190 while ( go_on )
00191 {
00192 LineRecord lr;
00193 if ( lr.ReadFromMytran2Stream(is) )
00194 {
00195
00196
00197 go_on = false;
00198 }
00199 else
00200 {
00201
00202 if ( fmin <= lr.F() )
00203 if ( lr.F() <= fmax )
00204 abs_lines.push_back(lr);
00205 }
00206 }
00207 out2 << " Read " << abs_lines.nelem() << " lines.\n";
00208 }
00209
00210
00211
00212 void abs_linesReadFromJpl(
00213 ArrayOfLineRecord& abs_lines,
00214
00215 const String& filename,
00216 const Numeric& fmin,
00217 const Numeric& fmax)
00218 {
00219 ifstream is;
00220
00221
00222 abs_lines.resize(0);
00223
00224 out2 << " Reading file: " << filename << "\n";
00225 open_input_file(is, filename);
00226
00227 bool go_on = true;
00228 while ( go_on )
00229 {
00230 LineRecord lr;
00231 if ( lr.ReadFromJplStream(is) )
00232 {
00233
00234
00235 go_on = false;
00236 }
00237 else
00238 {
00239
00240 if ( fmin <= lr.F() )
00241 {
00242 if ( lr.F() <= fmax )
00243 abs_lines.push_back(lr);
00244 else
00245 go_on = false;
00246 }
00247 }
00248 }
00249 out2 << " Read " << abs_lines.nelem() << " lines.\n";
00250 }
00251
00252
00253
00254 void abs_linesReadFromArts(
00255 ArrayOfLineRecord& abs_lines,
00256
00257 const String& filename,
00258 const Numeric& fmin,
00259 const Numeric& fmax)
00260 {
00261 xml_read_arts_catalogue_from_file (filename, abs_lines, fmin, fmax);
00262
00263 out2 << " Read " << abs_lines.nelem() << " lines.\n";
00264 }
00265
00266
00267
00268 void abs_linesReadFromArtsObsolete(
00269 ArrayOfLineRecord& abs_lines,
00270
00271 const String& filename,
00272 const Numeric& fmin,
00273 const Numeric& fmax)
00274 {
00275
00276 ifstream is;
00277
00278
00279
00280 LineRecord lr;
00281
00282
00283 abs_lines.resize(0);
00284
00285 out2 << " Reading file: " << filename << "\n";
00286 open_input_file(is, filename);
00287
00288
00289 {
00290 String v;
00291 is >> v;
00292 if ( v!=lr.Version() )
00293 {
00294 ostringstream os;
00295
00296
00297 if ( 9 <= v.nelem() )
00298 {
00299 if ( "ARTSCAT" == v.substr(0,7) )
00300 {
00301 os << "The ARTS line file you are trying contains a version tag "
00302 << "different from the current version.\n"
00303 << "Tag in file: " << v << "\n"
00304 << "Current version: " << lr.Version();
00305 throw runtime_error(os.str());
00306 }
00307 }
00308
00309 os << "The ARTS line file you are trying to read does not contain a valid version tag.\n"
00310 << "Probably it was created with an older version of ARTS that used different units.";
00311 throw runtime_error(os.str());
00312 }
00313 }
00314
00315 bool go_on = true;
00316 while ( go_on )
00317 {
00318 if ( lr.ReadFromArtsStream(is) )
00319 {
00320
00321
00322 go_on = false;
00323 }
00324 else
00325 {
00326
00327 if ( fmin <= lr.F() && lr.F() <= fmax )
00328 {
00329 abs_lines.push_back(lr);
00330 }
00331 }
00332 }
00333 out2 << " Read " << abs_lines.nelem() << " lines.\n";
00334 }
00335
00336
00337
00338 void linesElowToJoule(
00339 ArrayOfLineRecord& abs_lines )
00340 {
00341 for ( Index i=0; i<abs_lines.nelem(); ++i )
00342 abs_lines[i].melow = wavenumber_to_joule(abs_lines[i].melow);
00343 }
00344
00345
00346
00347 void abs_lines_per_speciesReadFromCatalogues(
00348 ArrayOfArrayOfLineRecord& abs_lines_per_species,
00349
00350 const ArrayOfArrayOfSpeciesTag& tgs,
00351
00352 const ArrayOfString& filenames,
00353 const ArrayOfString& formats,
00354 const Vector& fmin,
00355 const Vector& fmax)
00356 {
00357 const Index n_tg = tgs.nelem();
00358 const Index n_cat = filenames.nelem();
00359
00360
00361
00362
00363 if ( n_cat != formats.nelem() ||
00364 n_cat != fmin.nelem() ||
00365 n_cat != fmax.nelem() )
00366 {
00367 ostringstream os;
00368 os << "abs_lines_per_speciesReadFromCatalogues: All keyword\n"
00369 << "parameters must get the same number of arguments.\n"
00370 << "You specified:\n"
00371 << "filenames: " << n_cat << "\n"
00372 << "formats: " << formats.nelem() << "\n"
00373 << "fmin: " << fmin.nelem() << "\n"
00374 << "fmax: " << fmax.nelem();
00375 throw runtime_error(os.str());
00376 }
00377
00378
00379
00380
00381 if ( n_cat > n_tg )
00382 {
00383 ostringstream os;
00384 os << "abs_lines_per_speciesReadFromCatalogues: You specified more\n"
00385 << "catalugues than you have tag groups.\n"
00386 << "You specified:\n"
00387 << "Catalogues: " << n_cat << "\n"
00388 << "tgs: " << n_tg;
00389 throw runtime_error(os.str());
00390 }
00391
00392
00393
00394 if ( n_cat < 1 ||
00395 n_tg < 1 )
00396 {
00397 ostringstream os;
00398 os << "abs_lines_per_speciesReadFromCatalogues: You must have at\n"
00399 << "least one catalogue and at least one tag group.\n"
00400 << "You specified:\n"
00401 << "Catalogues: " << n_cat << "\n"
00402 << "tgs: " << n_tg;
00403 throw runtime_error(os.str());
00404 }
00405
00406
00407
00408
00409
00410
00411 MakeArray<String> real_filenames ( filenames[0] );
00412 MakeArray<String> real_formats ( formats[0] );
00413 MakeArray<Numeric> real_fmin ( fmin[0] );
00414 MakeArray<Numeric> real_fmax ( fmax[0] );
00415
00416 Array< ArrayOfIndex > real_tgs(1);
00417 real_tgs[0].resize(1);
00418 real_tgs[0][0] = 0;
00419
00420
00421
00422 Index last_cat = 0;
00423
00424 for ( Index i=1; i<n_tg; ++i )
00425 {
00426
00427 if ( n_cat > i )
00428 {
00429
00430
00431
00432
00433
00434
00435
00436 const Index that_cat = find( real_filenames.begin(),
00437 real_filenames.end(),
00438 filenames[i] ) - real_filenames.begin();
00439 if ( that_cat < real_filenames.nelem() )
00440 {
00441
00442
00443 real_tgs[that_cat].push_back(i);
00444
00445
00446 if ( formats[i] != real_formats[that_cat] ||
00447 fmin[i] != real_fmin[that_cat] ||
00448 fmax[i] != real_fmax[that_cat] )
00449 {
00450 ostringstream os;
00451 os << "abs_lines_per_speciesReadFromCatalogues: If you specify the\n"
00452 << "same catalogue repeatedly, format, fmin, and fmax must be\n"
00453 << "consistent. There is an inconsistency between\n"
00454 << "catalogue " << that_cat << " and " << i << ".";
00455 throw runtime_error(os.str());
00456 }
00457 }
00458 else
00459 {
00460
00461
00462 real_tgs.push_back( MakeArray<Index>(i) );
00463
00464 real_filenames.push_back( filenames[i] );
00465 real_formats.push_back ( formats[i] );
00466 real_fmin.push_back ( fmin[i] );
00467 real_fmax.push_back ( fmax[i] );
00468
00469 last_cat = i;
00470
00471 }
00472 }
00473 else
00474 {
00475
00476
00477 real_tgs[last_cat].push_back(i);
00478 }
00479 }
00480
00481 Index n_real_cat = real_filenames.nelem();
00482
00483
00484 out3 << " Catalogues to read and tgs for which these will be used:\n";
00485 for ( Index i=0; i<n_real_cat; ++i )
00486 {
00487 out3 << " " << real_filenames[i] << ":";
00488 for ( Index s=0; s<real_tgs[i].nelem(); ++s )
00489 out3 << " " << real_tgs[i][s];
00490 out3 << "\n";
00491 }
00492
00493
00494 abs_lines_per_species.resize( tgs.nelem() );
00495
00496
00497 for ( Index i=0; i<n_real_cat; ++i )
00498 {
00499 ArrayOfLineRecord abs_lines;
00500
00501
00502
00503 if ( "HITRAN96"==real_formats[i] )
00504 {
00505 abs_linesReadFromHitran( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00506 }
00507 else if ( "HITRAN04"==real_formats[i] )
00508 {
00509 abs_linesReadFromHitran2004( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00510 }
00511 else if ( "MYTRAN2"==real_formats[i] )
00512 {
00513 abs_linesReadFromMytran2( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00514 }
00515 else if ( "JPL"==real_formats[i] )
00516 {
00517 abs_linesReadFromJpl( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00518 }
00519 else if ( "ARTS"==real_formats[i] )
00520 {
00521 abs_linesReadFromArts( abs_lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00522 }
00523 else
00524 {
00525 ostringstream os;
00526 os << "abs_lines_per_speciesReadFromCatalogues: You specified the\n"
00527 << "format `" << real_formats[i] << "', which is unknown.\n"
00528 << "Allowd formats are: HITRAN96, HITRAN04, MYTRAN2, JPL, ARTS.";
00529 throw runtime_error(os.str());
00530 }
00531
00532
00533
00534 ArrayOfArrayOfSpeciesTag these_tgs(real_tgs[i].nelem());
00535 for ( Index s=0; s<real_tgs[i].nelem(); ++s )
00536 {
00537 these_tgs[s] = tgs[real_tgs[i][s]];
00538 }
00539
00540
00541 ArrayOfArrayOfLineRecord these_abs_lines_per_species;
00542 abs_lines_per_speciesCreateFromLines( these_abs_lines_per_species, abs_lines, these_tgs );
00543
00544
00545 for ( Index s=0; s<real_tgs[i].nelem(); ++s )
00546 {
00547 abs_lines_per_species[real_tgs[i][s]] = these_abs_lines_per_species[s];
00548 }
00549 }
00550 }
00551
00552
00553
00554 void abs_lines_per_speciesCreateFromLines(
00555 ArrayOfArrayOfLineRecord& abs_lines_per_species,
00556
00557 const ArrayOfLineRecord& abs_lines,
00558 const ArrayOfArrayOfSpeciesTag& tgs)
00559 {
00560
00561 extern const Array<SpeciesRecord> species_data;
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 std::vector<bool> species_used (species_data.nelem(),false);
00573
00574
00575 abs_lines_per_species = ArrayOfArrayOfLineRecord(tgs.nelem());
00576
00577
00578
00579
00580 for ( Index i=0; i<abs_lines_per_species.nelem(); ++i )
00581 abs_lines_per_species[i] = ArrayOfLineRecord();
00582
00583
00584 for ( Index i=0; i<abs_lines.nelem(); ++i )
00585 {
00586
00587 const LineRecord& this_line = abs_lines[i];
00588
00589
00590
00591
00592
00593
00594 bool found = false;
00595
00596
00597
00598 Index j;
00599
00600
00601 for ( j=0; j<tgs.nelem() && !found ; ++j )
00602 {
00603
00604 for ( Index k=0; k<tgs[j].nelem() && !found; ++k )
00605 {
00606
00607
00608 const SpeciesTag& this_tag = tgs[j][k];
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 if ( this_tag.Species() != this_line.Species() ) break;
00619
00620
00621
00622
00623
00624
00625 if ( this_tag.Isotope() != this_line.SpeciesData().Isotope().nelem() )
00626 if ( this_tag.Isotope() != this_line.Isotope() )
00627 continue;
00628
00629
00630
00631
00632
00633
00634 if ( this_tag.Lf() >= 0 )
00635 if ( this_tag.Lf() > this_line.F() )
00636 continue;
00637
00638
00639 if ( this_tag.Uf() >= 0 )
00640 if ( this_tag.Uf() < this_line.F() )
00641 continue;
00642
00643
00644
00645 found = true;
00646 }
00647 }
00648
00649
00650
00651 if (found)
00652 {
00653
00654
00655 abs_lines_per_species[j-1].push_back(this_line);
00656
00657
00658 if ( !species_used[this_line.Species()] )
00659 species_used[this_line.Species()] = true;
00660 }
00661 else
00662 {
00663
00664
00665 if ( species_used[this_line.Species()] )
00666 {
00667 out2 << " Your tags include other lines of species "
00668 << this_line.SpeciesData().Name()
00669 << ",\n"
00670 << "why do you not include line "
00671 << i
00672 << " (at "
00673 << this_line.F()
00674 << " Hz)?\n";
00675 }
00676 }
00677 }
00678
00679
00680 for (Index i=0; i<tgs.nelem(); ++i)
00681 {
00682 out3 << " " << i << ":";
00683
00684 for (Index s=0; s<tgs[i].nelem(); ++s)
00685 out3 << " " << tgs[i][s].Name();
00686
00687 out3 << ": " << abs_lines_per_species[i].nelem() << " lines\n";
00688 }
00689
00690 }
00691
00692
00693
00694 void abs_lines_per_speciesAddMirrorLines(
00695 ArrayOfArrayOfLineRecord& abs_lines_per_species)
00696 {
00697
00698
00699
00700
00701 for ( Index i=0; i<abs_lines_per_species.nelem(); ++i )
00702 {
00703
00704 ArrayOfLineRecord& ll = abs_lines_per_species[i];
00705
00706
00707 ll.reserve(2*ll.nelem());
00708
00709
00710 {
00711
00712
00713
00714
00715 Index n=ll.nelem();
00716 for ( Index j=0; j<n; ++j )
00717 {
00718 LineRecord dummy = ll[j];
00719 dummy.setF( -dummy.F() );
00720
00721 ll.push_back(dummy);
00722 }
00723 }
00724 }
00725
00726 }
00727
00728
00729
00730 void abs_lines_per_speciesCompact(
00731 ArrayOfArrayOfLineRecord& abs_lines_per_species,
00732
00733 const ArrayOfLineshapeSpec& abs_lineshape,
00734 const Vector& f_grid)
00735 {
00736
00737
00738 if ( abs_lines_per_species.nelem() != abs_lineshape.nelem() )
00739 {
00740 ostringstream os;
00741 os << "Dimension of abs_lines_per_species does\n"
00742 << "not match that of abs_lineshape.";
00743 throw runtime_error(os.str());
00744 }
00745
00746
00747 for ( Index s=0; s<f_grid.nelem()-1; ++s )
00748 {
00749 if ( f_grid[s+1] <= f_grid[s] )
00750 {
00751 ostringstream os;
00752 os << "The frequency grid f_grid is not properly sorted.\n"
00753 << "f_grid[" << s << "] = " << f_grid[s] << "\n"
00754 << "f_grid[" << s+1 << "] = " << f_grid[s+1];
00755 throw runtime_error(os.str());
00756 }
00757 }
00758
00759
00760 for ( Index i=0; i<abs_lines_per_species.nelem(); ++i )
00761 {
00762
00763 Numeric cutoff = abs_lineshape[i].Cutoff();
00764
00765
00766 if ( cutoff != -1)
00767 {
00768
00769 ArrayOfLineRecord& ll = abs_lines_per_species[i];
00770
00771
00772 Numeric upp = f_grid[f_grid.nelem()-1] + cutoff;
00773 Numeric low = f_grid[0] - cutoff;
00774
00775
00776 Array<ArrayOfLineRecord::iterator> keep;
00777 for ( ArrayOfLineRecord::iterator j=ll.begin(); j<ll.end(); ++j )
00778 {
00779
00780 const Numeric F0 = j->F();
00781
00782 if ( ( F0 >= low) && ( F0 <= upp) )
00783 {
00784
00785 keep.push_back (j);
00786
00787
00788
00789
00790 }
00791 }
00792
00793
00794 if (keep.nelem () != ll.nelem ())
00795 {
00796 ArrayOfLineRecord nll;
00797
00798 for (Array<ArrayOfLineRecord::iterator>::iterator j
00799 = keep.begin(); j != keep.end(); j++)
00800 {
00801 nll.push_back (**j);
00802 }
00803
00804 ll.resize (nll.nelem ());
00805 ll = nll;
00806 }
00807 }
00808 }
00809 }
00810
00811
00812
00813 void abs_speciesDefineAllInScenario(
00814 ArrayOfArrayOfSpeciesTag& tgs,
00815
00816 const String& basename)
00817 {
00818
00819 extern const Array<SpeciesRecord> species_data;
00820
00821
00822 ArrayOfString included(0), excluded(0);
00823
00824 tgs.resize(0);
00825
00826 for ( Index i=0; i<species_data.nelem(); ++i )
00827 {
00828 const String specname = species_data[i].Name();
00829 const String filename = basename + "." + specname + ".xml";
00830
00831
00832 try
00833 {
00834 ifstream file;
00835 open_input_file(file, filename);
00836
00837
00838
00839
00840 included.push_back(specname);
00841
00842
00843 SpeciesTag this_tag(specname);
00844
00845
00846
00847 ArrayOfSpeciesTag this_group(1);
00848 this_group[0] = this_tag;
00849
00850
00851 tgs.push_back(this_group);
00852 }
00853 catch (runtime_error)
00854 {
00855
00856 excluded.push_back(specname);
00857 }
00858 }
00859
00860
00861 out2 << " Included Species (" << included.nelem() << "):\n";
00862 for ( Index i=0; i<included.nelem(); ++i )
00863 out2 << " " << included[i] << "\n";
00864
00865 out2 << " Excluded Species (" << excluded.nelem() << "):\n";
00866 for ( Index i=0; i<excluded.nelem(); ++i )
00867 out2 << " " << excluded[i] << "\n";
00868 }
00869
00870
00871
00872 void abs_lineshapeDefine(
00873 ArrayOfLineshapeSpec& abs_lineshape,
00874
00875 const String& shape,
00876 const String& normalizationfactor,
00877 const Numeric& cutoff)
00878 {
00879
00880 extern const Array<LineshapeRecord> lineshape_data;
00881 extern const Array<LineshapeNormRecord> lineshape_norm_data;
00882
00883
00884
00885
00886
00887
00888 Index tag_sz = 1;
00889 abs_lineshape.resize(tag_sz);
00890
00891
00892 Index found0=-1;
00893 for ( Index i=0; i<lineshape_data.nelem() && (found0 == -1) ; ++i )
00894 {
00895 const String& str = lineshape_data[i].Name();
00896 if (str == shape)
00897 {
00898 out2 << " Selected lineshape: " << str << "\n";
00899 found0=i;
00900 }
00901 }
00902
00903
00904 Index found1=-1;
00905 for ( Index i=0; i<lineshape_norm_data.nelem() && (found1 == -1); ++i )
00906 {
00907 const String& str = lineshape_norm_data[i].Name();
00908 if (str == normalizationfactor)
00909 {
00910 out2 << " Selected normalization factor : " << normalizationfactor << "\n";
00911
00912 if ( (cutoff != -1) && (cutoff < 0.0) )
00913 throw runtime_error(" Cutoff must be -1 or positive.");
00914 out2 << " Selected cutoff frequency [Hz] : " << cutoff << "\n";
00915 found1=i;
00916 }
00917 }
00918
00919
00920
00921 if (found0 == -1)
00922 throw runtime_error("Selected lineshape not available.");
00923 if (found1 == -1)
00924 throw runtime_error("Selected normalization to lineshape not available.");
00925
00926
00927
00928 for (Index i=0; i<tag_sz; i++)
00929 {
00930 abs_lineshape[i].SetInd_ls( found0 );
00931 abs_lineshape[i].SetInd_lsn( found1 );
00932 abs_lineshape[i].SetCutoff( cutoff );
00933 }
00934 }
00935
00936
00937
00938 void abs_lineshape_per_tgDefine(
00939 ArrayOfLineshapeSpec& abs_lineshape,
00940
00941 const ArrayOfArrayOfSpeciesTag& tgs,
00942 const ArrayOfString& shape,
00943 const ArrayOfString& normalizationfactor,
00944 const Vector& cutoff )
00945 {
00946
00947 extern const Array<LineshapeRecord> lineshape_data;
00948 extern const Array<LineshapeNormRecord> lineshape_norm_data;
00949
00950
00951 Index tg_sz = tgs.nelem();
00952 if ( (tg_sz != shape.nelem()) ||
00953 (tg_sz != normalizationfactor.nelem()) ||
00954 (tg_sz != cutoff.nelem()) )
00955 {
00956 ostringstream os;
00957 os << "abs_lineshape_per_tgDefine: number of elements does\n"
00958 << "not match the number of tag groups defined.";
00959 throw runtime_error(os.str());
00960 }
00961
00962
00963
00964 abs_lineshape.resize(tg_sz);
00965
00966
00967 for (Index k=0; k<tg_sz; ++k)
00968 {
00969 Index found0=-1;
00970 for ( Index i=0; i<lineshape_data.nelem() && (found0 == -1); ++i )
00971 {
00972 const String& str = lineshape_data[i].Name();
00973 if (str == shape[k])
00974 {
00975 out2 << " Tag Group: [";
00976 for (Index s=0; s<tgs[k].nelem()-1; ++s)
00977 out2 << tgs[k][s].Name() << ", ";
00978 out2 << tgs[k][tgs[k].nelem()-1].Name() << "]\n";
00979 out2 << " Selected lineshape: " << str << "\n";
00980 found0=i;
00981 }
00982 }
00983
00984
00985 Index found1=-1;
00986 for ( Index i=0; i<lineshape_norm_data.nelem() && (found1 == -1); ++i )
00987 {
00988 const String& str = lineshape_norm_data[i].Name();
00989 if (str == normalizationfactor[k])
00990 {
00991 out2 << " Selected normalization factor: " << normalizationfactor[k] << "\n";
00992 if ( (cutoff[k] != -1) && (cutoff[k] < 0.0) )
00993 throw runtime_error(" Cutoff must be -1 or positive.");
00994 out2 << " Selected cutoff frequency : " << cutoff[k] << "\n";
00995 found1=i;
00996 }
00997 }
00998
00999
01000
01001 if (found0 == -1)
01002 {
01003 ostringstream os;
01004 os << "Selected lineshape not available: "<< shape[k] <<"\n";
01005 throw runtime_error(os.str());
01006 }
01007 if (found1 == -1)
01008 {
01009 ostringstream os;
01010 os << "Selected normalization to lineshape not available: "<<
01011 normalizationfactor[k] <<"\n";
01012 throw runtime_error(os.str());
01013 }
01014
01015
01016 abs_lineshape[k].SetInd_ls( found0 );
01017 abs_lineshape[k].SetInd_lsn( found1 );
01018 abs_lineshape[k].SetCutoff( cutoff[k] );
01019 }
01020 }
01021
01022 #if 0
01023
01024 void raw_vmrsReadFromScenario(
01025 ArrayOfMatrix& raw_vmrs,
01026
01027 const ArrayOfArrayOfSpeciesTag& tgs,
01028
01029 const String& basename)
01030 {
01031
01032 extern const Array<SpeciesRecord> species_data;
01033
01034
01035 for ( Index i=0; i<tgs.nelem(); ++i )
01036 {
01037
01038 String name =
01039 basename + "." +
01040 species_data[tgs[i][0].Species()].Name() + ".aa";
01041
01042
01043 raw_vmrs.push_back(Matrix());
01044
01045
01046
01047 MatrixReadAscii(raw_vmrs[i],"",name);
01048
01049
01050 out3 << " " << species_data[tgs[i][0].Species()].Name()
01051 << " profile read from file: " << name << "\n";
01052 }
01053 }
01054
01068 void raw_vmrsReadFromFiles(
01069 ArrayOfMatrix& raw_vmrs,
01070
01071 const ArrayOfArrayOfSpeciesTag& tgs,
01072
01073 const ArrayOfString& seltags,
01074 const ArrayOfString& filenames,
01075 const String& basename)
01076 {
01077
01078 extern const Array<SpeciesRecord> species_data;
01079 ArrayOfIndex i_seltags;
01080
01081
01082
01083
01084 get_tagindex_for_Strings( i_seltags, tgs, seltags );
01085
01086
01087
01088 ArrayOfString true_filenames(tgs.nelem());
01089 true_filenames = basename + '.';
01090
01091
01092
01093 for ( Index i=0; i<tgs.nelem(); ++i )
01094 {
01095 true_filenames[i] +=
01096 species_data[tgs[i][0].Species()].Name() + ".aa";
01097
01098
01099 }
01100
01101
01102
01103 for ( Index i=0; i<seltags.nelem(); ++i )
01104 {
01105 true_filenames[i_seltags[i]] = filenames[i];
01106 }
01107
01108
01109 for ( Index i=0; i<tgs.nelem(); ++i )
01110 {
01111
01112 raw_vmrs.push_back(Matrix());
01113
01114
01115
01116 MatrixReadAscii(raw_vmrs[i],"",true_filenames[i]);
01117
01118
01119 out3 << " " << species_data[tgs[i][0].Species()].Name()
01120 << " profile read from file: " << true_filenames[i] << "\n";
01121 }
01122 }
01123
01191 void WaterVaporSaturationInClouds(
01192 Matrix& abs_vmrs,
01193 Vector& abs_p,
01194
01195 const Vector& abs_t,
01196 const ArrayOfArrayOfSpeciesTag& tgs )
01197 {
01198
01199
01200 assert ( abs_vmrs.ncols() == abs_p.nelem() );
01201
01202
01203 extern const Array<SpeciesRecord> species_data;
01204
01205 Index liquid_index = 1+tgs.nelem();
01206 Index ice_index = 1+tgs.nelem();
01207 Index h2o_index[tgs.nelem()];
01208
01209
01210 assert ( abs_t.nelem() == abs_p.nelem() );
01211 assert ( abs_vmrs.ncols() == abs_p.nelem() );
01212
01213
01214 Index u = 0;
01215 for ( Index i=0; i<tgs.nelem(); ++i )
01216 {
01217 String tag_name = species_data[tgs[i][0].Species()].Name();
01218 if (tag_name == "liquidcloud")
01219 {
01220 liquid_index = i;
01221 }
01222 if (tag_name == "icecloud")
01223 {
01224 ice_index = i;
01225 }
01226 if (tag_name == "H2O")
01227 {
01228 h2o_index[u++] = i;
01229
01230
01231 }
01232 }
01233
01234
01235
01236 if (u < 1)
01237 {
01238 out2 << " WaterVaporSaturationInClouds: no H2O profile found to adjust for clouds.\n"
01239 << " Therefore no saturation calculation is performed\n";
01240 return;
01241 }
01242
01243
01244
01245 if ( (liquid_index >= 0) && (liquid_index < tgs.nelem()) )
01246 {
01247
01248 for (Index uu=0; uu<u; ++uu)
01249 {
01250 for (Index i=0; i<abs_vmrs.ncols() ; ++i)
01251 {
01252 if (abs_vmrs(liquid_index,i) > 0.000)
01253 {
01254
01255 Numeric p_dry = abs_p[i] * ( 1.000e0 - abs_vmrs(h2o_index[uu],i) );
01256
01257 Numeric e_s = WVSatPressureLiquidWater( abs_t[i] );
01258
01259 abs_p[i] = e_s + p_dry;
01260
01261 abs_vmrs(h2o_index[uu],i) = e_s / abs_p[i];
01262
01263 if ( (abs_vmrs(h2o_index[uu],i) < 0.000e0) || (abs_vmrs(h2o_index[uu],i) > 1.000e0) )
01264 {
01265 ostringstream os;
01266 os << "WaterVaporSaturationInClouds: The water vapor VMR value "
01267 << abs_vmrs(h2o_index[uu],i) << "\n"
01268 << " looks strange after setting it to the saturation pressure over liquid water.";
01269 throw runtime_error(os.str());
01270 return;
01271 }
01272 }
01273 }
01274 }
01275 }
01276
01277
01278
01279
01280 if ( (ice_index >= 0) && (ice_index < tgs.nelem()) )
01281 {
01282 for (Index uu=0; uu<u; ++uu)
01283 {
01284 for (Index i=0; i<abs_vmrs.ncols() ; ++i)
01285 {
01286 if (abs_vmrs(ice_index,i) > 0.000)
01287 {
01288
01289 Numeric p_dry = abs_p[i] * ( 1.000e0 - abs_vmrs(h2o_index[uu],i) );
01290
01291 Numeric e_s = WVSatPressureIce( abs_t[i] );
01292
01293 abs_p[i] = e_s + p_dry;
01294
01295 abs_vmrs(h2o_index[uu],i) = e_s / abs_p[i];
01296
01297 if ( (abs_vmrs(h2o_index[uu],i) < 0.000e0) || (abs_vmrs(h2o_index[uu],i) > 1.000e0) )
01298 {
01299 ostringstream os;
01300 os << "WaterVaporSaturationInClouds: The water vapor VMR value "
01301 << abs_vmrs(h2o_index[uu],i) << "\n"
01302 << " looks strange after setting it to the saturation pressure over ice.";
01303 throw runtime_error(os.str());
01304 return;
01305 }
01306 }
01307 }
01308 }
01309 }
01310
01311 return;
01312 }
01313
01314
01315
01328 void AtmFromRaw(
01329 Vector& abs_t,
01330 Vector& z_abs,
01331 Matrix& abs_vmrs,
01332
01333 const ArrayOfArrayOfSpeciesTag& tgs,
01334 const Vector& abs_p,
01335 const Matrix& raw_ptz,
01336 const ArrayOfMatrix& raw_vmrs)
01337 {
01338
01339
01340 {
01341
01342 if ( 3 != raw_ptz.ncols() )
01343 {
01344 ostringstream os;
01345 os << "The variable raw_ptz does not have the right dimensions,\n"
01346 << "ncols() should be 3, but is actually "<< raw_ptz.ncols();
01347 throw runtime_error(os.str());
01348 }
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359 Matrix tz_intp( 2, abs_p.nelem() );
01360
01361 interpp( tz_intp,
01362 raw_ptz(Range(joker),0),
01363 transpose(raw_ptz(Range(joker),Range(1,joker))),
01364 abs_p );
01365
01366
01367
01368
01369
01370
01371
01372 abs_t.resize( tz_intp.ncols() );
01373 abs_t = tz_intp(0,Range(joker));
01374
01375
01376
01377
01378 z_abs.resize( tz_intp.ncols() );
01379 z_abs = tz_intp(1,Range(joker));
01380
01381
01382 }
01383
01384
01385 {
01386
01387 assert ( tgs.nelem() == raw_vmrs.nelem() );
01388
01389
01390 abs_vmrs.resize( raw_vmrs.nelem(), abs_p.nelem() );
01391
01392
01393 for ( Index j=0; j<raw_vmrs.nelem(); ++j )
01394 {
01395
01396
01397 const Matrix& raw = raw_vmrs[j];
01398
01399
01400
01401
01402
01403 if ( 2 != raw.ncols() )
01404 {
01405 ostringstream os;
01406 os << "The variable raw_vmrs("
01407 << j
01408 << ") does not have the right dimensions,\n"
01409 << "ncols() should be 2, but is actually "<< raw.ncols();
01410 throw runtime_error(os.str());
01411 }
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427 interpp( abs_vmrs(j,Range(joker)),
01428 raw(Range(joker),0),
01429 raw(Range(joker),1),
01430 abs_p );
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442 }
01443 }
01444 }
01445
01446
01453 void hseSet(
01454 Vector& hse,
01455 const Numeric& pref,
01456 const Numeric& zref,
01457 const Numeric& g0,
01458 const Index& niter )
01459 {
01460 hse.resize( 5 );
01461
01462 hse[0] = 1;
01463 hse[1] = pref;
01464 hse[2] = zref;
01465 hse[3] = g0;
01466 hse[4] = Numeric( niter );
01467 }
01468
01475 void hseSetFromLatitude(
01476 Vector& hse,
01477 const Numeric& pref,
01478 const Numeric& zref,
01479 const Numeric& latitude,
01480 const Index& niter )
01481 {
01482
01483 hse.resize( 5 );
01484
01485 hse[0] = 1;
01486 hse[1] = pref;
01487 hse[2] = zref;
01488 hse[3] = g_of_lat(latitude);
01489 hse[4] = Numeric( niter );
01490 }
01491
01498 void hseSetFromLatitudeIndex(
01499 Vector& hse,
01500 const Vector& abs_p,
01501 const Vector& z_abs,
01502 const Numeric& latitude,
01503 const Index& index,
01504 const Index& niter )
01505 {
01506
01507
01508 check_if_in_range( 0, abs_p.nelem()-1, index, "index" );
01509
01510 hse.resize( 5 );
01511
01512 hse[0] = 1;
01513 hse[1] = abs_p[index];
01514 hse[2] = z_abs[index];
01515 hse[3] = g_of_lat(latitude);
01516 hse[4] = Numeric( niter );
01517 }
01518
01519
01526 void hseFromBottom(
01527 Vector& hse,
01528 const Vector& abs_p,
01529 const Vector& z_abs,
01530 const Numeric& g0,
01531 const Index& niter )
01532 {
01533 hseSet( hse, abs_p[0], z_abs[0], g0, niter );
01534 }
01535
01536
01537
01544 void hseOff(
01545 Vector& hse )
01546 {
01547 hse.resize( 1 );
01548 hse[0] = 0;
01549 }
01550
01551
01552
01553
01554
01555
01562 void hseCalc(
01563 Vector& z_abs,
01564 const Vector& abs_p,
01565 const Vector& abs_t,
01566 const Vector& abs_h2o,
01567 const Numeric& r_geoid,
01568 const Vector& hse )
01569 {
01570 check_if_bool( static_cast<Index>(hse[0]),
01571 "the HSE flag (first element of hse)");
01572
01573 if ( hse[0] )
01574 {
01575 if ( hse.nelem() != 5 )
01576 throw runtime_error("The length of the *hse* vector must be 5.");
01577
01578 const Index np = abs_p.nelem();
01579 Index i;
01580 Numeric g;
01581 Numeric r;
01582 Numeric tv;
01583 Numeric dz;
01584 Vector ztmp(np);
01585
01586
01587 const Numeric pref = hse[1];
01588 const Numeric zref = hse[2];
01589 const Numeric g0 = hse[3];
01590 const Index niter = Index( hse[4] );
01591
01592 check_lengths( z_abs, "z_abs", abs_t, "abs_t" );
01593 check_lengths( z_abs, "z_abs", abs_h2o, "abs_h2o" );
01594 if ( niter < 1 )
01595 throw runtime_error("The number of iterations must be > 0.");
01596
01597 for ( Index iter=0; iter<niter; iter++ )
01598 {
01599
01600 ztmp[0] = z_abs[0];
01601
01602
01603 for ( i=0; i<np-1; i++ )
01604 {
01605
01606 g = ( g_of_z(r_geoid,g0,z_abs[i]) +
01607 g_of_z(r_geoid,g0,z_abs[i+1]) ) / 2.0;
01608
01609
01610
01611 r = 18/28.96 * (abs_h2o[i]+abs_h2o[i+1])/2;
01612
01613
01614 tv = (1+0.61*r) * (abs_t[i]+abs_t[i+1])/2;
01615
01616
01617 dz = 287.053*tv/g * log( abs_p[i]/abs_p[i+1] );
01618 ztmp[i+1] = ztmp[i] + dz;
01619 }
01620
01621
01622 dz = interpp( abs_p, ztmp, pref ) - zref;
01623
01624
01625 z_abs = ztmp;
01626 z_abs -= dz;
01627 }
01628 }
01629 }
01630
01631
01638 void vmrsScale(
01639 Matrix& abs_vmrs,
01640 const ArrayOfArrayOfSpeciesTag& tgs,
01641 const ArrayOfString& scaltgs,
01642 const Vector& scalfac)
01643 {
01644 Index itag;
01645 ArrayOfIndex tagindex;
01646
01647 if ( scalfac.nelem() != scaltgs.nelem() )
01648 throw runtime_error("vmrScale: Number of tgs and fac are different!");
01649
01650 get_tagindex_for_Strings( tagindex, tgs, scaltgs );
01651
01652 const Index n = tagindex.nelem();
01653
01654 for ( itag=0; itag<n; itag++ )
01655 {
01656
01657 abs_vmrs(tagindex[itag],Range(joker)) *= scalfac[itag];
01658
01659
01660
01661
01662
01663 }
01664 }
01665
01666 #endif
01667
01668
01669
01670 void abs_h2oSet(Vector& abs_h2o,
01671 const ArrayOfArrayOfSpeciesTag& abs_species,
01672 const Matrix& abs_vmrs)
01673 {
01674 const Index h2o_index
01675 = find_first_species_tg( abs_species,
01676 species_index_from_species_name("H2O") );
01677
01678 if ( h2o_index < 0 )
01679 throw runtime_error("No tag group contains water!");
01680
01681 abs_h2o.resize( abs_vmrs.ncols() );
01682 abs_h2o = abs_vmrs(h2o_index,Range(joker));
01683 }
01684
01685
01686
01687 void abs_n2Set(Vector& abs_n2,
01688 const ArrayOfArrayOfSpeciesTag& abs_species,
01689 const Matrix& abs_vmrs)
01690 {
01691 const Index n2_index
01692 = find_first_species_tg( abs_species,
01693 species_index_from_species_name("N2") );
01694
01695 if ( n2_index < 0 )
01696 throw runtime_error("No tag group contains nitrogen!");
01697
01698 abs_n2.resize( abs_vmrs.ncols() );
01699 abs_n2 = abs_vmrs(n2_index,Range(joker));
01700 }
01701
01702
01703
01704 void AbsInputFromAtmFields (
01705 Vector& abs_p,
01706 Vector& abs_t,
01707 Matrix& abs_vmrs,
01708
01709 const Index& atmosphere_dim,
01710 const Vector& p_grid,
01711 const Tensor3& t_field,
01712 const Tensor4& vmr_field
01713 )
01714 {
01715
01716 if ( 1 != atmosphere_dim )
01717 {
01718 ostringstream os;
01719 os << "Atmospheric dimension must be 1D, but atmosphere_dim is "
01720 << atmosphere_dim << ".";
01721 throw runtime_error(os.str());
01722 }
01723
01724 abs_p = p_grid;
01725 abs_t = t_field (joker, 0, 0);
01726 abs_vmrs = vmr_field (joker, joker, 0, 0);
01727 }
01728
01729
01730
01731 void abs_coefCalc(
01732 Matrix& abs_coef,
01733 ArrayOfMatrix& abs_coef_per_species,
01734
01735 const ArrayOfArrayOfSpeciesTag& tgs,
01736 const Vector& f_grid,
01737 const Vector& abs_p,
01738 const Vector& abs_t,
01739 const Vector& abs_n2,
01740 const Vector& abs_h2o,
01741 const Matrix& abs_vmrs,
01742 const ArrayOfArrayOfLineRecord& abs_lines_per_species,
01743 const ArrayOfLineshapeSpec& abs_lineshape,
01744 const ArrayOfString& abs_cont_names,
01745 const ArrayOfString& abs_cont_models,
01746 const ArrayOfVector& abs_cont_parameters)
01747 {
01748
01749
01750
01751 ArrayOfMatrix abs_xsec_per_species;
01752
01753 abs_xsec_per_speciesInit( abs_xsec_per_species, tgs, f_grid, abs_p );
01754
01755 abs_xsec_per_speciesAddLines( abs_xsec_per_species,
01756 tgs,
01757 f_grid,
01758 abs_p,
01759 abs_t,
01760 abs_h2o,
01761 abs_vmrs,
01762 abs_lines_per_species,
01763 abs_lineshape );
01764
01765 abs_xsec_per_speciesAddConts( abs_xsec_per_species,
01766 tgs,
01767 f_grid,
01768 abs_p,
01769 abs_t,
01770 abs_n2,
01771 abs_h2o,
01772 abs_vmrs,
01773 abs_cont_names,
01774 abs_cont_parameters,
01775 abs_cont_models);
01776
01777 abs_coefCalcFromXsec(abs_coef,
01778 abs_coef_per_species,
01779 abs_xsec_per_species,
01780 abs_vmrs,
01781 abs_p,
01782 abs_t);
01783
01784 }
01785
01786
01787
01788 void abs_coefCalcSaveMemory(
01789 Matrix& abs_coef,
01790
01791 const ArrayOfArrayOfSpeciesTag& tgs,
01792 const Vector& f_grid,
01793 const Vector& abs_p,
01794 const Vector& abs_t,
01795 const Vector& abs_n2,
01796 const Vector& abs_h2o,
01797 const Matrix& abs_vmrs,
01798 const ArrayOfArrayOfLineRecord& abs_lines_per_species,
01799 const ArrayOfLineshapeSpec& abs_lineshape,
01800 const ArrayOfString& abs_cont_names,
01801 const ArrayOfString& abs_cont_models,
01802 const ArrayOfVector& abs_cont_parameters)
01803 {
01804
01805
01806
01807 ArrayOfMatrix abs_xsec_per_species;
01808
01809
01810 Matrix this_abs;
01811
01812
01813
01814
01815 ArrayOfMatrix this_abs_coef_per_species;
01816
01817
01818 ArrayOfArrayOfSpeciesTag this_tg(1);
01819
01820
01821 Matrix this_vmr(1,abs_p.nelem());
01822
01823
01824 ArrayOfArrayOfLineRecord these_lines(1);
01825
01826
01827 ArrayOfLineshapeSpec this_lineshape(1);
01828
01829
01830 abs_coef.resize( f_grid.nelem(), abs_p.nelem() );
01831 abs_coef = 0;
01832
01833 out3 << " Number of tag groups to do: " << tgs.nelem() << "\n";
01834
01835
01836 for ( Index i=0; i<tgs.nelem(); ++i )
01837 {
01838 out3 << " Doing tag group " << i << ".\n";
01839
01840
01841 this_tg[0].resize(tgs[i].nelem());
01842 this_tg[0] = tgs[i];
01843
01844
01845 this_vmr(0,joker) = abs_vmrs(i,joker);
01846
01847
01848 these_lines[0].resize(abs_lines_per_species[i].nelem());
01849 these_lines[0] = abs_lines_per_species[i];
01850
01851
01852 this_lineshape[0] = abs_lineshape[i];
01853
01854 abs_xsec_per_speciesInit( abs_xsec_per_species, this_tg, f_grid, abs_p );
01855
01856 abs_xsec_per_speciesAddLines( abs_xsec_per_species,
01857 this_tg,
01858 f_grid,
01859 abs_p,
01860 abs_t,
01861 abs_h2o,
01862 this_vmr,
01863 these_lines,
01864 this_lineshape );
01865
01866 abs_xsec_per_speciesAddConts( abs_xsec_per_species,
01867 this_tg,
01868 f_grid,
01869 abs_p,
01870 abs_t,
01871 abs_n2,
01872 abs_h2o,
01873 this_vmr,
01874 abs_cont_names,
01875 abs_cont_parameters,
01876 abs_cont_models);
01877
01878 abs_coefCalcFromXsec(this_abs,
01879 this_abs_coef_per_species,
01880 abs_xsec_per_species,
01881 this_vmr,
01882 abs_p,
01883 abs_t);
01884
01885
01886 assert(abs_coef.nrows()==this_abs.nrows());
01887 assert(abs_coef.ncols()==this_abs.ncols());
01888 abs_coef += this_abs;
01889 }
01890 }
01891
01892
01893
01894 void abs_coefCalcFromXsec(
01895 Matrix& abs_coef,
01896 ArrayOfMatrix& abs_coef_per_species,
01897
01898 const ArrayOfMatrix& abs_xsec_per_species,
01899 const Matrix& abs_vmrs,
01900 const Vector& abs_p,
01901 const Vector& abs_t)
01902 {
01903
01904
01905 if ( abs_vmrs.nrows() != abs_xsec_per_species.nelem() )
01906 {
01907 ostringstream os;
01908 os << "Variable abs_vmrs must have compatible dimension to abs_xsec_per_species.\n"
01909 << "abs_vmrs.nrows() = " << abs_vmrs.nrows() << "\n"
01910 << "abs_xsec_per_species.nelem() = " << abs_xsec_per_species.nelem();
01911 throw runtime_error(os.str());
01912 }
01913
01914
01915
01916
01917 if ( abs_vmrs.ncols() != abs_xsec_per_species[0].ncols() )
01918 {
01919 ostringstream os;
01920 os << "Variable abs_vmrs must have same numbers of altitudes as abs_xsec_per_species.\n"
01921 << "abs_vmrs.ncols() = " << abs_vmrs.ncols() << "\n"
01922 << "abs_xsec_per_species[0].ncols() = " << abs_xsec_per_species[0].ncols();
01923 throw runtime_error(os.str());
01924 }
01925
01926
01927 chk_size("abs_p", abs_p, abs_vmrs.ncols());
01928 chk_size("abs_t", abs_t, abs_vmrs.ncols());
01929
01930
01931
01932
01933
01934 abs_coef.resize( abs_xsec_per_species[0].nrows(), abs_xsec_per_species[0].ncols() );
01935 abs_coef = 0;
01936
01937 abs_coef_per_species.resize( abs_xsec_per_species.nelem() );
01938
01939 out3 << " Computing abs_coef and abs_coef_per_species from abs_xsec_per_species.\n";
01940
01941
01942 for ( Index i=0; i<abs_xsec_per_species.nelem(); ++i )
01943 {
01944 out3 << " Tag group " << i << "\n";
01945
01946
01947 abs_coef_per_species[i].resize( abs_xsec_per_species[i].nrows(), abs_xsec_per_species[i].ncols() );
01948 abs_coef_per_species[i] = 0;
01949
01950
01951 for ( Index j=0; j<abs_xsec_per_species[i].ncols(); j++)
01952 {
01953
01954 const Numeric n = number_density(abs_p[j],abs_t[j]);
01955
01956
01957 for ( Index k=0; k<abs_xsec_per_species[i].nrows(); k++)
01958 {
01959 abs_coef_per_species[i](k,j) = abs_xsec_per_species[i](k,j) * n * abs_vmrs(i,j);
01960 }
01961 }
01962
01963
01964 abs_coef += abs_coef_per_species[i];
01965
01966 }
01967 }
01968
01969
01970
01971 void abs_xsec_per_speciesInit(
01972 ArrayOfMatrix& abs_xsec_per_species,
01973
01974 const ArrayOfArrayOfSpeciesTag& tgs,
01975 const Vector& f_grid,
01976 const Vector& abs_p
01977 )
01978 {
01979
01980
01981 abs_xsec_per_species.resize( tgs.nelem() );
01982
01983
01984
01985 for ( Index i=0; i<tgs.nelem(); ++i )
01986 {
01987
01988 abs_xsec_per_species[i].resize( f_grid.nelem(), abs_p.nelem() );
01989 abs_xsec_per_species[i] = 0;
01990 }
01991
01992 out3 << " Initialized abs_xsec_per_species.\n"
01993 << " Number of frequencies : " << f_grid.nelem() << "\n"
01994 << " Number of pressure levels : " << abs_p.nelem() << "\n";
01995 }
01996
01997
01998
01999 void abs_xsec_per_speciesAddLines(
02000 ArrayOfMatrix& abs_xsec_per_species,
02001
02002 const ArrayOfArrayOfSpeciesTag& tgs,
02003 const Vector& f_grid,
02004 const Vector& abs_p,
02005 const Vector& abs_t,
02006 const Vector& abs_h2o,
02007 const Matrix& abs_vmrs,
02008 const ArrayOfArrayOfLineRecord& abs_lines_per_species,
02009 const ArrayOfLineshapeSpec& abs_lineshape)
02010 {
02011
02012
02013 {
02014 const Index n_tgs = tgs.nelem();
02015 const Index n_xsec = abs_xsec_per_species.nelem();
02016 const Index n_vmrs = abs_vmrs.nrows();
02017 const Index n_lines = abs_lines_per_species.nelem();
02018 const Index n_shapes = abs_lineshape.nelem();
02019
02020 if ( n_tgs != n_xsec ||
02021 n_tgs != n_vmrs ||
02022 n_tgs != n_lines ||
02023 ( n_tgs != n_shapes &&
02024 1 != n_shapes ) )
02025 {
02026 ostringstream os;
02027 os << "The following variables must all have the same dimension:\n"
02028 << "tgs: " << tgs.nelem() << "\n"
02029 << "abs_xsec_per_species: " << abs_xsec_per_species.nelem() << "\n"
02030 << "abs_vmrs: " << abs_vmrs.nrows() << "\n"
02031 << "abs_lines_per_species: " << abs_lines_per_species.nelem() << "\n"
02032 << "abs_lineshape: " << abs_lineshape.nelem() << "\n"
02033 << "(As a special case, abs_lineshape is allowed to have only one element.)";
02034 throw runtime_error(os.str());
02035 }
02036 }
02037
02038
02039
02040 out3 << " Calculating line spectra.\n";
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075 for ( Index i=0; i<tgs.nelem(); ++i )
02076 {
02077 out3 << " Tag group " << i
02078 << " (" << get_tag_group_name(tgs[i]) << "): ";
02079
02080
02081
02082
02083 const ArrayOfLineRecord& ll = abs_lines_per_species[i];
02084
02085
02086
02087
02088 LineshapeSpec ls;
02089 if (1==abs_lineshape.nelem())
02090 ls = abs_lineshape[0];
02091 else
02092 ls = abs_lineshape[i];
02093
02094
02095 if ( 0 < ll.nelem() )
02096 {
02097
02098
02099
02100
02101 if (ll[0].Species() != tgs[i][0].Species() )
02102 {
02103 ostringstream os;
02104 os << "The species in the line list does not match the species\n"
02105 << "for which you want to calculate absorption:\n"
02106 << "abs_species: " << get_tag_group_name(tgs[i]) << "\n"
02107 << "abs_lines_per_species: " << ll[0].Name();
02108 throw runtime_error(os.str());
02109 }
02110
02111
02112
02113
02114
02115
02116 extern const Array<SpeciesRecord> species_data;
02117 String species_name = species_data[ll[0].Species()].Name();
02118
02119
02120
02121
02122
02123
02124 extern const Array<LineshapeRecord> lineshape_data;
02125 String lineshape_name = lineshape_data[ls.Ind_ls()].Name();
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137 if ( "O2" == species_name )
02138 {
02139
02140
02141 if ( 0 != ll[0].Naux() )
02142 {
02143
02144
02145 if ( "Rosenkranz_Voigt_Drayson" != lineshape_name &&
02146 "Rosenkranz_Voigt_Kuntz6" != lineshape_name )
02147 {
02148 ostringstream os;
02149 os
02150 << "You are using a line catalogue that contains auxiliary parameters to\n"
02151 << "take care of overlap for oxygen lines. But you are not using a\n"
02152 << "lineshape that uses these parameters. Use Rosenkranz_Voigt_Drayson or\n"
02153 << "Rosenkranz_Voigt_Kuntz6.";
02154 throw runtime_error(os.str());
02155 }
02156 }
02157 }
02158
02159
02160
02161 if ( "Rosenkranz_Voigt_Drayson" == lineshape_name ||
02162 "Rosenkranz_Voigt_Kuntz6" == lineshape_name )
02163 {
02164
02165 if ( "O2" != species_name )
02166 {
02167 ostringstream os;
02168 os
02169 << "You are trying to use one of the special Rosenkranz lineshapes with\n"
02170 << "overlap correction for a species other than oxygen. Your species is\n"
02171 << species_name << ".\n"
02172 << "Select another lineshape for this species.";
02173 throw runtime_error(os.str());
02174 }
02175 else
02176 {
02177
02178
02179 if ( 0 == ll[0].Naux() )
02180 {
02181 ostringstream os;
02182 os
02183 << "You are trying to use one of the special Rosenkranz lineshapes with\n"
02184 << "overlap correction. But your line file does not contain aux\n"
02185 << "parameters. (I've checked only the first LineRecord). Use a line file\n"
02186 << "with overlap parameters.";
02187 throw runtime_error(os.str());
02188 }
02189 }
02190 }
02191
02192 out3 << ll.nelem() << " transitions\n";
02193 xsec_species( abs_xsec_per_species[i],
02194 f_grid,
02195 abs_p,
02196 abs_t,
02197 abs_h2o,
02198 abs_vmrs(i,Range(joker)),
02199 ll,
02200 ls.Ind_ls(),
02201 ls.Ind_lsn(),
02202 ls.Cutoff());
02203
02204
02205
02206 }
02207 else
02208 {
02209 out3 << ll.nelem() << " transitions, skipping\n";
02210 }
02211 }
02212 }
02213
02214
02215 void abs_xsec_per_speciesAddConts(
02216 ArrayOfMatrix& abs_xsec_per_species,
02217
02218 const ArrayOfArrayOfSpeciesTag& tgs,
02219 const Vector& f_grid,
02220 const Vector& abs_p,
02221 const Vector& abs_t,
02222 const Vector& abs_n2,
02223 const Vector& abs_h2o,
02224 const Matrix& abs_vmrs,
02225 const ArrayOfString& abs_cont_names,
02226 const ArrayOfVector& abs_cont_parameters,
02227 const ArrayOfString& abs_cont_models )
02228 {
02229
02230
02231 {
02232 const Index n_tgs = tgs.nelem();
02233 const Index n_xsec = abs_xsec_per_species.nelem();
02234 const Index n_vmrs = abs_vmrs.nrows();
02235
02236 if ( n_tgs != n_xsec || n_tgs != n_vmrs )
02237 {
02238 ostringstream os;
02239 os << "The following variables must all have the same dimension:\n"
02240 << "tgs: " << tgs.nelem() << "\n"
02241 << "abs_xsec_per_species: " << abs_xsec_per_species.nelem() << "\n"
02242 << "abs_vmrs.nrows(): " << abs_vmrs.nrows();
02243 throw runtime_error(os.str());
02244 }
02245 }
02246
02247
02248
02249 if ( abs_cont_names.nelem() !=
02250 abs_cont_parameters.nelem() )
02251 {
02252 for (Index i=0; i < abs_cont_names.nelem(); ++i)
02253 {
02254 cout << "abs_xsec_per_speciesAddConts: " << i << " name : " << abs_cont_names[i] << "\n";
02255 }
02256 for (Index i=0; i < abs_cont_parameters.nelem(); ++i)
02257 {
02258 cout << "abs_xsec_per_speciesAddConts: " << i << " param: " << abs_cont_parameters[i] << "\n";
02259 }
02260 for (Index i=0; i < abs_cont_models.nelem(); ++i)
02261 {
02262 cout << "abs_xsec_per_speciesAddConts: " << i << " option: " << abs_cont_models[i] << "\n";
02263 }
02264 ostringstream os;
02265 os << "The following variables must have the same dimension:\n"
02266 << "abs_cont_names: " << abs_cont_names.nelem() << "\n"
02267 << "abs_cont_parameters: " << abs_cont_parameters.nelem();
02268 throw runtime_error(os.str());
02269 }
02270
02271
02272 for ( Index i=0; i<abs_cont_names.nelem(); ++i )
02273 {
02274 check_continuum_model(abs_cont_names[i]);
02275 }
02276
02277
02278
02279
02280
02281
02282 if ( abs_t.nelem() != abs_p.nelem() )
02283 {
02284 ostringstream os;
02285 os << "Variable abs_t must have the same dimension as abs_p.\n"
02286 << "abs_t.nelem() = " << abs_t.nelem() << '\n'
02287 << "abs_p.nelem() = " << abs_p.nelem();
02288 throw runtime_error(os.str());
02289 }
02290
02291 if ( abs_vmrs.ncols() != abs_p.nelem() )
02292 {
02293 ostringstream os;
02294 os << "Variable dimension abs_vmrs.ncols() must\n"
02295 << "be the same as abs_p.nelem().\n"
02296 << "abs_vmrs.ncols() = " << abs_vmrs.ncols() << '\n'
02297 << "abs_p.nelem() = " << abs_p.nelem();
02298 throw runtime_error(os.str());
02299 }
02300
02301
02302
02303
02304
02305 out3 << " Calculating continuum spectra.\n";
02306
02307
02308 for ( Index i=0; i<tgs.nelem(); ++i )
02309 {
02310 extern const Array<SpeciesRecord> species_data;
02311
02312
02313
02314 for ( Index s=0; s<tgs[i].nelem(); ++s )
02315 {
02316
02317
02318
02319
02320
02321 if ( tgs[i][s].Isotope() <
02322 species_data[tgs[i][s].Species()].Isotope().nelem() )
02323 {
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346 if ( 0 >
02347 species_data[tgs[i][s].Species()].Isotope()[tgs[i][s].Isotope()].Abundance() )
02348 {
02349
02350
02351
02352
02353 const String name =
02354 species_data[tgs[i][s].Species()].Name() + "-"
02355 + species_data[tgs[i][s].Species()].Isotope()[tgs[i][s].Isotope()].Name();
02356
02357
02358
02359 check_continuum_model(name);
02360
02361
02362
02363
02364 const Index n =
02365 find( abs_cont_names.begin(),
02366 abs_cont_names.end(),
02367 name ) - abs_cont_names.begin();
02368
02369
02370
02371 if ( n==abs_cont_names.nelem() )
02372 {
02373 ostringstream os;
02374 os << "Cannot find model " << name
02375 << " in abs_cont_names.";
02376 throw runtime_error(os.str());
02377 }
02378
02379
02380
02381
02382 out3 << " Adding " << name
02383 << " to tag group " << i << ".\n";
02384
02385
02386
02387 const String ContOption = abs_cont_models[n];
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399 if ( -.99 > abs_h2o[0] )
02400 {
02401 ostringstream os;
02402 os << "The variable abs_h2o seems to be set to its global default\n"
02403 << "value of -1. You have to set this to a H2O VMR profile if\n"
02404 << "you want to use absorption contiua. If you are calling\n"
02405 << "absorption routines directly, or on the fly, you could\n"
02406 << "use for example the method *abs_h2oSet*.\n"
02407 << "If you are generating an absorption lookup table with\n"
02408 << "abs_lookupCreate, it should be enough to add a H2O species\n"
02409 << "to your calculation to fix this problem.";
02410 throw runtime_error(os.str());
02411 }
02412
02413
02414
02415 if ( abs_h2o.nelem() != abs_p.nelem() )
02416 {
02417 ostringstream os;
02418 os << "Variable abs_h2o must have the same dimension as abs_p.\n"
02419 << "abs_h2o.nelem() = " << abs_h2o.nelem() << '\n'
02420 << "abs_p.nelem() = " << abs_p.nelem();
02421 throw runtime_error(os.str());
02422 }
02423
02424
02425
02426
02427
02428
02429
02430
02431 Vector n2_prof(abs_p.nelem());
02432 if ( abs_n2.nelem() == abs_p.nelem() )
02433 {
02434 n2_prof = abs_n2;
02435 }
02436 else
02437 {
02438 if (1==abs_n2.nelem())
02439 {
02440
02441
02442
02443
02444 n2_prof = abs_n2[0];
02445 }
02446 else
02447 {
02448 ostringstream os;
02449 os << "Variable abs_n2 must have dimension 1, or\n"
02450 << "the same dimension as abs_p.\n"
02451 << "abs_n2.nelem() = " << abs_n2.nelem() << '\n'
02452 << "abs_p.nelem() = " << abs_p.nelem();
02453 throw runtime_error(os.str());
02454 }
02455 }
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465 xsec_continuum_tag( abs_xsec_per_species[i],
02466 name,
02467 abs_cont_parameters[n],
02468 abs_cont_models[n],
02469 f_grid,
02470 abs_p,
02471 abs_t,
02472 n2_prof,
02473 abs_h2o,
02474 abs_vmrs(i,Range(joker)) );
02475
02476
02477 }
02478 }
02479 }
02480 }
02481
02482 }
02483
02484 #if 0
02485
02494 void abs_coef_per_speciesReduce(
02495 ArrayOfMatrix& abs_coef_per_species,
02496
02497 const ArrayOfArrayOfSpeciesTag& tgs,
02498 const ArrayOfArrayOfSpeciesTag& wfs_tgs)
02499 {
02500
02501
02502
02503
02504 if ( abs_coef_per_species.nelem()!=tgs.nelem() )
02505 throw(runtime_error("The variables abs_coef_per_species and tgs must\n"
02506 "have the same dimension."));
02507
02508
02509
02510
02511
02512 ArrayOfMatrix abs_coef_per_species_out( wfs_tgs.nelem() );
02513
02514
02515 for ( Index i=0; i<wfs_tgs.nelem(); ++i )
02516 {
02517
02518 Index n;
02519 get_tag_group_index_for_tag_group( n, tgs, wfs_tgs[i] );
02520
02521 abs_coef_per_species_out[i].resize( abs_coef_per_species[n].nrows(), abs_coef_per_species[n].ncols() );
02522 abs_coef_per_species_out[i] = abs_coef_per_species[n];
02523
02524
02525 }
02526
02527
02528 abs_coef_per_species.resize( wfs_tgs.nelem() );
02529 abs_coef_per_species = abs_coef_per_species_out;
02530
02531
02532 }
02533
02534
02535
02536
02537
02538
02539
02546 void refrSet(
02547 Index& refr,
02548 Index& refr_lfac,
02549 String& refr_model,
02550 const Index& on,
02551 const String& model,
02552 const Index& lfac )
02553 {
02554 check_if_bool( on, "on" );
02555 if ( lfac < 1 )
02556 throw runtime_error("The length factor cannot be smaller than 1.");
02557
02558 refr = on;
02559 refr_lfac = lfac;
02560 refr_model = model;
02561 }
02562
02563
02564
02571 void refrOff(
02572 Index& refr,
02573 Index& refr_lfac,
02574 String& refr_model )
02575 {
02576 refrSet( refr, refr_lfac, refr_model, 0, "", 1 );
02577 refr_lfac = 0;
02578 }
02579
02580
02581
02588 void refrCalc (
02589 Vector& refr_index,
02590 const Vector& abs_p,
02591 const Vector& abs_t,
02592 const Vector& abs_h2o,
02593 const Index& refr,
02594 const String& refr_model )
02595 {
02596 check_if_bool( refr, "refr" );
02597
02598 if ( refr == 0 )
02599 refr_index.resize( 0 );
02600
02601 else
02602 {
02603 if ( refr_model == "Unity" )
02604 {
02605 const Index n = abs_p.nelem();
02606 refr_index.resize( n );
02607 refr_index = 1.0;
02608 }
02609
02610 else if ( refr_model == "Boudouris" )
02611 refr_index_Boudouris( refr_index, abs_p, abs_t, abs_h2o );
02612
02613 else if ( refr_model == "BoudourisDryAir" )
02614 refr_index_BoudourisDryAir( refr_index, abs_p, abs_t );
02615
02616 else
02617 {
02618 ostringstream os;
02619 os << "Unknown refraction parameterization: " << refr_model << "\n"
02620 << "Existing parameterizations are: \n"
02621 << "Unity\n"
02622 << "Boudouris\n"
02623 << "BoudourisDryAir";
02624 throw runtime_error(os.str());
02625 }
02626 }
02627 }
02628
02629 #endif
02630
02631
02632
02633
02634
02635
02636 void abs_cont_descriptionInit(
02637 ArrayOfString& names,
02638 ArrayOfString& options,
02639 ArrayOfVector& parameters)
02640 {
02641 names.resize(0);
02642 options.resize(0);
02643 parameters.resize(0);
02644 out2 << " Initialized abs_cont_names \n"
02645 " abs_cont_models\n"
02646 " abs_cont_parameters.\n";
02647 }
02648
02649
02650
02651 void abs_cont_descriptionAppend(
02652 ArrayOfString& abs_cont_names,
02653 ArrayOfString& abs_cont_models,
02654 ArrayOfVector& abs_cont_parameters,
02655
02656 const String& tagname,
02657 const String& model,
02658 const Vector& userparameters)
02659 {
02660
02661 check_continuum_model(tagname);
02662
02663
02664
02665
02666
02667
02668 abs_cont_names.push_back(tagname);
02669 abs_cont_models.push_back(model);
02670 abs_cont_parameters.push_back(userparameters);
02671 }
02672
02673
02674
02675 void abs_scalar_gasFromAbsCoef(
02676 Matrix& abs_scalar_gas,
02677
02678 const ArrayOfMatrix& abs_coef_per_species)
02679 {
02680
02681
02682
02683
02684 Index n_species = abs_coef_per_species.nelem();
02685
02686 if (0==n_species)
02687 {
02688 ostringstream os;
02689 os << "Must have at least one species.";
02690 throw runtime_error(os.str());
02691 }
02692
02693 Index n_f = abs_coef_per_species[0].nrows();
02694
02695
02696 if (1!=abs_coef_per_species[0].ncols())
02697 {
02698 ostringstream os;
02699 os << "Must have exactly one pressure.";
02700 throw runtime_error(os.str());
02701 }
02702
02703 abs_scalar_gas.resize(n_f,n_species);
02704
02705
02706 for ( Index si=0; si<n_species; ++si )
02707 abs_scalar_gas(Range(joker),si) = abs_coef_per_species[si](Range(joker),0);
02708
02709 }
02710
02711
02712
02713 void abs_scalar_gasCalcLBL(
02714 Matrix& abs_scalar_gas,
02715
02716 const Vector& f_grid,
02717 const ArrayOfArrayOfSpeciesTag& abs_species,
02718 const Vector& abs_n2,
02719 const ArrayOfArrayOfLineRecord& abs_lines_per_species,
02720 const ArrayOfLineshapeSpec& abs_lineshape,
02721 const ArrayOfString& abs_cont_names,
02722 const ArrayOfString& abs_cont_models,
02723 const ArrayOfVector& abs_cont_parameters,
02724 const Index& f_index,
02725 const Numeric& rte_pressure,
02726 const Numeric& rte_temperature,
02727 const Vector& rte_vmr_list)
02728 {
02729
02730 Vector abs_p;
02731 Vector abs_t;
02732 Matrix abs_vmrs;
02733
02734 Vector abs_h2o;
02735
02736 Matrix abs_coef;
02737 ArrayOfMatrix abs_coef_per_species;
02738
02739
02740
02741
02742
02743
02744 Vector local_f_grid;
02745 const Vector* f_grid_pointer;
02746 if (f_index>=0)
02747 {
02748
02749 local_f_grid = f_grid;
02750
02751
02752 f_gridSelectFIndex(local_f_grid, f_index);
02753
02754
02755 f_grid_pointer = &local_f_grid;
02756 }
02757 else
02758 {
02759
02760 f_grid_pointer = &f_grid;
02761 }
02762
02763 AbsInputFromRteScalars( abs_p,
02764 abs_t,
02765 abs_vmrs,
02766 rte_pressure,
02767 rte_temperature,
02768 rte_vmr_list );
02769
02770 abs_h2oSet( abs_h2o,
02771 abs_species,
02772 abs_vmrs );
02773
02774 abs_coefCalc( abs_coef,
02775 abs_coef_per_species,
02776 abs_species,
02777 *f_grid_pointer,
02778 abs_p,
02779 abs_t,
02780 abs_n2,
02781 abs_h2o,
02782 abs_vmrs,
02783 abs_lines_per_species,
02784 abs_lineshape,
02785 abs_cont_names,
02786 abs_cont_models,
02787 abs_cont_parameters );
02788
02789 abs_scalar_gasFromAbsCoef( abs_scalar_gas,
02790 abs_coef_per_species );
02791 }
02792
02793
02794
02795 void f_gridSelectFIndex(
02796 Vector& f_grid,
02797
02798 const Index& f_index)
02799 {
02800
02801
02802 if ( f_index >= 0 )
02803 {
02804
02805 if ( f_index >= f_grid.nelem() )
02806 {
02807 ostringstream os;
02808 os << "The frequency index you want is outside f_grid.\n"
02809 << "You have " << f_index
02810 << ", the largest allowed value is " << f_grid.nelem()-1 << ".";
02811 throw runtime_error( os.str() );
02812 }
02813
02814 Numeric this_f = f_grid[f_index];
02815 f_grid.resize(1);
02816 f_grid = this_f;
02817 }
02818
02819
02820 }