121   assert( 
abs(za) <= 180 );
   153   assert( 
abs(a_za) <= 180 );
   154   assert( r >= ppc - 
RTOL );
   195   assert( 
abs(za) <= 180 );
   223   assert( 
abs(za0) <= 180 );
   224   assert( 
abs(za) <= 180 );
   225   assert( ( za0 >= 0 && za >= 0 )  ||  ( za0 < 0 && za < 0 ) );
   227   return lat0 + za0 - za;
   251   assert( r >= ppc - 
RTOL );
   254     { 
return   sqrt( r*r - ppc*ppc ); }
   281   return sqrt( l*l + ppc*ppc );
   306   assert( 
abs(za0) <= 180 );
   307   assert( ( za0 >= 0 && lat >= lat0 )  ||  ( za0 <= 0 && lat <= lat0 ) );
   310   const Numeric za = za0 + lat0 -lat;
   351        const bool&     tanpoint,
   360   if( l1 < 0 ) { l2 *= -1; }
   376   lstep = ( l2 - l1 ) / (
Numeric)n;
   387   for( 
Index i=1; i<n; i++ )
   404   for( 
Index i=1; i<=n; i++ )
   408   lstep = 
abs( lstep );
   450   const Numeric r = sqrt( dx*dx + dy*dy + dz*dz );
   455   aa = 
RAD2DEG * atan2( dy, dx );
   496   dy = sin( aarad ) * 
dx;
   497   dx = cos( aarad ) * 
dx;
   525   assert( R.
ncols() == 3 );
   526   assert( R.
nrows() == 3 );
   527   assert( vrot.
nelem() == 3 );
   537   assert( sqrt( u2 + v2 + w2 ) );
   543   R(0,0) = u2 + (v2 + w2)*c;
   544   R(0,1) = u*v*(1-c) - w*s;
   545   R(0,2) = u*w*(1-c) + v*s;
   546   R(1,0) = u*v*(1-c) + w*s;
   547   R(1,1) = v2 + (u2+w2)*c;
   548   R(1,2) = v*w*(1-c) - u*s;
   549   R(2,0) = u*w*(1-c) - v*s;
   550   R(2,1) = v*w*(1-c)+u*s;
   551   R(2,2) = w2 + (u2+v2)*c;
   583   assert( 
abs( aa_grid ) <= 5 );
   591   zaaa2cart( xyz[0], xyz[1], xyz[2], 90, aa0 );
   604   zaaa2cart( xyz[0], xyz[1], xyz[2], 90, aa0+aa_grid );
   642         const Numeric&  refr_index_air )
   645   assert( 
abs(za) <= 180 );
   647   return r * refr_index_air * sin( 
DEG2RAD * 
abs(za) );
   680   assert( lon6 >= lon5 ); 
   682   if( lon < lon5  &&  lon+180 <= lon6 )
   684   else if( lon > lon6  &&  lon-180 >= lon5 )
   711   while( it < ppath.
np-1  &&  ppath.
pos(it+1,0) < zmin ) 
   714       zmin = ppath.
pos(it,0);
   716   if( it == 0  ||  it == ppath.
np-1 )
   750   return   r1 + ( lat - lat1 ) * ( r3 - r1 ) / ( lat3 - lat1 );
   791   const Numeric r1 = 
refell2r( refellipsoid, lat_grid[i1] ) + z_surf[i1];
   792   const Numeric r2 = 
refell2r( refellipsoid, lat_grid[i1+1] ) + z_surf[i1+1];
   794   c1 = ( r2 - r1 ) / ( lat_grid[i1+1] - lat_grid[i1] );
   824   c1 = ( r2 - r1 ) / ( lat2 - lat1 );
   879   assert( 
abs(za) <= 180 );
   882   if( za > (90-tilt)  ||  za < (-90-tilt) )
   923   assert( 
abs( za_start ) <= 180 );
   924   assert( r_start >= ppc ); 
   930   if( ( r_start >= r_hit  &&  absza <= 90 )  ||  ppc > r_hit )
   936       if( absza > 90  &&  r_start <= r_hit )
  1001   assert( zaabs != 180 );
  1002   assert( 
abs(c1) > 0 ); 
  1011   const Numeric   cv    = cos( beta );
  1012   const Numeric   sv    = sin( beta );
  1025   p0[0] =  r0s     - rp*sv;
  1027   p0[2] = -r0s/2   + cc;
  1028   p0[3] = -r0c/6   - cs/2;
  1029   p0[4] =  r0s/24  - cc/6;
  1030   p0[5] =  r0c/120 + cs/24;
  1031   p0[6] = -r0s/720 + cc/120;
  1038   if( 
abs( 90 - zaabs ) > 89.9 )
  1040   else if( 
abs( 90 - zaabs ) > 75 )
  1045   int solutionfailure = 1;
  1047   while( solutionfailure)
  1051       p = p0[
Range(0,n+1)];
  1053       if( solutionfailure )
  1054         { n -= 1; assert( n > 0 ); }
  1060   if( 
abs(r0-rp) < 1e-9 )  
  1066   for( 
Index i=0; i<n; i++ )
  1068       if( roots(i,1) == 0  &&  roots(i,0) > dmin  &&  roots(i,0) < dlat )
  1069         { dlat = roots(i,0); }
  1137   assert( absza <= 180 );
  1138   assert( lat_start >=lat1  &&  lat_start <= lat3 );
  1149           l   = 
max( 1e-9, r - r_start0 ); 
  1154   else if( absza > 180-
ANGTOL )
  1160           l   = 
max( 1e-9, r_start0 - r ); 
  1173       if( rmax-rmin < 1e-6 )
  1179             { 
if( r_start < rmax ) { r_start = r = rmax; } }
  1181             { 
if( r_start > rmin ) { r_start = r = rmin; } }
  1183           r_crossing_2d( lat, l, r, r_start, lat_start, za_start, ppc );
  1186           if( lat > lat3  ||  lat < lat1 )
  1196             { 
if( r_start < rmin ) { r_start = rmin; } }
  1198             { 
if( r_start > rmax ) { r_start = rmax; } }
  1203           if( r_start > rmax )
  1206               r_crossing_2d( lat, l, r, r_start, lat_start, za_start, ppc );
  1208           else if( r_start < rmin )
  1211               r_crossing_2d( lat, l, r, r_start, lat_start, za_start, ppc );
  1214             { r = r_start; lat = lat_start; l = 0; za = za_start; }
  1217           if( lat < lat1  ||  lat > lat3 )
  1226               const Numeric  rpl = r1 + cpl*(lat-lat1);
  1230                 { 
if( r < rpl ) { r = rpl; } }
  1232                 { 
if( r > rpl ) { r = rpl; } }
  1236                 { za = lat_start + za_start - lat; };
  1244               if( lat < lat1  ||  lat > lat3 )
  1253                   za = lat_start + za_start - lat;
  1256                   if( absza>90 && 
abs(za)<90 )
  1310     { 
return   r15 + ( lon - lon5 ) * ( r16 - r15 ) / ( lon6 -lon5 ); }
  1311   else if( lat == lat3 )
  1312     { 
return   r35 + ( lon - lon5 ) * ( r36 - r35 ) / ( lon6 -lon5 ); }
  1313   else if( lon == lon5 )
  1314     { 
return   r15 + ( lat - lat1 ) * ( r35 - r15 ) / ( lat3 -lat1 ); }
  1315   else if( lon == lon6 )
  1316     { 
return   r16 + ( lat - lat1 ) * ( r36 - r16 ) / ( lat3 -lat1 ); }
  1319       const Numeric   fdlat = ( lat - lat1 ) / ( lat3 - lat1 );
  1320       const Numeric   fdlon = ( lon - lon5 ) / ( lon6 - lon5 );
  1321       return   (1-fdlat)*(1-fdlon)*r15 + fdlat*(1-fdlon)*r35 + 
  1322                                          (1-fdlat)*fdlon*r16 + fdlat*fdlon*r36;
  1370   if( r15==r35 && r15==r36 && r15==r16 && r35==r36 && r35==r16 && r36==r16 )
  1380                                             r15, r35, r36, r16, lat, lon );
  1392                                          r15, r35, r36, r16, lat2, lon2 ) - r0;
  1397                                          r15, r35, r36, r16, lat2, lon2 ) - r0;
  1400       c1 = 0.5 * ( 4*dr1 - dr2 );
  1401       c2 = (dr1-c1)/(dang*dang);
  1454       if( lat_grid[llat] > 
POLELAT )
  1455         { ilat = llat - 1; }
  1457         { 
throw runtime_error( 
"The upper latitude end of the atmosphere "  1458                                "reached, that is not allowed." ); }
  1461   if( ilon >= lon_grid.
nelem() - 1 )
  1466         { 
throw runtime_error( 
"The upper longitude end of the atmosphere "  1467                                "reached, that is not allowed." ); }
  1474   lat = 
interp( itw, lat_grid, gp_lat );
  1476   lon = 
interp( itw, lon_grid, gp_lon );
  1479   const Numeric   lat1 = lat_grid[ilat];
  1480   const Numeric   lat3 = lat_grid[ilat+1];
  1481   const Numeric   lon5 = lon_grid[ilon];
  1482   const Numeric   lon6 = lon_grid[ilon+1];
  1485   const Numeric   r15  = re1 + z_surf(ilat,ilon);
  1486   const Numeric   r35  = re3 + z_surf(ilat+1,ilon);
  1487   const Numeric   r36  = re3 + z_surf(ilat+1,ilon+1);
  1488   const Numeric   r16  = re1 + z_surf(ilat,ilon+1);
  1490   plevel_slope_3d( c1, c2, lat1, lat3, lon5, lon6, r15, r35, r36, r16, 
  1527   const Numeric   cv = cos( beta );
  1528   const Numeric   sv = sin( beta );
  1543   p0[0] =  r0s     - rp*sv;
  1545   p0[2] = -r0s/2   + c1c     + c2s;
  1546   p0[3] = -r0c/6   - c1s/2   + c2c;
  1547   p0[4] =  r0s/24  - c1c/6   - c2s/2;
  1548   p0[5] =  r0c/120 + c1s/24  - c2c/6;
  1549   p0[6] = -r0s/720 + c1c/120 + c2s/24;
  1557   if( 
abs( 90 - za ) > 89.9 )
  1559   else if( 
abs( 90 - za ) > 75 )
  1564   int solutionfailure = 1;
  1566   while( solutionfailure)
  1570       p = p0[
Range(0,n+1)];
  1572       if( solutionfailure )
  1573         { n -= 1; assert( n > 0 ); }
  1586   for( 
Index i=0; i<n; i++ )
  1588       if( roots(i,1) == 0  &&  roots(i,0) > dmin  &&  roots(i,0) < dlat )
  1589         { dlat = roots(i,0); }
  1595       dlat = RAD2DEG * dlat; 
  1655   assert( za_start >=   0 );
  1656   assert( za_start <= 180 );
  1660   if( ( r_start >= r_hit  &&  za_start <= 90 )  ||  ppc > r_hit )
  1666       if( za_start < ANGTOL  ||  za_start > 180-
ANGTOL )
  1668           l   = 
abs( r_hit - r_start );
  1675           const Numeric   p  = x*dx + y*dy + z*dz;
  1677           const Numeric   q  = x*x + y*y + z*z - r_hit*r_hit;
  1678           const Numeric   sq = sqrt( pp - q );
  1695           lat = 
RAD2DEG * asin( ( z+dz*l ) / r_hit );
  1696           lon = 
RAD2DEG * atan2( y+dy*l, x+dx*l );
  1728         const Index&      atmosphere_dim,
  1732   assert( atmosphere_dim >= 1 );
  1733   assert( atmosphere_dim <= 3 );
  1735   ppath.
dim        = atmosphere_dim;
  1754   ppath.
gp_p.resize( np );
  1755   if( atmosphere_dim >= 2 )
  1757       ppath.
gp_lat.resize( np ); 
  1758       if( atmosphere_dim == 3 )
  1759         { ppath.
gp_lon.resize( np ); }
  1792         const Index&      case_nr )
  1816       os << 
