58 assert( n_new_grid == pos.
nelem() );
68 for (
Index i=0; i<n_new_grid; ++i )
74 while (
abs(new_grid[i]-old_grid[j]) > tolerance )
80 os <<
"Cannot find new frequency " << i
81 <<
" (" << new_grid[i] <<
"Hz) in the lookup table frequency grid.";
82 throw runtime_error( os.str() );
87 out3 <<
" " << new_grid[i] <<
" found, index = " << pos[i] <<
".\n";
132 const Index n_current_species = current_species.
nelem();
133 const Index n_current_f_grid = current_f_grid.
nelem();
141 out2 <<
" Original table: " << n_species <<
" species, "
142 << n_f_grid <<
" frequencies.\n"
143 <<
" Adapt to: " << n_current_species <<
" species, "
144 << n_current_f_grid <<
" frequencies.\n";
148 out2 <<
" Table contains no nonlinear species.\n";
153 for (
Index s=0; s<n_nls; ++s )
160 out2 <<
" Table contains no temperature perturbations.\n";
172 if ( 0 == n_species )
175 os <<
"The lookup table should have at least one species.";
176 throw runtime_error( os.str() );
184 os <<
"The table must not have duplicate nonlinear species.\n"
186 throw runtime_error( os.str() );
190 for (
Index i=0; i<n_nls; ++i )
193 os <<
"nonlinear_species[" << i <<
"]";
225 if ( 0 == n_nls_pert )
228 os <<
"The vector nls_pert should contain the perturbations\n"
229 <<
"for the nonlinear species, but it is empty.";
230 throw runtime_error( os.str() );
282 + n_nls * ( n_nls_pert - 1 );
293 for (
Index i=0,sp=0; i<n_species; ++i)
295 original_spec_pos_in_xsec[i] = sp;
296 if (non_linear[i]) sp += n_nls_pert;
305 if ( 0==n_current_species )
308 os <<
"The list of current species should not be empty.";
309 throw runtime_error( os.str() );
320 out3 <<
" Looking for species in lookup table:\n";
321 for (
Index i=0; i<n_current_species; ++i )
326 i_current_species[i] =
332 const Index spec_type = current_species[i][0].Type();
338 i_current_species[i] = -1;
344 <<
" is missing in absorption lookup table.";
345 throw runtime_error( os.str() );
349 out3 <<
"found (or trivial).\n";
353 Index n_current_nonlinear_species = 0;
359 out3 <<
" Finding out which of the current species are nonlinear:\n";
360 for (
Index i=0; i<n_current_species; ++i )
362 if (i_current_species[i]>=0)
365 if (non_linear[i_current_species[i]])
369 current_non_linear[i] = 1;
370 ++n_current_nonlinear_species;
383 out3 <<
" Looking for Frequencies in lookup table:\n";
398 new_table.
species.resize( n_current_species );
399 for (
Index i=0; i<n_current_species; ++i )
401 if (i_current_species[i]>=0)
406 if (current_non_linear[i])
414 new_table.
species[i] = current_species[i];
420 for (
Index i=0; i<n_current_f_grid; ++i )
432 for (
Index i=0; i<n_current_species; ++i )
434 if (i_current_species[i]>=0)
465 n_current_species+n_current_nonlinear_species*(n_nls_pert-1),
474 for (
Index i_s=0,sp=0; i_s<n_current_species; ++i_s )
478 if (current_non_linear[i_s])
487 for (
Index i_f=0; i_f<n_current_f_grid; ++i_f )
489 if (i_current_species[i_s]>=0)
497 Range(original_spec_pos_in_xsec[i_current_species[i_s]],n_v),
498 i_current_f_grid[i_f],
594 const Index& p_interp_order,
595 const Index& t_interp_order,
596 const Index& h2o_interp_order,
597 const Index& f_interp_order,
602 const Numeric& extpolfac)
const
626 const Index n_new_f_grid = new_f_grid.
nelem();
637 Index h2o_index = -1;
647 if ( h2o_index == -1 )
650 os <<
"With nonlinear species, at least one species must be a H2O species.";
651 throw runtime_error( os.str() );
664 if ( 0 == n_t_pert ) a = 1;
666 b = n_species + n_nls * ( n_nls_pert - 1 );
686 os <<
"The lookup table internal variable log_p_grid is not initialized.\n"
687 <<
"Use the abs_lookupAdapt method!";
688 throw runtime_error( os.str() );
697 if ( (n_p_grid < p_interp_order+1) )
700 os <<
"The number of pressure grid points in the table ("
701 << n_p_grid <<
") is not enough for the desired order of interpolation ("
702 << p_interp_order <<
").";
703 throw runtime_error( os.str() );
706 if ( (n_nls_pert != 0) && (n_nls_pert < h2o_interp_order+1) )
709 os <<
"The number of humidity perturbation grid points in the table ("
710 << n_nls_pert <<
") is not enough for the desired order of interpolation ("
711 << h2o_interp_order <<
").";
712 throw runtime_error( os.str() );
715 if ( (n_t_pert != 0) && (n_t_pert < t_interp_order+1) )
718 os <<
"The number of temperature perturbation grid points in the table ("
719 << n_t_pert <<
") is not enough for the desired order of interpolation ("
720 << t_interp_order <<
").";
721 throw runtime_error( os.str() );
724 if ( (n_f_grid < f_interp_order+1) )
727 os <<
"The number of frequency grid points in the table ("
728 << n_f_grid <<
") is not enough for the desired order of interpolation ("
729 << f_interp_order <<
").";
730 throw runtime_error( os.str() );
737 if ( !
is_size( abs_vmrs, n_species ) )
740 os <<
"Number of species in lookup table does not match number\n"
741 <<
"of species for which you want to extract absorption.\n"
742 <<
"Have you used abs_lookupAdapt? Or did you miss to add\n"
743 <<
"some VRM fields (e.g. for free electrons or particles)?\n";
744 throw runtime_error( os.str() );
761 if (f_interp_order==0)
763 if (n_new_f_grid==n_f_grid) {
777 os <<
"First frequency in f_grid inconsistent with lookup table.\n"
778 <<
"f_grid[0] = " <<
f_grid[0] <<
"\n"
779 <<
"new_f_grid[0] = " << new_f_grid[0] <<
".";
780 throw runtime_error( os.str() );
783 if (
abs(
f_grid[n_f_grid-1]-new_f_grid[n_new_f_grid-1]) > 1)
787 os <<
"Last frequency in f_grid inconsistent with lookup table.\n"
788 <<
"f_grid[n_f_grid-1] = " <<
f_grid[n_f_grid-1] <<
"\n"
789 <<
"new_f_grid[n_new_f_grid-1] = " << new_f_grid[n_new_f_grid-1] <<
".";
790 throw runtime_error( os.str() );
793 else if (n_new_f_grid==1) {
799 if (fgp_local[0].
w[0]!=1)
802 os <<
"Cannot find a matching lookup table frequency for frequency\n"
803 << new_f_grid[0] <<
".";
804 throw runtime_error( os.str() );
809 os <<
"With f_interp_order 0 the frequency grid has to have the same\n"
810 <<
"size as in the lookup table, or exactly one element.";
811 throw runtime_error( os.str() );
818 fgp_local.resize(n_new_f_grid);
827 const Index do_T = n_t_pert;
832 for (
Index s=0; s<n_nls; ++s )
850 if ( ( p > p_max ) ||
854 os <<
"Problem with gas absorption lookup table.\n"
855 <<
"Pressure p is outside the range covered by the lookup table.\n"
856 <<
"Your p value is " << p <<
" Pa.\n"
857 <<
"The allowed range is " << p_min <<
" to " << p_max <<
".\n"
858 <<
"The pressure grid range in the table is " <<
p_grid[n_p_grid-1]
859 <<
" to " <<
p_grid[0] <<
".\n"
860 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
861 throw runtime_error( os.str() );
877 pitw.
resize(p_interp_order+1);
886 gp_trivial[0].idx.resize(1);
887 gp_trivial[0].w.resize(1);
888 gp_trivial[0].idx[0] = 0;
889 gp_trivial[0].w[0] = 1;
896 Index this_t_interp_order;
899 this_t_interp_order = t_interp_order;
906 this_t_interp_order = 0;
936 xsec_pre_interpolated.
resize(p_interp_order+1, n_species,
937 1, 1, n_new_f_grid );
942 Tensor4 itw_withH2O, itw_noH2O, *itw;
944 for (
Index pi=0; pi<p_interp_order+1; ++pi )
964 const Index this_p_grid_index = pgp[0].idx[pi];
998 const Numeric effective_T_ref =
t_ref[this_p_grid_index];
1001 const Numeric T_offset = T - effective_T_ref;
1009 if ( ( T_offset > t_max ) ||
1010 ( T_offset < t_min ) )
1013 os <<
"Problem with gas absorption lookup table.\n"
1014 <<
"Temperature T is outside the range covered by the lookup table.\n"
1015 <<
"Your temperature was " << T
1016 <<
" K at a pressure of " << p <<
" Pa.\n"
1017 <<
"The temperature offset value is " << T_offset <<
".\n"
1018 <<
"The allowed range is " << t_min <<
" to " << t_max <<
".\n"
1019 <<
"The temperature perturbation grid range in the table is "
1021 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
1022 throw runtime_error( os.str() );
1053 const Numeric effective_vmr_ref =
vmrs_ref(h2o_index, this_p_grid_index);
1057 const Numeric VMR_frac = abs_vmrs[h2o_index] / effective_vmr_ref;
1066 if ( ( VMR_frac > x_max ) ||
1067 ( VMR_frac < x_min ) )
1070 os <<
"Problem with gas absorption lookup table.\n"
1071 <<
"VMR for H2O (species " << h2o_index
1072 <<
") is outside the range covered by the lookup table.\n"
1073 <<
"Your VMR was " << abs_vmrs[h2o_index]
1074 <<
" at a pressure of " << p <<
" Pa.\n"
1075 <<
"The reference VMR value there is " << effective_vmr_ref <<
"\n"
1076 <<
"The fractional VMR relative to the reference value is "
1077 << VMR_frac <<
".\n"
1078 <<
"The allowed range is " << x_min <<
" to " << x_max <<
".\n"
1079 <<
"The fractional VMR perturbation grid range in the table is "
1081 <<
"We allow a bit of extrapolation, but NOT SO MUCH!";
1082 throw runtime_error( os.str() );
1092 if (n_nls<n_species) {
1096 itw_noH2O.
resize(1, 1, n_new_f_grid,
1097 (this_t_interp_order+1)*
1099 (f_interp_order+1));
1105 itw_withH2O.
resize(1, 1, n_new_f_grid,
1106 (this_t_interp_order+1)*
1107 (h2o_interp_order+1)*
1108 (f_interp_order+1));
1114 for (
Index si=0; si<n_species; ++si )
1118 const Index do_VMR = non_linear[si];
1137 os <<
"Problem with gas absorption lookup table.\n"
1138 <<
"VMR interpolation is not allowed for species \""
1139 <<
species[si][0].Name() <<
"\"";
1140 throw runtime_error(os.str());
1148 Index this_h2o_extent;
1151 this_h2o_extent = n_nls_pert;
1155 this_h2o_extent = 1;
1162 Range(fpi,this_h2o_extent),
1164 this_p_grid_index );
1194 sga.
resize(n_species, n_new_f_grid);
1196 for (
Index pi=0; pi<p_interp_order+1; ++pi )
1205 xsec_pre_interpolated(pi,
1213 sga += xsec_pre_interpolated(pi,
Range(
joker),
1221 for (
Index si=0; si<n_species; ++si )
1222 sga(si,
Range(
joker)) *= ( n * abs_vmrs[si] );
1244 os <<
"GasAbsLookup: Output operator not implemented";