73 const double   RTOL = 1e-2;
 
   96 const double   ANGTOL = 1e-7; 
 
  134   assert( 
abs(za) <= 180 );
 
  166   assert( 
abs(a_za) <= 180 );
 
  167   assert( r >= ppc - 
RTOL );
 
  171       double za = 
RAD2DEG * asin( ppc / r );
 
  205   assert( 
abs(za) <= 180 );
 
  233   assert( 
abs(za0) <= 180 );
 
  234   assert( 
abs(za) <= 180 );
 
  235   assert( ( za0 >= 0 && za >= 0 )  ||  ( za0 < 0 && za < 0 ) );
 
  237   return lat0 + za0 - za;
 
  261   assert( r >= ppc - 
RTOL );
 
  264     { 
return   sqrt( r*r - ppc*ppc ); }
 
  292   return sqrt( l*l + ppc*ppc );
 
  317   assert( 
abs(za0) <= 180 );
 
  318   assert( ( za0 >= 0 && lat >= lat0 )  ||  ( za0 <= 0 && lat <= lat0 ) );
 
  321   const double za = za0 + lat0 -lat;
 
  371       n = 
Index( ceil( 
abs( l2 - l1 ) / lmax ) );
 
  381   lstep = ( l2 - l1 ) / (
double)n;
 
  392   for( 
Index i=1; i<n; i++ )
 
  407   for( 
Index i=1; i<=n; i++ )
 
  411   lstep = 
abs( lstep );
 
  449       const double dlat = 
abs( lat2 - lat1 );
 
  454                  sqrt( r1*r1 + r2*r2 - 2 * r1 * r2 * cos( 
DEG2RAD * dlat ) ) );
 
  499   assert( 
abs( lat ) <= 90 );
 
  500   assert( 
abs( lon ) <= 360 );
 
  502   const double   latrad = 
DEG2RAD * lat;
 
  503   const double   lonrad = 
DEG2RAD * lon;
 
  505   x = r * cos( latrad );   
 
  506   z = x * sin( lonrad );
 
  507   x = x * cos( lonrad );
 
  508   y = r * sin( latrad );
 
  535   r   = sqrt( x*x + y*y + z*z );
 
  585       const double   s = 
sign( lat );
 
  599       const double   latrad = 
DEG2RAD * lat;
 
  600       const double   lonrad = 
DEG2RAD * lon;
 
  601       const double   zarad  = 
DEG2RAD * za;
 
  602       const double   aarad  = 
DEG2RAD * aa;
 
  606       const double   coslat = cos( latrad );
 
  607       const double   sinlat = sin( latrad );
 
  608       const double   coslon = cos( lonrad );
 
  609       const double   sinlon = sin( lonrad );
 
  610       const double   cosza  = cos( zarad );
 
  611       const double   sinza  = sin( zarad );
 
  612       const double   cosaa  = cos( aarad );
 
  613       const double   sinaa  = sin( aarad );
 
  615       const double   dr   = cosza;
 
  616       const double   dlat = sinza * cosaa;         
 
  617       const double   dlon = sinza * sinaa / coslat; 
 
  619       dx = coslat*coslon * dr - sinlat*coslon * dlat - coslat*sinlon * dlon;
 
  620       dy =        sinlat * dr +        coslat * dlat;
 
  621       dz = coslat*sinlon * dr - sinlat*sinlon * dlat + coslat*coslon * dlon;
 
  666   assert( 
abs( sqrt( 
dx*
dx + dy*dy + dz*dz ) - 1 ) < 1e-6 );
 
  672   const double   coslat = cos( 
DEG2RAD * lat );
 
  673   const double   sinlat = sin( 
DEG2RAD * lat );
 
  674   const double   coslon = cos( 
DEG2RAD * lon );
 
  675   const double   sinlon = sin( 
DEG2RAD * lon );
 
  676   const double   dr   = coslat*coslon*
dx + sinlat*dy + coslat*sinlon*dz;
 
  677   const double   dlat = -sinlat*coslon/r*
dx + coslat/r*dy -sinlat*sinlon/r*dz;
 
  678   const double   dlon = -sinlon/coslat/r*
dx + coslon/coslat/r*dz;
 
  683   if( za < ANGTOL  ||  za > 180-
ANGTOL  )
 
  740   assert( lon6 >= lon5 ); 
 
  742   if( lon < lon5  &&  lon+180 <= lon6 )
 
  744   else if( lon > lon6  &&  lon-180 >= lon5 )
 
  753   assert( lon6 >= lon5 );
 
  755   if( lon < lon5  &&  lon+180 <= lon6 )
 
  757   else if( lon > lon6  &&  lon-180 >= lon5 )
 
  799   double   x, y, z, 
dx, dy, dz; 
 
  801   poslos2cart( x, y, z, 
dx, dy, dz, r, lat, lon, za, aa );
 
  803   l_tan = sqrt( r*r - ppc*ppc );
 
  805   cart2sph( r_tan, lat_tan, lon_tan, x+
dx*l_tan, y+dy*l_tan, z+dz*l_tan );
 
  841   const double   zarad  = 
DEG2RAD * za;
 
  842   const double   aarad  = 
DEG2RAD * aa;
 
  846   dy = sin( aarad ) * 
dx;
 
  847   dx = cos( aarad ) * 
dx;
 
  883   const double r = sqrt( 
dx*
dx + dy*dy + dz*dz );
 
  916   assert( R.
ncols() == 3 );
 
  917   assert( R.
nrows() == 3 );
 
  918   assert( vrot.
nelem() == 3 );
 
  920   const double u = vrot[0];
 
  921   const double v = vrot[1];
 
  922   const double w = vrot[2];
 
  924   const double u2 = u * u;
 
  925   const double v2 = v * v;
 
  926   const double w2 = w * w;
 
  928   assert( sqrt( u2 + v2 + w2 ) );
 
  930   const double c = cos( 
DEG2RAD * a );
 
  931   const double s = sin( 
DEG2RAD * a );
 
  934   R(0,0) = u2 + (v2 + w2)*c;
 
  935   R(0,1) = u*v*(1-c) - w*s;
 
  936   R(0,2) = u*w*(1-c) + v*s;
 
  937   R(1,0) = u*v*(1-c) + w*s;
 
  938   R(1,1) = v2 + (u2+w2)*c;
 
  939   R(1,2) = v*w*(1-c) - u*s;
 
  940   R(2,0) = u*w*(1-c) - v*s;
 
  941   R(2,1) = v*w*(1-c)+u*s;
 
  942   R(2,2) = w2 + (u2+v2)*c;
 
  972        const double&   aa_grid )
 
  974   assert( 
abs( aa_grid ) <= 5 );
 
  982   zaaa2cart( xyz[0], xyz[1], xyz[2], 90, aa0 );
 
  995   zaaa2cart( xyz[0], xyz[1], xyz[2], 90, aa0+aa_grid );
 
 1051   const double r1 = r_geoid[i1] + z_surf[i1];
 
 1052   const double r2 = r_geoid[i1+1] + z_surf[i1+1];
 
 1053   return ( r2 - r1 ) / ( lat_grid[i1+1] - lat_grid[i1] );
 
 1082   return   ( r2 - r1 ) / ( lat2 -lat1 );
 
 1109   return   r1 + ( lat - lat1 ) * ( r3 - r1 ) / ( lat3 - lat1 );
 
 1149     { 
return   r15 + ( lon - lon5 ) * ( r16 - r15 ) / ( lon6 -lon5 ); }
 
 1150   else if( lat == lat3 )
 
 1151     { 
return   r35 + ( lon - lon5 ) * ( r36 - r35 ) / ( lon6 -lon5 ); }
 
 1152   else if( lon == lon5 )
 
 1153     { 
return   r15 + ( lat - lat1 ) * ( r35 - r15 ) / ( lat3 -lat1 ); }
 
 1154   else if( lon == lon6 )
 
 1155     { 
return   r16 + ( lat - lat1 ) * ( r36 - r16 ) / ( lat3 -lat1 ); }
 
 1158       const double   fdlat = ( lat - lat1 ) / ( lat3 - lat1 );
 
 1159       const double   fdlon = ( lon - lon5 ) / ( lon6 - lon5 );
 
 1160       return   (1-fdlat)*(1-fdlon)*r15 + fdlat*(1-fdlon)*r35 + 
 
 1161                                          (1-fdlat)*fdlon*r16 + fdlat*fdlon*r36;
 
 1209   const double   dang = 1e-5;
 
 1213                                                 r15, r35, r36, r16, lat, lon );
 
 1218   double   x, y, z, 
dx, dy, dz;
 
 1219   poslos2cart( x, y, z, 
dx, dy, dz, r0, lat, lon, 90, aa );
 
 1222   const double   l = r0 * 
DEG2RAD * dang;
 
 1226   double   r2, lat2, lon2, za2, aa2;
 
 1227   cart2poslos( r2, lat2, lon2, za2, aa2, x+
dx*l, y+dy*l, z+dz*l, 
dx, dy, dz );
 
 1229   r2 = 
rsurf_at_latlon( lat1, lat3, lon5, lon6, r15, r35, r36, r16, lat2,lon2);
 
 1232   return   ( r2 - r0 ) / dang;
 
 1283   lat = 
interp( itw, lat_grid, gp_lat );
 
 1285   lon = 
interp( itw, lon_grid, gp_lon );
 
 1288   const double   lat1 = lat_grid[ilat];
 
 1289   const double   lat3 = lat_grid[ilat+1];
 
 1290   const double   lon5 = lon_grid[ilon];
 
 1291   const double   lon6 = lon_grid[ilon+1];
 
 1292   const double   r15  = r_geoid(ilat,ilon) + z_surf(ilat,ilon);
 
 1293   const double   r35  = r_geoid(ilat+1,ilon) + z_surf(ilat+1,ilon);
 
 1294   const double   r36  = r_geoid(ilat+1,ilon+1) + z_surf(ilat+1,ilon+1);
 
 1295   const double   r16  = r_geoid(ilat,ilon+1) + z_surf(ilat,ilon+1);
 
 1349         const Index&      atmosphere_dim,
 
 1358   if( atmosphere_dim == 1 )
 
 1360   else if( atmosphere_dim == 2 )
 
 1363                                           z_surface(
joker,0), gp_lat, los[0] );
 
 1372                                           z_surface, gp_lat, gp_lon, los[1]  );
 
 1374       const Numeric rv_surface = 
interp( itw, r_geoid, gp_lat, gp_lon ) +
 
 1375                                  interp( itw, z_surface, gp_lat, gp_lon );
 
 1404         const double&   tilt )
 
 1406   assert( 
abs(za) <= 180 );
 
 1409   if( za > (90-tilt)  ||  za < (-90-tilt) )
 
 1468   assert( 
abs(za) <= 180 );
 
 1470   const double no_crossing = 999;
 
 1478         { 
return no_crossing; }
 
 1485         { 
return no_crossing; }
 
 1492     { 
return no_crossing; }
 
 1498       if( ( rp < r0  &&  
abs(za) <= 90 )  ||  
 
 1499                                  ( rp > r0  &&  
abs(za) > 90  &&  r0 >= ppc ) )
 
 1502         { 
return no_crossing; }
 
 1517       const double   cv = cos( 
beta );
 
 1518       const double   sv = sin( 
beta );
 
 1528       p[0] = ( r0 - rp ) * sv;
 
 1529       p[1] = r0 * cv + c * sv;
 
 1530       p[2] = -r0 * sv / 2 + c * cv;
 
 1531       p[3] = -r0 * cv / 6 - c * sv / 2;
 
 1540       double dlat = no_crossing / 