"Case number " << case_nr << 
" is not defined.";
  1817       throw runtime_error(os.str());
  1843   else if( ppath.
background == 
"cloud box level" )
  1845   else if( ppath.
background == 
"cloud box interior" )
  1853          << 
" is not a valid background case.";
  1854       throw runtime_error(os.str());
  1878     const Ppath&  ppath2,
  1879     const Index&  ncopy )
  1887   assert( ppath1.
np >= n ); 
  1901   if( n == ppath1.
np )
  1916   for( 
Index i=0; i<n; i++ )
  1920       if( ppath1.
dim >= 2 )
  1923       if( ppath1.
dim == 3 )
  1950      const Ppath&   ppath2 )
  1964   for( 
Index i=1; i<n2; i++ )
  1968       ppath1.
pos(i1,0)  = ppath2.
pos(i,0);
  1969       ppath1.
pos(i1,1)  = ppath2.
pos(i,1);
  1970       ppath1.
los(i1,0)  = ppath2.
los(i,0);
  1971       ppath1.
r[i1]      = ppath2.
r[i];
  1976       if( ppath1.
dim >= 2 )
  1979       if( ppath1.
dim == 3 )
  1981           ppath1.
pos(i1,2)        = ppath2.
pos(i,2);
  1982           ppath1.
los(i1,1)        = ppath2.
los(i,1);
  2022         const Ppath&      ppath )
  2025   const Index   imax = ppath.
np - 1;
  2028   r_start   = ppath.
r[imax];
  2029   lat_start = ppath.
pos(imax,1);
  2030   za_start  = ppath.
los(imax,0);
  2063         const Index&      endface,
  2075   const Numeric   r1 = refellipsoid[0] + z_field[ip];
  2076   const Numeric   dr = z_field[ip+1] - z_field[ip];
  2078   for( 
Index i=0; i<np; i++ )
  2080       ppath.
r[i]      = r_v[i];
  2081       ppath.
pos(i,0)  = r_v[i] - refellipsoid[0];
  2082       ppath.
pos(i,1)  = lat_v[i];
  2083       ppath.
los(i,0)  = za_v[i];
  2084       ppath.
nreal[i]  = n_v[i];
  2085       ppath.
ngroup[i] = ng_v[i];
  2087       ppath.
gp_p[i].idx   = ip;
  2088       ppath.
gp_p[i].fd[0] = ( r_v[i] - r1 ) / dr;
  2089       ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
  2093         { ppath.
lstep[i-1] = lstep[i-1]; }
  2103   else if( endface <= 4 )
  2143   const Index imax = ppath.
np - 1;
  2146   r_start   = ppath.
r[imax];
  2147   lat_start = ppath.
pos(imax,1);
  2148   za_start  = ppath.
los(imax,0);
  2155   lat1 = lat_grid[ilat];
  2156   lat3 = lat_grid[ilat+1];
  2169   r1a = re1 + z_field(ip,ilat);        
  2170   r3a = re3 + z_field(ip,ilat+1);      
  2171   r3b = re3 + z_field(ip+1,ilat+1);    
  2172   r1b = re1 + z_field(ip+1,ilat);      
  2201           r1b = r1a;   r3b = r3a;
  2202           r1a = re1 + z_field(ip,ilat);
  2203           r3a = re3 + z_field(ip,ilat+1);
  2214           r1a = r1b;   r3a = r3b;
  2215           r3b = re3 + z_field(ip+1,ilat+1);
  2216           r1b = re1 + z_field(ip+1,ilat);    
  2222   rsurface1 = re1 + z_surface[ilat];
  2223   rsurface3 = re3 + z_surface[ilat+1];
  2253         const Index&      endface,
  2258   const Index   imax = np-1;
  2267   const Numeric   dlat  = lat_grid[ilat+1] - lat_grid[ilat];
  2268   const Numeric   z1low = z_field(ip,ilat);
  2269   const Numeric   z1upp = z_field(ip+1,ilat);
  2270   const Numeric   dzlow = z_field(ip,ilat+1) -z1low;
  2271   const Numeric   dzupp = z_field(ip+1,ilat+1) - z1upp;
  2273   const Numeric   r1low = re + z1low;
  2274   const Numeric   r1upp = re + z1upp;
  2275                   re    = 
refell2r( refellipsoid, lat_grid[ilat+1] );
  2276   const Numeric   drlow = re + z_field(ip,ilat+1) - r1low;
  2277   const Numeric   drupp = re + z_field(ip+1,ilat+1) - r1upp;
  2279   for( 
Index i=0; i<np; i++ )
  2281       ppath.
r[i]      = r_v[i];
  2282       ppath.
pos(i,1)  = lat_v[i];
  2283       ppath.
los(i,0)  = za_v[i];
  2284       ppath.
nreal[i]  = n_v[i];
  2285       ppath.
ngroup[i] = ng_v[i];
  2288       Numeric w = ( lat_v[i] - lat_grid[ilat] ) / dlat;
  2291       const Numeric rlow = r1low + w * drlow;
  2292       const Numeric rupp = r1upp + w * drupp;
  2295       const Numeric zlow = z1low + w * dzlow;
  2296       const Numeric zupp = z1upp + w * dzupp;
  2298       ppath.
gp_p[i].idx   = ip;
  2299       ppath.
gp_p[i].fd[0] = ( r_v[i] - rlow ) / ( rupp - rlow );
  2300       ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
  2303       ppath.
pos(i,0) = zlow + ppath.
gp_p[i].fd[0] * ( zupp -zlow );
  2305       ppath.
gp_lat[i].idx   = ilat;
  2306       ppath.
gp_lat[i].fd[0] = ( lat_v[i] - lat_grid[ilat] ) / dlat;
  2311         { ppath.
lstep[i-1] = lstep[i-1]; }
  2322   if( endface == 1  ||  endface == 3 )
  2324   else if( endface == 2  ||  endface == 4 )
  2329   if( ppath.
gp_p[imax].fd[0] < 0  ||  ppath.
gp_p[imax].fd[1] < 0 )
  2333   if( ppath.
gp_lat[imax].fd[0] < 0  ||  ppath.
gp_lat[imax].fd[1] < 0 )
  2386   const Index imax = ppath.
np - 1;
  2389   r_start   = ppath.
r[imax];
  2390   lat_start = ppath.
pos(imax,1);
  2391   lon_start = ppath.
pos(imax,2);
  2392   za_start  = ppath.
los(imax,0);
  2393   aa_start  = ppath.
los(imax,1);
  2404   if( lat_start == 90 )
  2408       gridpos( gp_tmp, lon_grid, aa_start );
  2409       if( aa_start < 180 )
  2414   else if( lat_start == -90 )
  2418       gridpos( gp_tmp, lon_grid, aa_start );
  2419       if( aa_start < 180 )
  2430       if( lon_start < lon_grid[nlon-1] )
  2433         { ilon = nlon - 2; }
  2436   lat1 = lat_grid[ilat];
  2437   lat3 = lat_grid[ilat+1];
  2438   lon5 = lon_grid[ilon];
  2439   lon6 = lon_grid[ilon+1];
  2452   r15a = re1 + z_field(ip,ilat,ilon);
  2453   r35a = re3 + z_field(ip,ilat+1,ilon); 
  2454   r36a = re3 + z_field(ip,ilat+1,ilon+1); 
  2455   r16a = re1 + z_field(ip,ilat,ilon+1);
  2456   r15b = re1 + z_field(ip+1,ilat,ilon);
  2457   r35b = re3 + z_field(ip+1,ilat+1,ilon); 
  2458   r36b = re3 + z_field(ip+1,ilat+1,ilon+1); 
  2459   r16b = re1 + z_field(ip+1,ilat,ilon+1);
  2466   if( fabs(za_start-90) <= 10 )  
  2473                        r15a, r35a, r36a, r16a, lat_start, lon_start, aa_start );
  2479               r15b = r15a;   r35b = r35a;   r36b = r36a;   r16b = r16a;
  2480               r15a = re1 + z_field(ip,ilat,ilon);
  2481               r35a = re3 + z_field(ip,ilat+1,ilon); 
  2482               r36a = re3 + z_field(ip,ilat+1,ilon+1); 
  2483               r16a = re1 + z_field(ip,ilat,ilon+1);
  2491                        r15b, r35b, r36b, r16b, lat_start, lon_start, aa_start );
  2497               r15a = r15b;   r35a = r35b;   r36a = r36b;   r16a = r16b;
  2498               r15b = re1 + z_field(ip+1,ilat,ilon);
  2499               r35b = re3 + z_field(ip+1,ilat+1,ilon); 
  2500               r36b = re3 + z_field(ip+1,ilat+1,ilon+1); 
  2501               r16b = re1 + z_field(ip+1,ilat,ilon+1);
  2507   rsurface15 = re1 + z_surface(ilat,ilon);
  2508   rsurface35 = re3 + z_surface(ilat+1,ilon);
  2509   rsurface36 = re3 + z_surface(ilat+1,ilon+1);
  2510   rsurface16 = re1 + z_surface(ilat,ilon+1);
  2544         const Index&      endface,
  2549   const Index   imax = np-1;
  2558   const Numeric   lat1  = lat_grid[ilat];
  2559   const Numeric   lat3  = lat_grid[ilat+1];
  2560   const Numeric   lon5  = lon_grid[ilon];
  2561   const Numeric   lon6  = lon_grid[ilon+1];
  2564   const Numeric   r15a  = re1 + z_field(ip,ilat,ilon);
  2565   const Numeric   r35a  = re3 + z_field(ip,ilat+1,ilon); 
  2566   const Numeric   r36a  = re3 + z_field(ip,ilat+1,ilon+1); 
  2567   const Numeric   r16a  = re1 + z_field(ip,ilat,ilon+1);
  2568   const Numeric   r15b  = re1 + z_field(ip+1,ilat,ilon);
  2569   const Numeric   r35b  = re3 + z_field(ip+1,ilat+1,ilon); 
  2570   const Numeric   r36b  = re3 + z_field(ip+1,ilat+1,ilon+1);
  2571   const Numeric   r16b  = re1 + z_field(ip+1,ilat,ilon+1);
  2572   const Numeric   dlat  = lat3 - lat1;
  2573   const Numeric   dlon  = lon6 - lon5;
  2575   for( 
Index i=0; i<np; i++ )
  2579                                   r15a, r35a, r36a, r16a, lat_v[i], lon_v[i] );
  2581                                   r15b, r35b, r36b, r16b, lat_v[i], lon_v[i] );
  2584       ppath.
r[i]      = r_v[i];
  2585       ppath.
