138 const Index& atmosphere_dim,
145 if (1!=atmosphere_dim)
148 os <<
"Atmospheric dimension must be one.";
149 throw runtime_error( os.str() );
158 if (field_names.
nelem()!=nf)
161 os <<
"Cannot extract fields from Matrix.\n"
162 <<
"*field_names* must have one element less than there are\n"
163 <<
"matrix columns.";
164 throw runtime_error( os.str() );
172 for(
Index f = 0; f < field_names.
nelem(); f++)
174 fn_upper = field_names[f];
175 std::transform ( fn_upper.begin(), fn_upper.end(), fn_upper.begin(), ::toupper);
176 if(fn_upper !=
"IGNORE") nf_1++;
181 for (
Index f=0; f< nf_1; f++) field_names_1[f] = field_names[f];
203 const Index& atmosphere_dim,
214 if (1!=atmosphere_dim)
217 os <<
"Atmospheric dimension must be one.";
218 throw runtime_error( os.str() );
229 if (field_names.
nelem()!= nf)
232 os <<
"Cannot extract fields from Matrix.\n"
233 <<
"*field_names* must have one element less than there are\n"
234 <<
"matrix columns.";
235 throw runtime_error( os.str() );
246 for(
Index f = 0; f < field_names.
nelem(); f++)
248 fn_upper = field_names[f];
249 std::transform ( fn_upper.begin(), fn_upper.end(), fn_upper.begin(), ::toupper);
250 if(fn_upper !=
"IGNORE" ) nf_1++;
255 if ( fn_upper !=
"IGNORE" && field_names[f] !=
"LWC" && field_names[f] !=
"IWC" &&
256 field_names[f] !=
"Rain" && field_names[f] !=
"Snow" )
269 for (
Index f=0; f< nf_1; f++) field_names_1[f] = field_names[f];
283 af_all.
resize(nf_1,np,1,1);
291 for (
Index i=0; i<nf_2; i++ ) field_names_2[i] = field_names[intarr[i]] ;
300 af_vmr.
resize ( nf_2,np,1,1 );
301 for (
Index i=0; i<nf_2; i++ )
360 p2gridpos(p_gridpos, sp_p_grid, af_p_grid);
362 if (sp_lat_grid.
nelem() > 1)
369 gridpos(lat_gridpos, sp_lat_grid, af_lat_grid);
371 if (sp_lon_grid.
nelem() > 1)
377 gridpos(lon_gridpos, sp_lon_grid, af_lon_grid);
383 interp(newfield, itw, species.
data, p_gridpos, lat_gridpos, lon_gridpos);
394 atm_fields_compact.
data(new_n_fields-1,
joker,
joker, 0) = newfield;
403 atm_fields_compact.
data(new_n_fields-1,
joker, 0, 0) = newfield;
412 Index& basics_checked,
413 const Index& atmosphere_dim,
426 const Index& stokes_dim,
434 p_grid, lat_grid, lon_grid );
436 p_grid, lat_grid, lon_grid );
438 if( abs_species.
nelem() )
440 p_grid, lat_grid, lon_grid );
441 chk_atm_surface(
"r_geoid", r_geoid, atmosphere_dim, lat_grid, lon_grid );
442 chk_atm_surface(
"z_surface", z_surface, atmosphere_dim, lat_grid, lon_grid );
445 for(
Index row=0; row<z_field.
nrows(); row++ )
447 for(
Index col=0; col<z_field.
ncols(); col++ )
450 os <<
"z_field (for latitude nr " << row <<
" and longitude nr "
460 for(
Index row=0; row<z_surface.
nrows(); row++ )
462 for(
Index col=0; col<z_surface.
ncols(); col++ )
464 if( z_surface(row,col)<z_field(0,row,col) ||
465 z_surface(row,col)>=z_field(z_field.
npages()-1,row,col) )
468 os <<
"The surface altitude (*z_surface*) cannot be outside "
469 <<
"of the altitudes in *z_field*.";
470 if( atmosphere_dim > 1 )
471 os <<
"\nThis was found to be the case for:\n"
472 <<
"latitude " << lat_grid[row];
473 if( atmosphere_dim > 2 )
474 os <<
"\nlongitude " << lon_grid[col];
475 throw runtime_error( os.str() );
481 if( wind_w_field.
npages() > 0 )
484 p_grid, lat_grid, lon_grid );
486 if( wind_v_field.
npages() > 0 )
489 p_grid, lat_grid, lon_grid );
491 if( atmosphere_dim > 2 && wind_u_field.
npages() > 0 )
494 p_grid, lat_grid, lon_grid );
499 if ( f_grid.
nelem() == 0 )
500 {
throw runtime_error (
"The frequency grid is empty." ); }
503 if (
min(f_grid) <= 0) {
504 throw runtime_error(
"All frequencies in *f_grid* must be > 0.");
523 for (
Index i=0; i<batch_atm_fields_compact.
nelem(); i++)
539 const Index nelem = batch_atm_fields_compact.
nelem();
543 #pragma omp parallel for if(!arts_omp_in_parallel())
544 for (
Index i=0; i<nelem; i++)
554 const Index& atmosphere_dim,
560 const Vector& extra_field_values,
570 if (extra_field_names.
nelem() != extra_field_values.
nelem())
573 os <<
"The keyword arguments extra_field_names and\n"
574 <<
"extra_field_values must have matching dimensions.";
575 throw runtime_error( os.str() );
579 batch_atm_fields_compact.resize(amnelem);
587 #pragma omp parallel for \
588 if(!arts_omp_in_parallel())
589 for (
Index i=0; i<amnelem; ++i)
606 for (
Index j=0; j<extra_field_names.
nelem(); ++j)
608 extra_field_names[j],
609 extra_field_values[j],
612 catch (runtime_error e)
627 const Index& atmosphere_dim,
633 const Vector& extra_field_values,
643 if (extra_field_names.
nelem() != extra_field_values.
nelem())
646 os <<
"The keyword arguments extra_field_names and\n"
647 <<
"extra_field_values must have matching dimensions.";
648 throw runtime_error( os.str() );
652 batch_atm_fields_compact.resize(amnelem);
653 batch_atm_fields_compact_all.resize(amnelem);
660 #pragma omp parallel for \
661 if(!arts_omp_in_parallel())
662 for (
Index i=0; i<amnelem; ++i)
674 batch_atm_fields_compact[i],
681 for (
Index j=0; j<extra_field_names.
nelem(); ++j){
683 extra_field_names[j],
684 extra_field_values[j],
688 extra_field_names[j],
689 extra_field_values[j],
693 catch (runtime_error e)
715 const Index& atmosphere_dim,
749 os <<
"There must be at least three fields in *atm_fields_compact*.\n"
750 <<
"T, z, and at least one VMR.";
751 throw runtime_error( os.str() );
758 os <<
"The first field must be \"T\", but it is:"
760 throw runtime_error( os.str() );
767 os <<
"The second field must be \"z\"*, but it is:"
769 throw runtime_error( os.str() );
776 os <<
"The third field must be \"LWC\"*, but it is:"
778 throw runtime_error( os.str() );
785 os <<
"The fourth field must be \"IWC\"*, but it is:"
787 throw runtime_error( os.str() );
794 os <<
"The fifth field must be \"Rain\"*, but it is:"
796 throw runtime_error( os.str() );
803 os <<
"The sixth field must be \"IWC\"*, but it is:"
805 throw runtime_error( os.str() );
818 if (tf_species != as_species)
821 os <<
"Field name not valid: "
822 << tf_species <<
"\n"
823 <<
"Based on *abs_species*, the field name should be: "
825 throw runtime_error( os.str() );
830 t_field.
resize(np,nlat,nlon);
834 z_field.
resize(np,nlat,nlon);
838 massdensity_field.
resize(4,np,nlat,nlon);
860 const Index& atmosphere_dim,
893 os <<
"There must be at least three fields in *atm_fields_compact*.\n"
894 <<
"T, z, and at least one VMR.";
895 throw runtime_error( os.str() );
902 os <<
"The first field must be \"T\", but it is:"
904 throw runtime_error( os.str() );
911 os <<
"The second field must be \"z\"*, but it is:"
913 throw runtime_error( os.str() );
926 if (tf_species != as_species)
929 os <<
"Field name not valid: "
930 << tf_species <<
"\n"
931 <<
"Based on *abs_species*, the field name should be: "
933 throw runtime_error( os.str() );
938 t_field.
resize(np,nlat,nlon);
942 z_field.
resize(np,nlat,nlon);
953 Index& atmosphere_dim,
961 out2 <<
" Sets the atmospheric dimensionality to 1.\n";
962 out3 <<
" atmosphere_dim = 1\n";
963 out3 <<
" lat_grid is set to be an empty vector\n";
964 out3 <<
" lon_grid is set to be an empty vector\n";
975 Index& atmosphere_dim,
982 out2 <<
" Sets the atmospheric dimensionality to 2.\n";
983 out3 <<
" atmosphere_dim = 2\n";
984 out3 <<
" lon_grid is set to be an empty vector\n";
993 Index& atmosphere_dim,
999 out2 <<
" Sets the atmospheric dimensionality to 3.\n";
1000 out3 <<
" atmosphere_dim = 3\n";
1019 const Index& atmosphere_dim,
1021 const Index& interp_order,
1033 out2 <<
" Interpolation order: " << interp_order <<
"\n";
1039 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
1049 if ( atmosphere_dim == 1)
1051 if( !( tfr_lat_grid.
nelem() == 1 &&
1052 tfr_lon_grid.
nelem() == 1 ))
1053 throw runtime_error(
1054 "Temperature data (T_field) has wrong dimension "
1058 if( !( zfr_lat_grid.
nelem() == 1 &&
1059 zfr_lon_grid.
nelem() == 1 ))
1060 throw runtime_error(
1061 "Altitude data (z_field) has wrong dimension "
1117 for (
Index gas_i = 0; gas_i < vmr_field_raw.
nelem(); gas_i++)
1121 if( !( vmr_field_raw[gas_i].get_numeric_grid(
GFIELD3_LAT_GRID).nelem() == 1 &&
1124 os <<
"VMR data of the " << gas_i <<
"th species has "
1125 <<
"wrong dimension (2D or 3D). \n";
1126 throw runtime_error( os.str() );
1131 os <<
"Raw VMR[" << gas_i <<
"] to p_grid, 1D case";
1148 itw, vmr_field_raw[gas_i].data(
joker, 0, 0), gp_p);
1154 else if(atmosphere_dim == 2)
1156 if( tfr_lat_grid.
nelem() == 1 &&
1157 tfr_lon_grid.
nelem() == 1 )
1158 throw runtime_error(
1159 "Raw data has wrong dimension (1D). "
1160 "You have to use \n"
1161 "AtmFieldsCalcExpand1D instead of AtmFieldsCalc."
1190 gridpos_poly( gp_lat, tfr_lat_grid, lat_grid, interp_order );
1193 Tensor3 itw(p_grid.
nelem(), lat_grid.
nelem(), (interp_order+1)*(interp_order+1));
1217 gridpos_poly( gp_lat, zfr_lat_grid, lat_grid, interp_order );
1229 for (
Index gas_i = 0; gas_i < vmr_field_raw.
nelem(); gas_i++)
1233 if( !( vmr_field_raw[gas_i].get_numeric_grid(
GFIELD3_LAT_GRID).nelem() != 1 &&
1236 os <<
"VMR data of the " << gas_i <<
"th species has "
1237 <<
"wrong dimension (1D or 3D). \n";
1238 throw runtime_error( os.str() );
1243 os <<
"Raw VMR[" << gas_i <<
"] to p_grid, 2D case";
1249 os <<
"Raw VMR[" << gas_i <<
"] to lat_grid, 2D case";
1257 p_grid, interp_order);
1259 lat_grid, interp_order);
1266 itw, vmr_field_raw[gas_i].data(
joker,
joker, 0),
1273 else if(atmosphere_dim == 3)
1275 if( tfr_lat_grid.
nelem() == 1 &&
1276 tfr_lon_grid.
nelem() == 1 )
1277 throw runtime_error(
1278 "Raw data has wrong dimension. You have to use \n"
1279 "AtmFieldsCalcExpand1D instead of AtmFieldsCalc."
1314 gridpos_poly( gp_lat, tfr_lat_grid, lat_grid, interp_order );
1315 gridpos_poly( gp_lon, tfr_lon_grid, lon_grid, interp_order );
1319 (interp_order+1)*(interp_order+1)*(interp_order+1));
1324 interp( t_field, itw, t_field_raw.
data, gp_p, gp_lat, gp_lon);
1346 gridpos_poly( gp_lat, zfr_lat_grid, lat_grid, interp_order );
1347 gridpos_poly( gp_lon, zfr_lon_grid, lon_grid, interp_order );
1353 interp( z_field, itw, z_field_raw.
data, gp_p, gp_lat, gp_lon);
1358 for (
Index gas_i = 0; gas_i < vmr_field_raw.
nelem(); gas_i++)
1362 if( !( vmr_field_raw[gas_i].get_numeric_grid(
GFIELD3_LAT_GRID).nelem() != 1 &&
1365 os <<
"VMR data of the " << gas_i <<
"th species has "
1366 <<
"wrong dimension (1D or 2D). \n";
1367 throw runtime_error( os.str() );
1372 os <<
"Raw VMR[" << gas_i <<
"] to p_grid, 3D case";
1378 os <<
"Raw VMR[" << gas_i <<
"] to lat_grid, 3D case";
1384 os <<
"Raw VMR[" << gas_i <<
"] to lon_grid, 3D case";
1392 p_grid, interp_order);
1394 lat_grid, interp_order);
1396 lon_grid, interp_order);
1403 itw, vmr_field_raw[gas_i].data, gp_p, gp_lat, gp_lon);
1425 const Index& atmosphere_dim,
1426 const Index& interp_order,
1430 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
1432 if( atmosphere_dim == 1 )
1433 {
throw runtime_error(
1434 "This function is intended for 2D and 3D. For 1D, use *AtmFieldsCalc*.");}
1440 AtmFieldsCalc(t_temp, z_temp, vmr_temp, p_grid, vempty, vempty,
1441 t_field_raw, z_field_raw, vmr_field_raw, 1, interp_order,
1448 if( atmosphere_dim == 2 )
1452 assert( t_temp.
npages() == np );
1454 t_field.
resize( np, nlat, nlon );
1455 z_field.
resize( np, nlat, nlon );
1456 vmr_field.
resize( nspecies, np, nlat, nlon );
1458 for(
Index ilon=0; ilon<nlon; ilon++ )
1460 for(
Index ilat=0; ilat<nlat; ilat++ )
1462 for(
Index ip=0; ip<np; ip++ )
1464 t_field(ip,ilat,ilon) = t_temp(ip,0,0);
1465 z_field(ip,ilat,ilon) = z_temp(ip,0,0);
1466 for(
Index is=0; is<nspecies; is++ )
1467 { vmr_field(is,ip,ilat,ilon) = vmr_temp(is,ip,0,0); }
1481 const Index& atmosphere_dim,
1485 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
1493 if( atmosphere_dim == 1 )
1494 {
throw runtime_error(
"No use in calling this method for 1D.");}
1502 Tensor3 t_temp = t_field, z_temp = z_field;
1506 t_field.
resize( np, nlat, nlon );
1507 z_field.
resize( np, nlat, nlon );
1508 vmr_field.
resize( nspecies, np, nlat, nlon );
1510 for(
Index ilon=0; ilon<nlon; ilon++ )
1512 for(
Index ilat=0; ilat<nlat; ilat++ )
1514 for(
Index ip=0; ip<np; ip++ )
1516 t_field(ip,ilat,ilon) = t_temp(ip,0,0);
1517 z_field(ip,ilat,ilon) = z_temp(ip,0,0);
1518 for(
Index is=0; is<nspecies; is++ )
1519 { vmr_field(is,ip,ilat,ilon) = vmr_temp(is,ip,0,0); }
1536 const Index& atmosphere_dim,
1553 p_grid, lat_grid, lon_grid);
1557 p_grid, lat_grid, lon_grid);
1561 vmr_field.
nbooks(), p_grid, lat_grid, lon_grid);
1567 os <<
"The keyword argument p_step must be >0.";
1568 throw runtime_error( os.str() );
1591 log_abs_p_a.push_back(log_p_grid[0]);
1595 const Numeric dp = log_p_grid[i-1] - log_p_grid[i];
1597 const Numeric dp_by_p_step = dp/p_step;
1610 for (
Index j=1; j<=n; ++j)
1611 log_abs_p_a.push_back(log_p_grid[i-1] - (
Numeric)j*ddp);
1618 log_abs_p[i] = log_abs_p_a[i];
1630 gridpos(gp, log_p_grid, log_abs_p);
1642 if (0 == nlat) nlat = 1;
1643 if (0 == nlon) nlon = 1;
1649 log_abs_p.
nelem(), nlat, nlon);
1651 for (
Index ilat=0; ilat<nlat; ++ilat)
1652 for (
Index ilon=0; ilon<nlon; ++ilon)
1656 t_field(
joker, ilat, ilon),
1661 z_field(
joker, ilat, ilon),
1664 for (
Index ivmr=0; ivmr<vmr_field.
nbooks(); ++ivmr)
1667 vmr_field(ivmr,
joker, ilat, ilon),
1676 vmr_field = abs_vmr;
1695 String file_name = basename +
".t.xml";
1698 out3 <<
"Temperature field read from file: " << file_name <<
"\n";
1701 file_name = basename +
".z.xml";
1704 out3 <<
"Altitude field read from file: " << file_name <<
"\n";
1712 for (
Index i=0; i<abs_species.
nelem(); i ++)
1717 species_data[abs_species[i][0].Species()].Name() +
".xml";
1721 vmr_field_raw.push_back(vmr_field_data);
1727 out3 <<
" " <<
species_data[abs_species[i][0].Species()].Name()
1728 <<
" profile read from file: " << file_name <<
"\n";
1736 const Index& atmosphere_dim,
1747 rte_gp_p, rte_gp_lat, rte_gp_lon );
1749 out3 <<
" Result = " << outvalue <<
"\n";
1761 while ( z_field_raw.
data(i,0,0)< 0.0 ) i++;
1764 p_grid=p_grid_raw[
Range(i,p_grid_raw.
nelem()-1)];
1777 g = g0 * pow( r/(r+z), 2 );
1782 const Index& atmosphere_dim,
1791 const Index& basics_checked,
1793 const Numeric& z_hse_accuracy,
1806 if( !basics_checked )
1807 throw runtime_error(
"The atmosphere must be flagged to have passed a "
1808 "consistency check (basics_checked=1)." );
1810 if( atmosphere_dim == 1 && lat_grid.
nelem() != 1 )
1811 {
throw runtime_error(
1812 "The method requires that, for 1D, *lat_grid* has length 1." );
1816 throw runtime_error(
1817 "Water vapour is a requiered (must be a tag group in *abs_species*)." );
1819 if( p_hse>p_grid[0] || p_hse < p_grid[np-1] )
1822 os <<
"The value of *p_hse* must be inside the range of *p_grid*:"
1823 <<
" p_hse = " << p_hse <<
" Pa\n"
1824 <<
" p_grid = << p_grid[np-1]" <<
" - " << p_grid[0] <<
" Pa\n";
1825 throw runtime_error( os.str() );
1828 if( z_hse_accuracy <= 0 )
1829 {
throw runtime_error(
"The value of *z_hse_accuracy* must be > 0." ); }
1842 for(
Index ilat=0; ilat<nlat; ilat++ )
1848 const Numeric x = fabs( lat_grid[ilat] );
1849 const Numeric g0 = 9.780327 * ( 1 + 5.3024e-3*pow(sin(
DEG2RAD*x),2) +
1850 5.8e-6*pow(sin(2*
DEG2RAD*x),2) );
1853 for(
Index ilon=0; ilon<nlon; ilon++ )
1857 interp( z_hse, itw, z_field(
joker,ilat,ilon), gp );
1859 Numeric z_acc = 2 * z_hse_accuracy;
1861 while( z_acc > z_hse_accuracy )
1866 for(
Index ip=0; ip<np-1; ip++ )
1871 z2g( g2, r_geoid(ilat,ilon), g0, z_field(ip,ilat,ilon) );
1874 z2g( g2, r_geoid(ilat,ilon), g0, z_field(ip+1,ilat,ilon) );
1876 const Numeric g = ( g1 + g2 ) / 2.0;
1881 const Numeric r = 0.3108 * ( vmr_field(firstH2O,ip,ilat,ilon)
1882 + vmr_field(firstH2O,ip+1,ilat,ilon) );
1885 const Numeric tv = 0.5 * ( 1 + 0.61*r) * (
1886 t_field(ip,ilat,ilon) + t_field(ip+1,ilat,ilon) );
1889 const Numeric dz = 287.053 * (tv/g) *
1890 log( p_grid[ip]/p_grid[ip+1] );
1893 Numeric znew = z_field(ip,ilat,ilon) + dz;
1894 z_acc =
max( z_acc, fabs(znew-z_field(ip+1,ilat,ilon)) );
1895 z_field(ip+1,ilat,ilon) = znew;
1900 interp( z_tmp, itw, z_field(
joker,ilat,ilon), gp );
1901 z_field(
joker,ilat,ilon) -= z_tmp[0] - z_hse[0];
1910 for(
Index row=0; row<z_surface.
nrows(); row++ )
1912 for(
Index col=0; col<z_surface.
ncols(); col++ )
1914 if( z_surface(row,col)<z_field(0,row,col) ||
1915 z_surface(row,col)>=z_field(z_field.
npages()-1,row,col) )
1918 os <<
"The surface altitude (*z_surface*) cannot be outside "
1919 <<
"of the altitudes in *z_field*.";
1920 if( atmosphere_dim > 1 )
1921 os <<
"\nThis was found to be the case for:\n"
1922 <<
"latitude " << lat_grid[row];
1923 if( atmosphere_dim > 2 )
1924 os <<
"\nlongitude " << lon_grid[col];
1925 throw runtime_error( os.str() );