RAD2DEG;
 
 1542       for( 
Index i=0; i<4; i++ )
 
 1544           if( roots(i,1) == 0  &&   roots(i,0) > 
dmin  &&  roots(i,0) < dlat )
 
 1545             { dlat = roots(i,0); }
 
 1549       if( dlat < no_crossing  &&  za < 0 )
 
 1604        const double     r_surf,
 
 1605        const double     r_start,         
 
 1606        const double     lat_start,       
 
 1607        const double     lon_start,       
 
 1608        const double     za_start,
 
 1616   assert( za_start >=   0 );
 
 1617   assert( za_start <= 180 );
 
 1626   if( ( za_start < 
ANGTOL  &&  r_start < r_surf )  || 
 
 1627                               ( za_start > 180-
ANGTOL  &&  r_start > r_surf ) )
 
 1632       l   = 
abs( r_surf - r_start );
 
 1637       const double   p  = x*
dx + y*dy + z*dz;
 
 1638       const double   pp = p * p;
 
 1639       const double   q  = x*x + y*y + z*z - r_surf*r_surf;
 
 1641       const double   l1 = -p + sqrt( pp - 
q );
 
 1642       const double   l2 = -p - sqrt( pp - 
q );
 
 1644       if( l1 < 0  &&  l2 > 0 )
 
 1646       else if( l1 > 0  &&  l2 < 0 )
 
 1656           lat = 
RAD2DEG * asin( ( y+dy*l ) / r );
 
 1657           lon = 
RAD2DEG * atan2( z+dz*l, x+
dx*l );
 
 1704         const double&   r_start0,
 
 1705         const double&   lat_start,
 
 1706         const double&   za_start,
 
 1711         const double&   rsurface )
 
 1713   double   r_start = r_start0;
 
 1716   assert( r_start >= ra - 
RTOL );
 
 1717   assert( r_start <= rb + 
RTOL );
 
 1722   else if( r_start > rb )
 
 1735   if( za_start <= 90 )
 
 1744       if( ( ra > rsurface )  &&  ( ra > ppc ) )
 
 1749       else if( ppc >= rsurface )
 
 1766                                                        za_start, r_end, lmax );
 
 1770     { za_v[za_v.
nelem()-1] = 90; }
 
 1832         const double&   r_start0,
 
 1833         const double&   lat_start,
 
 1834         const double&   za_start,
 
 1843         const double&   rsurface1,
 
 1844         const double&   rsurface3 )
 
 1846   double   r_start = r_start0;
 
 1849   assert( lat_start >= lat1 );
 
 1850   assert( lat_start <= lat3 );
 
 1855   const double  csurface = 
plevel_slope_2d( lat1, lat3, rsurface1, rsurface3 );
 
 1858   const double dlat_left  = lat_start - lat1;
 
 1861   const double   rlow = r1a + c2*dlat_left;
 
 1862   const double   rupp = r1b + c4*dlat_left;
 
 1865   double dlat_endface;
 
 1867     { dlat_endface = lat3 - lat_start; }
 
 1869     { dlat_endface = -dlat_left; }
 
 1872   assert( r_start >= rlow - 
RTOL );
 
 1873   assert( r_start <= rupp + 
RTOL );
 
 1876   if( r_start < rlow )
 
 1878   else if( r_start > rupp )
 
 1886   double   dlat2end = 999;
 
 1887   double   abs_za_start = 
abs( za_start );
 
 1896   if( r_start > rlow  &&  
abs(za_start) > 
ANGTOL )
 
 1908   if( rsurface1 >= r1a  ||  rsurface3 >= r3a )
 
 1910       double r_surface = rsurface1 + csurface * dlat_left;
 
 1912       assert( r_start >= r_surface );
 
 1916       if( 
abs(dlat2surface) <= 
abs(dlat2end) )
 
 1918           dlat2end = dlat2surface;
 
 1930   if( 
abs(dlat2end) > 
abs(dlat_endface)  &&  abs_za_start < 180-
ANGTOL )
 
 1938       if( 
abs(dlattry) < 
abs(dlat2end) )
 
 1946   if( 
abs(dlat2end) > 
abs(dlat_endface) )
 
 1948       dlat2end = dlat_endface; 
 
 1958   if( abs_za_start > 90  &&  ( abs_za_start - 
abs(dlat2end) ) <= 90 ) 
 
 1963       if( ( abs_za_start - 90 ) < 
abs( dlat2end ) )
 
 1966           dlat2end = 
sign(za_start) * ( abs_za_start - 90 ); 
 
 1981   else if( endface == 1 )
 
 1983   else if( endface == 2 )
 
 1984     { r_end = r1a + c2 * ( dlat_left + dlat2end ); }
 
 1985   else if( endface == 3 )
 
 1987   else if( endface == 4 )
 
 1988     { r_end = r1b + c4 * ( dlat_left + dlat2end ); }
 
 1989   else if( endface == 7 )
 
 1990     { r_end = rsurface1 + csurface * ( dlat_left + dlat2end ); }
 
 1995                                                        za_start, r_end, lmax );
 
 2001         { za_v[za_v.
nelem()-1] = 90; }
 
 2003         { za_v[za_v.
nelem()-1] = -90; }
 
 2007     { lat_v[lat_v.
nelem()-1] = lat1; }
 
 2008   else if( endface == 3 )
 
 2009     { lat_v[lat_v.
nelem()-1] = lat3; }
 
 2011     { lat_v[lat_v.
nelem()-1] = lat_start + dlat2end; }
 
 2078         const double&   r_start0, 
 
 2079         const double&   lat_start0,
 
 2080         const double&   lon_start0,
 
 2081         const double&   za_start,
 
 2082         const double&   aa_start,
 
 2097         const double&   rsurface15,
 
 2098         const double&   rsurface35,
 
 2099         const double&   rsurface36,
 
 2100         const double&   rsurface16 )
 
 2102   double   r_start   = r_start0;
 
 2103   double   lat_start = lat_start0;
 
 2104   double   lon_start = lon_start0;
 
 2107   assert( lat_start >= lat1 - 
LATLONTOL );
 
 2108   assert( lat_start <= lat3 + 
LATLONTOL );
 
 2109   assert( !( 
abs( lat_start) < 90  &&  lon_start < lon5 - 
LATLONTOL ) );
 
 2110   assert( !( 
abs( lat_start) < 90  &&  lon_start > lon6 + 
LATLONTOL ) );
 
 2113   if( lat_start < lat1 )
 
 2114     { lat_start = lat1; }
 
 2115   else if( lat_start > lat3 )
 
 2116     { lat_start = lat3; }
 
 2117   if( lon_start < lon5 )
 
 2118     { lon_start = lon5; }
 
 2119   else if( lon_start > lon6 )
 
 2120     { lon_start = lon6; }
 
 2124                                 r15a, r35a, r36a, r16a, lat_start, lon_start );
 
 2126                                 r15b, r35b, r36b, r16b, lat_start, lon_start );
 
 2129   assert( r_start >= rlow - 
RTOL );
 
 2130   assert( r_start <= rupp + 
RTOL );
 
 2133   if( r_start < rlow )
 
 2135   else if( r_start > rupp )
 
 2139   double   x, y, z, 
dx, dy, dz;
 
 2140   poslos2cart( x, y, z, 
dx, dy, dz, r_start, lat_start, lon_start, 
 
 2141                                                           za_start, aa_start );
 
 2148   double   r_end, lat_end, lon_end, l_end;
 
 2157       lat_end = lat_start;
 
 2158       lon_end = lon_start;
 
 2159       l_end   = rupp - r_start;
 
 2164   else if( za_start > 180-
ANGTOL )
 
 2167                                rsurface15, rsurface35, rsurface36, rsurface16, 
 
 2168                                                  lat_start, lon_start );
 
 2170       if( rlow > rsurface )
 
 2180       lat_end = lat_start;
 
 2181       lon_end = lon_start;
 
 2182       l_end   = r_start - r_end;
 
 2191       double   r_corr, lat_corr, lon_corr;
 
 2193       cart2sph( r_corr, lat_corr, lon_corr, x, y, z );
 
 2196       lat_corr -= lat_start;
 
 2197       lon_corr -= lon_start;
 
 2210       double   l_acc  = 1e-3;
 
 2211       double   l_in   = 0, l_out = l_end;
 
 2212       bool     ready  = 
false, startup = 
true;
 
 2213       double   abs_aa = 
abs( aa_start );
 
 2215       double   l_tan = 99e6;
 
 2217         { l_tan = sqrt( r_start*r_start - ppc*ppc ); }
 
 2219       bool   do_surface = 
false;
 
 2220       if( rsurface15+
RTOL >= r15a  ||  rsurface35+
RTOL >= r35a  ||  
 
 2221           rsurface36+
RTOL >= r36a  ||  rsurface16+
RTOL >= r16a )
 
 2222         { do_surface = 
true; }
 
 2228                                           x+
dx*l_end, y+dy*l_end, z+dz*l_end );
 
 2230           lat_end -= lat_corr;
 
 2231           lon_end -= lon_corr;
 
 2235           if( 
abs( lat_start ) < 90  &&  ( 
abs(aa_start) < 
ANGTOL  ||  
 
 2237             { lon_end = lon_start; }
 
 2242               if( lat_start == 0 )
 
 2244               else if( lat_start > 0  &&  lat_end > lat_start )
 
 2245                 { lat_end = lat_start; }
 
 2246               else if( lat_start < 0  &&  lat_end < lat_start )
 
 2247                 { lat_end = lat_start; }
 
 2253                                 r15a, r35a, r36a, r16a, lat_end, lon_end );
 
 2255                                 r15b, r35b, r36b, r16b, lat_end, lon_end );
 
 2259               const double   r_surface = 
 
 2261                            rsurface15, rsurface35, rsurface36, rsurface16, 
 
 2264               if( r_surface+
RTOL >= rlow  &&  r_end <= r_surface+
RTOL )
 
 2265                 { inside = 
false;   endface = 7; }
 
 2270               if( lat_end < lat1 )
 
 2271                 { inside = 
false;   endface = 1; }
 
 2272               else if( lat_end > lat3 )
 
 2273                 { inside = 
false;   endface = 3; }
 
 2274               else if( lon_end < lon5 )
 
 2275                 { inside = 
false;   endface = 5; }
 
 2276               else if( lon_end > lon6 )
 
 2277                 { inside = 
false;   endface = 6; }
 
 2278               else if( r_end < rlow )
 
 2279                 { inside = 
false;   endface = 2; }
 
 2280               else if( r_end > rupp )
 
 2281                 { inside = 
false;   endface = 4; }
 
 2288                   if( l_end < l_tan  &&  l_end*10 > l_tan )
 
 2296                   l_end = ( l_out + l_in ) / 2;
 
 2307               if( ( l_out - l_in ) < l_acc )
 
 2310                 { l_end = ( l_out + l_in ) / 2; }
 
 2318       lat_end += lat_corr;
 
 2319       lon_end += lon_corr;
 
 2326       else if( endface == 2 )
 
 2328                                                     r16a, lat_end, lon_end ); }
 
 2329       else if( endface == 3 )
 
 2331       else if( endface == 4 )
 
 2333                                                     r16b, lat_end, lon_end ); }
 
 2334       else if( endface == 5 )
 
 2336       else if( endface == 6 )
 
 2338       else if( endface == 7 )
 
 2340                       rsurface35, rsurface36, rsurface16, lat_end, lon_end ); }
 
 2349                                   r_start, lat_start, lon_start, 
 
 2350                                   za_start, aa_start, ppc );
 
 2355           else if( l_tan == l_end )
 
 2366       n = 
Index( ceil( 
abs( l_end / lmax ) ) );
 
 2378   lat_v[0] = lat_start;
 
 2379   lon_v[0] = lon_start;
 
 2383   double  ldouble = l_end / (double)n;
 
 2386   for( 
Index j=1; j<=n; j++ )
 
 2388       const double   l  = ldouble * (double)j;
 
 2394       cart2poslos( r_v[j], lat_v[j], lon_v[j], za_v[j], aa_v[j],
 
 2395                                           x+
dx*l, y+dy*l, z+dz*l, 
dx, dy, dz );
 
 2397       double   rtmp, lattmp, lontmp, zatmp, aatmp;
 
 2399                                           x+