pos(i,1)  = lat_v[i];
  2586       ppath.
pos(i,2)  = lon_v[i];
  2587       ppath.
los(i,0)  = za_v[i];
  2588       ppath.
los(i,1)  = aa_v[i];
  2589       ppath.
nreal[i]  = n_v[i];
  2590       ppath.
ngroup[i] = ng_v[i];
  2593       ppath.
gp_p[i].idx   = ip;
  2594       ppath.
gp_p[i].fd[0] = ( r_v[i] - rlow ) / ( rupp - rlow );
  2595       ppath.
gp_p[i].fd[1] = 1 - ppath.
gp_p[i].fd[0];
  2600                                        re1, re3, re3, re1, lat_v[i], lon_v[i] );
  2601       const Numeric   zlow = rlow - re;
  2602       const Numeric   zupp = rupp - re;
  2604       ppath.
pos(i,0) = zlow + ppath.
gp_p[i].fd[0] * ( zupp -zlow );
  2607       ppath.
gp_lat[i].idx   = ilat;
  2608       ppath.
gp_lat[i].fd[0] = ( lat_v[i] - lat1 ) / dlat;
  2619           ppath.
gp_lon[i].idx   = ilon;
  2620           ppath.
gp_lon[i].fd[0] = ( lon_v[i] - lon5 ) / dlon;
  2627           ppath.
gp_lon[i].fd[0] = 0;
  2628           ppath.
gp_lon[i].fd[1] = 1;
  2632         { ppath.
lstep[i-1] = lstep[i-1]; }
  2641   if( endface == 1  ||  endface == 3 )
  2643   else if( endface == 2  ||  endface == 4 )
  2645   else if( endface == 5  ||  endface == 6 )
  2650   if( ppath.
gp_p[imax].fd[0] < 0  ||  ppath.
gp_p[imax].fd[1] < 0 )
  2654   if( ppath.
gp_lat[imax].fd[0] < 0  ||  ppath.
gp_lat[imax].fd[1] < 0 )
  2658   if( ppath.
gp_lon[imax].fd[0] < 0  ||  ppath.
gp_lon[imax].fd[1] < 0 )
  2717   assert( r_start >= ra - 
RTOL );
  2718   assert( r_start <= rb + 
RTOL );
  2723   else if( r_start > rb )
  2727   bool tanpoint = 
false;
  2731   if( za_start <= 90 )
  2732     { endface = 4;   r_end = rb; }
  2737       if( ra > rsurface  &&  ra > ppc ) 
  2738         { endface = 2;   r_end = ra; }
  2741       else if( rsurface > ppc )
  2742         { endface = 7;   r_end = rsurface; }
  2746         { endface = 4;   r_end = rb;   tanpoint = 
true; }
  2749   assert( endface > 0 );
  2752                           za_start, r_end, tanpoint, lmax );
  2791   Numeric r_start, lat_start, za_start;
  2818                    r_start, lat_start, za_start, ppc, lmax, 
  2819                    refellipsoid[0]+z_field[ip], refellipsoid[0]+z_field[ip+1], 
  2820                    refellipsoid[0]+z_surface );
  2825                 Vector(np,1), z_field, refellipsoid, ip, endface, ppc );
  2860   Numeric   lat_start = lat_start0;
  2862   assert( icall < 4 );
  2865   assert( lat_start >= lat1 - 
LATLONTOL );
  2866   assert( lat_start <= lat3 + 
LATLONTOL );
  2869   if( lat_start < lat1 )
  2870     { lat_start = lat1; }
  2871   else if( lat_start > lat3 )
  2872     { lat_start = lat3; }
  2879   assert( r_start >= rlow - 
RTOL );
  2880   assert( r_start <= rupp + 
RTOL );
  2883   if( r_start < rlow )
  2885   else if( r_start > rupp )
  2890   poslos2cart( x, z, dx, dz, r_start, lat_start, za_start );
  2893   bool unsafe     = 
false;
  2894   bool do_surface = 
false;
  2900   Numeric   r_end, lat_end, l_end;
  2908       l_end   = rupp - r_start;
  2913   else if( absza > 180-
ANGTOL )
  2918       if( rlow > rsurface )
  2920           l_end   = r_start - rlow;
  2925           l_end   = r_start - rsurface;
  2939       cart2pol( r_corr, lat_corr, x, z, lat_start, za_start );
  2942       lat_corr -= lat_start;
  2955         { l_end = l_start; }
  2957         { l_end = 2 * ( rupp - rlow ); }
  2959       Numeric   l_in   = 0, l_out = l_end;
  2960       bool      ready  = 
false, startup = 
true;
  2962       if( rsurface1+
RTOL >= r1a  ||  rsurface3+
RTOL >= r3a )
  2963         { do_surface = 
true; }
  2967           cart2pol( r_end, lat_end, x+dx*l_end, z+dz*l_end, lat_start, 
  2970           lat_end -= lat_corr;
  2979                                                          rsurface3, lat_end );
  2980               if( r_surface >= rlow  &&  r_end <= r_surface )
  2981                 { inside = 
false;   endface = 7; }
  2986               if( lat_end < lat1 )
  2987                 { inside = 
false;   endface = 1; }
  2988               else if( lat_end > lat3 )
  2989                 { inside = 
false;   endface = 3; }
  2990               else if( r_end < rlow )
  2991                 { inside = 
false;   endface = 2; }
  2996                     { inside = 
false;   endface = 4; }
  3010                   l_end = ( l_out + l_in ) / 2;
  3021               if( ( l_out - l_in ) < 
LACC )
  3024                 { l_end = ( l_out + l_in ) / 2; }
  3035       n = 
Index( ceil( 
abs( l_end / lmax ) ) );
  3045   lat_v[0] = lat_start;
  3052   for( 
Index j=1; j<=n; j++ )
  3055       cart2poslos( r_v[j], lat_v[j], za_v[j], x+dx*l, z+dz*l, dx, dz, ppc, 
  3056                                                         lat_start, za_start );
  3074                                              rsurface1, rsurface3, lat_v[j] ); 
  3075                   const Numeric r_test = 
max( r_surface, rlow );
  3076                   if(  r_v[j] < r_test )
  3077                     {  ready = 
false;   
break; }
  3079               else  if( r_v[j] < rlow )
  3080                 { ready = 
false;   
break; }
  3084                 { ready = 
false;   
break; }
  3094                 { lat_v[n] = lat1; }
  3095               else if( endface == 2 )
  3096                 { r_v[n] = 
rsurf_at_lat( lat1, lat3, r1a, r3a, lat_v[n] ); }
  3097               else if( endface == 3 )
  3098                 { lat_v[n] = lat3; }
  3099               else if( endface == 4 )
  3100                 { r_v[n] = 
rsurf_at_lat( lat1, lat3, r1b, r3b, lat_v[n] ); }
  3101               else if( endface == 7 )
  3102                 { r_v[n] = 
rsurf_at_lat( lat1, lat3, rsurface1, rsurface3, 
  3111                               lat_start, za_start, l, icall+1, ppc, lmax, 
  3112                               lat1, lat3, r1a, r3a, r3b, r1b,
  3113                               rsurface1, rsurface3 );
  3145   Numeric   r_start, lat_start, za_start;
  3151   Numeric   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
  3155                   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3,
  3156                   ppath, lat_grid, z_field, refellipsoid, z_surface );
  3172                               lat_start, za_start, -1, 0, ppc, lmax, 
  3173                               lat1, lat3, r1a, r3a, r3b, r1b,
  3174                               rsurface1, rsurface3 );
  3178                 Vector(np,1), lat_grid, z_field, refellipsoid, ip, ilat, 
  3226   Numeric   lat_start = lat_start0;
  3227   Numeric   lon_start = lon_start0;
  3229   assert( icall < 4 );
  3232   assert( lat_start >= lat1 - 
LATLONTOL );
  3233   assert( lat_start <= lat3 + 
LATLONTOL );
  3238   if( lat_start < lat1 )
  3239     { lat_start = lat1; }
  3240   else if( lat_start > lat3 )
  3241     { lat_start = lat3; }
  3242   if( lon_start < lon5 )
  3243     { lon_start = lon5; }
  3244   else if( lon_start > lon6 )
  3245     { lon_start = lon6; }
  3249                                 r15a, r35a, r36a, r16a, lat_start, lon_start );
  3251                                 r15b, r35b, r36b, r16b, lat_start, lon_start );
  3254   assert( r_start >= rlow - 
RTOL );
  3255   assert( r_start <= rupp + 
RTOL );
  3258   if( r_start < rlow )
  3260   else if( r_start > rupp )
  3265   poslos2cart( x, y, z, dx, dy, dz, r_start, lat_start, lon_start, 
  3266                                                           za_start, aa_start );
  3269   bool unsafe     = 
false;
  3270   bool do_surface = 
false;
  3276   Numeric   r_end, lat_end, lon_end, l_end;
  3283       l_end   = rupp - r_start;
  3288   else if( za_start > 180-
ANGTOL )
  3291                                rsurface15, rsurface35, rsurface36, rsurface16, 
  3292                                                  lat_start, lon_start );
  3294       if( rlow > rsurface )
  3296           l_end   = r_start - rlow;
  3301           l_end   = r_start - rsurface;
  3313       Numeric   r_corr, lat_corr, lon_corr;
  3315       cart2sph( r_corr, lat_corr, lon_corr, x, y, z, lat_start, lon_start,
  3316                                                      za_start,  aa_start );
  3319       lat_corr -= lat_start;
  3320       lon_corr -= lon_start;
  3333         { l_end = l_start; }
  3335         { l_end = 2 * ( rupp - rlow ); }
  3337       Numeric   l_in   = 0, l_out = l_end;
  3338       bool      ready  = 
false, startup = 
true;
  3340       if( rsurface15+
RTOL >= r15a  ||  rsurface35+
RTOL >= r35a  ||  
  3341           rsurface36+
RTOL >= r36a  ||  rsurface16+
RTOL >= r16a )
  3342         { do_surface = 
true; }
  3346           cart2sph( r_end, lat_end, lon_end, x+dx*l_end, y+dy*l_end, 
  3347                     z+dz*l_end, lat_start, lon_start, za_start,  aa_start );
  3349           lat_end -= lat_corr;
  3350           lon_end -= lon_corr;
  3356             { lon_end = lon_start; }
  3361                                 r15a, r35a, r36a, r16a, lat_end, lon_end );
  3367                            rsurface15, rsurface35, rsurface36, rsurface16, 
  3369               if( r_surface >= rlow  &&  r_end <= r_surface )
  3370                 { inside = 
false;   endface = 7; }
  3375               if( lat_end < lat1 )
  3376                 { inside = 
false;   endface = 1; }
  3377               else if( lat_end > lat3 )
  3378                 { inside = 
false;   endface = 3; }
  3379               else if( lon_end < lon5 )
  3380                 { inside = 
false;   endface = 5; }
  3381               else if( lon_end > lon6 )
  3382                 { inside = 
false;   endface = 6; }
  3383               else if( r_end < rlow )
  3384                 { inside = 
false;   endface = 2; }
  3388                                 r15b, r35b, r36b, r16b, lat_end, lon_end );
  3390                     { inside = 
false;   endface = 4; }
  3404                   l_end = ( l_out + l_in ) / 2;
  3415               if( ( l_out - l_in ) < 
LACC )
  3418                 { l_end = ( l_out + l_in ) / 2; }
  3429       n = 
