165 if (lon_grid.
nelem() == 0)
169 if (lat_grid.
nelem() == 0)
196 field_out = gfraw_in.
data;
216 field_out = gfraw_in.
data;
236 field_out = gfraw_in.
data;
251 if (!gfraw_in.
nelem())
254 out1 <<
" Warning: gfraw_in is empty, proceeding anyway\n";
255 field_out.
resize(0, 0, 0, 0);
260 gfraw_in[0].data.nrows(), gfraw_in[0].data.ncols());
266 chk_if_equal(
"p_grid",
"gfield.p_grid", p_grid, gfraw_in[i].get_numeric_grid(0));
285 if (&gfraw_in_orig == &gfraw_out)
287 gfraw_in_copy = gfraw_in_orig;
288 gfraw_in_pnt = &gfraw_in_copy;
291 gfraw_in_pnt = &gfraw_in_orig;
299 throw runtime_error(
"Can't expand data because number of Latitudes and Longitudes is greater than 1");
307 v[0] = -90; v[1] = 90;
316 v[0] = 0; v[1] = 360;
325 v[0] = -90; v[1] = 90;
327 v[0] = 0; v[1] = 360;
331 gfraw_out.
data = gfraw_in.
data(0, 0);
346 if (&gfraw_in_orig == &gfraw_out)
348 gfraw_in_copy = gfraw_in_orig;
349 gfraw_in_pnt = &gfraw_in_copy;
352 gfraw_in_pnt = &gfraw_in_orig;
360 throw runtime_error(
"Can't expand data because number of Latitudes and Longitudes is greater than 1");
370 v[0] = -90; v[1] = 90;
380 v[0] = 0; v[1] = 360;
390 v[0] = -90; v[1] = 90;
392 v[0] = 0; v[1] = 360;
411 if (&gfraw_in_orig == &gfraw_out)
413 gfraw_in_copy = gfraw_in_orig;
414 gfraw_in_pnt = &gfraw_in_copy;
417 gfraw_in_pnt = &gfraw_in_orig;
425 throw runtime_error(
"Can't expand data because number of Latitudes and Longitudes is greater than 1");
439 v[0] = -90; v[1] = 90;
450 v[0] = 0; v[1] = 360;
461 v[0] = -90; v[1] = 90;
463 v[0] = 0; v[1] = 360;
481 gfraw_out.resize(gfraw_in.
nelem());
513 const Index p_grid_index,
515 const Index& interp_order,
516 const Index& zeropadding,
523 out2 <<
" Interpolation order: " << interp_order <<
"\n";
528 gfraw_out.
set_grid(p_grid_index, p_grid);
533 if (in_p_grid[0]<p_grid[p_grid.
nelem()-1] ||
534 in_p_grid[in_p_grid.
nelem()-1]>p_grid[0])
541 "Raw field to p_grid",
549 ing_max = p_grid.
nelem()-1;
555 Index nelem_in_range = ing_max - ing_min + 1;
558 if (nelem_in_range>0)
560 gp_p.resize(nelem_in_range);
565 itw.
resize(nelem_in_range, interp_order+1);
578 const Index& interp_order,
579 const Index& zeropadding,
585 if (&gfraw_in_orig == &gfraw_out)
587 gfraw_in_copy = gfraw_in_orig;
588 gfraw_in_pnt = &gfraw_in_copy;
591 gfraw_in_pnt = &gfraw_in_orig;
595 const Index p_grid_index = 0;
607 Index ing_min, ing_max;
610 gp_p, itw, gfraw_out,
611 gfraw_in, p_grid_index,
612 p_grid, interp_order, zeropadding,
616 if (ing_max - ing_min < 0)
619 if (ing_max - ing_min + 1 != p_grid.
nelem())
648 const Index& interp_order,
649 const Index& zeropadding,
655 if (&gfraw_in_orig == &gfraw_out)
657 gfraw_in_copy = gfraw_in_orig;
658 gfraw_in_pnt = &gfraw_in_copy;
661 gfraw_in_pnt = &gfraw_in_orig;
665 const Index p_grid_index = 1;
680 Index ing_min, ing_max;
683 gp_p, itw, gfraw_out,
684 gfraw_in, p_grid_index,
685 p_grid, interp_order, zeropadding,
689 if (ing_max - ing_min < 0)
692 if (ing_max - ing_min + 1 != p_grid.
nelem())
704 itw, gfraw_in.
data(b,
joker, i, j), gp_p);
712 itw, gfraw_in.
data(b,
joker, i, j), gp_p);
723 const Index& interp_order,
724 const Index& zeropadding,
727 agfraw_out.resize(agfraw_in.
nelem());
732 interp_order, zeropadding,
760 const Index lat_grid_index,
761 const Index lon_grid_index,
764 const Index& interp_order,
769 if (!lat_true.
nelem())
throw runtime_error(
"The new latitude grid is not allowed to be empty.");
770 if (!lon_true.
nelem())
throw runtime_error(
"The new longitude grid is not allowed to be empty.");
775 throw runtime_error(
"Raw data has to be true 3D data (nlat>1 and nlon>1).");
777 out2 <<
" Interpolation order: " << interp_order <<
"\n";
783 gfraw_out.
set_grid(lat_grid_index, lat_true);
785 gfraw_out.
set_grid(lon_grid_index, lon_true);
794 gp_lat.resize(lat_true.
nelem());
795 gp_lon.resize(lon_true.
nelem());
796 gridpos_poly(gp_lat, in_lat_grid, lat_true, interp_order);
799 gp_lon, in_lon_grid, lon_true, interp_order);
802 itw.
resize(lat_true.
nelem(), lon_true.
nelem(), (interp_order+1)*(interp_order+1));
815 const Index& interp_order,
818 if (!lat_true.
nelem())
throw runtime_error(
"The new latitude grid is not allowed to be empty.");
819 if (!lon_true.
nelem())
throw runtime_error(
"The new longitude grid is not allowed to be empty.");
824 if (&gfraw_in_orig == &gfraw_out)
826 gfraw_in_copy = gfraw_in_orig;
827 gfraw_in_pnt = &gfraw_in_copy;
830 gfraw_in_pnt = &gfraw_in_orig;
834 const Index lat_grid_index = 0;
835 const Index lon_grid_index = 1;
841 os <<
"Raw data has to be true 3D data (nlat>1 and nlon>1).\n"
842 <<
"Use GriddedFieldLatLonExpand to convert 1D or 2D data to 3D!\n";
843 throw runtime_error(os.str());
859 for (
Index lat = 0; lat < in_lat_grid.
nelem(); lat++)
862 gfraw_in.
data(lat, in_lon_grid.
nelem()-1),
866 os <<
"Data values at 0 and 360 degrees for a cyclic longitude grid must match: \n"
867 <<
"Mismatch at latitude index : "
868 << lat <<
" (" << in_lat_grid[lat] <<
" degrees)\n"
869 <<
"Value at 0 degrees longitude : "
870 << gfraw_in.
data(lat, 0) <<
"\n"
871 <<
"Value at 360 degrees longitude: "
872 << gfraw_in.
data(lat, in_lon_grid.
nelem()-1) <<
"\n"
874 << gfraw_in.
data(lat, in_lon_grid.
nelem()-1) - gfraw_in.
data(lat, 0) <<
"\n"
876 throw runtime_error(os.str());
882 gfraw_in, lat_grid_index, lon_grid_index,
883 lat_true, lon_true, interp_order,
899 const Index& interp_order,
902 if (!lat_true.
nelem())
throw runtime_error(
"The new latitude grid is not allowed to be empty.");
903 if (!lon_true.
nelem())
throw runtime_error(
"The new longitude grid is not allowed to be empty.");
908 if (&gfraw_in_orig == &gfraw_out)
910 gfraw_in_copy = gfraw_in_orig;
911 gfraw_in_pnt = &gfraw_in_copy;
914 gfraw_in_pnt = &gfraw_in_orig;
918 const Index lat_grid_index = 1;
919 const Index lon_grid_index = 2;
925 os <<
"Raw data has to be true 3D data (nlat>1 and nlon>1).\n"
926 <<
"Use GriddedFieldLatLonExpand to convert 1D or 2D data to 3D!\n";
927 throw runtime_error(os.str());
946 for (
Index g0 = 0; g0 < in_grid0.
nelem(); g0++)
947 for (
Index lat = 0; lat < in_lat_grid.
nelem(); lat++)
950 gfraw_in.
data(g0, lat, in_lon_grid.
nelem()-1),
954 os <<
"Data values at 0 and 360 degrees for a cyclic longitude grid must match: \n"
955 <<
"Mismatch at 1st grid index : "
956 << g0 <<
" (" << in_grid0[g0] <<
")\n"
957 <<
" at latitude index : "
958 << lat <<
" (" << in_lat_grid[lat] <<
" degrees)\n"
959 <<
"Value at 0 degrees longitude : "
960 << gfraw_in.
data(g0, lat, 0) <<
"\n"
961 <<
"Value at 360 degrees longitude: "
962 << gfraw_in.
data(g0, lat, in_lon_grid.
nelem()-1) <<
"\n"
964 << gfraw_in.
data(g0, lat, in_lon_grid.
nelem()-1) - gfraw_in.
data(g0, lat, 0) <<
"\n"
966 throw runtime_error(os.str());
972 gfraw_in, lat_grid_index, lon_grid_index,
973 lat_true, lon_true, interp_order,
991 const Index& interp_order,
994 if (!lat_true.
nelem())
throw runtime_error(
"The new latitude grid is not allowed to be empty.");
995 if (!lon_true.
nelem())
throw runtime_error(
"The new longitude grid is not allowed to be empty.");
1000 if (&gfraw_in_orig == &gfraw_out)
1002 gfraw_in_copy = gfraw_in_orig;
1003 gfraw_in_pnt = &gfraw_in_copy;
1006 gfraw_in_pnt = &gfraw_in_orig;
1010 const Index lat_grid_index = 2;
1011 const Index lon_grid_index = 3;
1017 os <<
"Raw data has to be true 3D data (nlat>1 and nlon>1).\n"
1018 <<
"Use GriddedFieldLatLonExpand to convert 1D or 2D data to 3D!\n";
1019 throw runtime_error(os.str());
1035 gfraw_in, lat_grid_index, lon_grid_index,
1036 lat_true, lon_true, interp_order,
1047 for (
Index g0 = 0; g0 < in_grid0.
nelem(); g0++)
1048 for (
Index g1 = 0; g1 < in_grid1.
nelem(); g1++)
1049 for (
Index lat = 0; lat < in_lat_grid.
nelem(); lat++)
1052 gfraw_in.
data(g0, g1, lat, in_lon_grid.
nelem()-1),
1056 os <<
"Data values at 0 and 360 degrees for a cyclic longitude grid must match: \n"
1057 <<
"Mismatch at 1st grid index : "
1058 << g0 <<
" (" << in_grid0[g0] <<
")\n"
1059 <<
" at 2nd grid index : "
1060 << g1 <<
" (" << in_grid1[g1] <<
")\n"
1061 <<
" at latitude index : "
1062 << lat <<
" (" << in_lat_grid[lat] <<
" degrees)\n"
1063 <<
"Value at 0 degrees longitude : "
1064 << gfraw_in.
data(g0, g1, lat, 0) <<
"\n"
1065 <<
"Value at 360 degrees longitude: "
1066 << gfraw_in.
data(g0, g1, lat, in_lon_grid.
nelem()-1) <<
"\n"
1068 << gfraw_in.
data(g0, g1, lat, in_lon_grid.
nelem()-1) - gfraw_in.
data(g0, g1, lat, 0) <<
"\n"
1070 throw runtime_error(os.str());
1091 const Index& interp_order,
1094 agfraw_out.resize(agfraw_in.
nelem());
1096 for (
Index i = 0; i < agfraw_in.
nelem(); i++)
1099 interp_order, verbosity);
1127 const Index z_grid_index,
1129 const Index& interp_order,
1130 const Index& zeropadding,
1137 out2 <<
" Interpolation order: " << interp_order <<
"\n";
1143 if (in_z_grid[0] > z_grid[z_grid.
nelem()-1] ||
1144 in_z_grid[in_z_grid.
nelem()-1] < z_grid[0])
1147 ing_max = ing_min-1;
1151 "Raw field to z_grid",
1159 ing_max = z_grid.
nelem()-1;
1166 Index nelem_in_range = ing_max - ing_min + 1;
1169 if (nelem_in_range>0)
1171 gp_p.resize(nelem_in_range);
1176 itw.
resize(nelem_in_range, interp_order+1);
1192 const Index& interp_order,
1193 const Index& zeropadding,
1199 throw std::runtime_error(
"*z_field* must be of the same size as *p_grid*, *lat_grid*, and *lon_grid* in *GriddedFieldZToPRegrid*.");
1209 throw std::runtime_error(
"Gridding of field to regrid is bad.\n*GriddedFieldZToPRegrid* requires latitude and longitude to be on the same grid as *z_field*.");
1213 if(lat_grid[ii]!=lat_in[ii])
1214 throw std::runtime_error(
"Gridding of field to regrid is bad.\n*GriddedFieldZToPRegrid* requires latitude and longitude to be the same as for *z_field*.");
1216 if(lon_grid[ii]!=lon_in[ii])
1217 throw std::runtime_error(
"Gridding of field to regrid is bad.\n*GriddedFieldZToPRegrid* requires latitude and longitude to be the same as for *z_field*.");
1224 if (&gfraw_in_orig == &gfraw_out)
1226 gfraw_in_copy = gfraw_in_orig;
1227 gfraw_in_pnt = &gfraw_in_copy;
1230 gfraw_in_pnt = &gfraw_in_orig;
1243 gfraw_out.
data = 0.;
1248 Index ing_min, ing_max;
1250 for(
Index lat_index = 0;lat_index<lat_grid.
nelem();lat_index++)
1252 for(
Index lon_index = 0;lon_index<lon_grid.
nelem();lon_index++)
1254 const Vector z_out = z_field(
joker,lat_index,lon_index);
1259 z_out, interp_order, zeropadding,
1262 if (ing_max - ing_min >= 0)
1266 if (ing_max - ing_min + 1 != z_out.
nelem())
1268 r =
Range(ing_min, ing_max-ing_min+1);
1271 interp(gfraw_out.
data(r, lat_index, lon_index),
1272 itw, gfraw_in.
data(
joker, lat_index, lon_index), gp_p);
1284 const Index& atmosphere_dim,
1291 if (1!=atmosphere_dim)
1294 os <<
"Atmospheric dimension must be one.";
1295 throw runtime_error( os.str() );
1304 if (field_names.
nelem()!=nf)
1307 os <<
"Cannot extract fields from Matrix.\n"
1308 <<
"*field_names* must have one element less than there are\n"
1309 <<
"matrix columns.";
1310 throw runtime_error( os.str() );
1317 for(
Index f = 0; f < field_names.
nelem(); f++)
1319 fn_upper = field_names[f];
1322 if(fn_upper !=
"IGNORE")
1334 Index nf_1=f_1.size();
1336 for (
Index f=0; f<nf_1; f++)
1338 field_names_1[f] = field_names[f_1[f]];
1354 for (
Index f = 0; f < nf_1; f++)
1410 p2gridpos(p_gridpos, sp_p_grid, af_p_grid);
1412 if (sp_lat_grid.
nelem() > 1)
1419 gridpos(lat_gridpos, sp_lat_grid, af_lat_grid);
1421 if (sp_lon_grid.
nelem() > 1)
1427 gridpos(lon_gridpos, sp_lon_grid, af_lon_grid);
1433 interp(newfield, itw, species.
data, p_gridpos, lat_gridpos, lon_gridpos);
1444 atm_fields_compact.
data(new_n_fields-1,
joker,
joker, 0) = newfield;
1453 atm_fields_compact.
data(new_n_fields-1,
joker, 0, 0) = newfield;
1469 for (
Index i=0; i<batch_atm_fields_compact.
nelem(); i++)
1485 const Index nelem = batch_atm_fields_compact.
nelem();
1488 bool failed =
false;
1492 #pragma omp parallel for \
1493 if (!arts_omp_in_parallel() \
1494 && nelem >= arts_omp_get_max_threads())
1495 for (
Index i=0; i<nelem; i++)
1500 catch (runtime_error e)
1502 #pragma omp critical (batch_atm_fields_compactAddSpecies_fail)
1503 { fail_msg = e.what(); failed =
true; }
1507 if (failed)
throw runtime_error(fail_msg);
1514 const Index& atmosphere_dim,
1520 const Vector& extra_field_values,
1528 os <<
"No elements in atmospheric scenario batch.\n"
1529 <<
"Check, whether any batch atmosphere file has been read!";
1530 throw runtime_error( os.str() );
1538 if (extra_field_names.
nelem() != extra_field_values.
nelem())
1541 os <<
"The keyword arguments extra_field_names and\n"
1542 <<
"extra_field_values must have matching dimensions.";
1543 throw runtime_error( os.str() );
1547 batch_atm_fields_compact.resize(amnelem);
1550 bool failed =
false;
1553 #pragma omp parallel for \
1554 if (!arts_omp_in_parallel() \
1555 && amnelem >= arts_omp_get_max_threads())
1556 for (
Index i=0; i<amnelem; ++i)
1559 if (failed)
continue;
1576 for (
Index j=0; j<extra_field_names.
nelem(); ++j)
1578 extra_field_names[j],
1579 extra_field_values[j],
1582 catch (runtime_error e)
1584 #pragma omp critical (batch_atm_fields_compactFromArrayOfMatrix_fail)
1585 { fail_msg = e.what(); failed =
true; }
1589 if (failed)
throw runtime_error(fail_msg);
1605 const Index& atmosphere_dim,
1634 const Index nsa = nf-nsp-2;
1640 os <<
"There must be at least three fields in *atm_fields_compact*.\n"
1641 <<
"T, z, and at least one VMR.";
1642 throw runtime_error( os.str() );
1649 os <<
"The first field must be \"T\", but it is:"
1651 throw runtime_error( os.str() );
1658 os <<
"The second field must be \"z\"*, but it is:"
1660 throw runtime_error( os.str() );
1664 for (
Index i=0; i<nsp; ++i)
1669 if (tf_species != ps_species)
1672 os <<
"Field name for particle field not valid: "
1673 << tf_species <<
"\n"
1674 <<
"Based on *part_species*, the field name should be: "
1676 throw runtime_error( os.str() );
1681 for (
Index i=0; i<nsa; ++i)
1683 if (i >= abs_species.
nelem())
1686 os <<
"Based on the field names for absorption species,\n"
1687 <<
"these species are missing in *abs_species*:\n";
1688 for (
Index itf_species = i; itf_species < nsa; ++itf_species)
1690 throw runtime_error(os.str());
1700 if (tf_species != as_species)
1703 os <<
"Field name for absorption species field not valid: "
1704 << tf_species <<
"\n"
1705 <<
"Based on *abs_species*, the field name should be: "
1707 throw runtime_error( os.str() );
1712 t_field.
resize(np,nlat,nlon);
1716 z_field.
resize(np,nlat,nlon);
1720 massdensity_field.
resize(nsp,np,nlat,nlon);
1724 vmr_field.
resize(nsa,np,nlat,nlon);
1731 Index& atmosphere_dim,
1739 out2 <<
" Sets the atmospheric dimensionality to 1.\n";
1740 out3 <<
" atmosphere_dim = 1\n";
1741 out3 <<
" lat_grid is set to be an empty vector\n";
1742 out3 <<
" lon_grid is set to be an empty vector\n";
1753 Index& atmosphere_dim,
1760 out2 <<
" Sets the atmospheric dimensionality to 2.\n";
1761 out3 <<
" atmosphere_dim = 2\n";
1762 out3 <<
" lon_grid is set to be an empty vector\n";
1771 Index& atmosphere_dim,
1777 out2 <<
" Sets the atmospheric dimensionality to 3.\n";
1778 out3 <<
" atmosphere_dim = 3\n";
1797 const Index& atmosphere_dim,
1799 const Index& interp_order,
1800 const Index& vmr_zeropadding,
1801 const Index& vmr_nonegative,
1813 out2 <<
" Interpolation order: " << interp_order <<
"\n";
1819 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
1823 if ( atmosphere_dim == 1)
1825 if( !( tfr_lat_grid.
nelem() == 1 &&
1826 tfr_lon_grid.
nelem() == 1 ))
1827 throw runtime_error(
1828 "Temperature data (T_field) has wrong dimension "
1832 if( !( zfr_lat_grid.
nelem() == 1 &&
1833 zfr_lon_grid.
nelem() == 1 ))
1834 throw runtime_error(
1835 "Altitude data (z_field) has wrong dimension "
1842 t_field = temp_gfield3.
data;
1845 z_field = temp_gfield3.
data;
1850 vmr_zeropadding, verbosity);
1851 }
catch (runtime_error e) {
1853 os << e.what() <<
"\n"
1854 <<
"Note that you can explicitly set vmr_zeropadding to 1 in the method call.";
1855 throw runtime_error(os.str());
1862 else if(atmosphere_dim == 2)
1864 if( tfr_lat_grid.
nelem() == 1 &&
1865 tfr_lon_grid.
nelem() == 1 )
1866 throw runtime_error(
1867 "Raw data has wrong dimension (1D). "
1868 "You have to use \n"
1869 "AtmFieldsCalcExpand1D instead of AtmFieldsCalc."
1898 gridpos_poly( gp_lat, tfr_lat_grid, lat_grid, interp_order );
1901 Tensor3 itw(p_grid.
nelem(), lat_grid.
nelem(), (interp_order+1)*(interp_order+1));
1925 gridpos_poly( gp_lat, zfr_lat_grid, lat_grid, interp_order );
1937 for (
Index gas_i = 0; gas_i < vmr_field_raw.
nelem(); gas_i++)
1941 if( !( vmr_field_raw[gas_i].get_numeric_grid(
GFIELD3_LAT_GRID).nelem() != 1 &&
1944 os <<
"VMR data of the " << gas_i <<
"th species has "
1945 <<
"wrong dimension (1D or 3D). \n";
1946 throw runtime_error( os.str() );
1951 os <<
"Raw VMR[" << gas_i <<
"] to p_grid, 2D case";
1957 os <<
"Raw VMR[" << gas_i <<
"] to lat_grid, 2D case";
1965 p_grid, interp_order);
1967 lat_grid, interp_order);
1974 itw, vmr_field_raw[gas_i].data(
joker,
joker, 0),
1981 else if(atmosphere_dim == 3)
1983 if( tfr_lat_grid.
nelem() == 1 &&
1984 tfr_lon_grid.
nelem() == 1 )
1985 throw runtime_error(
1986 "Raw data has wrong dimension. You have to use \n"
1987 "AtmFieldsCalcExpand1D instead of AtmFieldsCalc."
1994 t_field = temp_gfield3.
data;
1998 z_field = temp_gfield3.
data;
2004 vmr_zeropadding, verbosity);
2005 }
catch (runtime_error e) {
2007 os << e.what() <<
"\n"
2008 <<
"Note that you can explicitly set vmr_zeropadding to 1 in the method call.";
2009 throw runtime_error(os.str());
2022 if( vmr_nonegative )
2028 for(
Index ir=0; ir<vmr_field.
nrows(); ir++ )
2030 for(
Index ic=0; ic<vmr_field.
ncols(); ic++ )
2032 if( vmr_field(ib,ip,ir,ic) < 0 )
2033 { vmr_field(ib,ip,ir,ic) = 0; }
2049 const Index& atmosphere_dim,
2050 const Index& interp_order,
2051 const Index& vmr_zeropadding,
2052 const Index& vmr_nonegative,
2056 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
2058 if( atmosphere_dim == 1 )
2059 {
throw runtime_error(
2060 "This function is intended for 2D and 3D. For 1D, use *AtmFieldsCalc*.");}
2066 AtmFieldsCalc(t_temp, z_temp, vmr_temp, p_grid, vempty, vempty,
2067 t_field_raw, z_field_raw, vmr_field_raw, 1, interp_order,
2068 vmr_zeropadding, vmr_nonegative, verbosity);
2074 if( atmosphere_dim == 2 )
2078 assert( t_temp.
npages() == np );
2080 t_field.
resize( np, nlat, nlon );
2081 z_field.
resize( np, nlat, nlon );
2082 vmr_field.
resize( nspecies, np, nlat, nlon );
2084 for(
Index ilon=0; ilon<nlon; ilon++ )
2086 for(
Index ilat=0; ilat<nlat; ilat++ )
2088 for(
Index ip=0; ip<np; ip++ )
2090 t_field(ip,ilat,ilon) = t_temp(ip,0,0);
2091 z_field(ip,ilat,ilon) = z_temp(ip,0,0);
2092 for(
Index is=0; is<nspecies; is++ )
2093 { vmr_field(is,ip,ilat,ilon) = vmr_temp(is,ip,0,0); }
2107 const Index& atmosphere_dim,
2111 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
2119 if( atmosphere_dim == 1 )
2120 {
throw runtime_error(
"No use in calling this method for 1D.");}
2128 Tensor3 t_temp = t_field, z_temp = z_field;
2132 t_field.
resize( np, nlat, nlon );
2133 z_field.
resize( np, nlat, nlon );
2134 vmr_field.
resize( nspecies, np, nlat, nlon );
2136 for(
Index ilon=0; ilon<nlon; ilon++ )
2138 for(
Index ilat=0; ilat<nlat; ilat++ )
2140 for(
Index ip=0; ip<np; ip++ )
2142 t_field(ip,ilat,ilon) = t_temp(ip,0,0);
2143 z_field(ip,ilat,ilon) = z_temp(ip,0,0);
2144 for(
Index is=0; is<nspecies; is++ )
2145 { vmr_field(is,ip,ilat,ilon) = vmr_temp(is,ip,0,0); }
2162 const Index& atmosphere_dim,
2179 p_grid, lat_grid, lon_grid);
2183 p_grid, lat_grid, lon_grid);
2187 vmr_field.
nbooks(), p_grid, lat_grid, lon_grid);
2193 os <<
"The keyword argument p_step must be >0.";
2194 throw runtime_error( os.str() );
2217 log_abs_p_a.push_back(log_p_grid[0]);
2221 const Numeric dp = log_p_grid[i-1] - log_p_grid[i];
2223 const Numeric dp_by_p_step = dp/p_step;
2236 for (
Index j=1; j<=n; ++j)
2237 log_abs_p_a.push_back(log_p_grid[i-1] - (
Numeric)j*ddp);
2244 log_abs_p[i] = log_abs_p_a[i];
2256 gridpos(gp, log_p_grid, log_abs_p);
2268 if (0 == nlat) nlat = 1;
2269 if (0 == nlon) nlon = 1;
2275 log_abs_p.
nelem(), nlat, nlon);
2277 for (
Index ilat=0; ilat<nlat; ++ilat)
2278 for (
Index ilon=0; ilon<nlon; ++ilon)
2282 t_field(
joker, ilat, ilon),
2287 z_field(
joker, ilat, ilon),
2290 for (
Index ivmr=0; ivmr<vmr_field.
nbooks(); ++ivmr)
2293 vmr_field(ivmr,
joker, ilat, ilon),
2302 vmr_field = abs_vmr;
2320 String tmp_basename = basename;
2321 if (basename.length() && basename[basename.length()-1] !=
'/')
2322 tmp_basename +=
".";
2325 String file_name = tmp_basename +
"t.xml";
2328 out3 <<
"Temperature field read from file: " << file_name <<
"\n";
2331 file_name = tmp_basename +
"z.xml";
2334 out3 <<
"Altitude field read from file: " << file_name <<
"\n";
2337 vmr_field_raw.resize(0);
2343 for (
Index i=0; i<abs_species.
nelem(); i ++)
2346 file_name = tmp_basename +
2347 species_data[abs_species[i][0].Species()].Name() +
".xml";
2351 vmr_field_raw.push_back(vmr_field_data);
2357 out3 <<
" " <<
species_data[abs_species[i][0].Species()].Name()
2358 <<
" profile read from file: " << file_name <<
"\n";
2367 const Index& atmosphere_dim,
2377 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
2378 chk_atm_field(
"input argument *field*", field, atmosphere_dim,
2379 p_grid, lat_grid, lon_grid );
2385 p_grid, lat_grid, lon_grid, z_field, rtp_pos );
2392 out3 <<
" Result = " << outvalue <<
"\n";
2404 {
throw runtime_error(
"Argument *nfill* must be >= 0." ); }
2410 const Vector p0( p_grid);
2413 p_grid.
resize( (n0-1)*(1+nfill) + 1 );
2418 for(
Index i=1; i<n0; i++ )
2422 for(
Index j=1; j<nfill+2; j++ )
2425 p_grid[iout] = pnew[j];
2438 const Index& no_negZ,
2453 while ( z_field_raw.
data(i,0,0)< 0.0 ) i++;
2462 while ( z_field_raw.
data(i,0,0)< 0.0 ) i--;
2469 os <<
"z_field_raw needs to be monotonous, but this is not the case.\n";
2470 throw runtime_error( os.str() );
2500 const Index& atmosphere_dim,
2504 const Vector& refellipsoid,
2506 const Numeric& planet_rotation_period,
2509 if( atmosphere_dim < 3 )
2510 throw runtime_error(
"No need to use this method for 1D and 2D." );
2517 p_grid, lat_grid, lon_grid );
2518 if( wind_u_field.
npages() > 0 )
2519 {
chk_atm_field(
"wind_u_field", wind_u_field, atmosphere_dim,
2520 p_grid, lat_grid, lon_grid );}
2523 wind_u_field.
resize( np, na, no );
2527 const Numeric k1 = 2 *
PI / planet_rotation_period;
2530 for(
Index a=0; a<na; a++ )
2535 for(
Index o=0; o<no; o++ )
2537 for(
Index p=0; p<np; p++ )
2539 wind_u_field(p,a,o) += k2 * ( re + z_field(p,a,o) );
2563 const Index& atmosphere_dim,
2572 const Vector& refellipsoid,
2574 const Index& atmfields_checked,
2576 const Numeric& molarmass_dry_air,
2578 const Numeric& z_hse_accuracy,
2581 if( atmfields_checked != 1 )
2582 throw runtime_error(
"The atmospheric fields must be flagged to have "
2583 "passed a consistency check (atmfields_checked=1)." );
2596 os <<
"No water vapour tag group in *abs_species*.\n"
2597 <<
"Be aware that this leads to significant variations in atmospheres\n"
2598 <<
"that contain considerable amounts of water vapour (e.g. Earth)!\n";
2605 if( p_hse>p_grid[0] || p_hse < p_grid[np-1] )
2608 os <<
"The value of *p_hse* must be inside the range of *p_grid*:"
2609 <<
" p_hse = " << p_hse <<
" Pa\n"
2610 <<
" p_grid = << p_grid[np-1]" <<
" - " << p_grid[0] <<
" Pa\n";
2611 throw runtime_error( os.str() );
2614 if( z_hse_accuracy <= 0 )
2615 {
throw runtime_error(
"The value of *z_hse_accuracy* must be > 0." ); }
2632 const Numeric k = 1 - mw/molarmass_dry_air;
2639 for(
Index ilat=0; ilat<nlat; ilat++ )
2648 if( atmosphere_dim == 1 )
2649 { re = refellipsoid[0]; }
2651 { re =
refell2r( refellipsoid, lat_grid[ilat] ); }
2653 for(
Index ilon=0; ilon<nlon; ilon++ )
2657 Vector pos(atmosphere_dim);
2658 if( atmosphere_dim >= 2 )
2660 pos[1] = lat_grid[ilat];
2661 if( atmosphere_dim == 3 )
2662 { pos[2] = lon_grid[ilon]; }
2673 interp( z_hse, itw, z_field(
joker,ilat,ilon), gp );
2675 Numeric z_acc = 2 * z_hse_accuracy;
2677 while( z_acc > z_hse_accuracy )
2682 for(
Index ip=0; ip<np-1; ip++ )
2686 {
z2g( g2, re, g0, z_field(ip,ilat,ilon) ); }
2688 z2g( g2, re, g0, z_field(ip+1,ilat,ilon) );
2690 const Numeric g = ( g1 + g2 ) / 2.0;
2700 hm = 0.5* ( vmr_field(firstH2O,ip,ilat,ilon)
2701 + vmr_field(firstH2O,ip+1,ilat,ilon) );
2706 const Numeric tv = ( 1 / ( 2 * (1-hm*k) ) ) *
2707 ( t_field(ip,ilat,ilon) + t_field(ip+1,ilat,ilon) );
2711 const Numeric dz = rd*(tv/g)*log( p_grid[ip]/p_grid[ip+1] );
2714 Numeric znew = z_field(ip,ilat,ilon) + dz;
2715 z_acc =
max( z_acc, fabs(znew-z_field(ip+1,ilat,ilon)) );
2716 z_field(ip+1,ilat,ilon) = znew;
2721 interp( z_tmp, itw, z_field(
joker,ilat,ilon), gp );
2722 z_field(
joker,ilat,ilon) -= z_tmp[0] - z_hse[0];
2731 for(
Index row=0; row<z_surface.
nrows(); row++ )
2733 for(
Index col=0; col<z_surface.
ncols(); col++ )
2735 if( z_surface(row,col)<z_field(0,row,col) ||
2736 z_surface(row,col)>=z_field(z_field.
npages()-1,row,col) )
2739 os <<
"The surface altitude (*z_surface*) cannot be outside "
2740 <<
"of the altitudes in *z_field*.";
2741 throw runtime_error( os.str() );