dx*l, y+dy*l, z+dz*l, 
dx, dy, dz );
 
 2415   if( za_start < ANGTOL  ||  za_start > 180-
ANGTOL )
 
 2416     { za_v[n] = za_start; }
 
 2424   if( 
abs( lat_start ) < 90  &&  
 
 2428       lon_v[n] = lon_start;
 
 2432   for( 
Index j=1; j<n; j++ )
 
 2463         const Index&      atmosphere_dim,
 
 2466   assert( atmosphere_dim >= 1 );
 
 2467   assert( atmosphere_dim <= 3 );
 
 2469   ppath.
dim        = atmosphere_dim;
 
 2472   if( atmosphere_dim < 3 )
 
 2481       ppath.
gp_lon.resize( np );
 
 2483   ppath.
gp_p.resize( np );
 
 2484   if( atmosphere_dim >= 2 )
 
 2485     { ppath.
gp_lat.resize( np ); }
 
 2521         const Index&      case_nr )
 
 2542       os << 
"Case number " << case_nr << 
" is not defined.";
 
 2543       throw runtime_error(os.str());
 
 2569   else if( ppath.
background == 
"cloud box level" )
 
 2571   else if( ppath.
background == 
"cloud box interior" )
 
 2577          << 
" is not a valid background case.";
 
 2578       throw runtime_error(os.str());
 
 2600      const Ppath&      ppath2 )
 
 2602   assert( ppath1.
np >= ppath2.
np ); 
 
 2612   ppath1.
z[
Range(0,ppath2.
np)]         = ppath2.
z;
 
 2615   for( 
Index i=0; i<ppath2.
np; i++ )
 
 2619       if( ppath1.
dim >= 2 )
 
 2622       if( ppath1.
dim == 3 )
 
 2654      const Ppath&   ppath2 )
 
 2668   for( 
Index i=1; i<n2; i++ )
 
 2672       ppath1.
pos(i1,0)      = ppath2.
pos(i,0);
 
 2673       ppath1.
pos(i1,1)      = ppath2.
pos(i,1);
 
 2674       ppath1.
los(i1,0)      = ppath2.
los(i,0);
 
 2675       ppath1.
z[i1]          = ppath2.
z[i];
 
 2678       if( ppath1.
dim >= 2 )
 
 2681       if( ppath1.
dim == 3 )
 
 2683           ppath1.
pos(i1,2)        = ppath2.
pos(i,2);
 
 2684           ppath1.
los(i1,1)        = ppath2.
los(i,1);
 
 2728      const double&     r_geoid,
 
 2733   const double   r1 = r_geoid + z_field[ip];
 
 2734   const double   dr = z_field[ip+1] - z_field[ip];
 
 2738       ppath.
pos(i,0) = r[i];
 
 2739       ppath.
pos(i,1) = lat[i];
 
 2740       ppath.
los(i,0) = za[i];
 
 2742       ppath.
gp_p[i].idx   = ip;
 
 2743       ppath.
gp_p[i].fd[0] = ( r[i] - r1 ) / dr;
 
 2744       ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
 
 2747       ppath.
z[i] = r[i] - r_geoid;
 
 2750         { ppath.
l_step[i-1] = lstep[i-1]; }
 
 2787      const double&     lstep,
 
 2795   const double   dlat  = lat_grid[ilat+1] - lat_grid[ilat];
 
 2796   const double   r1low = r_geoid[ilat] + z_field(ip,ilat);
 
 2797   const double   drlow = r_geoid[ilat+1] + z_field(ip,ilat+1) -r1low;
 
 2798   const double   r1upp = r_geoid[ilat] + z_field(ip+1,ilat);
 
 2799   const double   drupp = r_geoid[ilat+1] + z_field(ip+1,ilat+1) - r1upp;
 
 2800   const double   z1low =  z_field(ip,ilat);
 
 2801   const double   dzlow =  z_field(ip,ilat+1) -z1low;
 
 2802   const double   z1upp =  z_field(ip+1,ilat);
 
 2803   const double   dzupp =  z_field(ip+1,ilat+1) - z1upp;
 
 2807       ppath.
pos(i,0) = r[i];
 
 2808       ppath.
pos(i,1) = lat[i];
 
 2809       ppath.
los(i,0) = za[i];
 
 2812       double w = ( lat[i] - lat_grid[ilat] ) / dlat;
 
 2815       const double rlow = r1low + w * drlow;
 
 2816       const double rupp = r1upp + w * drupp;
 
 2819       const double zlow = z1low + w * dzlow;
 
 2820       const double zupp = z1upp + w * dzupp;
 
 2822       ppath.
gp_p[i].idx   = ip;
 
 2823       ppath.
gp_p[i].fd[0] = ( r[i] - rlow ) / ( rupp - rlow );
 
 2824       ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
 
 2827       ppath.
z[i] = zlow + ppath.
gp_p[i].fd[0] * ( zupp -zlow );
 
 2829       ppath.
gp_lat[i].idx   = ilat;
 
 2830       ppath.
gp_lat[i].fd[0] = ( lat[i] - lat_grid[ilat] ) / dlat;
 
 2835         { ppath.
l_step[i-1] = lstep; }
 
 2878      const double&     lstep,
 
 2888   const double   lat1  = lat_grid[ilat];
 
 2889   const double   lat3  = lat_grid[ilat+1];
 
 2890   const double   lon5  = lon_grid[ilon];
 
 2891   const double   lon6  = lon_grid[ilon+1];
 
 2892   const double   r15a  = r_geoid(ilat,ilon) + z_field(ip,ilat,ilon);
 
 2893   const double   r35a  = r_geoid(ilat+1,ilon) + z_field(ip,ilat+1,ilon); 
 
 2894   const double   r36a  = r_geoid(ilat+1,ilon+1) + z_field(ip,ilat+1,ilon+1); 
 
 2895   const double   r16a  = r_geoid(ilat,ilon+1) + z_field(ip,ilat,ilon+1);
 
 2896   const double   r15b  = r_geoid(ilat,ilon) + z_field(ip+1,ilat,ilon);
 
 2897   const double   r35b  = r_geoid(ilat+1,ilon) + z_field(ip+1,ilat+1,ilon); 
 
 2898   const double   r36b  = r_geoid(ilat+1,ilon+1) + z_field(ip+1,ilat+1,ilon+1);
 
 2899   const double   r16b  = r_geoid(ilat,ilon+1) + z_field(ip+1,ilat,ilon+1);
 
 2900   const double   rg15  = r_geoid(ilat,ilon);
 
 2901   const double   rg35  = r_geoid(ilat+1,ilon); 
 
 2902   const double   rg36  = r_geoid(ilat+1,ilon+1);
 
 2903   const double   rg16  = r_geoid(ilat,ilon+1);     
 
 2904   const double   dlat  = lat3 - lat1;
 
 2905   const double   dlon  = lon6 - lon5;
 
 2911                                       r15a, r35a, r36a, r16a, lat[i], lon[i] );
 
 2913                                       r15b, r35b, r36b, r16b, lat[i], lon[i] );
 
 2916       ppath.
pos(i,0) = r[i];
 
 2917       ppath.
pos(i,1) = lat[i];
 
 2918       ppath.
pos(i,2) = lon[i];
 
 2919       ppath.
los(i,0) = za[i];
 
 2920       ppath.
los(i,1) = aa[i];
 
 2923       ppath.
gp_p[i].idx   = ip;
 
 2924       ppath.
gp_p[i].fd[0] = ( ppath.
pos(i,0) - rlow ) / ( rupp - rlow );
 
 2925       ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
 
 2930                                       rg15, rg35, rg36, rg16, lat[i], lon[i] );
 
 2931       const double   zlow = rlow - rgeoid;
 
 2932       const double   zupp = rupp - rgeoid;
 
 2934       ppath.
z[i] = zlow + ppath.
gp_p[i].fd[0] * ( zupp -zlow );
 
 2937       ppath.
gp_lat[i].idx   = ilat;
 
 2938       ppath.
gp_lat[i].fd[0] = ( lat[i] - lat1 ) / dlat;
 
 2947       if( 
abs( lat[i] ) < 90 )
 
 2949           ppath.
gp_lon[i].idx   = ilon;
 
 2950           ppath.
gp_lon[i].fd[0] = ( lon[i] - lon5 ) / dlon;
 
 2957           ppath.
gp_lon[i].fd[0] = 0;
 
 2958           ppath.
gp_lon[i].fd[1] = 1;
 
 2962         { ppath.
l_step[i-1] = lstep; }
 
 2991         const double&   refr_index )
 
 2994   assert( 
abs(za) <= 180 );
 
 2996   return r * refr_index * sin( 
DEG2RAD * 
abs(za) );
 
 3028         const Ppath&      ppath )
 
 3031   const Index   imax = ppath.
np - 1;
 
 3034   r_start   = ppath.
pos(imax,0);
 
 3035   lat_start = ppath.
pos(imax,1);
 
 3036   za_start  = ppath.
los(imax,0);
 
 3063         const double&     lstep,
 
 3065         const double&     r_geoid,
 
 3067         const Index&      endface,
 
 3068         const Index&      tanpoint,
 
 3094       ppath.
tan_pos[1] = lat_v[np-1];
 
 3140   const Index imax = ppath.
np - 1;
 
 3143   r_start   = ppath.
pos(imax,0);
 
 3144   lat_start = ppath.
pos(imax,1);
 
 3145   za_start  = ppath.
los(imax,0);
 
 3152   lat1 = lat_grid[ilat];
 
 3153   lat3 = lat_grid[ilat+1];
 
 3163   r1a = r_geoid[ilat] + z_field(ip,ilat);        
 
 3164   r3a = r_geoid[ilat+1] + z_field(ip,ilat+1);    
 
 3165   r3b = r_geoid[ilat+1] + z_field(ip+1,ilat+1);  
 
 3166   r1b = r_geoid[ilat] + z_field(ip+1,ilat);      
 
 3172     const double   rlow = 
rsurf_at_lat( lat1, lat3, r1a, r3a, lat_start );
 
 3173     const double   rupp = 