Index( ceil( 
abs( l_end / lmax ) ) );
  3441   lat_v[0] = lat_start;
  3442   lon_v[0] = lon_start;
  3450   for( 
Index j=1; j<=n; j++ )
  3453       cart2poslos( r_v[j], lat_v[j], lon_v[j], za_v[j], aa_v[j], x+dx*l, 
  3454                    y+dy*l, z+dz*l, dx, dy, dz, ppc, lat_start, lon_start,
  3455                    za_start, aa_start );
  3473                                       r36a, r16a, lat_v[j], lon_v[j] );
  3477                                lat1, lat3, lon5, lon6, rsurface15, rsurface35,
  3478                                rsurface36, rsurface16, lat_v[j], lon_v[j] ); 
  3479                   const Numeric r_test = 
max( r_surface, rlow );
  3480                   if(  r_v[j] < r_test )
  3481                     {  ready = 
false;   
break; }
  3483               else  if( r_v[j] < rlow )
  3484                 { ready = 
false;   
break; }
  3487                                   r36b, r16b, lat_v[j], lon_v[j] );
  3489                 { ready = 
false;   
break; }
  3499                 { lat_v[n] = lat1; }
  3500               else if( endface == 2 )
  3502                                             r15a, r35a, r36a, r16a, 
  3503                                             lat_v[n], lon_v[n] ); }
  3504               else if( endface == 3 )
  3505                 { lat_v[n] = lat3; }
  3506               else if( endface == 4 )
  3508                                             r15b, r35b, r36b, r16b, 
  3509                                             lat_v[n], lon_v[n] ); }
  3510               else if( endface == 5 )
  3511                 { lon_v[n] = lon5; }
  3512               else if( endface == 6 )
  3513                 { lon_v[n] = lon6; }
  3514               else if( endface == 7 )
  3516                                             rsurface15, rsurface35, 
  3517                                             rsurface36, rsurface16, 
  3518                                             lat_v[n], lon_v[n] ); }
  3526                               r_start, lat_start, lon_start, za_start, aa_start,
  3527                               l, icall+1, ppc, lmax, lat1, lat3, lon5, lon6, 
  3528                               r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b,
  3529                               rsurface15, rsurface35, rsurface36, rsurface16 );
  3563   Numeric   r_start, lat_start, lon_start, za_start, aa_start;
  3566   Index   ip, ilat, ilon;
  3570   Numeric   lat1, lat3, lon5, lon6;
  3571   Numeric   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
  3572   Numeric   rsurface15, rsurface35, rsurface36, rsurface16;
  3575   ppath_start_3d( r_start, lat_start, lon_start, za_start, aa_start, 
  3576                   ip, ilat, ilon, lat1, lat3, lon5, lon6,
  3577                   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b, 
  3578                   rsurface15, rsurface35, rsurface36, rsurface16,
  3579                   ppath, lat_grid, lon_grid, z_field, refellipsoid, z_surface );
  3592   Vector   r_v, lat_v, lon_v, za_v, aa_v;
  3597                           r_start, lat_start, lon_start, za_start, aa_start, 
  3598                           -1, 0, ppc, lmax, lat1, lat3, lon5, lon6, 
  3599                           r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b,
  3600                           rsurface15, rsurface35, rsurface36, rsurface16 );
  3605                 Vector(np,1), 
Vector(np,1), lat_grid, lon_grid, z_field, 
  3606                 refellipsoid, ip, ilat, ilon, endface, ppc );
  3674         const Agenda&          refr_index_air_agenda,
  3687   Numeric refr_index_air, refr_index_air_group;
  3689                      refr_index_air_agenda, p_grid, refellipsoid, 
  3690                      z_field, t_field, vmr_field, f_grid, r );
  3691   r_array.push_back( r );
  3692   lat_array.push_back( lat );
  3693   za_array.push_back( za );
  3694   n_array.push_back( refr_index_air );
  3695   ng_array.push_back( refr_index_air_group );
  3699   Numeric   lstep, lcum = 0, dlat;
  3708                        ppc_step, -1, r1, r3, rsurface );
  3709       assert( r_v.
nelem() == 2 );
  3717       if( lstep <= lraytrace )
  3720           dlat  = lat_v[1] - lat;
  3734                 { za_flagside = 180-za_flagside; } 
  3741           dlat  = lat_new - lat;
  3750                          refr_index_air_agenda, p_grid, refellipsoid, z_field, 
  3751                          t_field, vmr_field, f_grid, r );
  3758       za += (
RAD2DEG * lstep / refr_index_air) * ( -sin(za_rad) * dndr );
  3767       if( ready  ||  ( lmax > 0  &&  lcum + lraytrace > lmax ) )
  3769           r_array.push_back( r );
  3770           lat_array.push_back( lat );
  3771           za_array.push_back( za );
  3772           n_array.push_back( refr_index_air );
  3773           ng_array.push_back( refr_index_air_group );
  3774           l_array.push_back( lcum );
  3820         const Agenda&     refr_index_air_agenda,
  3821         const String&     rtrace_method,
  3825   Numeric   r_start, lat_start, za_start;
  3841       Numeric refr_index_air, refr_index_air_group;
  3843                          refr_index_air_agenda, p_grid, refellipsoid, 
  3844                          z_field, t_field, vmr_field, f_grid, r_start );
  3855   Array<Numeric>   r_array, lat_array, za_array, l_array, n_array, ng_array;
  3858   if( rtrace_method  == 
"linear_basic" )
  3869             n_array, ng_array, endface, p_grid, refellipsoid, z_field, t_field,
  3870             vmr_field, f_grid, lmax, refr_index_air_agenda, lraytrace, 
  3871             refellipsoid[0] + z_surface, refellipsoid[0]+z_field(ip,0,0), 
  3872             refellipsoid[0]+z_field(ip+1,0,0), r_start, lat_start, za_start );
  3883   Vector r_v(np), lat_v(np), za_v(np), l_v(np-1), n_v(np), ng_v(np);
  3884   for( 
Index i=0; i<np; i++ )
  3886       r_v[i]   = r_array[i];    
  3887       lat_v[i] = lat_array[i];
  3888       za_v[i]  = za_array[i];   
  3889       n_v[i]   = n_array[i];
  3890       ng_v[i]  = ng_array[i];
  3892         { l_v[i] = l_array[i]; }
  3895   ppath_end_1d( ppath, r_v, lat_v, za_v, l_v, n_v, ng_v, z_field(
joker,0,0), 
  3896                 refellipsoid, ip, endface, ppc );
  3964         const Agenda&          refr_index_air_agenda,
  3982   Numeric refr_index_air, refr_index_air_group;
  3984                      refr_index_air_agenda, p_grid, lat_grid, refellipsoid, 
  3985                      z_field, t_field, vmr_field, f_grid, r, lat );
  3986   r_array.push_back( r );
  3987   lat_array.push_back( lat );
  3988   za_array.push_back( za );
  3989   n_array.push_back( refr_index_air );
  3990   ng_array.push_back( refr_index_air_group );
  3994   Numeric   lstep, lcum = 0, dlat;
  4003                                   lraytrace, 0, ppc_step, -1, lat1, lat3, 
  4004                                   r1a, r3a, r3b, r1b, rsurface1, rsurface3 );
  4005       assert( r_v.
nelem() == 2 );
  4013       if( lstep <= lraytrace )
  4016           dlat  = lat_v[1] - lat;
  4030                 { za_flagside = 
sign(za)*180-za_flagside; } 
  4037           dlat  = lat_new - lat;
  4046           else if( lat > lat3 )
  4053                          dndlat, refr_index_air_agenda, p_grid, lat_grid, 
  4054                          refellipsoid, z_field, t_field, vmr_field, f_grid, 
  4062       za += (
RAD2DEG * lstep / refr_index_air) * ( -sin(za_rad) * dndr +
  4063                                                         cos(za_rad) * dndlat );
  4073       if( lat == lat1  &&  za < 0 )
  4074         { endface = 1;   ready = 1; }
  4075       else if( lat == lat3  &&  za > 0 )
  4076         { endface = 3;   ready = 1; }
  4079       if( ready  ||  ( lmax > 0  &&  lcum + lraytrace > lmax ) )
  4081           r_array.push_back( r );
  4082           lat_array.push_back( lat );
  4083           za_array.push_back( za );
  4084           n_array.push_back( refr_index_air );
  4085           ng_array.push_back( refr_index_air_group );
  4086           l_array.push_back( lcum );
  4133         const Agenda&     refr_index_air_agenda,
  4134         const String&     rtrace_method,
  4138   Numeric   r_start, lat_start, za_start;
  4144   Numeric   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3;
  4148                   lat1, lat3, r1a, r3a, r3b, r1b, rsurface1, rsurface3,
  4149                   ppath, lat_grid, z_field(
joker,
joker,0), refellipsoid, 
  4158   Array<Numeric>   r_array, lat_array, za_array, l_array, n_array, ng_array;
  4161   if( rtrace_method  == 
"linear_basic" )
  4164                                 n_array, ng_array, endface, p_grid, lat_grid, 
  4165                                 refellipsoid, z_field, t_field, vmr_field,
  4167                                 refr_index_air_agenda, lraytrace, lat1, lat3,
  4168                                 rsurface1, rsurface3, r1a, r3a, r3b, r1b, 
  4169                                 r_start, lat_start, za_start );
  4180   Vector r_v(np), lat_v(np), za_v(np), l_v(np-1), n_v(np), ng_v(np);
  4181   for( 
Index i=0; i<np; i++ )
  4183       r_v[i]   = r_array[i];    
  4184       lat_v[i] = lat_array[i];
  4185       za_v[i]  = za_array[i];   
  4186       n_v[i]   = n_array[i];
  4187       ng_v[i]  = ng_array[i];
  4189         { l_v[i] = l_array[i]; }
  4192   ppath_end_2d( ppath, r_v, lat_v, za_v, l_v, n_v, ng_v, lat_grid, 
  4193                 z_field(
joker,
joker,0), refellipsoid, ip, ilat, endface, -1 );
  4278         const Agenda&          refr_index_air_agenda,
  4306   Numeric refr_index_air, refr_index_air_group;
  4308                      refr_index_air_agenda, p_grid, lat_grid, lon_grid, 
  4309                      refellipsoid, z_field, t_field, vmr_field, f_grid, 
  4311   r_array.push_back( r );
  4312   lat_array.push_back( lat );
  4313   lon_array.push_back( lon );
  4314   za_array.push_back( za );
  4315   aa_array.push_back( aa );
  4316   n_array.push_back( refr_index_air );
  4317   ng_array.push_back( refr_index_air_group );
  4320   Vector    r_v, lat_v, lon_v, za_v, aa_v;
  4331                               r, lat, lon, za, aa, lraytrace, 0, 
  4332                               ppc_step, -1, lat1, lat3, lon5, lon6,
  4333                               r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b,
  4334                               rsurface15, rsurface35, rsurface36, rsurface16 );
  4335       assert( r_v.
nelem() == 2 );
  4340       if( lstep <= lraytrace )
  4353           Numeric   x, y, z, 
