00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00032 #include <math.h>
00033 #include <algorithm>
00034 #include "arts.h"
00035 #include "matpackI.h"
00036 #include "array.h"
00037 #include "messages.h"
00038 #include "file.h"
00039 #include "absorption.h"
00040 #include "auto_wsv.h"
00041 #include "auto_md.h"
00042 #include "math_funcs.h"
00043 #include "make_array.h"
00044 #include "atm_funcs.h"
00045 #include "continua.h"
00046 #include "make_vector.h"
00047
00054 void lines_per_tgSetEmpty(
00055 ArrayOfArrayOfLineRecord& lines_per_tg,
00056
00057 const TagGroups& tgs)
00058 {
00059
00060 lines_per_tg.resize( tgs.nelem() );
00061
00062 for (Index i=0; i<tgs.nelem(); ++i)
00063 {
00064 lines_per_tg[i].resize(0);
00065 }
00066 }
00067
00077 void linesReadFromHitran(
00078 ArrayOfLineRecord& lines,
00079
00080 const String& filename,
00081 const Numeric& fmin,
00082 const Numeric& fmax)
00083 {
00084 ifstream is;
00085
00086
00087 lines.resize(0);
00088
00089 out2 << " Reading file: " << filename << '\n';
00090 open_input_file(is, filename);
00091
00092 bool go_on = true;
00093 while ( go_on )
00094 {
00095 LineRecord lr;
00096 if ( lr.ReadFromHitranStream(is) )
00097 {
00098
00099
00100 go_on = false;
00101 }
00102 else
00103 {
00104 if ( fmin <= lr.F() )
00105 {
00106 if ( lr.F() <= fmax )
00107 lines.push_back(lr);
00108 else
00109 go_on = false;
00110 }
00111 }
00112 }
00113 out2 << " Read " << lines.nelem() << " lines.\n";
00114 }
00115
00116
00126 void linesReadFromHitran2004(
00127 ArrayOfLineRecord& lines,
00128
00129 const String& filename,
00130 const Numeric& fmin,
00131 const Numeric& fmax)
00132 {
00133 ifstream is;
00134
00135
00136 lines.resize(0);
00137
00138 out2 << " Reading file: " << filename << '\n';
00139 open_input_file(is, filename);
00140
00141 bool go_on = true;
00142 while ( go_on )
00143 {
00144 LineRecord lr;
00145 if ( lr.ReadFromHitran2004Stream(is) )
00146 {
00147
00148
00149 go_on = false;
00150 }
00151 else
00152 {
00153 if ( fmin <= lr.F() )
00154 {
00155 if ( lr.F() <= fmax )
00156 lines.push_back(lr);
00157 else
00158 go_on = false;
00159 }
00160 }
00161 }
00162 out2 << " Read " << lines.nelem() << " lines.\n";
00163 }
00164
00165
00166 void linesReadFromMytran2(
00167 ArrayOfLineRecord& lines,
00168
00169 const String& filename,
00170 const Numeric& fmin,
00171 const Numeric& fmax)
00172 {
00173 ifstream is;
00174
00175
00176 lines.resize(0);
00177
00178 out2 << " Reading file: " << filename << '\n';
00179 open_input_file(is, filename);
00180
00181 bool go_on = true;
00182 while ( go_on )
00183 {
00184 LineRecord lr;
00185 if ( lr.ReadFromMytran2Stream(is) )
00186 {
00187
00188
00189 go_on = false;
00190 }
00191 else
00192 {
00193
00194 if ( fmin <= lr.F() )
00195 if ( lr.F() <= fmax )
00196 lines.push_back(lr);
00197 }
00198 }
00199 out2 << " Read " << lines.nelem() << " lines.\n";
00200 }
00201
00202
00210 void linesReadFromJpl(
00211 ArrayOfLineRecord& lines,
00212
00213 const String& filename,
00214 const Numeric& fmin,
00215 const Numeric& fmax)
00216 {
00217 ifstream is;
00218
00219
00220 lines.resize(0);
00221
00222 out2 << " Reading file: " << filename << '\n';
00223 open_input_file(is, filename);
00224
00225 bool go_on = true;
00226 while ( go_on )
00227 {
00228 LineRecord lr;
00229 if ( lr.ReadFromJplStream(is) )
00230 {
00231
00232
00233 go_on = false;
00234 }
00235 else
00236 {
00237
00238 if ( fmin <= lr.F() )
00239 {
00240 if ( lr.F() <= fmax )
00241 lines.push_back(lr);
00242 else
00243 go_on = false;
00244 }
00245 }
00246 }
00247 out2 << " Read " << lines.nelem() << " lines.\n";
00248 }
00249
00250
00251 void linesReadFromArts(
00252 ArrayOfLineRecord& lines,
00253
00254 const String& filename,
00255 const Numeric& fmin,
00256 const Numeric& fmax)
00257 {
00258
00259 ifstream is;
00260
00261
00262
00263 LineRecord lr;
00264
00265
00266 lines.resize(0);
00267
00268 out2 << " Reading file: " << filename << '\n';
00269 open_input_file(is, filename);
00270
00271
00272 {
00273 String v;
00274 is >> v;
00275 if ( v!=lr.Version() )
00276 {
00277 ostringstream os;
00278
00279
00280 if ( 9 <= v.nelem() )
00281 {
00282 if ( "ARTSCAT" == v.substr(0,7) )
00283 {
00284 os << "The ARTS line file you are trying contains a version tag "
00285 << "different from the current version.\n"
00286 << "Tag in file: " << v << "\n"
00287 << "Current version: " << lr.Version();
00288 throw runtime_error(os.str());
00289 }
00290 }
00291
00292 os << "The ARTS line file you are trying to read does not contain a valid version tag.\n"
00293 << "Probably it was created with an older version of ARTS that used different units.";
00294 throw runtime_error(os.str());
00295 }
00296 }
00297
00298 bool go_on = true;
00299 while ( go_on )
00300 {
00301 if ( lr.ReadFromArtsStream(is) )
00302 {
00303
00304
00305 go_on = false;
00306 }
00307 else
00308 {
00309
00310 if ( fmin <= lr.F() && lr.F() <= fmax )
00311 {
00312 lines.push_back(lr);
00313 }
00314 }
00315 }
00316 out2 << " Read " << lines.nelem() << " lines.\n";
00317 }
00318
00319 void linesElowToJoule(
00320 ArrayOfLineRecord& lines )
00321 {
00322 for ( Index i=0; i<lines.nelem(); ++i )
00323 lines[i].melow = wavenumber_to_joule(lines[i].melow);
00324 }
00325
00371 void lines_per_tgReadFromCatalogues(
00372 ArrayOfArrayOfLineRecord& lines_per_tg,
00373
00374 const TagGroups& tgs,
00375
00376 const ArrayOfString& filenames,
00377 const ArrayOfString& formats,
00378 const Vector& fmin,
00379 const Vector& fmax)
00380 {
00381 const Index n_tg = tgs.nelem();
00382 const Index n_cat = filenames.nelem();
00383
00384
00385
00386
00387 if ( n_cat != formats.nelem() ||
00388 n_cat != fmin.nelem() ||
00389 n_cat != fmax.nelem() )
00390 {
00391 ostringstream os;
00392 os << "lines_per_tgReadFromCatalogues: All keyword\n"
00393 << "parameters must get the same number of arguments.\n"
00394 << "You specified:\n"
00395 << "filenames: " << n_cat << "\n"
00396 << "formats: " << formats.nelem() << "\n"
00397 << "fmin: " << fmin.nelem() << "\n"
00398 << "fmax: " << fmax.nelem();
00399 throw runtime_error(os.str());
00400 }
00401
00402
00403
00404
00405 if ( n_cat > n_tg )
00406 {
00407 ostringstream os;
00408 os << "lines_per_tgReadFromCatalogues: You specified more\n"
00409 << "catalugues than you have tag groups.\n"
00410 << "You specified:\n"
00411 << "Catalogues: " << n_cat << "\n"
00412 << "tgs: " << n_tg;
00413 throw runtime_error(os.str());
00414 }
00415
00416
00417
00418 if ( n_cat < 1 ||
00419 n_tg < 1 )
00420 {
00421 ostringstream os;
00422 os << "lines_per_tgReadFromCatalogues: You must have at\n"
00423 << "least one catalogue and at least one tag group.\n"
00424 << "You specified:\n"
00425 << "Catalogues: " << n_cat << "\n"
00426 << "tgs: " << n_tg;
00427 throw runtime_error(os.str());
00428 }
00429
00430
00431
00432
00433
00434
00435 MakeArray<String> real_filenames ( filenames[0] );
00436 MakeArray<String> real_formats ( formats[0] );
00437 MakeArray<Numeric> real_fmin ( fmin[0] );
00438 MakeArray<Numeric> real_fmax ( fmax[0] );
00439
00440 Array< ArrayOfIndex > real_tgs(1);
00441 real_tgs[0].resize(1);
00442 real_tgs[0][0] = 0;
00443
00444
00445
00446 Index last_cat = 0;
00447
00448 for ( Index i=1; i<n_tg; ++i )
00449 {
00450
00451 if ( n_cat > i )
00452 {
00453
00454
00455
00456
00457
00458
00459
00460 const Index that_cat = find( real_filenames.begin(),
00461 real_filenames.end(),
00462 filenames[i] ) - real_filenames.begin();
00463 if ( that_cat < real_filenames.nelem() )
00464 {
00465
00466
00467 real_tgs[that_cat].push_back(i);
00468
00469
00470 if ( formats[i] != real_formats[that_cat] ||
00471 fmin[i] != real_fmin[that_cat] ||
00472 fmax[i] != real_fmax[that_cat] )
00473 {
00474 ostringstream os;
00475 os << "lines_per_tgReadFromCatalogues: If you specify the\n"
00476 << "same catalogue repeatedly, format, fmin, and fmax must be\n"
00477 << "consistent. There is an inconsistency between\n"
00478 << "catalogue " << that_cat << " and " << i << ".";
00479 throw runtime_error(os.str());
00480 }
00481 }
00482 else
00483 {
00484
00485
00486 real_tgs.push_back( MakeArray<Index>(i) );
00487
00488 real_filenames.push_back( filenames[i] );
00489 real_formats.push_back ( formats[i] );
00490 real_fmin.push_back ( fmin[i] );
00491 real_fmax.push_back ( fmax[i] );
00492
00493 last_cat = i;
00494
00495 }
00496 }
00497 else
00498 {
00499
00500
00501 real_tgs[last_cat].push_back(i);
00502 }
00503 }
00504
00505 Index n_real_cat = real_filenames.nelem();
00506
00507
00508 out3 << " Catalogues to read and tgs for which these will be used:\n";
00509 for ( Index i=0; i<n_real_cat; ++i )
00510 {
00511 out3 << " " << real_filenames[i] << ":";
00512 for ( Index s=0; s<real_tgs[i].nelem(); ++s )
00513 out3 << " " << real_tgs[i][s];
00514 out3 << "\n";
00515 }
00516
00517
00518 lines_per_tg.resize( tgs.nelem() );
00519
00520
00521 for ( Index i=0; i<n_real_cat; ++i )
00522 {
00523 ArrayOfLineRecord lines;
00524
00525
00526
00527 if ( "HITRAN96"==real_formats[i] )
00528 {
00529 linesReadFromHitran( lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00530 }
00531 else if ( "HITRAN04"==real_formats[i] )
00532 {
00533 linesReadFromHitran2004( lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00534 }
00535 else if ( "MYTRAN2"==real_formats[i] )
00536 {
00537 linesReadFromMytran2( lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00538 }
00539 else if ( "JPL"==real_formats[i] )
00540 {
00541 linesReadFromJpl( lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00542 }
00543 else if ( "ARTS"==real_formats[i] )
00544 {
00545 linesReadFromArts( lines, real_filenames[i], real_fmin[i], real_fmax[i] );
00546 }
00547 else
00548 {
00549 ostringstream os;
00550 os << "lines_per_tgReadFromCatalogues: You specified the\n"
00551 << "format `" << real_formats[i] << "', which is unknown.\n"
00552 << "Allowd formats are: HITRAN96, HITRAN04, MYTRAN2, JPL, ARTS.";
00553 throw runtime_error(os.str());
00554 }
00555
00556
00557
00558 TagGroups these_tgs(real_tgs[i].nelem());
00559 for ( Index s=0; s<real_tgs[i].nelem(); ++s )
00560 {
00561 these_tgs[s] = tgs[real_tgs[i][s]];
00562 }
00563
00564
00565 ArrayOfArrayOfLineRecord these_lines_per_tg;
00566 lines_per_tgCreateFromLines( these_lines_per_tg, lines, these_tgs );
00567
00568
00569 for ( Index s=0; s<real_tgs[i].nelem(); ++s )
00570 {
00571 lines_per_tg[real_tgs[i][s]] = these_lines_per_tg[s];
00572 }
00573 }
00574 }
00575
00576
00577 void lines_per_tgCreateFromLines(
00578 ArrayOfArrayOfLineRecord& lines_per_tg,
00579
00580 const ArrayOfLineRecord& lines,
00581 const TagGroups& tgs)
00582 {
00583
00584 extern const Array<SpeciesRecord> species_data;
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 std::vector<bool> species_used (species_data.nelem(),false);
00596
00597
00598 lines_per_tg = ArrayOfArrayOfLineRecord(tgs.nelem());
00599
00600
00601
00602
00603 for ( Index i=0; i<lines_per_tg.nelem(); ++i )
00604 lines_per_tg[i] = ArrayOfLineRecord();
00605
00606
00607 for ( Index i=0; i<lines.nelem(); ++i )
00608 {
00609
00610 const LineRecord& this_line = lines[i];
00611
00612
00613
00614
00615
00616
00617 bool found = false;
00618
00619
00620
00621 Index j;
00622
00623
00624 for ( j=0; j<tgs.nelem() && !found ; ++j )
00625 {
00626
00627 for ( Index k=0; k<tgs[j].nelem() && !found; ++k )
00628 {
00629
00630
00631 const OneTag& this_tag = tgs[j][k];
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 if ( this_tag.Species() != this_line.Species() ) break;
00642
00643
00644
00645
00646
00647
00648 if ( this_tag.Isotope() != this_line.SpeciesData().Isotope().nelem() )
00649 if ( this_tag.Isotope() != this_line.Isotope() )
00650 continue;
00651
00652
00653
00654
00655
00656
00657 if ( this_tag.Lf() >= 0 )
00658 if ( this_tag.Lf() > this_line.F() )
00659 continue;
00660
00661
00662 if ( this_tag.Uf() >= 0 )
00663 if ( this_tag.Uf() < this_line.F() )
00664 continue;
00665
00666
00667
00668 found = true;
00669 }
00670 }
00671
00672
00673
00674 if (found)
00675 {
00676
00677
00678 lines_per_tg[j-1].push_back(this_line);
00679
00680
00681 if ( !species_used[this_line.Species()] )
00682 species_used[this_line.Species()] = true;
00683 }
00684 else
00685 {
00686
00687
00688 if ( species_used[this_line.Species()] )
00689 {
00690 out2 << "Your tags include other lines of species "
00691 << this_line.SpeciesData().Name()
00692 << ",\n"
00693 << "why do you not include line "
00694 << i
00695 << " (at "
00696 << this_line.F()
00697 << " Hz)?\n";
00698 }
00699 }
00700 }
00701
00702
00703 for (Index i=0; i<tgs.nelem(); ++i)
00704 {
00705 out3 << " " << i << ":";
00706
00707 for (Index s=0; s<tgs[i].nelem(); ++s)
00708 out3 << " " << tgs[i][s].Name();
00709
00710 out3 << ": " << lines_per_tg[i].nelem() << " lines\n";
00711 }
00712
00713 }
00714
00722 void lines_per_tgAddMirrorLines(
00723 ArrayOfArrayOfLineRecord& lines_per_tg)
00724 {
00725
00726
00727
00728
00729 for ( Index i=0; i<lines_per_tg.nelem(); ++i )
00730 {
00731
00732 ArrayOfLineRecord& ll = lines_per_tg[i];
00733
00734
00735 ll.reserve(2*ll.nelem());
00736
00737
00738 {
00739
00740
00741
00742
00743 Index n=ll.nelem();
00744 for ( Index j=0; j<n; ++j )
00745 {
00746 LineRecord dummy = ll[j];
00747 dummy.setF( -dummy.F() );
00748
00749 ll.push_back(dummy);
00750 }
00751 }
00752 }
00753
00754 }
00755
00766 void lines_per_tgCompact(
00767 ArrayOfArrayOfLineRecord& lines_per_tg,
00768
00769 const ArrayOfLineshapeSpec& lineshape,
00770 const Vector& f_mono)
00771 {
00772
00773
00774 if ( lines_per_tg.nelem() != lineshape.nelem() )
00775 {
00776 ostringstream os;
00777 os << "Dimension of lines_per_tg does\n"
00778 << "not match that of lineshape.";
00779 throw runtime_error(os.str());
00780 }
00781
00782
00783 for ( Index s=0; s<f_mono.nelem()-1; ++s )
00784 {
00785 if ( f_mono[s+1] <= f_mono[s] )
00786 {
00787 ostringstream os;
00788 os << "The frequency grid f_mono is not properly sorted.\n"
00789 << "f_mono[" << s << "] = " << f_mono[s] << "\n"
00790 << "f_mono[" << s+1 << "] = " << f_mono[s+1];
00791 throw runtime_error(os.str());
00792 }
00793 }
00794
00795
00796 for ( Index i=0; i<lines_per_tg.nelem(); ++i )
00797 {
00798
00799 Numeric cutoff = lineshape[i].Cutoff();
00800
00801
00802 if ( cutoff != -1)
00803 {
00804
00805 ArrayOfLineRecord& ll = lines_per_tg[i];
00806
00807
00808 Numeric upp = f_mono[f_mono.nelem()-1] + cutoff;
00809 Numeric low = f_mono[0] - cutoff;
00810
00811
00812 Array<ArrayOfLineRecord::iterator> keep;
00813 for ( ArrayOfLineRecord::iterator j=ll.begin(); j<ll.end(); ++j )
00814 {
00815
00816 const Numeric F0 = j->F();
00817
00818 if ( ( F0 >= low) && ( F0 <= upp) )
00819 {
00820
00821 keep.push_back (j);
00822
00823
00824
00825
00826 }
00827 }
00828
00829
00830 if (keep.nelem () != ll.nelem ())
00831 {
00832 ArrayOfLineRecord nll;
00833
00834 for (Array<ArrayOfLineRecord::iterator>::iterator j
00835 = keep.begin(); j != keep.end(); j++)
00836 {
00837 nll.push_back (**j);
00838 }
00839
00840 ll.resize (nll.nelem ());
00841 ll = nll;
00842 }
00843 }
00844 }
00845 }
00846
00847
00848 void linesWriteAscii(
00849 const ArrayOfLineRecord& lines,
00850
00851 const String& f)
00852 {
00853 String filename = f;
00854
00855
00856 if ( "" == filename )
00857 {
00858 extern const String out_basename;
00859 filename = out_basename+".lines.aa";
00860 }
00861
00862 ofstream os;
00863
00864 out2 << " Writing file: " << filename << '\n';
00865 open_output_file(os, filename);
00866
00867 write_lines_to_stream(os,lines);
00868 }
00869
00870
00871 void lines_per_tgWriteAscii(
00872 const ArrayOfArrayOfLineRecord& lines_per_tg,
00873
00874 const String& f)
00875 {
00876 String filename = f;
00877
00878
00879 if ( "" == filename )
00880 {
00881 extern const String out_basename;
00882 filename = out_basename+".lines_per_tg.aa";
00883 }
00884
00885 ofstream os;
00886
00887 out2 << " Writing file: " << filename << '\n';
00888 open_output_file(os, filename);
00889
00890 os << lines_per_tg.nelem() << '\n';
00891
00892 for ( Index i=0; i<lines_per_tg.nelem(); ++i )
00893 {
00894 const ArrayOfLineRecord& lines = lines_per_tg[i];
00895 write_lines_to_stream( os, lines );
00896 }
00897 }
00898
00899
00900 void tgsDefine(
00901 TagGroups& tgs,
00902
00903 const ArrayOfString& tags)
00904 {
00905 tgs.resize(tags.nelem());
00906
00907
00908
00909
00910
00911 for ( Index i=0; i<tags.nelem(); ++i )
00912 {
00913
00914
00915 ArrayOfString tag_def;
00916
00917 bool go_on = true;
00918 String these_tags = tags[i];
00919 while (go_on)
00920 {
00921 Index n = these_tags.find(',');
00922 if ( n == these_tags.npos )
00923 {
00924
00925
00926 tag_def.push_back(these_tags);
00927 go_on = false;
00928 }
00929 else
00930 {
00931 tag_def.push_back(these_tags.substr(0,n));
00932 these_tags.erase(0,n+1);
00933 }
00934 }
00935
00936
00937
00938
00939
00940 tgs[i].resize(0);
00941
00942 for ( Index s=0; s<tag_def.nelem(); ++s )
00943 {
00944
00945 while ( ' ' == tag_def[s][0] ||
00946 '\t' == tag_def[s][0] ) tag_def[s].erase(0,1);
00947
00948 OneTag this_tag(tag_def[s]);
00949
00950
00951 if (s>0)
00952 if ( tgs[i][0].Species() != this_tag.Species() )
00953 throw runtime_error("Tags in a tag group must belong to the same species.");
00954
00955 tgs[i].push_back(this_tag);
00956 }
00957 }
00958
00959
00960 out3 << " Defined tag groups:";
00961 for ( Index i=0; i<tgs.nelem(); ++i )
00962 {
00963 out3 << "\n " << i << ":";
00964 for ( Index s=0; s<tgs[i].nelem(); ++s )
00965 {
00966 out3 << " " << tgs[i][s].Name();
00967 }
00968 }
00969 out3 << '\n';
00970
00971
00972 }
00973
00974 void tgsDefineAllInScenario(
00975 TagGroups& tgs,
00976
00977 const String& basename)
00978 {
00979
00980 extern const Array<SpeciesRecord> species_data;
00981
00982
00983 ArrayOfString included(0), excluded(0);
00984
00985 tgs.resize(0);
00986
00987 for ( Index i=0; i<species_data.nelem(); ++i )
00988 {
00989 const String specname = species_data[i].Name();
00990 const String filename = basename + "." + specname + ".aa";
00991
00992
00993 try
00994 {
00995 ifstream file;
00996 open_input_file(file, filename);
00997
00998
00999
01000
01001 included.push_back(specname);
01002
01003
01004 OneTag this_tag(specname);
01005
01006
01007 Array<OneTag> this_group(1);
01008 this_group[0] = this_tag;
01009
01010
01011 tgs.push_back(this_group);
01012 }
01013 catch (runtime_error x)
01014 {
01015
01016 excluded.push_back(specname);
01017 }
01018 }
01019
01020
01021 out2 << " Included Species (" << included.nelem() << "):\n";
01022 for ( Index i=0; i<included.nelem(); ++i )
01023 out2 << " " << included[i] << "\n";
01024
01025 out2 << " Excluded Species (" << excluded.nelem() << "):\n";
01026 for ( Index i=0; i<excluded.nelem(); ++i )
01027 out2 << " " << excluded[i] << "\n";
01028 }
01029
01030 void lineshapeDefine(
01031 ArrayOfLineshapeSpec& lineshape,
01032
01033 const TagGroups& tgs,
01034 const String& shape,
01035 const String& normalizationfactor,
01036 const Numeric& cutoff)
01037 {
01038
01039 extern const Array<LineshapeRecord> lineshape_data;
01040 extern const Array<LineshapeNormRecord> lineshape_norm_data;
01041
01042
01043
01044 Index tag_sz = tgs.nelem();
01045 lineshape.resize(tag_sz);
01046
01047
01048 Index found0=-1;
01049 for ( Index i=0; i<lineshape_data.nelem() && (found0 == -1) ; ++i )
01050 {
01051 const String& str = lineshape_data[i].Name();
01052 if (str == shape)
01053 {
01054 out2 << " Selected lineshape: " << str << "\n";
01055 found0=i;
01056 }
01057 }
01058
01059
01060 Index found1=-1;
01061 for ( Index i=0; i<lineshape_norm_data.nelem() && (found1 == -1); ++i )
01062 {
01063 const String& str = lineshape_norm_data[i].Name();
01064 if (str == normalizationfactor)
01065 {
01066 out2 << " Selected normalization factor : " << normalizationfactor << "\n";
01067
01068 if ( (cutoff != -1) && (cutoff < 0.0) )
01069 throw runtime_error(" Cutoff must be -1 or positive.");
01070 out2 << " Selected cutoff frequency [Hz] : " << cutoff << "\n";
01071 found1=i;
01072 }
01073 }
01074
01075
01076
01077 if (found0 == -1)
01078 throw runtime_error("Selected lineshape not available.");
01079 if (found1 == -1)
01080 throw runtime_error("Selected normalization to lineshape not available.");
01081
01082
01083
01084 for (Index i=0; i<tag_sz; i++)
01085 {
01086 lineshape[i].SetInd_ls( found0 );
01087 lineshape[i].SetInd_lsn( found1 );
01088 lineshape[i].SetCutoff( cutoff );
01089 }
01090 }
01091
01092 void lineshape_per_tgDefine(
01093 ArrayOfLineshapeSpec& lineshape,
01094
01095 const TagGroups& tgs,
01096 const ArrayOfString& shape,
01097 const ArrayOfString& normalizationfactor,
01098 const Vector& cutoff )
01099 {
01100
01101 extern const Array<LineshapeRecord> lineshape_data;
01102 extern const Array<LineshapeNormRecord> lineshape_norm_data;
01103
01104
01105 Index tg_sz = tgs.nelem();
01106 if ( (tg_sz != shape.nelem()) ||
01107 (tg_sz != normalizationfactor.nelem()) ||
01108 (tg_sz != cutoff.nelem()) )
01109 {
01110 ostringstream os;
01111 os << "lineshape_per_tgDefine: number of elements does\n"
01112 << "not match the number of tag groups defined.";
01113 throw runtime_error(os.str());
01114 }
01115
01116
01117
01118 lineshape.resize(tg_sz);
01119
01120
01121 for (Index k=0; k<tg_sz; ++k)
01122 {
01123 Index found0=-1;
01124 for ( Index i=0; i<lineshape_data.nelem() && (found0 == -1); ++i )
01125 {
01126 const String& str = lineshape_data[i].Name();
01127 if (str == shape[k])
01128 {
01129 out2 << " Tag Group: [";
01130 for (Index s=0; s<tgs[k].nelem()-1; ++s)
01131 out2 << tgs[k][s].Name() << ", ";
01132 out2 << tgs[k][tgs[k].nelem()-1].Name() << "]\n";
01133 out2 << " Selected lineshape: " << str << "\n";
01134 found0=i;
01135 }
01136 }
01137
01138
01139 Index found1=-1;
01140 for ( Index i=0; i<lineshape_norm_data.nelem() && (found1 == -1); ++i )
01141 {
01142 const String& str = lineshape_norm_data[i].Name();
01143 if (str == normalizationfactor[k])
01144 {
01145 out2 << " Selected normalization factor: " << normalizationfactor[k] << "\n";
01146 if ( (cutoff[k] != -1) && (cutoff[k] < 0.0) )
01147 throw runtime_error(" Cutoff must be -1 or positive.");
01148 out2 << " Selected cutoff frequency : " << cutoff[k] << "\n";
01149 found1=i;
01150 }
01151 }
01152
01153
01154
01155 if (found0 == -1)
01156 {
01157 ostringstream os;
01158 os << "Selected lineshape not available: "<< shape[k] <<"\n";
01159 throw runtime_error(os.str());
01160 }
01161 if (found1 == -1)
01162 {
01163 ostringstream os;
01164 os << "Selected normalization to lineshape not available: "<<
01165 normalizationfactor[k] <<"\n";
01166 throw runtime_error(os.str());
01167 }
01168
01169
01170 lineshape[k].SetInd_ls( found0 );
01171 lineshape[k].SetInd_lsn( found1 );
01172 lineshape[k].SetCutoff( cutoff[k] );
01173 }
01174 }
01175
01176
01177
01178 void raw_vmrsReadFromScenario(
01179 ArrayOfMatrix& raw_vmrs,
01180
01181 const TagGroups& tgs,
01182
01183 const String& basename)
01184 {
01185
01186 extern const Array<SpeciesRecord> species_data;
01187
01188
01189 for ( Index i=0; i<tgs.nelem(); ++i )
01190 {
01191
01192 String name =
01193 basename + "." +
01194 species_data[tgs[i][0].Species()].Name() + ".aa";
01195
01196
01197 raw_vmrs.push_back(Matrix());
01198
01199
01200
01201 MatrixReadAscii(raw_vmrs[i],"",name);
01202
01203
01204 out3 << " " << species_data[tgs[i][0].Species()].Name()
01205 << " profile read from file: " << name << "\n";
01206 }
01207 }
01208
01222 void raw_vmrsReadFromFiles(
01223 ArrayOfMatrix& raw_vmrs,
01224
01225 const TagGroups& tgs,
01226
01227 const ArrayOfString& seltags,
01228 const ArrayOfString& filenames,
01229 const String& basename)
01230 {
01231
01232 extern const Array<SpeciesRecord> species_data;
01233 ArrayOfIndex i_seltags;
01234
01235
01236
01237
01238 get_tagindex_for_Strings( i_seltags, tgs, seltags );
01239
01240
01241
01242 ArrayOfString true_filenames(tgs.nelem());
01243 true_filenames = basename + '.';
01244
01245
01246
01247 for ( Index i=0; i<tgs.nelem(); ++i )
01248 {
01249 true_filenames[i] +=
01250 species_data[tgs[i][0].Species()].Name() + ".aa";
01251
01252
01253 }
01254
01255
01256
01257 for ( Index i=0; i<seltags.nelem(); ++i )
01258 {
01259 true_filenames[i_seltags[i]] = filenames[i];
01260 }
01261
01262
01263 for ( Index i=0; i<tgs.nelem(); ++i )
01264 {
01265
01266 raw_vmrs.push_back(Matrix());
01267
01268
01269
01270 MatrixReadAscii(raw_vmrs[i],"",true_filenames[i]);
01271
01272
01273 out3 << " " << species_data[tgs[i][0].Species()].Name()
01274 << " profile read from file: " << true_filenames[i] << "\n";
01275 }
01276 }
01277
01345 void WaterVaporSaturationInClouds(
01346 Matrix& vmrs,
01347 Vector& p_abs,
01348
01349 const Vector& t_abs,
01350 const TagGroups& tgs )
01351 {
01352
01353
01354 assert ( vmrs.ncols() == p_abs.nelem() );
01355
01356
01357 extern const Array<SpeciesRecord> species_data;
01358
01359 Index liquid_index = 1+tgs.nelem();
01360 Index ice_index = 1+tgs.nelem();
01361 Index h2o_index[tgs.nelem()];
01362
01363
01364 assert ( t_abs.nelem() == p_abs.nelem() );
01365 assert ( vmrs.ncols() == p_abs.nelem() );
01366
01367
01368 Index u = 0;
01369 for ( Index i=0; i<tgs.nelem(); ++i )
01370 {
01371 String tag_name = species_data[tgs[i][0].Species()].Name();
01372 if (tag_name == "liquidcloud")
01373 {
01374 liquid_index = i;
01375 }
01376 if (tag_name == "icecloud")
01377 {
01378 ice_index = i;
01379 }
01380 if (tag_name == "H2O")
01381 {
01382 h2o_index[u++] = i;
01383
01384
01385 }
01386 }
01387
01388
01389
01390 if (u < 1)
01391 {
01392 out2 << "WaterVaporSaturationInClouds: no H2O profile found to adjust for clouds.\n"
01393 << "Therefore no saturation calculation is performed\n";
01394 return;
01395 }
01396
01397
01398
01399 if ( (liquid_index >= 0) && (liquid_index < tgs.nelem()) )
01400 {
01401
01402 for (Index uu=0; uu<u; ++uu)
01403 {
01404 for (Index i=0; i<vmrs.ncols() ; ++i)
01405 {
01406 if (vmrs(liquid_index,i) > 0.000)
01407 {
01408
01409 Numeric p_dry = p_abs[i] * ( 1.000e0 - vmrs(h2o_index[uu],i) );
01410
01411 Numeric e_s = WVSatPressureLiquidWater( t_abs[i] );
01412
01413 p_abs[i] = e_s + p_dry;
01414
01415 vmrs(h2o_index[uu],i) = e_s / p_abs[i];
01416
01417 if ( (vmrs(h2o_index[uu],i) < 0.000e0) || (vmrs(h2o_index[uu],i) > 1.000e0) )
01418 {
01419 ostringstream os;
01420 os << "WaterVaporSaturationInClouds: The water vapor VMR value "
01421 << vmrs(h2o_index[uu],i) << "\n"
01422 << " looks strange after setting it to the saturation pressure over liquid water.";
01423 throw runtime_error(os.str());
01424 return;
01425 }
01426 }
01427 }
01428 }
01429 }
01430
01431
01432
01433
01434 if ( (ice_index >= 0) && (ice_index < tgs.nelem()) )
01435 {
01436 for (Index uu=0; uu<u; ++uu)
01437 {
01438 for (Index i=0; i<vmrs.ncols() ; ++i)
01439 {
01440 if (vmrs(ice_index,i) > 0.000)
01441 {
01442
01443 Numeric p_dry = p_abs[i] * ( 1.000e0 - vmrs(h2o_index[uu],i) );
01444
01445 Numeric e_s = WVSatPressureIce( t_abs[i] );
01446
01447 p_abs[i] = e_s + p_dry;
01448
01449 vmrs(h2o_index[uu],i) = e_s / p_abs[i];
01450
01451 if ( (vmrs(h2o_index[uu],i) < 0.000e0) || (vmrs(h2o_index[uu],i) > 1.000e0) )
01452 {
01453 ostringstream os;
01454 os << "WaterVaporSaturationInClouds: The water vapor VMR value "
01455 << vmrs(h2o_index[uu],i) << "\n"
01456 << " looks strange after setting it to the saturation pressure over ice.";
01457 throw runtime_error(os.str());
01458 return;
01459 }
01460 }
01461 }
01462 }
01463 }
01464
01465 return;
01466 }
01467
01468
01469
01482 void AtmFromRaw(
01483 Vector& t_abs,
01484 Vector& z_abs,
01485 Matrix& vmrs,
01486
01487 const TagGroups& tgs,
01488 const Vector& p_abs,
01489 const Matrix& raw_ptz,
01490 const ArrayOfMatrix& raw_vmrs)
01491 {
01492
01493
01494 {
01495
01496 if ( 3 != raw_ptz.ncols() )
01497 {
01498 ostringstream os;
01499 os << "The variable raw_ptz does not have the right dimensions,\n"
01500 << "ncols() should be 3, but is actually "<< raw_ptz.ncols();
01501 throw runtime_error(os.str());
01502 }
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513 Matrix tz_intp( 2, p_abs.nelem() );
01514
01515 interpp( tz_intp,
01516 raw_ptz(Range(joker),0),
01517 transpose(raw_ptz(Range(joker),Range(1,joker))),
01518 p_abs );
01519
01520
01521
01522
01523
01524
01525
01526 t_abs.resize( tz_intp.ncols() );
01527 t_abs = tz_intp(0,Range(joker));
01528
01529
01530
01531
01532 z_abs.resize( tz_intp.ncols() );
01533 z_abs = tz_intp(1,Range(joker));
01534
01535
01536 }
01537
01538
01539 {
01540
01541 assert ( tgs.nelem() == raw_vmrs.nelem() );
01542
01543
01544 vmrs.resize( raw_vmrs.nelem(), p_abs.nelem() );
01545
01546
01547 for ( Index j=0; j<raw_vmrs.nelem(); ++j )
01548 {
01549
01550
01551 const Matrix& raw = raw_vmrs[j];
01552
01553
01554
01555
01556
01557 if ( 2 != raw.ncols() )
01558 {
01559 ostringstream os;
01560 os << "The variable raw_vmrs("
01561 << j
01562 << ") does not have the right dimensions,\n"
01563 << "ncols() should be 2, but is actually "<< raw.ncols();
01564 throw runtime_error(os.str());
01565 }
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581 interpp( vmrs(j,Range(joker)),
01582 raw(Range(joker),0),
01583 raw(Range(joker),1),
01584 p_abs );
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596 }
01597 }
01598 }
01599
01600
01607 void hseSet(
01608 Vector& hse,
01609 const Numeric& pref,
01610 const Numeric& zref,
01611 const Numeric& g0,
01612 const Index& niter )
01613 {
01614 hse.resize( 5 );
01615
01616 hse[0] = 1;
01617 hse[1] = pref;
01618 hse[2] = zref;
01619 hse[3] = g0;
01620 hse[4] = Numeric( niter );
01621 }
01622
01629 void hseSetFromLatitude(
01630 Vector& hse,
01631 const Numeric& pref,
01632 const Numeric& zref,
01633 const Numeric& latitude,
01634 const Index& niter )
01635 {
01636
01637 hse.resize( 5 );
01638
01639 hse[0] = 1;
01640 hse[1] = pref;
01641 hse[2] = zref;
01642 hse[3] = g_of_lat(latitude);
01643 hse[4] = Numeric( niter );
01644 }
01645
01652 void hseSetFromLatitudeIndex(
01653 Vector& hse,
01654 const Vector& p_abs,
01655 const Vector& z_abs,
01656 const Numeric& latitude,
01657 const Index& index,
01658 const Index& niter )
01659 {
01660
01661
01662 check_if_in_range( 0, p_abs.nelem()-1, index, "index" );
01663
01664 hse.resize( 5 );
01665
01666 hse[0] = 1;
01667 hse[1] = p_abs[index];
01668 hse[2] = z_abs[index];
01669 hse[3] = g_of_lat(latitude);
01670 hse[4] = Numeric( niter );
01671 }
01672
01673
01680 void hseFromBottom(
01681 Vector& hse,
01682 const Vector& p_abs,
01683 const Vector& z_abs,
01684 const Numeric& g0,
01685 const Index& niter )
01686 {
01687 hseSet( hse, p_abs[0], z_abs[0], g0, niter );
01688 }
01689
01690
01691
01698 void hseOff(
01699 Vector& hse )
01700 {
01701 hse.resize( 1 );
01702 hse[0] = 0;
01703 }
01704
01705
01706
01707
01708
01709
01716 void hseCalc(
01717 Vector& z_abs,
01718 const Vector& p_abs,
01719 const Vector& t_abs,
01720 const Vector& h2o_abs,
01721 const Numeric& r_geoid,
01722 const Vector& hse )
01723 {
01724 check_if_bool( static_cast<Index>(hse[0]),
01725 "the HSE flag (first element of hse)");
01726
01727 if ( hse[0] )
01728 {
01729 if ( hse.nelem() != 5 )
01730 throw runtime_error("The length of the *hse* vector must be 5.");
01731
01732 const Index np = p_abs.nelem();
01733 Index i;
01734 Numeric g;
01735 Numeric r;
01736 Numeric tv;
01737 Numeric dz;
01738 Vector ztmp(np);
01739
01740
01741 const Numeric pref = hse[1];
01742 const Numeric zref = hse[2];
01743 const Numeric g0 = hse[3];
01744 const Index niter = Index( hse[4] );
01745
01746 check_lengths( z_abs, "z_abs", t_abs, "t_abs" );
01747 check_lengths( z_abs, "z_abs", h2o_abs, "h2o_abs" );
01748 if ( niter < 1 )
01749 throw runtime_error("The number of iterations must be > 0.");
01750
01751 for ( Index iter=0; iter<niter; iter++ )
01752 {
01753
01754 ztmp[0] = z_abs[0];
01755
01756
01757 for ( i=0; i<np-1; i++ )
01758 {
01759
01760 g = ( g_of_z(r_geoid,g0,z_abs[i]) +
01761 g_of_z(r_geoid,g0,z_abs[i+1]) ) / 2.0;
01762
01763
01764
01765 r = 18/28.96 * (h2o_abs[i]+h2o_abs[i+1])/2;
01766
01767
01768 tv = (1+0.61*r) * (t_abs[i]+t_abs[i+1])/2;
01769
01770
01771 dz = 287.053*tv/g * log( p_abs[i]/p_abs[i+1] );
01772 ztmp[i+1] = ztmp[i] + dz;
01773 }
01774
01775
01776 dz = interpp( p_abs, ztmp, pref ) - zref;
01777
01778
01779 z_abs = ztmp;
01780 z_abs -= dz;
01781 }
01782 }
01783 }
01784
01785
01792 void h2o_absSet(
01793 Vector& h2o_abs,
01794 const TagGroups& tgs,
01795 const Matrix& vmrs )
01796 {
01797 const Index n = tgs.nelem();
01798 Index found = -1;
01799 String s;
01800
01801 for( Index i=0; i<n && found<0; i++ )
01802 {
01803 s = tgs[i][0].Name();
01804
01805 if ( s.substr(0,4) == "H2O-" )
01806 found = i;
01807 }
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824 h2o_abs.resize( vmrs.ncols() );
01825 if ( found >= 0 )
01826 {
01827 h2o_abs = vmrs(found,Range(joker));
01828 } else {
01829 out2 << " WARNING in h2o_absSet: could not find any H2O tag. So H2O vmr is set to zero!\n";
01830 for( Index i=0; i<h2o_abs.nelem(); i++ ) h2o_abs[i] = 0.0000000000e0;
01831 }
01832
01833
01834
01835
01836 }
01837
01838
01839
01840
01847 void vmrsScale(
01848 Matrix& vmrs,
01849 const TagGroups& tgs,
01850 const ArrayOfString& scaltgs,
01851 const Vector& scalfac)
01852 {
01853 Index itag;
01854 ArrayOfIndex tagindex;
01855
01856 if ( scalfac.nelem() != scaltgs.nelem() )
01857 throw runtime_error("vmrScale: Number of tgs and fac are different!");
01858
01859 get_tagindex_for_Strings( tagindex, tgs, scaltgs );
01860
01861 const Index n = tagindex.nelem();
01862
01863 for ( itag=0; itag<n; itag++ )
01864 {
01865
01866 vmrs(tagindex[itag],Range(joker)) *= scalfac[itag];
01867
01868
01869
01870
01871
01872 }
01873 }
01874
01875
01876
01885 void n2_absSet(
01886 Vector& n2_abs,
01887 const TagGroups& tgs,
01888 const Matrix& vmrs )
01889 {
01890 const Index n = tgs.nelem();
01891 Index found = -1;
01892 String s;
01893
01894 for( Index i=0; i<n && found<0; i++ )
01895 {
01896 s = tgs[i][0].Name();
01897
01898 if ( s.substr(0,3) == "N2-" )
01899 found = i;
01900 }
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917 n2_abs.resize( vmrs.ncols() );
01918 if ( found >= 0 )
01919 {
01920 n2_abs = vmrs(found,Range(joker));
01921 } else {
01922 out2 << " WARNING in n2_absSet: could not find any N2 tag. So N2 vmr is set to zero!\n";
01923 for( Index i=0; i<n2_abs.nelem(); i++ ) n2_abs[i] = 0.0000000000e0;
01924 }
01925 }
01926
01927
01955 void absCalc(
01956 Matrix& abs,
01957 ArrayOfMatrix& abs_per_tg,
01958
01959 const TagGroups& tgs,
01960 const Vector& f_mono,
01961 const Vector& p_abs,
01962 const Vector& t_abs,
01963 const Vector& n2_abs,
01964 const Vector& h2o_abs,
01965 const Matrix& vmrs,
01966 const ArrayOfArrayOfLineRecord& lines_per_tg,
01967 const ArrayOfLineshapeSpec& lineshape,
01968 const ArrayOfString& cont_description_names,
01969 const ArrayOfString& cont_description_models,
01970 const ArrayOfVector& cont_description_parameters)
01971 {
01972
01973
01974
01975 ArrayOfMatrix xsec_per_tg;
01976
01977 xsec_per_tgInit( xsec_per_tg, tgs, f_mono, p_abs );
01978
01979 xsec_per_tgAddLines( xsec_per_tg,
01980 tgs,
01981 f_mono,
01982 p_abs,
01983 t_abs,
01984 h2o_abs,
01985 vmrs,
01986 lines_per_tg,
01987 lineshape );
01988
01989 xsec_per_tgAddConts( xsec_per_tg,
01990 tgs,
01991 f_mono,
01992 p_abs,
01993 t_abs,
01994 n2_abs,
01995 h2o_abs,
01996 vmrs,
01997 cont_description_names,
01998 cont_description_parameters,
01999 cont_description_models);
02000
02001 absCalcFromXsec(abs,
02002 abs_per_tg,
02003 xsec_per_tg,
02004 vmrs );
02005
02006 }
02007
02033 void absCalcSaveMemory(
02034 Matrix& abs,
02035
02036 const TagGroups& tgs,
02037 const Vector& f_mono,
02038 const Vector& p_abs,
02039 const Vector& t_abs,
02040 const Vector& n2_abs,
02041 const Vector& h2o_abs,
02042 const Matrix& vmrs,
02043 const ArrayOfArrayOfLineRecord& lines_per_tg,
02044 const ArrayOfLineshapeSpec& lineshape,
02045 const ArrayOfString& cont_description_names,
02046 const ArrayOfString& cont_description_models,
02047 const ArrayOfVector& cont_description_parameters)
02048 {
02049
02050
02051
02052 ArrayOfMatrix xsec_per_tg;
02053
02054
02055 Matrix this_abs;
02056
02057
02058
02059
02060 ArrayOfMatrix this_abs_per_tg;
02061
02062
02063 TagGroups this_tg(1);
02064
02065
02066 Matrix this_vmr(1,p_abs.nelem());
02067
02068
02069 ArrayOfArrayOfLineRecord these_lines(1);
02070
02071
02072 ArrayOfLineshapeSpec this_lineshape(1);
02073
02074
02075 abs.resize( f_mono.nelem(), p_abs.nelem() );
02076 abs = 0;
02077
02078 out2 << " Number of tag groups to do: " << tgs.nelem() << "\n";
02079
02080
02081 for ( Index i=0; i<tgs.nelem(); ++i )
02082 {
02083 out2 << " Doing tag group " << i << ".\n";
02084
02085
02086 this_tg[0].resize(tgs[i].nelem());
02087 this_tg[0] = tgs[i];
02088
02089
02090 this_vmr(0,joker) = vmrs(i,joker);
02091
02092
02093 these_lines[0].resize(lines_per_tg[i].nelem());
02094 these_lines[0] = lines_per_tg[i];
02095
02096
02097 this_lineshape[0] = lineshape[i];
02098
02099 xsec_per_tgInit( xsec_per_tg, this_tg, f_mono, p_abs );
02100
02101 xsec_per_tgAddLines( xsec_per_tg,
02102 this_tg,
02103 f_mono,
02104 p_abs,
02105 t_abs,
02106 h2o_abs,
02107 this_vmr,
02108 these_lines,
02109 this_lineshape );
02110
02111 xsec_per_tgAddConts( xsec_per_tg,
02112 this_tg,
02113 f_mono,
02114 p_abs,
02115 t_abs,
02116 n2_abs,
02117 h2o_abs,
02118 this_vmr,
02119 cont_description_names,
02120 cont_description_parameters,
02121 cont_description_models);
02122
02123 absCalcFromXsec(this_abs,
02124 this_abs_per_tg,
02125 xsec_per_tg,
02126 this_vmr );
02127
02128
02129 assert(abs.nrows()==this_abs.nrows());
02130 assert(abs.ncols()==this_abs.ncols());
02131 abs += this_abs;
02132 }
02133 }
02134
02135
02151 void absCalcFromXsec(
02152 Matrix& abs,
02153 ArrayOfMatrix& abs_per_tg,
02154
02155 const ArrayOfMatrix& xsec_per_tg,
02156 const Matrix& vmrs)
02157 {
02158
02159
02160 if ( vmrs.nrows() != xsec_per_tg.nelem() )
02161 {
02162 ostringstream os;
02163 os << "Variable vmrs must have compatible dimension to xsec_per_tg.\n"
02164 << "vmrs.nrows() = " << vmrs.nrows() << '\n'
02165 << "xsec_per_tg.nelem() = " << xsec_per_tg.nelem();
02166 throw runtime_error(os.str());
02167 }
02168
02169
02170
02171
02172 if ( vmrs.ncols() != xsec_per_tg[0].ncols() )
02173 {
02174 ostringstream os;
02175 os << "Variable vmrs must have same numbers of altitudes as xsec_per_tg.\n"
02176 << "vmrs.ncols() = " << vmrs.ncols() << '\n'
02177 << "xsec_per_tg[0].ncols() = " << xsec_per_tg[0].ncols();
02178 throw runtime_error(os.str());
02179 }
02180
02181
02182
02183
02184 abs.resize( xsec_per_tg[0].nrows(), xsec_per_tg[0].ncols() );
02185 abs = 0;
02186
02187 abs_per_tg.resize( xsec_per_tg.nelem() );
02188
02189 out2 << " Computing abs and abs_per_tg from xsec_per_tg.\n";
02190
02191
02192 for ( Index i=0; i<xsec_per_tg.nelem(); ++i )
02193 {
02194 out2 << " Tag group " << i << '\n';
02195
02196
02197 abs_per_tg[i].resize( xsec_per_tg[i].nrows(), xsec_per_tg[i].ncols() );
02198 abs_per_tg[i] = 0;
02199
02200
02201 for ( Index j=0; j<xsec_per_tg[i].ncols(); j++)
02202 {
02203
02204 for ( Index k=0; k<xsec_per_tg[i].nrows(); k++)
02205 {
02206 abs_per_tg[i](k,j) = xsec_per_tg[i](k,j) * vmrs(i,j);
02207 }
02208 }
02209
02210
02211 abs += abs_per_tg[i];
02212
02213 }
02214 }
02215
02216
02230 void xsec_per_tgInit(
02231 ArrayOfMatrix& xsec_per_tg,
02232
02233 const TagGroups& tgs,
02234 const Vector& f_mono,
02235 const Vector& p_abs
02236 )
02237 {
02238
02239
02240 xsec_per_tg.resize( tgs.nelem() );
02241
02242
02243
02244 for ( Index i=0; i<tgs.nelem(); ++i )
02245 {
02246
02247 xsec_per_tg[i].resize( f_mono.nelem(), p_abs.nelem() );
02248 xsec_per_tg[i] = 0;
02249 }
02250
02251 out2 << " Initialized xsec_per_tg.\n"
02252 << " Number of frequencies : " << f_mono.nelem() << "\n"
02253 << " Number of pressure levels : " << p_abs.nelem() << "\n";
02254 }
02255
02273 void xsec_per_tgAddLines(
02274 ArrayOfMatrix& xsec_per_tg,
02275
02276 const TagGroups& tgs,
02277 const Vector& f_mono,
02278 const Vector& p_abs,
02279 const Vector& t_abs,
02280 const Vector& h2o_abs,
02281 const Matrix& vmrs,
02282 const ArrayOfArrayOfLineRecord& lines_per_tg,
02283 const ArrayOfLineshapeSpec& lineshape)
02284 {
02285
02286
02287 {
02288 const Index n_tgs = tgs.nelem();
02289 const Index n_xsec = xsec_per_tg.nelem();
02290 const Index n_vmrs = vmrs.nrows();
02291 const Index n_lines = lines_per_tg.nelem();
02292 const Index n_shapes = lineshape.nelem();
02293
02294 if ( n_tgs != n_xsec ||
02295 n_tgs != n_vmrs ||
02296 n_tgs != n_lines ||
02297 n_tgs != n_shapes )
02298 {
02299 ostringstream os;
02300 os << "The following variables must all have the same dimension:\n"
02301 << "tgs: " << tgs.nelem() << '\n'
02302 << "xsec_per_tg: " << xsec_per_tg.nelem() << '\n'
02303 << "vmrs: " << vmrs.nrows() << '\n'
02304 << "lines_per_tg: " << lines_per_tg.nelem() << '\n'
02305 << "lineshape: " << lineshape.nelem();
02306 throw runtime_error(os.str());
02307 }
02308 }
02309
02310
02311
02312 out2 << " Calculating line spectra.\n";
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347 for ( Index i=0; i<tgs.nelem(); ++i )
02348 {
02349 out2 << " Tag group " << i
02350 << " (" << get_tag_group_name(tgs[i]) << "): ";
02351
02352
02353
02354
02355 const ArrayOfLineRecord& ll = lines_per_tg[i];
02356
02357
02358 const LineshapeSpec& ls = lineshape[i];
02359
02360
02361 if ( 0 < ll.nelem() )
02362 {
02363
02364
02365
02366
02367
02368
02369 extern const Array<SpeciesRecord> species_data;
02370 String species_name = species_data[ll[0].Species()].Name();
02371
02372
02373
02374
02375
02376
02377 extern const Array<LineshapeRecord> lineshape_data;
02378 String lineshape_name = lineshape_data[ls.Ind_ls()].Name();
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390 if ( "O2" == species_name )
02391 {
02392
02393
02394 if ( 0 != ll[0].Naux() )
02395 {
02396
02397
02398 if ( "Rosenkranz_Voigt_Drayson" != lineshape_name &&
02399 "Rosenkranz_Voigt_Kuntz6" != lineshape_name )
02400 {
02401 ostringstream os;
02402 os
02403 << "You are using a line catalogue that contains auxiliary parameters to\n"
02404 << "take care of overlap for oxygen lines. But you are not using a\n"
02405 << "lineshape that uses these parameters. Use Rosenkranz_Voigt_Drayson or\n"
02406 << "Rosenkranz_Voigt_Kuntz6.";
02407 throw runtime_error(os.str());
02408 }
02409 }
02410 }
02411
02412
02413
02414 if ( "Rosenkranz_Voigt_Drayson" == lineshape_name ||
02415 "Rosenkranz_Voigt_Kuntz6" == lineshape_name )
02416 {
02417
02418 if ( "O2" != species_name )
02419 {
02420 ostringstream os;
02421 os
02422 << "You are trying to use one of the special Rosenkranz lineshapes with\n"
02423 << "overlap correction for a species other than oxygen. Your species is\n"
02424 << species_name << ".\n"
02425 << "Select another lineshape for this species.";
02426 throw runtime_error(os.str());
02427 }
02428 else
02429 {
02430
02431
02432 if ( 0 == ll[0].Naux() )
02433 {
02434 ostringstream os;
02435 os
02436 << "You are trying to use one of the special Rosenkranz lineshapes with\n"
02437 << "overlap correction. But your line file does not contain aux\n"
02438 << "parameters. (I've checked only the first LineRecord). Use a line file\n"
02439 << "with overlap parameters.";
02440 throw runtime_error(os.str());
02441 }
02442 }
02443 }
02444
02445 out2 << ll.nelem() << " transitions\n";
02446 xsec_species( xsec_per_tg[i],
02447 f_mono,
02448 p_abs,
02449 t_abs,
02450 h2o_abs,
02451 vmrs(i,Range(joker)),
02452 ll,
02453 ls.Ind_ls(),
02454 ls.Ind_lsn(),
02455 ls.Cutoff());
02456
02457
02458
02459 }
02460 else
02461 {
02462 out2 << ll.nelem() << " transitions, skipping\n";
02463 }
02464 }
02465 }
02466
02490 void xsec_per_tgAddConts(
02491 ArrayOfMatrix& xsec_per_tg,
02492
02493 const TagGroups& tgs,
02494 const Vector& f_mono,
02495 const Vector& p_abs,
02496 const Vector& t_abs,
02497 const Vector& n2_abs,
02498 const Vector& h2o_abs,
02499 const Matrix& vmrs,
02500 const ArrayOfString& cont_description_names,
02501 const ArrayOfVector& cont_description_parameters,
02502 const ArrayOfString& cont_description_models )
02503 {
02504
02505
02506 {
02507 const Index n_tgs = tgs.nelem();
02508 const Index n_xsec = xsec_per_tg.nelem();
02509 const Index n_vmrs = vmrs.nrows();
02510
02511 if ( n_tgs != n_xsec || n_tgs != n_vmrs )
02512 {
02513 ostringstream os;
02514 os << "The following variables must all have the same dimension:\n"
02515 << "tgs: " << tgs.nelem() << '\n'
02516 << "xsec_per_tg: " << xsec_per_tg.nelem() << '\n'
02517 << "vmrs: " << vmrs.nrows();
02518 throw runtime_error(os.str());
02519 }
02520 }
02521
02522
02523
02524 if ( cont_description_names.nelem() !=
02525 cont_description_parameters.nelem() )
02526 {
02527 for (Index i=0; i < cont_description_names.nelem(); ++i)
02528 {
02529 cout << "xsec_per_tgAddConts: " << i << " name : " << cont_description_names[i] << "\n";
02530 }
02531 for (Index i=0; i < cont_description_parameters.nelem(); ++i)
02532 {
02533 cout << "xsec_per_tgAddConts: " << i << " param: " << cont_description_parameters[i] << "\n";
02534 }
02535 for (Index i=0; i < cont_description_models.nelem(); ++i)
02536 {
02537 cout << "xsec_per_tgAddConts: " << i << " option: " << cont_description_models[i] << "\n";
02538 }
02539 ostringstream os;
02540 os << "The following variables must have the same dimension:\n"
02541 << "cont_description_names: " << cont_description_names.nelem() << '\n'
02542 << "cont_description_parameters: " << cont_description_parameters.nelem();
02543 throw runtime_error(os.str());
02544 }
02545
02546
02547 for ( Index i=0; i<cont_description_names.nelem(); ++i )
02548 {
02549 check_continuum_model(cont_description_names[i]);
02550 }
02551
02552 out2 << " Calculating continuum spectra.\n";
02553
02554
02555 for ( Index i=0; i<tgs.nelem(); ++i )
02556 {
02557 extern const Array<SpeciesRecord> species_data;
02558
02559
02560
02561 for ( Index s=0; s<tgs[i].nelem(); ++s )
02562 {
02563
02564
02565
02566
02567
02568 if ( tgs[i][s].Isotope() <
02569 species_data[tgs[i][s].Species()].Isotope().nelem() )
02570 {
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593 if ( 0 >
02594 species_data[tgs[i][s].Species()].Isotope()[tgs[i][s].Isotope()].Abundance() )
02595 {
02596
02597
02598
02599
02600 const String name =
02601 species_data[tgs[i][s].Species()].Name() + "-"
02602 + species_data[tgs[i][s].Species()].Isotope()[tgs[i][s].Isotope()].Name();
02603
02604
02605
02606 check_continuum_model(name);
02607
02608
02609
02610
02611 const Index n =
02612 find( cont_description_names.begin(),
02613 cont_description_names.end(),
02614 name ) - cont_description_names.begin();
02615
02616
02617
02618 if ( n==cont_description_names.nelem() )
02619 {
02620 ostringstream os;
02621 os << "Cannot find model " << name
02622 << " in cont_description_names.";
02623 throw runtime_error(os.str());
02624 }
02625
02626
02627
02628
02629 out2 << " Adding " << name
02630 << " to tag group " << i << ".\n";
02631
02632
02633
02634 const String ContOption = cont_description_models[n];
02635
02636
02637
02638
02639
02640
02641 xsec_continuum_tag( xsec_per_tg[i],
02642 name,
02643 cont_description_parameters[n],
02644 cont_description_models[n],
02645 f_mono,
02646 p_abs,
02647 t_abs,
02648 n2_abs,
02649 h2o_abs,
02650 vmrs(i,Range(joker)) );
02651
02652
02653 }
02654 }
02655 }
02656 }
02657
02658 }
02659
02668 void abs_per_tgReduce(
02669 ArrayOfMatrix& abs_per_tg,
02670
02671 const TagGroups& tgs,
02672 const TagGroups& wfs_tgs)
02673 {
02674
02675
02676
02677
02678 if ( abs_per_tg.nelem()!=tgs.nelem() )
02679 throw(runtime_error("The variables abs_per_tg and tgs must\n"
02680 "have the same dimension."));
02681
02682
02683
02684
02685
02686 ArrayOfMatrix abs_per_tg_out( wfs_tgs.nelem() );
02687
02688
02689 for ( Index i=0; i<wfs_tgs.nelem(); ++i )
02690 {
02691
02692 Index n;
02693 get_tag_group_index_for_tag_group( n, tgs, wfs_tgs[i] );
02694
02695 abs_per_tg_out[i].resize( abs_per_tg[n].nrows(), abs_per_tg[n].ncols() );
02696 abs_per_tg_out[i] = abs_per_tg[n];
02697
02698
02699 }
02700
02701
02702 abs_per_tg.resize( wfs_tgs.nelem() );
02703 abs_per_tg = abs_per_tg_out;
02704
02705
02706 }
02707
02708
02709
02710
02711
02712
02713
02720 void refrSet(
02721 Index& refr,
02722 Index& refr_lfac,
02723 String& refr_model,
02724 const Index& on,
02725 const String& model,
02726 const Index& lfac )
02727 {
02728 check_if_bool( on, "on" );
02729 if ( lfac < 1 )
02730 throw runtime_error("The length factor cannot be smaller than 1.");
02731
02732 refr = on;
02733 refr_lfac = lfac;
02734 refr_model = model;
02735 }
02736
02737
02738
02745 void refrOff(
02746 Index& refr,
02747 Index& refr_lfac,
02748 String& refr_model )
02749 {
02750 refrSet( refr, refr_lfac, refr_model, 0, "", 1 );
02751 refr_lfac = 0;
02752 }
02753
02754
02755
02762 void refrCalc (
02763 Vector& refr_index,
02764 const Vector& p_abs,
02765 const Vector& t_abs,
02766 const Vector& h2o_abs,
02767 const Index& refr,
02768 const String& refr_model )
02769 {
02770 check_if_bool( refr, "refr" );
02771
02772 if ( refr == 0 )
02773 refr_index.resize( 0 );
02774
02775 else
02776 {
02777 if ( refr_model == "Unity" )
02778 {
02779 const Index n = p_abs.nelem();
02780 refr_index.resize( n );
02781 refr_index = 1.0;
02782 }
02783
02784 else if ( refr_model == "Boudouris" )
02785 refr_index_Boudouris( refr_index, p_abs, t_abs, h2o_abs );
02786
02787 else if ( refr_model == "BoudourisDryAir" )
02788 refr_index_BoudourisDryAir( refr_index, p_abs, t_abs );
02789
02790 else
02791 {
02792 ostringstream os;
02793 os << "Unknown refraction parameterization: " << refr_model << "\n"
02794 << "Existing parameterizations are: \n"
02795 << "Unity\n"
02796 << "Boudouris\n"
02797 << "BoudourisDryAir";
02798 throw runtime_error(os.str());
02799 }
02800 }
02801 }
02802
02803
02804
02805
02806
02807
02808
02809
02826 void cont_descriptionInit(
02827 ArrayOfString& names,
02828 ArrayOfString& options,
02829 ArrayOfVector& parameters)
02830 {
02831 names.resize(0);
02832 options.resize(0);
02833 parameters.resize(0);
02834 out2 << " Initialized cont_description_names \n"
02835 " cont_description_models\n"
02836 " cont_description_parameters.\n";
02837 }
02838
02839
02850 void cont_descriptionAppend(
02851 ArrayOfString& cont_description_names,
02852 ArrayOfString& cont_description_models,
02853 ArrayOfVector& cont_description_parameters,
02854
02855 const String& tagname,
02856 const String& model,
02857 const Vector& userparameters)
02858 {
02859
02860 check_continuum_model(tagname);
02861
02862
02863
02864
02865
02866
02867 cont_description_names.push_back(tagname);
02868 cont_description_models.push_back(model);
02869 cont_description_parameters.push_back(userparameters);
02870 }