rsurf_at_lat( lat1, lat3, r1b, r3b, lat_start );
 
 3194           r1b = r1a;   r3b = r3a;   c4 = c2;
 
 3195           r1a = r_geoid[ilat] + z_field(ip,ilat);
 
 3196           r3a = r_geoid[ilat+1] + z_field(ip,ilat+1);
 
 3207           r1a = r1b;   r3a = r3b;   c2 = c4;
 
 3208           r3b = r_geoid[ilat+1] + z_field(ip+1,ilat+1);
 
 3209           r1b = r_geoid[ilat] + z_field(ip+1,ilat);    
 
 3215   rsurface1 = r_geoid[ilat] + z_surface[ilat];
 
 3216   rsurface3 = r_geoid[ilat+1] + z_surface[ilat+1];
 
 3238         const double&     lstep,
 
 3244         const Index&      endface,
 
 3245         const Index&      tanpoint,
 
 3250   const Index   imax = np-1;
 
 3258   ppath_fill_2d( ppath, r_v, lat_v, za_v, lstep, r_geoid, z_field, lat_grid, 
 
 3271       ppath.
tan_pos[1] = lat_v[np-1];
 
 3276   if( endface == 1  ||  endface == 3 )
 
 3278   else if( endface == 2  ||  endface == 4 )
 
 3283   if( ppath.
gp_p[imax].fd[0] < 0  ||  ppath.
gp_p[imax].fd[1] < 0 )
 
 3287   if( ppath.
gp_lat[imax].fd[0] < 0  ||  ppath.
gp_lat[imax].fd[1] < 0 )
 
 3340   const Index imax = ppath.
np - 1;
 
 3343   r_start   = ppath.
pos(imax,0);
 
 3344   lat_start = ppath.
pos(imax,1);
 
 3345   lon_start = ppath.
pos(imax,2);
 
 3346   za_start  = ppath.
los(imax,0);
 
 3347   aa_start  = ppath.
los(imax,1);
 
 3358   if( lat_start == 90 )
 
 3362       gridpos( gp_tmp, lon_grid, aa_start );
 
 3363       if( aa_start < 180 )
 
 3368   else if( lat_start == -90 )
 
 3372       gridpos( gp_tmp, lon_grid, aa_start );
 
 3373       if( aa_start < 180 )
 
 3384       if( lon_start < lon_grid[nlon-1] )
 
 3387         { ilon = nlon - 2; }
 
 3390   lat1 = lat_grid[ilat];
 
 3391   lat3 = lat_grid[ilat+1];
 
 3392   lon5 = lon_grid[ilon];
 
 3393   lon6 = lon_grid[ilon+1];
 
 3403   r15a = r_geoid(ilat,ilon) + z_field(ip,ilat,ilon);
 
 3404   r35a = r_geoid(ilat+1,ilon) + z_field(ip,ilat+1,ilon); 
 
 3405   r36a = r_geoid(ilat+1,ilon+1) + z_field(ip,ilat+1,ilon+1); 
 
 3406   r16a = r_geoid(ilat,ilon+1) + z_field(ip,ilat,ilon+1);
 
 3407   r15b = r_geoid(ilat,ilon) + z_field(ip+1,ilat,ilon);
 
 3408   r35b = r_geoid(ilat+1,ilon) + z_field(ip+1,ilat+1,ilon); 
 
 3409   r36b = r_geoid(ilat+1,ilon+1) + z_field(ip+1,ilat+1,ilon+1); 
 
 3410   r16b = r_geoid(ilat,ilon+1) + z_field(ip+1,ilat,ilon+1);
 
 3417   if( fabs(za_start-90) <= 
PTILTMAX )
 
 3423                        r15a, r35a, r36a, r16a, lat_start, lon_start, aa_start );
 
 3434               r15b = r15a;   r35b = r35a;   r36b = r36a;   r16b = r16a;
 
 3435               r15a = r_geoid(ilat,ilon) + z_field(ip,ilat,ilon);
 
 3436               r35a = r_geoid(ilat+1,ilon) + z_field(ip,ilat+1,ilon); 
 
 3437               r36a = r_geoid(ilat+1,ilon+1) + z_field(ip,ilat+1,ilon+1); 
 
 3438               r16a = r_geoid(ilat,ilon+1) + z_field(ip,ilat,ilon+1);
 
 3445                        r15b, r35b, r36b, r16b, lat_start, lon_start, aa_start );
 
 3451               r15a = r15b;   r35a = r35b;   r36a = r36b;   r16a = r16b;
 
 3452               r15b = r_geoid(ilat,ilon) + z_field(ip+1,ilat,ilon);
 
 3453               r35b = r_geoid(ilat+1,ilon) + z_field(ip+1,ilat+1,ilon); 
 
 3454               r36b = r_geoid(ilat+1,ilon+1) + z_field(ip+1,ilat+1,ilon+1); 
 
 3455               r16b = r_geoid(ilat,ilon+1) + z_field(ip+1,ilat,ilon+1);
 
 3461   rsurface15 = r_geoid(ilat,ilon) + z_surface(ilat,ilon);
 
 3462   rsurface35 = r_geoid(ilat+1,ilon) + z_surface(ilat+1,ilon);
 
 3463   rsurface36 = r_geoid(ilat+1,ilon+1) + z_surface(ilat+1,ilon+1);
 
 3464   rsurface16 = r_geoid(ilat,ilon+1) + z_surface(ilat,ilon+1);
 
 3488         const double&     lstep,
 
 3496         const Index&      endface,
 
 3497         const Index&      tanpoint,
 
 3502   const Index   imax = np-1;
 
 3511                         r_geoid, z_field, lat_grid, lon_grid, ip, ilat, ilon );
 
 3514   assert( ppath.
gp_p[imax].fd[0] > -0.01 );   
 
 3515   assert( ppath.
gp_p[imax].fd[0] < 1.01 );
 
 3516   assert( ppath.
gp_lat[imax].fd[0] > -0.01 );
 
 3517   assert( ppath.
gp_lat[imax].fd[0] < 1.01 );
 
 3518   assert( ppath.
gp_lon[imax].fd[0] > -0.01 );
 
 3519   assert( ppath.
gp_lon[imax].fd[0] < 1.01 );
 
 3528       ppath.
tan_pos[1] = lat_v[imax];
 
 3529       ppath.
tan_pos[2] = lon_v[imax];
 
 3534   if( endface == 1  ||  endface == 3 )
 
 3536   else if( endface == 2  ||  endface == 4 )
 
 3538   else if( endface == 5  ||  endface == 6 )
 
 3543   if( ppath.
gp_p[imax].fd[0] < 0  ||  ppath.
gp_p[imax].fd[1] < 0 )
 
 3547   if( ppath.
gp_lat[imax].fd[0] < 0  ||  ppath.
gp_lat[imax].fd[1] < 0 )
 
 3551   if( ppath.
gp_lon[imax].fd[0] < 0  ||  ppath.
gp_lon[imax].fd[1] < 0 )
 
 3585        const double&     lmax )
 
 3593         double   ltotsum = l_rt.
sum();
 
 3596     { n = 
max (
Index( ceil( ltotsum / lmax ) ) + 1, 
Index(2)); }
 
 3604       r_v[0] = r_rt[0];     r_v[1] = r_rt[nrt-1];
 
 3605       za_v[0] = za_rt[0];   za_v[1] = za_rt[nrt-1];
 
 3606       lat_v[0] = lat_rt[0]; lat_v[1] = lat_rt[nrt-1];
 
 3608       if( lon_rt.
nelem() > 0 )
 
 3610             lon_v.
resize(n); lon_v[0] = lon_rt[0]; lon_v[1] = lon_rt[nrt-1];
 
 3611             aa_v.
resize(n);  aa_v[0] = aa_rt[0];   aa_v[1] = aa_rt[nrt-1];
 
 3616       Vector           lsum(nrt), llin(n);
 
 3621       for( 
Index i=1; i<nrt; i++ )
 
 3622         { lsum[i] = lsum[i-1] + l_rt[i-1]; }
 
 3630       interp( r_v, itw, r_rt, gp );
 
 3631       interp( za_v, itw, za_rt, gp );
 
 3632       interp( lat_v, itw, lat_rt, gp );
 
 3633       lstep = llin[1] - llin[0];
 
 3635       if( lon_rt.
nelem() > 0 )
 
 3664        const Index&           reversed,
 
 3665        const double&          lmax )
 
 3672   Vector    r_rt(nrt), lat_rt(nrt), za_rt(nrt), l_rt(nrt-1);    
 
 3676       for( 
Index i=0; i<nrt; i++ )
 
 3678           r_rt[i]   = r_array[i];
 
 3679           lat_rt[i] = lat_array[i]; 
 
 3680           za_rt[i]  = za_array[i];
 
 3682             { l_rt[i]   = l_array[i]; }
 
 3687       for( 
Index i=0; i<nrt; i++ )
 
 3689           const Index i1 = nrt - 1 - i;
 
 3690           r_rt[i]   = r_array[i1];
 
 3691           lat_rt[i] = lat_array[0]+ lat_array[nrt-1] - lat_array[i1]; 
 
 3692           za_rt[i]  = 180 - za_array[i1];
 
 3694             { l_rt[i]   = l_array[i1-1]; }
 
 3704       r_rt, lat_rt, 
Vector(0), za_rt, 
Vector(0), l_rt, lmax );
 
 3730        const double&          lmax )
 
 3737   Vector    r_rt(nrt), lat_rt(nrt), lon_rt(nrt);
 
 3738   Vector    za_rt(nrt), aa_rt(nrt),l_rt(nrt-1);    
 
 3740   for( 
Index i=0; i<nrt; i++ )
 
 3742       r_rt[i]   = r_array[i];
 
 3743       lat_rt[i] = lat_array[i]; 
 
 3744       lon_rt[i] = lon_array[i]; 
 
 3745       za_rt[i]  = za_array[i];
 
 3746       aa_rt[i]  = aa_array[i];
 
 3748         { l_rt[i]   = l_array[i]; }
 
 3755                               r_rt, lat_rt, lon_rt, za_rt, aa_rt, l_rt, lmax );
 
 3795         const double&     r_geoid,
 
 3796         const double&     z_surface,
 
 3797         const double&     lmax )
 
 3800   double r_start, lat_start, za_start;
 
 3824   Index     endface, tanpoint;
 
 3827                    r_start, lat_start, za_start, ppc, lmax, 
 
 3828                r_geoid+z_field[ip], r_geoid+z_field[ip+1], r_geoid+z_surface );
 
 3833   ppath_end_1d( ppath, r_v, lat_v, za_v, lstep, z_field, r_geoid, ip, endface, 
 
 3838   if( endface == 0  &&  tanpoint )
 
 3878         const double&     lmax )
 
 3881   double   r_start, lat_start, za_start;
 
 3887   double   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
 
 3891                   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3,
 
 3892                   ppath, lat_grid, z_field, r_geoid, z_surface );
 
 3906   Index     endface, tanpoint;
 
 3909                   r_start, lat_start, za_start, ppc, lmax, lat1, lat3, 
 
 3910                                     r1a, r3a, r3b, r1b, rsurface1, rsurface3 );
 
 3914   ppath_end_2d( ppath, r_v, lat_v, za_v, lstep, lat_grid, z_field, r_geoid, 
 
 3915                                             ip, ilat, endface, tanpoint, ppc );
 
 3920   if( endface == 0  &&  tanpoint )
 
 3928                                                      r_geoid, z_surface, lmax );
 
 3964         const double&      lmax )
 
 3967   double   r_start, lat_start, lon_start, za_start, aa_start;
 
 3970   Index   ip, ilat, ilon;
 
 3974   double   lat1, lat3, lon5, lon6;
 
 3975   double   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
 
 3976   double   rsurface15, rsurface35, rsurface36, rsurface16;
 
 3979   ppath_start_3d( r_start, lat_start, lon_start, za_start, aa_start, 
 
 3980                   ip, ilat, ilon, lat1, lat3, lon5, lon6,
 
 3981                   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b, 
 
 3982                   rsurface15, rsurface35, rsurface36, rsurface16,
 
 3983                   ppath, lat_grid, lon_grid, z_field, r_geoid, z_surface );
 
 3996   Vector    r_v, lat_v, lon_v, za_v, aa_v;
 
 3998   Index     endface, tanpoint;
 
 4000   do_gridcell_3d( r_v, lat_v, lon_v, za_v, aa_v, lstep, endface, tanpoint,
 
 4001                   r_start, lat_start, lon_start, za_start, aa_start, ppc, lmax,
 
 4002                   lat1, lat3, lon5, lon6, 
 
 4003                   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b,
 
 4004                   rsurface15, rsurface35, rsurface36, rsurface16 );
 
 4008   ppath_end_3d( ppath, r_v, lat_v, lon_v, za_v, aa_v, lstep, lat_grid, 
 
 4009           lon_grid, z_field, r_geoid, ip, ilat, ilon, endface, tanpoint, ppc );
 
 4014   if( endface == 0  &&  tanpoint )
 
 4022                                                      r_geoid, z_surface, lmax );
 
 4105         const Agenda&          refr_index_agenda,
 
 4107         const double&          lraytrace,
 
 4110         const double&          r_surface,
 
 4111         const double&          r_geoid,
 
 4122   double   lstep, dlat = 9999;
 
 4130       do_gridrange_1d( r_v, lat_v, za_v, lstep, endface, tanpoint, r, lat, za,
 
 4131                                               ppc_step, -1, r1, r3, r_surface );
 
 4133       assert( r_v.
nelem() == 2 );
 
 4142       if( lstep <= 1.01 * lraytrace )
 
 4145           dlat  = lat_v[1] - lat;
 
 4152             { lstep = lraytrace; }
 
 4154             { lstep = -lraytrace; }
 
 4159           dlat = 