dx, dy, dz, lat_new, lon_new;
  4355           poslos2cart( x, y, z, dx, dy, dz, r, lat, lon, za, aa ); 
  4357           cart2poslos( r, lat_new, lon_new, za_new, aa_new, x+dx*lstep, 
  4358                        y+dy*lstep, z+dz*lstep, dx, dy, dz, ppc_step,
  4372                          dndr, dndlat, dndlon, refr_index_air_agenda, 
  4373                          p_grid, lat_grid, lon_grid, refellipsoid, 
  4374                          z_field, t_field, vmr_field, 
  4375                          f_grid, r, lat, lon );
  4381       const Numeric   sinza  = sin( za_rad );
  4382       const Numeric   sinaa  = sin( aa_rad );
  4383       const Numeric   cosaa  = cos( aa_rad );
  4385       Vector los(2);   los[0] = za_new;   los[1] = aa_new;
  4387       if( za < ANGTOL  ||  za > 180-
ANGTOL )
  4389           los[0] += aterm * ( cos(za_rad) * 
  4390                                          ( cosaa * dndlat + sinaa * dndlon ) );
  4391           los[1]  = 
RAD2DEG * atan2( dndlon, dndlat); 
  4395           los[0] += aterm * ( -sinza * dndr + cos(za_rad) * 
  4396                               ( cosaa * dndlat + sinaa * dndlon ) );
  4397           los[1] += aterm * sinza * ( cosaa * dndlon - sinaa * dndlat ); 
  4408       if( za > 0  &&  za < 180 )
  4410           if( lon == lon5  &&  aa < 0 )
  4411             { endface = 5;   ready = 1; }
  4412           else if( lon == lon6  &&  aa > 0 )
  4413             { endface = 6;   ready = 1; }
  4414           else if( lat == lat1  &&  lat != -90  &&  
abs( aa ) > 90 ) 
  4415             { endface = 1;   ready = 1; }
  4416           else if( lat == lat3  &&  lat != 90  &&  
abs( aa ) < 90 ) 
  4417             { endface = 3;   ready = 1; }
  4421       if( ready  ||  ( lmax > 0  &&  lcum + lraytrace > lmax ) )
  4423           r_array.push_back( r );
  4424           lat_array.push_back( lat );
  4425           lon_array.push_back( lon );
  4426           za_array.push_back( za );
  4427           aa_array.push_back( aa );
  4428           n_array.push_back( refr_index_air );
  4429           ng_array.push_back( refr_index_air_group );
  4430           l_array.push_back( lcum );
  4479         const Agenda&     refr_index_air_agenda,
  4480         const String&     rtrace_method,
  4484   Numeric   r_start, lat_start, lon_start, za_start, aa_start;
  4487   Index   ip, ilat, ilon;
  4491   Numeric   lat1, lat3, lon5, lon6;
  4492   Numeric   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b;
  4493   Numeric   rsurface15, rsurface35, rsurface36, rsurface16;
  4496   ppath_start_3d( r_start, lat_start, lon_start, za_start, aa_start, 
  4497                   ip, ilat, ilon, lat1, lat3, lon5, lon6,
  4498                   r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b, 
  4499                   rsurface15, rsurface35, rsurface36, rsurface16,
  4500                   ppath, lat_grid, lon_grid, z_field, refellipsoid, z_surface );
  4508   Array<Numeric>   r_array, lat_array, lon_array, za_array, aa_array;
  4512   if( rtrace_method  == 
"linear_basic" )
  4515                            aa_array, l_array, n_array, ng_array, endface, 
  4516                            refellipsoid, p_grid, lat_grid, lon_grid, 
  4517                            z_field, t_field, vmr_field, 
  4518                            f_grid, lmax, refr_index_air_agenda, lraytrace, 
  4519                            lat1, lat3, lon5, lon6, 
  4520                            rsurface15, rsurface35, rsurface36, rsurface16,
  4521                            r15a, r35a, r36a, r16a, r15b, r35b, r36b, r16b,
  4522                            r_start, lat_start, lon_start, za_start, aa_start );
  4533   Vector r_v(np), lat_v(np), lon_v(np), za_v(np), aa_v(np), l_v(np-1);
  4534   Vector n_v(np), ng_v(np);
  4535   for( 
Index i=0; i<np; i++ )
  4537       r_v[i]   = r_array[i];    
  4538       lat_v[i] = lat_array[i];
  4539       lon_v[i] = lon_array[i];
  4540       za_v[i]  = za_array[i];   
  4541       aa_v[i]  = aa_array[i];   
  4542       n_v[i]   = n_array[i];
  4543       ng_v[i]  = ng_array[i];
  4545         { l_v[i] = l_array[i]; }
  4549   ppath_end_3d( ppath, r_v, lat_v, lon_v, za_v, aa_v, l_v, n_v, ng_v, lat_grid, 
  4550                 lon_grid, z_field, refellipsoid, ip, ilat, ilon, endface, -1 );
  4608     const Index&          atmosphere_dim,
  4615     const Index&          cloudbox_on, 
  4617     const bool&           ppath_inside_cloudbox_do,
  4635   if( atmosphere_dim == 1 )
  4638       ppath.
end_pos[0] = rte_pos[0];
  4640       ppath.
end_los[0] = rte_los[0];
  4643       if( rte_pos[0] < z_field(lp,0,0) )
  4646           if( (rte_pos[0] + 
RTOL) < z_surface(0,0) )
  4649               os << 
"The ppath starting point is placed "   4650                  << (z_surface(0,0) - rte_pos[0])/1e3 
  4651                  << 
" km below the surface.";
  4652               throw runtime_error(os.str());
  4657           ppath.
r[0]         = refellipsoid[0] + rte_pos[0];
  4666           if( ppath.
pos(0,0) <= z_surface(0,0)  &&  ppath.
los(0,0) > 90 )
  4671           if( cloudbox_on  &&  !ppath_inside_cloudbox_do )
  4674               if( fgp >= cloudbox_limits[0]  &&  fgp <= cloudbox_limits[1] )
  4682               assert( fgp >= cloudbox_limits[0] && fgp <= cloudbox_limits[1] );
  4696           if( rte_los[0] <= 90  ||  
  4697               ppath.
constant >= refellipsoid[0] + z_field(lp,0,0) )
  4699               ppath.
pos(0,0) = rte_pos[0];
  4701               ppath.
r[0]     = refellipsoid[0] + rte_pos[0];
  4702               ppath.
los(0,0) = rte_los[0];
  4705               out1 << 
"  --- WARNING ---, path is totally outside of the "  4706                    << 
"model atmosphere\n";
  4712               ppath.
r[0]     = refellipsoid[0] + z_field(lp,0,0);
  4713               ppath.
pos(0,0) = z_field(lp,0,0);
  4719                                               refellipsoid[0] + rte_pos[0] ) -
  4723               ppath.
gp_p[0].idx   = lp-1; 
  4724               ppath.
gp_p[0].fd[0] = 1;
  4725               ppath.
gp_p[0].fd[1] = 0;
  4728               if( cloudbox_on  &&  cloudbox_limits[1] == lp )
  4736   else if( atmosphere_dim == 2 )
  4739       ppath.
end_pos[0] = rte_pos[0];
  4740       ppath.
end_pos[1] = rte_pos[1];
  4741       ppath.
end_los[0] = rte_los[0];
  4750       bool      islatin = 
false;
  4753       if( rte_pos[1] > lat_grid[0]  &&  rte_pos[1] < lat_grid[llat] )
  4756           gridpos( gp_lat, lat_grid, rte_pos[1] );
  4758           z_toa = 
interp( itw, z_field(lp,
joker,0), gp_lat );
  4759           r_e   = 
refell2d( refellipsoid, lat_grid, gp_lat );
  4762         { r_e = 
refell2r( refellipsoid, rte_pos[1] ); }
  4765       if( islatin  &&  rte_pos[0] < z_toa )
  4770           if( (rte_pos[0] + 
RTOL) < z_s )
  4773               os << 
"The ppath starting point is placed "   4774                  << (z_s - rte_pos[0])/1e3 << 
" km below the surface.";
  4775               throw runtime_error(os.str());
  4780           ppath.
r[0]         = r_e + rte_pos[0];
  4786                 atmosphere_dim, p_grid, lat_grid, lon_grid, z_field, rte_pos );
  4793           if( ppath.
pos(0,0) <= z_s )
  4798                                z_surface(
joker,0), gp_lat, ppath.
los(0,0) );
  4812           if( cloudbox_on  &&  !ppath_inside_cloudbox_do )
  4816               if( fgp >= cloudbox_limits[0]  &&  fgp <= cloudbox_limits[1]  &&
  4817                   fgl >= cloudbox_limits[2]  &&  fgl <= cloudbox_limits[3]  )
  4826               assert( fgp >= cloudbox_limits[0] && fgp <= cloudbox_limits[1] &&
  4827                       fgl >= cloudbox_limits[2] && fgl <= cloudbox_limits[3]  );
  4835           if( ( rte_pos[1] <= lat_grid[0]     &&  rte_los[0] <= 0 )  || 
  4836               ( rte_pos[1] >= lat_grid[llat]  &&  rte_los[0] >= 0 ) )
  4839               os << 
"The sensor is outside (or at the limit) of the model "  4840                  << 
"atmosphere but\nlooks in the wrong direction (wrong sign "  4841                  << 
"for the zenith angle?).\nThis case includes nadir "  4842                  << 
"looking exactly at the latitude end points.";
  4843               throw runtime_error( os.str() );
  4849           const Numeric r_p = r_e + rte_pos[0];
  4854           Numeric   r_toa_min = 99e99, r_toa_max = -1;
  4855           for( 
Index ilat=0; ilat<=llat; ilat++ )
  4857               r_toa[ilat] = 
refell2r( refellipsoid, lat_grid[ilat] ) +
  4859               if( r_toa[ilat] < r_toa_min )
  4860                 { r_toa_min = r_toa[ilat]; } 
  4861               if( r_toa[ilat] > r_toa_max )
  4862                 { r_toa_max = r_toa[ilat]; } 
  4864           if( r_p <= r_toa_max )
  4867               os << 
"The sensor is horizontally outside (or at the limit) of "  4868                  << 
"the model\natmosphere, but is at a radius smaller than "  4869                  << 
"the maximum value of\nthe top-of-the-atmosphere radii. "  4870                  << 
"This is not allowed. Make the\nmodel atmosphere larger "  4871                  << 
"to also cover the sensor position?";
  4872               throw runtime_error( os.str() );
  4876           if( 
abs(rte_los[0]) <= 90 )
  4878               ppath.
pos(0,0) = rte_pos[0];
  4879               ppath.
pos(0,1) = rte_pos[1]; 
  4880               ppath.
r[0]     = r_e + rte_pos[0];
  4881               ppath.
los(0,0) = rte_los[0];
  4884               out1 << 
"  ------- WARNING -------: path is totally outside of "  4885                    << 
"the model atmosphere\n";
  4891               bool      above=
false, ready=
false, failed=
false;
  4898                 { above=
true; ready=
true; }
  4901                   if( islatin  ||  ppath.
constant > r_toa_min ) 
  4909               while( !ready && !failed )
  4926                       if( latt < lat_grid[0]  ||  latt > lat_grid[llat] )
  4938                           gridpos( gp_latt, lat_grid, latt );
  4940                           rt = 
interp( itwt, r_toa, gp_latt );
  4948                   os << 
"The path does not enter the model atmosphere. It "  4949                      << 
"reaches the\ntop of the atmosphere "  4950                      << 
"altitude around latitude " << latt << 
" deg.";
  4951                   throw runtime_error( os.str() );
  4955                   ppath.
pos(0,0) = rte_pos[0];
  4956                   ppath.
pos(0,1) = rte_pos[1]; 
  4957                   ppath.
r[0]     = r_e + rte_pos[0];
  4958                   ppath.
los(0,0) = rte_los[0];
  4961                   out1 << 
"  ------- WARNING -------: path is totally outside "  4962                        << 
"of the model atmosphere\n";
  4976                   ppath.
gp_p[0].idx   = lp-1; 
  4977                   ppath.
gp_p[0].fd[0] = 1;
  4978                   ppath.
gp_p[0].fd[1] = 0;
  4984                   if( cloudbox_on  &&  cloudbox_limits[1] == lp )
  4987                       if( fgp >= (
Numeric)cloudbox_limits[2]  &&
  4988                           fgp <= (
Numeric)cloudbox_limits[3] )
  5006       resolve_lon( lon2use, lon_grid[0], lon_grid[llon] );
  5009       ppath.
end_pos[0] = rte_pos[0];
  5010       ppath.
end_pos[1] = rte_pos[1];
  5012       ppath.
end_los[0] = rte_los[0];
  5013       ppath.
end_los[1] = rte_los[1];
  5019       bool      islatlonin = 
false;
  5023       if( rte_pos[1] >= lat_grid[0]  &&  rte_pos[1] <= lat_grid[llat]  &&
  5024           lon2use >= lon_grid[0]  &&  lon2use <= lon_grid[llon] )
  5027           gridpos( gp_lat, lat_grid, rte_pos[1] );
  5028           gridpos( gp_lon, lon_grid, lon2use );
  5031           r_e   = 
refell2d( refellipsoid, lat_grid, gp_lat );
  5034         { r_e = 
refell2r( refellipsoid, rte_pos[1] ); }
  5037       if( islatlonin  &&  rte_pos[0] < z_toa )
  5039           const Numeric z_s = 
interp( itw, z_surface, gp_lat, gp_lon );
  5042           if( (rte_pos[0] + 
RTOL) < z_s )
  5045               os << 
"The ppath starting point is placed "   5046                  << (z_s - rte_pos[0])/1e3 << 
" km below the surface.";
  5047               throw runtime_error(os.str());
  5052           ppath.
r[0]         = r_e + rte_pos[0];
  5057                 atmosphere_dim, p_grid, lat_grid, lon_grid, z_field, rte_pos );
  5065           if( ppath.
pos(0,0) <= z_s )
  5070                                z_surface, gp_lat, gp_lon, ppath.
los(0,1) );
  5084           if( cloudbox_on  &&  !ppath_inside_cloudbox_do )
  5089               if( fgp >= cloudbox_limits[0]  &&  fgp <= cloudbox_limits[1]  &&
  5090                   fgl >= cloudbox_limits[2]  &&  fgl <= cloudbox_limits[3]  &&
  5091                   fgo >= cloudbox_limits[4]  &&  fgo <= cloudbox_limits[5]  )
  5101               assert( fgp >= cloudbox_limits[0] && fgp <= cloudbox_limits[1] &&
  5102                       fgl >= cloudbox_limits[2] && fgl <= cloudbox_limits[3] &&
  5103                       fgo >= cloudbox_limits[4] && fgo <= cloudbox_limits[5] );
  5112           if( ( rte_pos[1] <= lat_grid[0]     &&  
abs( rte_los[1] ) >= 90 )  || 
  5113               ( rte_pos[1] >= lat_grid[llat]  &&  
abs( rte_los[1] ) <= 90 ) )
  5116               os << 
"The sensor is north or south (or at the limit) of the "  5117                  << 
"model atmosphere\nbut looks in the wrong direction.";
  5118               throw runtime_error( os.str() );
  5124           if( ( lon2use <= lon_grid[0]     &&  rte_los[1] < 0 )  || 
  5125               ( lon2use >= lon_grid[llon]  &&  rte_los[1] > 0 ) )
  5128               os << 
"The sensor is east or west (or at the limit) of the "  5129                  << 
"model atmosphere\nbut looks in the wrong direction.";
  5130               throw runtime_error( os.str() );
  5136           const Numeric r_p = r_e + rte_pos[0];
  5140           Matrix   r_toa(llat+1,llon+1);
  5141           Numeric   r_toa_min = 99e99, r_toa_max = -1;
  5142           for( 
Index ilat=0; ilat<=llat; ilat++ )
  5145               for( 
Index ilon=0; ilon<=llon; ilon++ )
  5147                   r_toa(ilat,ilon) = r_lat+ z_field(lp,ilat,ilon);
  5148                   if( r_toa(ilat,ilon) < r_toa_min )
  5149                     { r_toa_min = r_toa(ilat,ilon); } 
  5150                   if( r_toa(ilat,ilon) > r_toa_max )
  5151                     { r_toa_max = r_toa(ilat,ilon); } 
  5155           if( r_p <= r_toa_max )
  5158               os << 
"The sensor is horizontally outside (or at the limit) of "  5159                  << 
"the model\natmosphere, but is at a radius smaller than "  5160                  << 
"the maximum value of\nthe top-of-the-atmosphere radii. "  5161                  << 
"This is not allowed. Make the\nmodel atmosphere larger "  5162                  << 
"to also cover the sensor position?";
  5163               throw runtime_error( os.str() );
  5167           if( rte_los[0] <= 90 )
  5169               ppath.
pos(0,0) = rte_pos[0];
  5170               ppath.
pos(0,1) = rte_pos[1]; 
  5171               ppath.
pos(0,1) = lon2use; 
  5172               ppath.
r[0]     = r_e + rte_pos[0];
  5173               ppath.
los(0,0) = rte_los[0];
  5174               ppath.
los(0,1) = rte_los[1];
  5177               out1 << 
"  ------- WARNING -------: path is totally outside of "  5178                    << 
"the model atmosphere\n";
  5184               bool      above=
false, ready=
false, failed=
false;
  5191                 { above=
true; ready=
true; }
  5194                   if( islatlonin  ||  ppath.
constant > r_toa_min ) 
  5202               poslos2cart( x, y, z, dx, dy, dz, r_p, rte_pos[1], lon2use, 
  5203                                                      rte_los[0], rte_los[1] );
  5207               while( !ready && !failed )
  5220                                      lon2use, rte_los[0], ppath.
constant, 
  5221                                      x, y, z, dx, dy, dz );
  5225                       if( latt < lat_grid[0]  ||  latt > lat_grid[llat]  ||
  5226                           lont < lon_grid[0]  ||  lont > lon_grid[llon] )
  5238                           gridpos( gp_latt, lat_grid, latt );
  5239                           gridpos( gp_lont, lon_grid, lont );
  5241                           rt = 
interp( itwt, r_toa, gp_latt, gp_lont );
  5249                   os << 
"The path does not enter the model atmosphere. It\n"  5250                      << 
"reaches the top of the atmosphere altitude around:\n"  5251                      << 
"  lat: " << latt << 
" deg.\n  lon: " << lont 
  5253                   throw runtime_error( os.str() );
  5257                   ppath.
pos(0,0) = rte_pos[0];
  5258                   ppath.
pos(0,1) = rte_pos[1]; 
  5259                   ppath.
pos(0,1) = lon2use; 
  5260                   ppath.
r[0]     = r_e + rte_pos[0];
  5261                   ppath.
los(0,0) = rte_los[0];
  5262                   ppath.
los(0,1) = rte_los[1];
  5265                   out1 << 
"  ------- WARNING -------: path is totally outside "  5266                        << 
"of the model atmosphere\n";
  5274                                ppath.
los(0,0), ppath.
los(0,1),x+dx*lt, y+dy*lt,
  5275                                z+dz*lt, 
dx, dy, dz, ppath.
constant, rte_pos[1],
  5276                                lon2use, rte_los[0], rte_los[1] );
  5277                   assert( 
abs( ppath.
r[0] -rt ) < 
RTOL );
  5285                   ppath.
gp_p[0].idx   = lp-1; 
  5286                   ppath.
gp_p[0].fd[0] = 1;
  5287                   ppath.
gp_p[0].fd[1] = 0;
  5294                   if( cloudbox_on  &&  cloudbox_limits[1] == lp )
  5298                       if( fgp1 >= (
Numeric)cloudbox_limits[2]  &&
  5299                           fgp1 <= (
Numeric)cloudbox_limits[3]  && 
  5300                           fgp2 >= (
Numeric)cloudbox_limits[4]  &&
  5301                           fgp2 <= (
Numeric)cloudbox_limits[5])
  5347     const Agenda&         ppath_step_agenda,
  5348     const Index&          atmosphere_dim,
  5356     const Vector&         refellipsoid,
  5358     const Index&          cloudbox_on, 
  5362     const Numeric&        ppath_lraytrace,
  5363     const bool&           ppath_inside_cloudbox_do,
  5374   if( ppath_inside_cloudbox_do  &&  !cloudbox_on )
  5375     throw runtime_error( 
"The WSV *ppath_inside_cloudbox_do* can only be set "  5376                          "to 1 if also *cloudbox_on* is 1." );
  5392                         lon_grid, z_field, refellipsoid, z_surface,
  5393                         cloudbox_on, cloudbox_limits, ppath_inside_cloudbox_do, 
  5394                         rte_pos, rte_los, verbosity );
  5428                                 z_field, vmr_field, f_grid, 
  5429                                 ppath_step_agenda );
  5434       const Index n = ppath_step.
np;
  5440         throw runtime_error(
  5441           "10 000 path points have been reached. Is this an infinite loop?" );
  5449       if( !ppath_inside_cloudbox_do )
  5455               ( 
abs(ppath_step.
los(n-1,0))<90  &&
  5462           if( atmosphere_dim == 2 )
  5468                   os << 
"The path exits the atmosphere through the lower "  5469                      << 
"latitude end face.\nThe exit point is at an altitude"   5470                      << 
" of " << ppath_step.
pos(n-1,0)/1e3 << 
" km.";
  5471                   throw runtime_error( os.str() );
  5476                   os << 
"The path exits the atmosphere through the upper "  5477                      << 
"latitude end face.\nThe exit point is at an altitude"   5478                      << 
" of " << ppath_step.
pos(n-1,0)/1e3 << 
" km.";
  5479                   throw runtime_error( os.str() );
  5482           if( atmosphere_dim == 3 )
  5485               if( lat_grid[0] > -90  && 
  5489                   os << 
"The path exits the atmosphere through the lower "  5490                      << 
"latitude end face.\nThe exit point is at an altitude"   5491                      << 
" of " << ppath_step.
pos(n-1,0)/1e3 << 
" km.";
  5492                   throw runtime_error( os.str() );
  5494               if( lat_grid[imax_lat] < 90  && 
  5498                   os << 
"The path exits the atmosphere through the upper "  5499                      << 
"latitude end face.\nThe exit point is at an altitude"   5500                      << 
" of " << ppath_step.
pos(n-1,0)/1e3 << 
" km.";
  5501                   throw runtime_error( os.str() );
  5508                   ppath_step.
los(n-1,1) < 0  &&  
  5509                   abs( ppath_step.
pos(n-1,1) ) < 90 )
  5512                   if( lon_grid[imax_lon] - lon_grid[0] >= 360 )
  5514                       ppath_step.
pos(n-1,2) = ppath_step.
pos(n-1,2) + 360;
  5516                                                        ppath_step.
pos(n-1,2) );
  5521                       os << 
"The path exits the atmosphere through the lower "   5522                          << 
"longitude end face.\nThe exit point is at an "  5523                          << 
"altitude of " << ppath_step.
pos(n-1,0)/1e3 
  5525                       throw runtime_error( os.str() );
  5530                    ppath_step.
los(n-1,1) > 0  &&  
  5531                    abs( ppath_step.
pos(n-1,1) ) < 90 )
  5534                   if( lon_grid[imax_lon] - lon_grid[0] >= 360 )
  5536                       ppath_step.