RAD2DEG * acos( ( r_new*r_new + r*r - 
 
 4160                                              lstep*lstep ) / ( 2 * r_new*r ) );
 
 4163           lstep = 
abs( lstep );
 
 4170                          rte_vmr_list, refr_index_agenda,
 
 4171                          p_grid, r_geoid, z_field, t_field, vmr_field, r );
 
 4173       const double   ppc_local = ppc / refr_index; 
 
 4175       if( ready  &&  tanpoint )
 
 4177       else if( r >= ppc_local )
 
 4193       r_array.push_back( r );
 
 4194       lat_array.push_back( lat );
 
 4195       za_array.push_back( za );
 
 4196       l_array.push_back( lstep );
 
 4272         const Agenda&          refr_index_agenda,
 
 4273         const double&          lraytrace,
 
 4280         const double&          rsurface1,
 
 4281         const double&          rsurface3,
 
 4294   double   lstep, dlat = 9999, r_new, lat_new;
 
 4303                      r, lat, za, ppc_step, -1, lat1, lat3, r1a, r3a, r3b, r1b, 
 
 4304                       rsurface1, rsurface3 );
 
 4306       assert( r_v.
nelem() == 2 );
 
 4315       if( lstep <= 1.01 * lraytrace )
 
 4318           dlat    = lat_v[1] - lat;
 
 4325             { lstep = lraytrace; }
 
 4327             { lstep = -lraytrace; }
 
 4331           dlat = 
RAD2DEG * acos( ( r_new*r_new + r*r - 
 
 4332                                              lstep*lstep ) / ( 2 * r_new*r ) );
 
 4336           lat_new = lat + dlat;
 
 4337           lstep   = 
abs( lstep );
 
 4341           if( lat_new < lat1 )
 
 4343           else if( lat_new > lat3 )
 
 4348       if( ready  &&  tanpoint )
 
 4359           const double   za_rad = 
DEG2RAD * za;
 
 4362                              rte_temperature, rte_vmr_list, refr_index_agenda,
 
 4363                              p_grid, lat_grid, r_geoid, z_field, t_field, 
 
 4364                              vmr_field, r, lat );
 
 4366           za += -dlat + 
RAD2DEG * lstep / refr_index * ( -sin(za_rad) * dndr +
 
 4367                                                         cos(za_rad) * dndlat );
 
 4381       if( lat == lat1  &&  za < 0 )
 
 4382         { endface = 1;   ready = 1; }
 
 4383       else if( lat == lat3  &&  za > 0 )
 
 4384         { endface = 3;   ready = 1; }
 
 4387       r_array.push_back( r );
 
 4388       lat_array.push_back( lat );
 
 4389       za_array.push_back( za );
 
 4390       l_array.push_back( lstep );
 
 4484         const Agenda&          refr_index_agenda,
 
 4485         const double&          lraytrace,
 
 4498         const double&          rsurface15,
 
 4499         const double&          rsurface35,
 
 4500         const double&          rsurface36,
 
 4501         const double&          rsurface16,
 
 4514   Vector    r_v, lat_v, lon_v, za_v, aa_v;
 
 4515   double    r_new, lat_new, lon_new, za_new, aa_new;
 
 4524       do_gridcell_3d( r_v, lat_v, lon_v, za_v, aa_v, lstep, endface, tanpoint,
 
 4525                     r, lat, lon, za, aa, ppc_step, -1, lat1, lat3, lon5, lon6, 
 
 4526                     r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b,
 
 4527                       rsurface15, rsurface35, rsurface36, rsurface16 );
 
 4529       assert( r_v.
nelem() == 2 );
 
 4538       if( lstep <= 1.01 * lraytrace )
 
 4550           double   x, y, z, 
dx, dy, dz;
 
 4551           poslos2cart( x, y, z, 
dx, dy, dz, r, lat, lon, za, aa ); 
 
 4555           cart2poslos( r_new, lat_new, lon_new, za_new, aa_new, 
 
 4556                               x+
dx*lstep, y+dy*lstep, z+dz*lstep, 
dx, dy, dz );
 
 4560           if( lat_new < lat1 )
 
 4562           else if( lat_new > lat3 )
 
 4564           if( lon_new < lon5 )
 
 4566           else if( lon_new > lon6 )
 
 4574           if( za < ANGTOL  ||  za > 180-
ANGTOL )
 
 4581           if( 
abs( lat ) < 90  &&  
 
 4593       if( ready  &&  tanpoint )
 
 4606                              refr_index, dndr, dndlat, dndlon, rte_pressure, 
 
 4607                              rte_temperature, rte_vmr_list, refr_index_agenda, 
 
 4608                              p_grid, lat_grid, lon_grid, r_geoid, z_field, 
 
 4609                              t_field, vmr_field, r, lat, lon );
 
 4611           const double   aterm = 
RAD2DEG * lstep / refr_index;
 
 4612           const double   za_rad = 
DEG2RAD * za;
 
 4613           const double   aa_rad = 
DEG2RAD * aa;
 
 4614           const double   sinza = sin( za_rad );
 
 4615           const double   sinaa = sin( aa_rad );
 
 4616           const double   cosaa = cos( aa_rad );
 
 4619           if( za < ANGTOL  ||  za > 180-
ANGTOL )
 
 4621               za_new += aterm * ( cos(za_rad) * 
 
 4622                                        ( cosaa * dndlat + sinaa * dndlon ) );
 
 4623               aa_new = 
RAD2DEG * atan2( dndlon, dndlat); 
 
 4627               za_new += aterm * ( -sinza * dndr + cos(za_rad) * 
 
 4628                                        ( cosaa * dndlat + sinaa * dndlon ) );
 
 4629               aa_new += aterm * sinza * ( cosaa * dndlon - sinaa * dndlat ); 
 
 4634             { za_new = 180 - za_new; }
 
 4635           else if( za_new < 0 )
 
 4636             { za_new = -za_new; }
 
 4640           else if( aa_new < -180 )
 
 4653       if( lon == lon5  &&  aa < 0 )
 
 4654         { endface = 5;   ready = 1; }
 
 4655       else if( lon == lon6  &&  aa > 0 )
 
 4656         { endface = 6;   ready = 1; }
 
 4657       else if( za > 0  &&  za < 180 )
 
 4659           if( lat == lat1  &&  lat != -90  &&  
abs( aa ) > 90 ) 
 
 4660             { endface = 1;   ready = 1; }
 
 4661           else if( lat == lat3  &&  lat != 90  &&  
abs( aa ) < 90 ) 
 
 4662             { endface = 3;   ready = 1; }
 
 4666       r_array.push_back( r );
 
 4667       lat_array.push_back( lat );
 
 4668       lon_array.push_back( lon );
 
 4669       za_array.push_back( za );
 
 4670       aa_array.push_back( aa );
 
 4671       l_array.push_back( lstep );
 
 4721         const Agenda&     refr_index_agenda,
 
 4726         const double&     r_geoid,
 
 4727         const double&     z_surface,
 
 4728         const String&     rtrace_method,
 
 4729         const double&     lraytrace,
 
 4730         const double&     lmax )
 
 4733   double   r_start, lat_start, za_start;
 
 4751                          refr_index_agenda, p_grid, r_geoid, z_field, 
 
 4752                          t_field, vmr_field, r_start );
 
 4766   r_array.push_back( r_start );
 
 4767   lat_array.push_back( lat_start );
 
 4768   za_array.push_back( za_start );
 
 4771   Index   endface, tanpoint;
 
 4773   if( rtrace_method  == 
"linear_euler" )
 
 4776         r_array, lat_array, za_array, l_array, endface,
 
 4777         tanpoint, r_start, lat_start, za_start, rte_pressure, rte_temperature, 
 
 4778             rte_vmr_list, refr_index, refr_index_agenda, ppc, lraytrace, 
 
 4779             r_geoid+z_field[ip], r_geoid+z_field[ip+1], r_geoid + z_surface, 
 
 4780                                 r_geoid, p_grid, z_field, t_field, vmr_field );
 
 4785       bool   known_ray_trace_method = 
false;
 
 4786       assert( known_ray_trace_method );
 
 4798                               r_array, lat_array, za_array, l_array, 0, lmax );
 
 4802   ppath_end_1d( ppath, r_v, lat_v, za_v, lstep, z_field, r_geoid, ip, endface, 
 
 4807   if( endface == 0  &&  tanpoint )
 
 4816                 ppath2, rte_pressure, rte_temperature, rte_vmr_list,
 
 4817                 refr_index, refr_index_agenda, p_grid, z_field, t_field,
 
 4818                 vmr_field, r_geoid, z_surface, rtrace_method, lraytrace, lmax );
 
 4864         const Agenda&     refr_index_agenda,
 
 4872         const String&     rtrace_method,
 
 4873         const double&     lraytrace,
 
 4874         const double&     lmax )
 
 4877   double   r_start, lat_start, za_start;
 
 4883   double   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
 
 4887                   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3,
 
 4888                   ppath, lat_grid, z_field, r_geoid, z_surface );
 
 4899   r_array.push_back( r_start );
 
 4900   lat_array.push_back( lat_start );
 
 4901   za_array.push_back( za_start );
 
 4904   Index   endface, tanpoint;
 
 4906   if( rtrace_method  == 
"linear_euler" )
 
 4909         r_array, lat_array, za_array, l_array, endface,
 
 4910         tanpoint, r_start, lat_start, za_start, rte_pressure, rte_temperature, 
 
 4911         rte_vmr_list, refr_index, refr_index_agenda, lraytrace, 
 
 4912         lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3,
 
 4913         p_grid, lat_grid, r_geoid, z_field, t_field, vmr_field );
 
 4918       bool   known_ray_trace_method = 
false;
 
 4919       assert( known_ray_trace_method );
 
 4931                               r_array, lat_array, za_array, l_array, 0, lmax );
 
 4935   ppath_end_2d( ppath, r_v, lat_v, za_v, lstep, lat_grid, z_field, r_geoid, 
 
 4936                                              ip, ilat, endface, tanpoint, -1 );
 
 4941   if( endface == 0  &&  tanpoint )
 
 4949                     ppath2, rte_pressure, rte_temperature, rte_vmr_list,
 
 4950                     refr_index, refr_index_agenda, p_grid, lat_grid, z_field, 
 
 4952                     r_geoid, z_surface, rtrace_method, lraytrace, lmax );
 
 4999         const Agenda&     refr_index_agenda,
 
 5008         const String&     rtrace_method,
 
 5009         const double&     lraytrace,
 
 5010         const double&     lmax )
 
 5013   double   r_start, lat_start, lon_start, za_start, aa_start;
 
 5016   Index   ip, ilat, ilon;
 
 5020   double   lat1, lat3, lon5, lon6;
 
 5021   double   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
 
 5022   double   rsurface15, rsurface35, rsurface36, rsurface16;
 
 5025   ppath_start_3d( r_start, lat_start, lon_start, za_start, aa_start, 
 
 5026                   ip, ilat, ilon, lat1, lat3, lon5, lon6,
 
 5027                   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b, 
 
 5028                   rsurface15, rsurface35, rsurface36, rsurface16,
 
 5029                   ppath, lat_grid, lon_grid, z_field, r_geoid, z_surface );
 
 5037   Array<double>   r_array, lat_array, lon_array, za_array, aa_array, l_array;
 
 5040   r_array.push_back( r_start );
 
 5041   lat_array.push_back( lat_start );
 
 5042   lon_array.push_back( lon_start );
 
 5043   za_array.push_back( za_start );
 
 5044   aa_array.push_back( aa_start );
 
 5047   Index   endface, tanpoint;
 
 5049   if( rtrace_method  == 
"linear_euler" )
 
 5052                                 aa_array, l_array, endface, tanpoint, r_start,
 
 5053                                 lat_start, lon_start, za_start, aa_start, 
 
 5054                                 rte_pressure, rte_temperature, rte_vmr_list, 
 
 5055                                 refr_index, refr_index_agenda, lraytrace, 
 
 5056                                 lat1, lat3, lon5, lon6, 
 
 5057                                 r15a, r35a, r36a, r15a, r15b, r35b, r36b, r15b,
 
 5058                                 rsurface15, rsurface35, rsurface36, rsurface16,
 
 5059                                 p_grid, lat_grid, lon_grid, 
 
 5060                                 r_geoid, z_field, t_field, vmr_field );
 
 5065       bool   known_ray_trace_method = 