pos(n-1,2) = ppath_step.
pos(n-1,2) - 360;
  5538                                                        ppath_step.
pos(n-1,2) );
  5543                       os << 
"The path exits the atmosphere through the upper "  5544                          << 
"longitude end face.\nThe exit point is at an "  5545                          << 
"altitude of " << ppath_step.
pos(n-1,0)/1e3 
  5547                       throw runtime_error( os.str() );
  5558               if( ipos >= 
Numeric( cloudbox_limits[0] )  && 
  5559                   ipos <= 
Numeric( cloudbox_limits[1] ) )
  5561                   if( atmosphere_dim == 1 )
  5567                       if( ipos >= 
Numeric( cloudbox_limits[2] )  && 
  5568                           ipos <= 
Numeric( cloudbox_limits[3] ) )
  5570                           if( atmosphere_dim == 2 )
  5577                               if( ipos >= 
Numeric( cloudbox_limits[4] )  && 
  5578                                   ipos <= 
Numeric( cloudbox_limits[5] ) )
  5598           assert( ipos1 >= cloudbox_limits[0] );
  5599           assert( ipos1 <= cloudbox_limits[1] );
  5600           if( ipos1 <= cloudbox_limits[0]  &&  ipos1 < ipos2 )
  5603           else if( ipos1 >= 
Numeric( cloudbox_limits[1] )  &&  ipos1 > ipos2 )
  5606           else if( atmosphere_dim > 1 )
  5611               assert( ipos1 >= cloudbox_limits[2] );
  5612               assert( ipos1 <= cloudbox_limits[3] );
  5613               if( ipos1 <= 
Numeric( cloudbox_limits[2] )  &&  ipos1 < ipos2 )  
  5616               else if( ipos1 >= 
Numeric( cloudbox_limits[3] ) && ipos1 > ipos2 )
  5619               else if ( atmosphere_dim > 2 )
  5624                   assert( ipos1 >= cloudbox_limits[4] );
  5625                   assert( ipos1 <= cloudbox_limits[5] );
  5626                   if( ipos1 <= 
Numeric( cloudbox_limits[4] )  &&  ipos1<ipos2 )
  5629                   else if( ipos1 >= 
Numeric( cloudbox_limits[5] )  &&
  5648       ppath_array.push_back( ppath_step );
  5668                                     z_field, vmr_field, f_grid, 
  5669                                     ppath_step_agenda );
  5679       for( 
Index i=0; i<na; i++ )
  5685           Index n = ppath_array[i].np;
  5693           ppath.
r[ 
Range(np,n-i1) ] = ppath_array[i].r[ 
Range(i1,n-i1) ];
  5699                                         ppath_array[i].nreal[ 
Range(i1,n-i1) ];
  5701                                        ppath_array[i].ngroup[ 
Range(i1,n-i1) ];
  5702           ppath.
lstep[ 
Range(np-i1,n-1) ] = ppath_array[i].lstep; 
  5705           for( 
Index j=i1; j<n; j++ )
  5706             { ppath.
gp_p[np+j-i1] = ppath_array[i].gp_p[j]; }
  5707           if( atmosphere_dim >= 2 )
  5709               for( 
Index j=i1; j<n; j++ )
  5710                 { ppath.
gp_lat[np+j-i1] = ppath_array[i].gp_lat[j]; }
  5712           if( atmosphere_dim == 3 )
  5714               for( 
Index j=i1; j<n; j++ )
  5715                 { ppath.
gp_lon[np+j-i1] = ppath_array[i].gp_lon[j]; }
 INDEX Index
The type to use for all integer numbers and indices. 
 
void latlon_at_aa(Numeric &lat2, Numeric &lon2, const Numeric &lat1, const Numeric &lon1, const Numeric &aa, const Numeric &ddeg)
latlon_at_aa 
 
void get_refr_index_2d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat)
get_refr_index_2d 
 
bool is_lon_cyclic(ConstVectorView grid, const Numeric &epsilon)
Check if the given longitude grid is cyclic. 
 
void get_refr_index_3d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat, const Numeric &lon)
 
Numeric geompath_za_at_r(const Numeric &ppc, const Numeric &a_za, const Numeric &r)
geompath_za_at_r 
 
const Numeric LON_NOT_FOUND
 
Index nelem() const
Number of elements. 
 
Declarations having to do with the four output streams. 
 
void zaaa2cart(Numeric &dx, Numeric &dy, Numeric &dz, const Numeric &za, const Numeric &aa)
zaaa2cart 
 
Contains the code to determine roots of polynomials. 
 
Numeric refraction_ppc(const Numeric &r, const Numeric &za, const Numeric &refr_index_air)
refraction_ppc 
 
void ppath_copy(Ppath &ppath1, const Ppath &ppath2, const Index &ncopy)
ppath_copy 
 
void ppath_start_stepping(Ppath &ppath, const Index &atmosphere_dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstMatrixView z_surface, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const bool &ppath_inside_cloudbox_do, ConstVectorView rte_pos, ConstVectorView rte_los, const Verbosity &verbosity)
ppath_start_stepping 
 
void raytrace_3d_linear_basic(Workspace &ws, Array< Numeric > &r_array, Array< Numeric > &lat_array, Array< Numeric > &lon_array, Array< Numeric > &za_array, Array< Numeric > &aa_array, Array< Numeric > &l_array, Array< Numeric > &n_array, Array< Numeric > &ng_array, Index &endface, ConstVectorView refellipsoid, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &lmax, const Agenda &refr_index_air_agenda, const Numeric &lraytrace, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &rsurface15, const Numeric &rsurface35, const Numeric &rsurface36, const Numeric &rsurface16, const Numeric &r15a, const Numeric &r35a, const Numeric &r36a, const Numeric &r16a, const Numeric &r15b, const Numeric &r35b, const Numeric &r36b, const Numeric &r16b, Numeric r, Numeric lat, Numeric lon, Numeric za, Numeric aa)
raytrace_3d_linear_basic 
 
Numeric geompath_r_at_l(const Numeric &ppc, const Numeric &l)
geompath_r_at_l 
 
void do_gridcell_2d_byltest(Vector &r_v, Vector &lat_v, Vector &za_v, Numeric &lstep, Index &endface, const Numeric &r_start0, const Numeric &lat_start0, const Numeric &za_start, const Numeric &l_start, const Index &icall, const Numeric &ppc, const Numeric &lmax, const Numeric &lat1, const Numeric &lat3, const Numeric &r1a, const Numeric &r3a, const Numeric &r3b, const Numeric &r1b, const Numeric &rsurface1, const Numeric &rsurface3)
do_gridcell_2d_byltest 
 
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate. 
 
void raytrace_2d_linear_basic(Workspace &ws, Array< Numeric > &r_array, Array< Numeric > &lat_array, Array< Numeric > &za_array, Array< Numeric > &l_array, Array< Numeric > &n_array, Array< Numeric > &ng_array, Index &endface, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &lmax, const Agenda &refr_index_air_agenda, const Numeric &lraytrace, const Numeric &lat1, const Numeric &lat3, const Numeric &rsurface1, const Numeric &rsurface3, const Numeric &r1a, const Numeric &r3a, const Numeric &r3b, const Numeric &r1b, Numeric r, Numeric lat, Numeric za)
raytrace_2d_linear_basic 
 
void ppath_step_refr_2d(Workspace &ws, Ppath &ppath, ConstVectorView p_grid, ConstVectorView lat_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, ConstVectorView refellipsoid, ConstVectorView z_surface, const Numeric &lmax, const Agenda &refr_index_air_agenda, const String &rtrace_method, const Numeric &lraytrace)
ppath_step_refr_2d 
 
void ppath_step_agendaExecute(Workspace &ws, Ppath &ppath_step, const Numeric ppath_lraytrace, const Tensor3 &t_field, const Tensor3 &z_field, const Tensor4 &vmr_field, const Vector &f_grid, const Agenda &input_agenda)
 
void rotationmat3D(Matrix &R, ConstVectorView vrot, const Numeric &a)
rotationmat3D 
 
void ppath_step_geom_3d(Ppath &ppath, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstMatrixView z_surface, const Numeric &lmax)
ppath_step_geom_3d 
 
void cart2zaaa(Numeric &za, Numeric &aa, const Numeric &dx, const Numeric &dy, const Numeric &dz)
cart2zaaa 
 
void ppath_end_2d(Ppath &ppath, ConstVectorView r_v, ConstVectorView lat_v, ConstVectorView za_v, ConstVectorView lstep, ConstVectorView n_v, ConstVectorView ng_v, ConstVectorView lat_grid, ConstMatrixView z_field, ConstVectorView refellipsoid, const Index &ip, const Index &ilat, const Index &endface, const Numeric &ppc)
ppath_end_2d 
 
Numeric fractional_gp(const GridPos &gp)
fractional_gp 
 
cmplx FADDEEVA() w(cmplx z, double relerr)
 
void plevel_slope_3d(Numeric &c1, Numeric &c2, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15, const Numeric &r35, const Numeric &r36, const Numeric &r16, const Numeric &lat, const Numeric &lon, const Numeric &aa)
plevel_slope_3d 
 
void raytrace_1d_linear_basic(Workspace &ws, Array< Numeric > &r_array, Array< Numeric > &lat_array, Array< Numeric > &za_array, Array< Numeric > &l_array, Array< Numeric > &n_array, Array< Numeric > &ng_array, Index &endface, ConstVectorView p_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &lmax, const Agenda &refr_index_air_agenda, const Numeric &lraytrace, const Numeric &rsurface, const Numeric &r1, const Numeric &r3, Numeric r, Numeric lat, Numeric za)
raytrace_1d_linear_basic 
 
Numeric refell2d(ConstVectorView refellipsoid, ConstVectorView lat_grid, const GridPos gp)
refell2d 
 
Index gridpos2gridrange(const GridPos &gp, const bool &upwards)
gridpos2gridrange 
 
Numeric rslope_crossing3d(const Numeric &rp, const Numeric &za, const Numeric &r0, Numeric c1, Numeric c2)
rslope_crossing3d 
 
const Numeric LAT_NOT_FOUND
 
void get_refr_index_1d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r)
get_refr_index_1d 
 
Numeric geompath_lat_at_za(const Numeric &za0, const Numeric &lat0, const Numeric &za)
geompath_lat_at_za 
 
bool is_gridpos_at_index_i(const GridPos &gp, const Index &i, const bool &strict)
is_gridpos_at_index_i 
 
void resolve_lon(Numeric &lon, const Numeric &lon5, const Numeric &lon6)
resolve_lon 
 
Index nelem() const
Returns the number of elements. 
 
Numeric geometrical_ppc(const Numeric &r, const Numeric &za)
geometrical_ppc 
 
Structure to store a grid position. 
 
A constant view of a Tensor4. 
 
Index ppath_what_background(const Ppath &ppath)
ppath_what_background 
 
Numeric sign(const Numeric &x)
sign 
 
const Numeric L_NOT_FOUND
 
This file contains the definition of Array. 
 
void gridpos_check_fd(GridPos &gp)
gridpos_check_fd 
 
void mult(VectorView y, const ConstMatrixView &M, const ConstVectorView &x)
Matrix Vector multiplication. 
 
void map_daa(Numeric &za, Numeric &aa, const Numeric &za0, const Numeric &aa0, const Numeric &aa_grid)
 
void plevel_slope_2d(Numeric &c1, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstVectorView z_surf, const GridPos &gp, const Numeric &za)
plevel_slope_2d 
 
The implementation for String, the ARTS string class. 
 
Index ncols() const
Returns the number of columns. 
 
void ppath_set_background(Ppath &ppath, const Index &case_nr)
ppath_set_background 
 
Numeric rslope_crossing2d(const Numeric &rp, const Numeric &za, const Numeric &r0, Numeric c1)
rslope_crossing2d 
 
void do_gridrange_1d(Vector &r_v, Vector &lat_v, Vector &za_v, Numeric &lstep, Index &endface, const Numeric &r_start0, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc, const Numeric &lmax, const Numeric &ra, const Numeric &rb, const Numeric &rsurface)
do_gridrange_1d 
 
void geompath_from_r1_to_r2(Vector &r, Vector &lat, Vector &za, Numeric &lstep, const Numeric &ppc, const Numeric &r1, const Numeric &lat1, const Numeric &za1, const Numeric &r2, const bool &tanpoint, const Numeric &lmax)
geompath_from_r1_to_r2 
 
void ppath_end_1d(Ppath &ppath, ConstVectorView r_v, ConstVectorView lat_v, ConstVectorView za_v, ConstVectorView lstep, ConstVectorView n_v, ConstVectorView ng_v, ConstVectorView z_field, ConstVectorView refellipsoid, const Index &ip, const Index &endface, const Numeric &ppc)
ppath_end_1d 
 
void ppath_end_3d(Ppath &ppath, ConstVectorView r_v, ConstVectorView lat_v, ConstVectorView lon_v, ConstVectorView za_v, ConstVectorView aa_v, ConstVectorView lstep, ConstVectorView n_v, ConstVectorView ng_v, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, const Index &ip, const Index &ilat, const Index &ilon, const Index &endface, const Numeric &ppc)
ppath_end_3d 
 
void do_gridcell_3d_byltest(Vector &r_v, Vector &lat_v, Vector &lon_v, Vector &za_v, Vector &aa_v, Numeric &lstep, Index &endface, const Numeric &r_start0, const Numeric &lat_start0, const Numeric &lon_start0, const Numeric &za_start, const Numeric &aa_start, const Numeric &l_start, const Index &icall, const Numeric &ppc, const Numeric &lmax, const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15a, const Numeric &r35a, const Numeric &r36a, const Numeric &r16a, const Numeric &r15b, const Numeric &r35b, const Numeric &r36b, const Numeric &r16b, const Numeric &rsurface15, const Numeric &rsurface35, const Numeric &rsurface36, const Numeric &rsurface16)
do_gridcell_3d_byltest 
 
Declarations for agendas. 
 
void ppath_init_structure(Ppath &ppath, const Index &atmosphere_dim, const Index &np)
ppath_init_structure 
 
void cart2poslos(Numeric &r, Numeric &lat, Numeric &za, const Numeric &x, const Numeric &z, const Numeric &dx, const Numeric &dz, const Numeric &ppc, const Numeric &lat0, const Numeric &za0)
cart2poslos 
 
void ppath_append(Ppath &ppath1, const Ppath &ppath2)
ppath_append 
 
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array. 
 
void ppath_start_1d(Numeric &r_start, Numeric &lat_start, Numeric &za_start, Index &ip, const Ppath &ppath)
ppath_start_1d 
 
const Numeric R_NOT_FOUND
 
void find_tanpoint(Index &it, const Ppath ppath)
find_tanpoint 
 
NUMERIC Numeric
The type to use for all floating point numbers. 
 
Numeric plevel_angletilt(const Numeric &r, const Numeric &c1)
plevel_angletilt 
 
void refr_gradients_3d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, Numeric &dndr, Numeric &dndlat, Numeric &dndlon, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat, const Numeric &lon)
refr_gradients_3d 
 
Numeric refell2r(ConstVectorView refellipsoid, const Numeric &lat)
refell2r 
 
void gridpos_copy(GridPos &gp_new, const GridPos &gp_old)
gridpos_copy 
 
bool is_los_downwards(const Numeric &za, const Numeric &tilt)
is_los_downwards 
 
Header file for special_interp.cc. 
 
Propagation path structure and functions. 
 
void ppath_step_geom_2d(Ppath &ppath, ConstVectorView lat_grid, ConstMatrixView z_field, ConstVectorView refellipsoid, ConstVectorView z_surface, const Numeric &lmax)
ppath_step_geom_2d 
 
void ppath_step_geom_1d(Ppath &ppath, ConstVectorView z_field, ConstVectorView refellipsoid, const Numeric &z_surface, const Numeric &lmax)
ppath_step_geom_1d 
 
void ppath_start_3d(Numeric &r_start, Numeric &lat_start, Numeric &lon_start, Numeric &za_start, Numeric &aa_start, Index &ip, Index &ilat, Index &ilon, Numeric &lat1, Numeric &lat3, Numeric &lon5, Numeric &lon6, Numeric &r15a, Numeric &r35a, Numeric &r36a, Numeric &r16a, Numeric &r15b, Numeric &r35b, Numeric &r36b, Numeric &r16b, Numeric &rsurface15, Numeric &rsurface35, Numeric &rsurface36, Numeric &rsurface16, Ppath &ppath, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView refellipsoid, ConstMatrixView z_surface)
ppath_start_3d 
 
void r_crossing_3d(Numeric &lat, Numeric &lon, Numeric &l, const Numeric &r_hit, const Numeric &r_start, const Numeric &lat_start, const Numeric &lon_start, const Numeric &za_start, const Numeric &ppc, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &dx, const Numeric &dy, const Numeric &dz)
r_crossing_3d 
 
void r_crossing_2d(Numeric &lat, Numeric &l, const Numeric &r_hit, const Numeric &r_start, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc)
r_crossing_2d 
 
Header file for logic.cc. 
 
Numeric rsurf_at_latlon(const Numeric &lat1, const Numeric &lat3, const Numeric &lon5, const Numeric &lon6, const Numeric &r15, const Numeric &r35, const Numeric &r36, const Numeric &r16, const Numeric &lat, const Numeric &lon)
rsurf_at_latlon 
 
void adjust_los(VectorView los, const Index &atmosphere_dim)
adjust_los 
 
Numeric geompath_r_at_lat(const Numeric &ppc, const Numeric &lat0, const Numeric &za0, const Numeric &lat)
geompath_r_at_lat 
 
void ppath_step_refr_1d(Workspace &ws, Ppath &ppath, ConstVectorView p_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, ConstVectorView refellipsoid, const Numeric &z_surface, const Numeric &lmax, const Agenda &refr_index_air_agenda, const String &rtrace_method, const Numeric &lraytrace)
ppath_step_refr_1d 
 
void rte_pos2gridpos(GridPos &gp_p, GridPos &gp_lat, GridPos &gp_lon, const Index &atmosphere_dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstVectorView rte_pos)
rte_pos2gridpos 
 
void cart2pol(Numeric &r, Numeric &lat, const Numeric &x, const Numeric &z, const Numeric &lat0, const Numeric &za0)
cart2pol 
 
void resize(Index n)
Assignment operator from VectorView. 
 
A constant view of a Tensor3. 
 
A constant view of a Vector. 
 
void ppath_start_2d(Numeric &r_start, Numeric &lat_start, Numeric &za_start, Index &ip, Index &ilat, Numeric &lat1, Numeric &lat3, Numeric &r1a, Numeric &r3a, Numeric &r3b, Numeric &r1b, Numeric &rsurface1, Numeric &rsurface3, Ppath &ppath, ConstVectorView lat_grid, ConstMatrixView z_field, ConstVectorView refellipsoid, ConstVectorView z_surface)
ppath_start_2d 
 
void refr_gradients_1d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, Numeric &dndr, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r)
refr_gradients_1d 
 
A constant view of a Matrix. 
 
void refr_gradients_2d(Workspace &ws, Numeric &refr_index_air, Numeric &refr_index_air_group, Numeric &dndr, Numeric &dndlat, const Agenda &refr_index_air_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView refellipsoid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, const Numeric &r, const Numeric &lat)
refr_gradients_2d 
 
void cart2sph(Numeric &r, Numeric &lat, Numeric &lon, const Numeric &x, const Numeric &y, const Numeric &z, const Numeric &lat0, const Numeric &lon0, const Numeric &za0, const Numeric &aa0)
cart2sph 
 
Numeric geompath_r_at_za(const Numeric &ppc, const Numeric &za)
geompath_r_at_za 
 
Numeric rsurf_at_lat(const Numeric &lat1, const Numeric &lat3, const Numeric &r1, const Numeric &r3, const Numeric &lat)
rsurf_at_lat 
 
void ppath_calc(Workspace &ws, Ppath &ppath, const Agenda &ppath_step_agenda, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &t_field, const Tensor3 &z_field, const Tensor4 &vmr_field, const Vector &f_grid, const Vector &refellipsoid, const Matrix &z_surface, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Vector &rte_pos, const Vector &rte_los, const Numeric &ppath_lraytrace, const bool &ppath_inside_cloudbox_do, const Verbosity &verbosity)
ppath_calc 
 
The structure to describe a propagation path and releated quantities. 
 
Header file for helper functions for OpenMP. 
 
void ppath_step_refr_3d(Workspace &ws, Ppath &ppath, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView f_grid, ConstVectorView refellipsoid, ConstMatrixView z_surface, const Numeric &lmax, const Agenda &refr_index_air_agenda, const String &rtrace_method, const Numeric &lraytrace)
ppath_step_refr_3d 
 
void plevel_crossing_2d(Numeric &r, Numeric &lat, Numeric &l, const Numeric &r_start0, const Numeric &lat_start, const Numeric &za_start, const Numeric &ppc, const Numeric &lat1, const Numeric &lat3, const Numeric &r1, const Numeric &r3, const bool &above)
plevel_crossing_2d 
 
int poly_root_solve(Matrix &roots, Vector &coeffs)
 
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights. 
 
void poslos2cart(Numeric &x, Numeric &z, Numeric &dx, Numeric &dz, const Numeric &r, const Numeric &lat, const Numeric &za)
poslos2cart 
 
Index nrows() const
Returns the number of rows. 
 
Numeric geompath_l_at_r(const Numeric &ppc, const Numeric &r)
geompath_l_at_r 
 
void gridpos_force_end_fd(GridPos &gp, const Index &n)
gridpos_force_end_fd 
 
This file contains the definition of String, the ARTS string class. 
 
Declaration of functions in rte.cc. 
 
void resize(Index r, Index c)
Resize function.