false;
 
 5066       assert( known_ray_trace_method );
 
 5074   Vector    r_v, lat_v, lon_v, za_v, aa_v;
 
 5078                                         lstep, r_array, lat_array, lon_array, 
 
 5079                                            za_array, aa_array, l_array, lmax );
 
 5083   ppath_end_3d( ppath, r_v, lat_v, lon_v, za_v, aa_v, lstep, lat_grid, 
 
 5084            lon_grid, z_field, r_geoid, ip, ilat, ilon, endface, tanpoint, -1 );
 
 5089   if( endface == 0  &&  tanpoint )
 
 5097                           ppath2, rte_pressure, rte_temperature, rte_vmr_list,
 
 5098                           refr_index, refr_index_agenda, p_grid, lat_grid, 
 
 5099                           lon_grid, z_field, t_field, vmr_field, 
 
 5100                           r_geoid, z_surface, rtrace_method, lraytrace, lmax );
 
 5165                           const Index&          atmosphere_dim,
 
 5172                           const Index&          cloudbox_on, 
 
 5174                           const bool&           outside_cloudbox,
 
 5194   if( atmosphere_dim == 1 )
 
 5197       const double r_surface = r_geoid(0,0) + z_surface(0,0);
 
 5200       const double r_top = r_geoid(0,0) + z_field(np-1,0,0);
 
 5203       if( (rte_pos[0] + 
RTOL) < r_surface )
 
 5206           os << 
"The ppath starting point is placed "  
 5207              << (r_surface - rte_pos[0])/1e3 << 
" km below surface level.\n" 
 5208              << 
"This point must be above the surface.";
 
 5209           throw runtime_error(os.str());
 
 5212       out2 << 
"  sensor altitude        : " << (rte_pos[0]-r_geoid(0,0))/1e3 
 
 5217       if( rte_los[0] > 90 )
 
 5219           geom_tan_pos.resize(2);
 
 5222           out2 << 
"  geom. tangent radius   : " << geom_tan_pos[0]/1e3 
 
 5224           out2 << 
"  geom. tangent latitude : " << geom_tan_pos[1] << 
"\n";
 
 5225           out2 << 
"  geom. tangent altitude : "  
 5226                << (geom_tan_pos[0]-r_geoid(0,0))/1e3 << 
" km\n";
 
 5230       ppath.
pos(0,0) = rte_pos[0];
 
 5231       ppath.
los(0,0) = rte_los[0];
 
 5233       ppath.
z[0]     = ppath.
pos(0,0) - r_geoid(0,0);
 
 5237       if( rte_pos[0] < r_top )
 
 5245           if( ppath.
pos(0,0) == r_surface  &&  ppath.
los(0,0) > 90 )
 
 5251               if( outside_cloudbox )
 
 5254                   if( ppath.
z[0] > z_field(cloudbox_limits[0],0,0)  && 
 
 5255                                  ppath.
z[0] < z_field(cloudbox_limits[1],0,0) )
 
 5258                   else if( ( ppath.
z[0] == z_field(cloudbox_limits[0],0,0)  && 
 
 5259                                                         ppath.
los(0,0) <= 90 )
 
 5261                            ( ppath.
z[0] == z_field(cloudbox_limits[1],0,0)  && 
 
 5262                                                         ppath.
los(0,0) > 90 ) )
 
 5274           if( rte_los[0] <= 90 )
 
 5277               out1 << 
"  --- WARNING ---, path is totally outside of the " 
 5278                    << 
"model atmosphere\n";
 
 5289                   out1 << 
"  --- WARNING ---, path is totally outside of the " 
 5290                        << 
"model atmosphere\n";
 
 5296                   ppath.
z[0]     = z_field(np-1,0,0);
 
 5297                   ppath.
pos(0,0) = r_top;
 
 5305                       if( ppath.
z[0] == z_field(cloudbox_limits[1],0,0) )
 
 5315       if( ppath.
z[0] <= z_field(np-1,0,0) )
 
 5322       if( geom_tan_pos.nelem() == 2 )
 
 5332   else if( atmosphere_dim == 2 )
 
 5342       bool      is_inside = 
false;   
 
 5343       double    rv_geoid=-1, rv_surface=-1;  
 
 5347       if( rte_pos[1] >= lat_grid[0]  &&  rte_pos[1] <= lat_grid[nlat-1] )
 
 5349           gridpos( gp_lat, lat_grid, rte_pos[1] );
 
 5352           rv_geoid  = 
interp( itw, r_geoid(
joker,0), gp_lat );
 
 5353           rv_surface = rv_geoid + 
interp( itw, z_surface(
joker,0), gp_lat );
 
 5355           out2 << 
"  sensor altitude        : " << (rte_pos[0]-rv_geoid)/1e3 
 
 5358           if( rte_pos[0] < ( rv_geoid + 
 
 5360             { is_inside = 
true; }
 
 5368       double geom_tan_z=-2, geom_tan_atmtop=-1;  
 
 5370       if( 
abs(rte_los[0]) > 90 )
 
 5374           if( rte_los[0] > 0 )
 
 5380           out2 << 
"  geom. tangent radius   : " << geom_tan_pos[0] / 1e3
 
 5382           out2 << 
"  geom. tangent latitude : " << geom_tan_pos[1] 
 
 5385           if( geom_tan_pos[1] >= lat_grid[0]  &&  
 
 5386                                           geom_tan_pos[1] <= lat_grid[nlat-1] )
 
 5390               gridpos( gp_tan, lat_grid, geom_tan_pos[1] );
 
 5392               geom_tan_z = geom_tan_pos[0] - 
 
 5396               out2 << 
"  geom. tangent altitude : " << geom_tan_z/1e3 
 
 5402       ppath.
pos(0,0) = rte_pos[0];
 
 5403       ppath.
pos(0,1) = rte_pos[1];
 
 5404       ppath.
los(0,0) = rte_los[0];
 
 5410           if( (rte_pos[0] + 
RTOL) < rv_surface )
 
 5413             os << 
"The ppath starting point is placed "  
 5414                << (rv_surface - rte_pos[0])/1e3 << 
" km below surface level.\n" 
 5415                << 
"This point must be above the surface.";
 
 5416             throw runtime_error(os.str());
 
 5420           if( ( rte_pos[1] == lat_grid[0]  &&   rte_los[0] < 0 ) )
 
 5421             throw runtime_error( 
"The sensor is at the lower latitude end " 
 5422                                            "point and the zenith angle < 0." );
 
 5423           if( rte_pos[1] == lat_grid[nlat-1]  &&   rte_los[0] >= 0 ) 
 
 5424             throw runtime_error( 
"The sensor is at the upper latitude end " 
 5425                                           "point and the zenith angle >= 0." );
 
 5428           ppath.
z[0] = ppath.
pos(0,0) - rv_geoid;
 
 5435           ppath.
gp_lat[0].fd[0] = gp_lat.
fd[0];
 
 5436           ppath.
gp_lat[0].fd[1] = gp_lat.
fd[1];
 
 5446           if( ppath.
pos(0,0) == rv_surface )
 
 5451                                                       gp_lat, ppath.
los(0,0) );
 
 5472           if( ( rte_pos[1] <= lat_grid[0]  &&  rte_los[0] <= 0 )  || 
 
 5473                       ( rte_pos[1] >= lat_grid[nlat-1]  &&  rte_los[0] >= 0 ) )
 
 5476               os << 
"The sensor is outside (or at the limit) of the model " 
 5477                  << 
"atmosphere but\nlooks in the wrong direction (wrong sign " 
 5478                  << 
"for the zenith angle?).\nThis case includes nadir " 
 5479                  << 
"looking exactly at the latitude end points.";
 
 5480               throw runtime_error( os.str() );
 
 5484           if( 
abs(rte_los[0]) <= 90 )
 
 5487               out1 << 
"  ------- WARNING -------: path is totally outside of " 
 5488                    << 
"the model atmosphere\n";
 
 5500               if( rte_pos[1] < lat_grid[0]  ||  rte_pos[1] > lat_grid[nlat-1] )
 
 5504                   if( rte_pos[1] > lat_grid[0] )
 
 5505                     { ic = nlat - 1;   sc = 
"upper"; }
 
 5507                                          rte_pos[1], rte_los[0], lat_grid[ic] );
 
 5508                   if( rv < ( r_geoid(ic,0) + z_field(np-1,ic,0) ) )
 
 5511                       os << 
"The sensor is outside of the model atmosphere and " 
 5512                          << 
"looks in the\n" << sc << 
" latitude end face.\n" 
 5513                          << 
"The geometrical altitude of the corner point is " 
 5514                          << z_field(np-1,ic,0)/1e3 << 
" km.\n" 
 5515                          << 
"The geometrical altitude of the entrance point is " 
 5516                          << (rv-r_geoid(ic,0))/1e3 << 
" km.";
 
 5517                       throw runtime_error( os.str() );
 
 5524               if( ( geom_tan_pos[1] < lat_grid[0]  ||  
 
 5525                                           geom_tan_pos[1] > lat_grid[nlat-1] ) )
 
 5529                   if( rte_los[0] >= 0 )
 
 5530                     { ic = nlat - 1;   sc = 
"upper"; }
 
 5532                                          rte_pos[1], rte_los[0], lat_grid[ic] );
 
 5533                   if( rv >= ( r_geoid(ic,0) + z_field(np-1,ic,0) ) )
 
 5536                       os << 
"The combination of sensor position and line-of-" 
 5537                          << 
"sight gives a\npropagation path that goes above " 
 5538                          << 
"the model atmosphere, with\na tangent point " 
 5539                          << 
"outside the covered latitude range.\nThe latitude " 
 5540                          << 
"of the tangent point is " << geom_tan_pos[1] 
 
 5542                       throw runtime_error( os.str() );
 
 5555               if( geom_tan_pos[1] >= lat_grid[0]  &&  
 
 5556                                geom_tan_pos[1] <= lat_grid[nlat-1]   &&  
 
 5557                                                  geom_tan_z >= geom_tan_atmtop )
 
 5560                   out1 << 
"  ------- WARNING -------: " 
 5561                        << 
"path is totally outside of the model atmosphere\n";
 
 5582                   if( rte_pos[1] <= lat_grid[0] )
 
 5588                   else if( rte_pos[1] >= lat_grid[nlat-1] )
 
 5590                       lat0  = lat_grid[nlat-1]; 
 
 5597                       if( rte_los[0] >= 0 )
 
 5620                                                  rte_pos[1], rte_los[0], lat0 );
 
 5625                       double rv1 = r_geoid(ilat0,0) + z_field(np-1,ilat0,0);
 
 5626                       double rv2 = r_geoid(ilat0+istep,0) + 
 
 5627                                                     z_field(np-1,ilat0+istep,0);
 
 5628                       double latstep = 
abs( lat_grid[ilat0+istep] - 
 
 5630                       double c = ( rv2 - rv1 ) / latstep;
 
 5632                       if( lat0 != lat_grid[ilat0] )
 
 5633                         { rv1 = rv1 + c * 
abs( lat0 - lat_grid[ilat0] ); } 
 
 5637                       if( dlat <= latstep )
 
 5640                           ppath.
pos(0,1) = lat0 + (double)istep*dlat;
 
 5641                           ppath.
pos(0,0) = rv1 + c * dlat;
 
 5643                                                    rte_los[0], ppath.
pos(0,0) );
 
 5645                           rv1 = r_geoid(ilat0,0);
 
 5646                           rv2 = r_geoid(ilat0+istep,0);
 
 5647                           c   = ( rv2 - rv1 ) / latstep;
 
 5648                           ppath.
z[0] = ppath.
pos(0,0) - ( rv1 + c * 
 
 5649                                       abs( ppath.
pos(0,1) - lat_grid[ilat0] ) );
 
 5650                           ppath.
gp_p[0].idx = np - 2;
 
 5651                           ppath.
gp_p[0].fd[0] = 1;
 
 5652                           ppath.
gp_p[0].fd[1] = 0;
 
 5658                           lat0   = lat_grid[ilat0];
 
 5670       if( geom_tan_pos.
nelem() == 2 )
 
 5690       bool      is_inside = 
false;   
 
 5691       double   rv_geoid=-1, rv_surface=-1;  
 
 5695       if( rte_pos[1] >= lat_grid[0]  &&  rte_pos[1] <= lat_grid[nlat-1]  &&
 
 5696                 rte_pos[2] >= lon_grid[0]  &&  rte_pos[2] <= lon_grid[nlon-1] )
 
 5698           gridpos( gp_lat, lat_grid, rte_pos[1] );
 
 5699           gridpos( gp_lon, lon_grid, rte_pos[2] );
 
 5702           rv_geoid  = 
interp( itw, r_geoid, gp_lat, gp_lon );
 
 5703           rv_surface = rv_geoid + 
interp( itw, z_surface, gp_lat, gp_lon );
 
 5705           out2 << 
"  sensor altitude        : " << (rte_pos[0]-rv_geoid)/1e3 
 
 5708           if( rte_pos[0] < ( rv_geoid + 
interp( itw, 
 
 5709                                 z_field(np-1,
joker,
joker), gp_lat, gp_lon ) ) )
 
 5710             { is_inside = 
true; }
 
 5718       double geom_tan_z=-2, geom_tan_atmtop=-1;  
 
 5720       if( rte_los[0] > 90 )
 
 5722           geom_tan_pos.resize(3);
 
 5725                    geom_tan_pos[2], dummy, rte_pos[0], rte_pos[1], rte_pos[2], 
 
 5726                    rte_los[0], rte_los[1], 
 
 5728           resolve_lon( geom_tan_pos[2], lon_grid[0], lon_grid[nlon-1] ); 
 
 5729           out2 << 
"  geom. tangent radius   : " << geom_tan_pos[0] / 1e3
 
 5731           out2 << 
"  geom. tangent latitude : " << geom_tan_pos[1] 
 
 5733           out2 << 
"  geom. tangent longitude: " << geom_tan_pos[2] 
 
 5737           if( geom_tan_pos[1] >= lat_grid[0]       &&  
 
 5738               geom_tan_pos[1] <= lat_grid[nlat-1]  &&
 
 5739               geom_tan_pos[2] >= lon_grid[0]       &&
 
 5740               geom_tan_pos[2] <= lon_grid[nlon-1] )
 
 5744               gridpos( gp_tanlat, lat_grid, geom_tan_pos[1] );
 
 5745               gridpos( gp_tanlon, lon_grid, geom_tan_pos[2] );
 
 5747               geom_tan_z = geom_tan_pos[0] - 
 
 5748                               interp( itw_tan, r_geoid, gp_tanlat, gp_tanlon );
 
 5749               geom_tan_atmtop = 
interp( itw_tan, 
 
 5750                z_field(np-1,
joker,
joker), gp_tanlat, gp_tanlon );
 
 5751               out2 << 
"  geom. tangent altitude : " << geom_tan_z/1e3 
 
 5757       ppath.
pos(0,0) = rte_pos[0];
 
 5758       ppath.
pos(0,1) = rte_pos[1];
 
 5759       ppath.
pos(0,2) = rte_pos[2];
 
 5760       ppath.
los(0,0) = rte_los[0];
 
 5761       ppath.
los(0,1) = rte_los[1];
 
 5768           if( (rte_pos[0] + 
RTOL) < rv_surface )
 
 5771             os << 
"The ppath starting point is placed "  
 5772                << (rv_surface - rte_pos[0])/1e3 << 
" km below surface level.\n" 
 5773                << 
"This point must be above the surface.";
 
 5774             throw runtime_error(os.str());
 
 5778           if( rte_pos[1] > -90  &&  rte_pos[1] == lat_grid[0]  &&  
 
 5779                                                        abs( rte_los[1] > 90 ) )
 
 5780             throw runtime_error( 
"The sensor is at the lower latitude end " 
 5781                    "point and the absolute value of the azimuth angle > 90." );
 
 5782           if( rte_pos[1] < 90  &&  rte_pos[1] == lat_grid[nlat-1]  &&  
 
 5783                                                      abs( rte_los[1] ) <= 90 ) 
 
 5784             throw runtime_error( 
"The sensor is at the upper latitude end " 
 5785                   "point and the absolute value of the azimuth angle <= 90." );
 
 5788           if( rte_pos[2] == lon_grid[0]  &&  rte_los[1] < 0 )
 
 5789             throw runtime_error( 
"The sensor is at the lower longitude end " 
 5790                                           "point and the azimuth angle < 0." );
 
 5791           if( rte_pos[2] == lon_grid[nlon-1]  &&  rte_los[1] > 0 ) 
 
 5792             throw runtime_error( 
"The sensor is at the upper longitude end " 
 5793                                           "point and the azimuth angle > 0." );
 
 5796           ppath.
z[0] = ppath.
pos(0,0) - rv_geoid;
 
 5803           ppath.
gp_lat[0].fd[0] = gp_lat.
fd[0];
 
 5804           ppath.
gp_lat[0].fd[1] = gp_lat.
fd[1];
 
 5806           ppath.
gp_lon[0].fd[0] = gp_lon.
fd[0];
 
 5807           ppath.
gp_lon[0].fd[1] = gp_lon.
fd[1];
 
 5812           z_at_latlon( z_grid, p_grid, lat_grid, lon_grid, z_field, 
 
 5817           if( ppath.
pos(0,0) == rv_surface )
 
 5821                           r_geoid, z_surface, gp_lat, gp_lon, ppath.
los(0,1)  );
 
 5844               if( ppath.
pos(0,1) >= lat_grid[cloudbox_limits[2]]  &&
 
 5845                   ppath.
pos(0,1) <= lat_grid[cloudbox_limits[3]]  &&
 
 5846                   ppath.
pos(0,2) >= lon_grid[cloudbox_limits[4]]  &&
 
 5847                   ppath.
pos(0,2) <= lon_grid[cloudbox_limits[5]]  )
 
 5852                   const double   rv_low = rv_geoid + 
interp( itw, 
 
 5853                      z_field(cloudbox_limits[0],
joker,
joker), gp_lat, gp_lon );
 
 5854                   const double   rv_upp = rv_geoid + 
interp( itw, 
 
 5855                      z_field(cloudbox_limits[1],
joker,
joker), gp_lat, gp_lon );
 
 5857                   if( ppath.
pos(0,0) >= rv_low  &&  ppath.
pos(0,0) <= rv_upp )
 
 5859                       if( outside_cloudbox )
 
 5862                   else if( ppath.
pos(0,0) <= rv_low-
RTOL  &&  
 
 5863                            ppath.
pos(0,0) >= rv_upp+
RTOL )
 
 5864                     { assert( outside_cloudbox ); }
 
 5867                 { assert( outside_cloudbox ); }
 
 5881           if( ( rte_pos[1] <= lat_grid[0]  &&  
abs( rte_los[1] ) >= 90 )  || 
 
 5882               ( rte_pos[1] >= lat_grid[nlat-1]  &&  
abs( rte_los[1] ) <= 90 ) )
 
 5885               os << 
"The sensor is north or south (or at the limit) of the " 
 5886                  << 
"model atmosphere but\nlooks in the wrong direction.\n";
 
 5887               throw runtime_error( os.str() );
 
 5893           if( ( rte_pos[2] <= lon_grid[0]  &&  rte_los[1] < 0 )  || 
 
 5894                        ( rte_pos[2] >= lon_grid[nlon-1]  &&  rte_los[1] > 0 ) )
 
 5897               os << 
"The sensor is east or west (or at the limit) of the " 
 5898                  << 
"model atmosphere but\nlooks in the wrong direction.\n";
 
 5899               throw runtime_error( os.str() );
 
 5903           if( 
abs(rte_los[0]) <= 90 )
 
 5906               out1 << 
"  ------- WARNING -------: path is totally outside of " 
 5907                    << 
"the model atmosphere\n";
 
 5926               if( geom_tan_pos[1] >= lat_grid[0]  &&  
 
 5927                                geom_tan_pos[1] <= lat_grid[nlat-1]   &&  
 
 5928                                geom_tan_pos[2] >= lon_grid[0]        &&  
 
 5929                                geom_tan_pos[2] <= lon_grid[nlon-1]   &&  
 
 5930                                                 geom_tan_z >= geom_tan_atmtop )
 
 5933                   out1 << 
"  ------- WARNING -------: path is totally " 
 5934                        << 
"outside of the model atmosphere\n";
 
 5941                   Matrix r_atmtop(nlat,nlon);
 
 5943                   for( 
Index ilat=0; ilat<nlat; ilat++ )
 
 5945                       for( 
Index ilon=0; ilon<nlon; ilon++ )
 
 5946                         { r_atmtop(ilat,ilon) = r_geoid(ilat,ilon) +
 
 5947                                                       z_field(np-1,ilat,ilon); }
 
 5951                   double   rtopmin = 
min( r_atmtop );
 
 5952                   if( rte_pos[0] <= rtopmin )
 
 5955                       os << 
"The sensor radius is smaller than the minimum " 
 5956                          << 
"radius of the top of\nthe atmosphere. This gives " 
 5957                          << 
"no possible OK entrance point for the path.";
 
 5958                       throw runtime_error( os.str() );
 
 5963                   double   rtopmax = 
max( r_atmtop );
 
 5964                   if( geom_tan_pos[0] >= rtopmax )
 
 5967                       os << 
"The combination of sensor position and line-of-" 
 5968                          << 
"sight gives a\npropagation path that goes above " 
 5969                          << 
"the model atmosphere, with\na tangent point " 
 5970                          << 
"outside the covered latitude and longitude " 
 5971                          << 
"ranges.\nThe position of the " 
 5972                          << 
"tangent point is:\n   lat : " << geom_tan_pos[1] 
 
 5973                          << 
"\n   lon : " << geom_tan_pos[2];
 
 5974                       throw runtime_error( os.str() );
 
 5978                   double   x, y, z, 
dx, dy, dz;
 
 5980                                rte_pos[1], rte_pos[2], rte_los[0], rte_los[1] );
 
 5983                   bool   failed = 
false;
 
 5986                   double   r_top, lat_top, lon_top, l_top;
 
 5988                                    rtopmin, rte_pos[0], rte_pos[1], rte_pos[2], 
 
 5989                                       rte_los[0], x, y, z, 
dx, dy, dz );
 
 5990                   resolve_lon( lon_top, lon_grid[0], lon_grid[nlon-1] ); 
 
 5996                   if( lat_top < lat_grid[0]  ||  lat_top > lat_grid[nlat-1] ||
 
 5997                       lon_top < lon_grid[0]  ||  lon_top > lon_grid[nlon-1] )
 
 6000                                     rtopmax, rte_pos[0], rte_pos[1], rte_pos[2],
 
 6001                                        rte_los[0], x, y, z, 
dx, dy, dz );
 
 6002                       resolve_lon( lon_top, lon_grid[0], lon_grid[nlon-1] ); 
 
 6004                       if( lat_top < lat_grid[0] || lat_top > lat_grid[nlat-1] ||
 
 6005                           lon_top < lon_grid[0] || lon_top > lon_grid[nlon-1] )
 
 6014                   while( !failed  &&  !ready )
 
 6018                       double   lat1, lat3, lon5, lon6, r15, r35, r36, r16;
 
 6020                       gridpos( gp_lattop, lat_grid, lat_top );
 
 6022                       gridpos( gp_lontop, lon_grid, lon_top );
 
 6024                       r15   = r_geoid(ilat,ilon) + z_field(np-1,ilat,ilon);
 
 6025                       r35   = r_geoid(ilat+1,ilon) + z_field(np-1,ilat+1,ilon);
 
 6026                       r36   = r_geoid(ilat+1,ilon+1) + z_field(np-1,ilat+1,ilon+1);
 
 6027                       r16   = r_geoid(ilat,ilon+1) + z_field(np-1,ilat,ilon+1);
 
 6028                       lat1  = lat_grid[ilat];
 
 6029                       lat3  = lat_grid[ilat+1];
 
 6030                       lon5  = lon_grid[ilon];
 
 6031                       lon6  = lon_grid[ilon+1];
 
 6033                                          r15, r35, r36, r16, lat_top, lon_top );
 
 6037                       double   lat_top2, lon_top2;
 
 6039                                      r_top, rte_pos[0], rte_pos[1], rte_pos[2], 
 
 6040                                      rte_los[0], x, y, z, 
dx, dy, dz );
 
 6041                       resolve_lon( lon_top2, lon_grid[0], lon_grid[nlon-1] ); 
 
 6044                       if( 
abs( lat_top2 - lat_top ) < 1e-6  &&  
 
 6045                                               abs( lon_top2 - lon_top ) < 1e-6 )
 
 6049                       else if( lat_top < lat_grid[0]  ||  
 
 6050                                lat_top > lat_grid[nlat-1] ||
 
 6051                                lon_top < lon_grid[0]  ||  
 
 6052                                lon_top > lon_grid[nlon-1] )
 
 6062                       os << 
"The path does not enter the model atmosphere at " 
 6063                          << 
"the top.\nThe path reaches the top of the " 
 6064                          << 
"atmosphere altitude\napproximately at the " 
 6065                          << 
"position:\n   lat : " << lat_top << 
"\n   lon : "  
 6067                       throw runtime_error( os.str() );
 
 6072                   if( rte_los[0] == 180 )
 
 6074                       lat_top = rte_pos[1];
 
 6075                       lon_top = rte_pos[2];
 
 6077                   else if( 
abs( rte_pos[1] ) < 90  && ( 
abs(rte_los[1]) < 
ANGTOL 
 6079                     { lon_top = rte_pos[2]; } 
 
 6084                   ppath.
pos(0,0) = r_top;
 
 6085                   ppath.
pos(0,1) = lat_top;
 
 6086                   ppath.
pos(0,2) = lon_top;
 
 6089                   ppath.
gp_p[0].idx = np - 2;
 
 6090                   ppath.
gp_p[0].fd[0] = 1;
 
 6091                   ppath.
gp_p[0].fd[1] = 0;
 
 6098                   ppath.
z[0] = ppath.
pos(0,0) - 
interp(itw2,  r_geoid,
 
 6102                   double   zatmp, aatmp;
 
 6103                   cart2poslos( r_top, lat_top, lon_top, zatmp, aatmp,
 
 6104                                x+
dx*l_top, y+dy*l_top, z+dz*l_top, 
dx, dy, dz );
 
 6105                   ppath.
los(0,0) = zatmp;
 
 6106                   ppath.
los(0,1) = aatmp;
 
 6109                   if( rte_los[0] == 180 )
 
 6110                     { ppath.
los(0,0) = 180; }
 
 6111                   if( 
abs( rte_pos[1] ) < 90  &&  ( 
abs( rte_los[1] ) < 
ANGTOL   
 6113                     { ppath.
los(0,1) = rte_los[1]; } 
 
 6125       if( geom_tan_pos.
nelem() == 3 )
 
 6175                 const Agenda&         ppath_step_agenda,
 
 6176                 const Index&          atmosphere_dim,
 
 6183                 const Index&          cloudbox_on, 
 
 6187                 const bool&           outside_cloudbox,
 
 6202   if( atmosphere_dim == 1 )
 
 6207   else if( atmosphere_dim == 2 )
 
 6220   assert( outside_cloudbox  ||  cloudbox_on );
 
 6226   out2 << 
"  -------------------------------------\n";
 
 6227   out2 << 
"  sensor radius          : " << rte_pos[0]/1e3 << 
" km\n";
 
 6228   if( atmosphere_dim >= 2 )    
 
 6229     out2 << 
"  sensor latitude        : " << rte_pos[1] << 
"\n";
 
 6230   if( atmosphere_dim == 3 )
 
 6231     out2 << 
"  sensor longitude       : " << rte_pos[2] << 
"\n";
 
 6232   out2 << 
"  sensor zenith angle    : " << rte_los[0] << 
"\n";
 
 6233   if( atmosphere_dim == 3 )
 
 6234     out2 << 
"  sensor azimuth angle   : " << rte_los[1] << 
"\n";
 
 6249                         lon_grid, z_field, r_geoid, z_surface,
 
 6250                         cloudbox_on, cloudbox_limits, outside_cloudbox, rte_pos, rte_los,
 
 6253   out2 << 
"  -------------------------------------\n";
 
 6262   ppath_array.push_back( ppath_step );
 
 6279                                 lat_grid, lon_grid, z_field, r_geoid, z_surface,
 
 6280                                 ppath_step_agenda );
 
 6283       const Index n = ppath_step.
np;
 
 6289         throw runtime_error(
 
 6290           "10 000 path points have been reached. Is this an infinite loop?" );
 
 6298       if( outside_cloudbox )
 
 6308           if( atmosphere_dim == 2 )
 
 6314                   os << 
"The path exits the atmosphere through the lower " 
 6315                      << 
"latitude end face.\nThe exit point is at an altitude"  
 6316                      << 
"of " << ppath_step.
z[n-1]/1e3 << 
" km.";
 
 6317                   throw runtime_error( os.str() );
 
 6322                   os << 
"The path exits the atmosphere through the upper " 
 6323                      << 
"latitude end face.\nThe exit point is at an altitude"  
 6324                      << 
" of " << ppath_step.
z[n-1]/1e3 << 
" km.";
 
 6325                   throw runtime_error( os.str() );
 
 6328           if( atmosphere_dim == 3 )
 
 6331               if( lat_grid[0] > -90  && 
 
 6335                   os << 
"The path exits the atmosphere through the lower " 
 6336                      << 
"latitude end face.\nThe exit point is at an altitude"  
 6337                      << 
" of " << ppath_step.
z[n-1]/1e3 << 
" km.";
 
 6338                   throw runtime_error( os.str() );
 
 6340               if( lat_grid[imax_lat] < 90  && 
 
 6344                   os << 
"The path exits the atmosphere through the upper" 
 6345                      << 
"latitude end face.\nThe exit point is at an altitude"  
 6346                      << 
" of " << ppath_step.
z[n-1]/1e3 << 
" km.";
 
 6347                   throw runtime_error( os.str() );
 
 6354                   ppath_step.
los(n-1,1) < 0  &&  
 
 6355                   abs( ppath_step.
pos(n-1,1) ) < 90 )
 
 6358                   if( lon_grid[imax_lon] - lon_grid[0] >= 360 )
 
 6360                       ppath_step.
pos(n-1,2) = ppath_step.
pos(n-1,2) + 360;
 
 6362                                                        ppath_step.
pos(n-1,2) );
 
 6367                       os << 
"The path exits the atmosphere through the lower "  
 6368                          << 
"longitude end face.\nThe exit point is at an " 
 6369                          << 
"altitude of " << ppath_step.
z[n-1]/1e3 << 
" km.";
 
 6370                       throw runtime_error( os.str() );
 
 6375                    ppath_step.
los(n-1,1) > 0  &&  
 
 6376                    abs( ppath_step.
pos(n-1,1) ) < 90 )
 
 6379                   if( lon_grid[imax_lon] - lon_grid[0] >= 360 )
 
 6381                       ppath_step.
pos(n-1,2) = ppath_step.
pos(n-1,2) - 360;
 
 6383                                                        ppath_step.
pos(n-1,2) );
 
 6388                       os << 
"The path exits the atmosphere through the upper " 
 6389                          << 
"longitude end face.\nThe exit point is at an " 
 6390                          << 
"altitude of " << ppath_step.
z[n-1]/1e3 << 
" km.";
 
 6391                       throw runtime_error( os.str() );
 
 6402               if( ipos >= 
double( cloudbox_limits[0] )  && 
 
 6403                   ipos <= 
double( cloudbox_limits[1] ) )
 
 6405                   if( atmosphere_dim == 1 )
 
 6411                       if( ipos >= 
double( cloudbox_limits[2] )  && 
 
 6412                           ipos <= 
double( cloudbox_limits[3] ) )
 
 6414                           if( atmosphere_dim == 2 )
 
 6421                               if( ipos >= 
double( cloudbox_limits[4] )  && 
 
 6422                                   ipos <= 
double( cloudbox_limits[5] ) )
 
 6442           if( ipos1 <= 
double( cloudbox_limits[0] )  &&  ipos1 < ipos2 )
 
 6445           else if( ipos1 >= 
double( cloudbox_limits[1] )  &&  ipos1 > ipos2 )
 
 6448           else if( atmosphere_dim > 1 )
 
 6453               if( ipos1 <= 
double( cloudbox_limits[2] )  &&  ipos1 < ipos2 )  
 
 6456               else if( ipos1 >= 
double( cloudbox_limits[3] )  &&  ipos1 > ipos2 )
 
 6459               else if ( atmosphere_dim > 2 )
 
 6464                   if( ipos1 <= 
double( cloudbox_limits[4] )  &&  ipos1 < ipos2 )
 
 6467                   else if( ipos1 >= 
double( cloudbox_limits[5] )  &&
 
 6479       ppath_array.push_back( ppath_step );
 
 6497       Index n = ppath_array[i].np;
 
 6506             { assert( n > 1 ); }
 
 6509           ppath.
z[ 
Range(np,n-i1) ] = ppath_array[i].z[ 
Range(i1,n-i1) ];
 
 6518             { ppath.
l_step[ 
Range(np-1,n-1) ] = ppath_array[i].l_step; }
 
 6521           for( 
Index j=i1; j<n; j++ )
 
 6522             { ppath.
gp_p[np+j-i1] = ppath_array[i].gp_p[j]; }
 
 6523           if( atmosphere_dim >= 2 )
 
 6525               for( 
Index j=i1; j<n; j++ )
 
 6526                 { ppath.
gp_lat[np+j-i1] = ppath_array[i].gp_lat[j]; }
 
 6528           if( atmosphere_dim == 3 )
 
 6530               for( 
Index j=i1; j<n; j++ )
 
 6531                 { ppath.
gp_lon[np+j-i1] = ppath_array[i].gp_lon[j]; }
 
 6535           if( ppath_array[i].tan_pos.
nelem() )
 
 6538               ppath.
tan_pos               = ppath_array[i].tan_pos; 
 
 6540           if( ppath_array[i].geom_tan_pos.
nelem() )