70 const Index& atmosphere_dim,
80 chk_atm_surface(
"input argument *field*", field, atmosphere_dim, lat_grid,
87 if( rtp_pos[0] < zmin-dzok || rtp_pos[0] > zmax+dzok )
90 os <<
"The given position does not match *z_surface*.\nThe altitude in "
91 <<
"*rtp_pos* is " << rtp_pos[0]/1e3 <<
" km.\n"
92 <<
"The altitude range covered by *z_surface* is [" << zmin/1e3
93 <<
"," << zmax/1e3 <<
"] km.\n"
94 <<
"One possible mistake is to mix up *rtp_pos* and *rte_pos*.";
95 throw runtime_error( os.str() );
98 if( atmosphere_dim == 1 )
99 { outvalue = field(0,0); }
104 gridpos( gp_lat, lat_grid, rtp_pos[1] );
105 if( atmosphere_dim == 3 )
109 gridpos( gp_lon, lon_grid, rtp_pos[2] );
118 out3 <<
" Result = " << outvalue <<
"\n";
128 const Tensor3& iy_transmission,
129 const Index& jacobian_do,
130 const Index& atmosphere_dim,
134 const Index& cloudbox_on,
135 const Index& stokes_dim,
140 const Agenda& iy_main_agenda,
141 const Agenda& surface_rtprop_agenda,
155 surface_rmatrix, f_grid, rtp_pos, rtp_los,
156 surface_rtprop_agenda );
166 "Number of columns in *surface_los* is not correct." );
167 if( nlos != surface_rmatrix.
nbooks() )
169 "Mismatch in size of *surface_los* and *surface_rmatrix*." );
170 if( surface_rmatrix.
npages() != nf )
172 "Mismatch in size of *surface_rmatrix* and *f_grid*." );
173 if( surface_rmatrix.
nrows() != stokes_dim ||
174 surface_rmatrix.
ncols() != stokes_dim )
176 "Mismatch between size of *surface_rmatrix* and *stokes_dim*." );
178 if( surface_emission.
ncols() != stokes_dim )
180 "Mismatch between size of *surface_emission* and *stokes_dim*." );
181 if( surface_emission.
nrows() != nf )
183 "Mismatch in size of *surface_emission* and f_grid*." );
186 Tensor3 I( nlos, nf, stokes_dim );
191 for(
Index ilos=0; ilos<nlos; ilos++ )
201 if( iy_transmission.
npages() )
214 cloudbox_on, jacobian_do, t_field,
215 z_field, vmr_field, f_grid, rtp_pos,
216 los, rte_pos2, iy_main_agenda );
219 if( iy.
ncols() != stokes_dim || iy.
nrows() != nf )
222 os <<
"The size of *iy* returned from *"
223 << iy_main_agenda.
name() <<
"* is\n"
225 <<
" expected size = [" << nf <<
"," << stokes_dim <<
"]\n"
226 <<
" size of iy = [" << iy.
nrows() <<
"," << iy.
ncols()
228 throw runtime_error( os.str() );
236 surface_calc( iy, I, surface_los, surface_rmatrix, surface_emission );
248 const Index& atmosphere_dim,
251 const Vector& refellipsoid,
258 if( atmosphere_dim == 1 )
260 surface_normal[0] = 0;
261 specular_los[0] = 180 - rtp_los[0];
264 else if( atmosphere_dim == 2 )
268 gridpos( gp_lat, lat_grid, rtp_pos[1] );
271 gp_lat, rtp_los[0] );
276 specular_los[0] =
sign( rtp_los[0] ) * 180 - rtp_los[0] +
280 else if( atmosphere_dim == 3 )
286 gridpos( gp_lat, lat_grid, rtp_pos[1] );
287 gridpos( gp_lon, lon_grid, rtp_pos[2] );
293 +
interp( itw, z_surface, gp_lat, gp_lon );
297 gp_lat, gp_lon, 90 );
300 Vector tangentSN(3), tangentEW(3), normal(3);
301 zaaa2cart( tangentSN[0], tangentSN[1], tangentSN[2], zaSN, 0 );
302 zaaa2cart( tangentEW[0], tangentEW[1], tangentEW[2], zaEW, 90 );
303 cross3( normal, tangentSN, tangentEW );
306 zaaa2cart( di[0], di[1], di[2], rtp_los[0], rtp_los[1] );
309 cart2zaaa( surface_normal[0], surface_normal[1], normal[0], normal[1],
314 for(
Index i=0; i<3; i++ )
315 { speccart[i] =
fac*normal[i] - di[i]; }
316 cart2zaaa( specular_los[0], specular_los[1], speccart[0], speccart[1],
330 const Index& stokes_dim,
332 const Agenda& blackbody_radiation_agenda,
339 out2 <<
" Sets variables to model a blackbody surface with a temperature "
340 <<
" of " << surface_skin_t <<
" K.\n";
343 surface_rmatrix.
resize(0,0,0,0);
347 blackbody_radiation_agenda );
350 surface_emission.
resize( nf, stokes_dim );
351 surface_emission = 0.0;
353 for(
Index iv=0; iv<nf; iv++ )
355 surface_emission(iv,0) = b[iv];
356 for(
Index is=1; is<stokes_dim; is++ )
357 { surface_emission(iv,is) = 0; }
370 const Index& stokes_dim,
371 const Index& atmosphere_dim,
373 const Vector& specular_los,
376 const Agenda& blackbody_radiation_agenda,
390 Matrix n_real(nf,1), n_imag(nf,1);
393 "surface_complex_refr_index", f_grid,
394 Vector(1,surface_skin_t) );
396 out2 <<
" Sets variables to model a flat surface\n";
397 out3 <<
" surface temperature: " << surface_skin_t <<
" K.\n";
400 surface_los(0,
joker) = specular_los;
402 surface_emission.
resize( nf, stokes_dim );
403 surface_rmatrix.
resize( 1, nf, stokes_dim, stokes_dim );
407 assert( incang <= 90 );
412 for(
Index iv=0; iv<nf; iv++ )
415 Complex n2( n_real(iv,0), n_imag(iv,0) );
422 surface_emission(iv,
joker), Rv, Rh,
423 f_grid[iv], stokes_dim, surface_skin_t,
424 blackbody_radiation_agenda );
437 const Index& stokes_dim,
438 const Index& atmosphere_dim,
439 const Vector& specular_los,
441 const Tensor3& surface_reflectivity,
442 const Agenda& blackbody_radiation_agenda,
453 if( surface_reflectivity.
nrows() != stokes_dim &&
454 surface_reflectivity.
ncols() != stokes_dim )
457 os <<
"The number of rows and columnss in *surface_reflectivity* must\n"
458 <<
"match *stokes_dim*."
459 <<
"\n stokes_dim : " << stokes_dim
460 <<
"\n number of rows in *surface_reflectivity* : "
461 << surface_reflectivity.
nrows()
462 <<
"\n number of columns in *surface_reflectivity* : "
463 << surface_reflectivity.
ncols()
465 throw runtime_error( os.str() );
468 if( surface_reflectivity.
npages() != nf &&
469 surface_reflectivity.
npages() != 1 )
472 os <<
"The number of pages in *surface_reflectivity* should\n"
473 <<
"match length of *f_grid* or be 1."
474 <<
"\n length of *f_grid* : " << nf
475 <<
"\n dimension of *surface_reflectivity* : "
476 << surface_reflectivity.
npages()
478 throw runtime_error( os.str() );
481 out2 <<
" Sets variables to model a flat surface\n";
484 surface_los(0,
joker) = specular_los;
486 surface_emission.
resize( nf, stokes_dim );
487 surface_rmatrix.
resize(1,nf,stokes_dim,stokes_dim);
489 Matrix R, IR(stokes_dim,stokes_dim);
493 blackbody_radiation_agenda );
496 for(
Index iv=0; iv<nf; iv++ )
498 if( iv == 0 || surface_reflectivity.
npages() > 1 )
501 for(
Index i=0; i<stokes_dim; i++ )
503 for(
Index j=0; j<stokes_dim; j++ )
506 { IR(i,j) = 1 - R(i,j); }
508 { IR(i,j) = -R(i,j); }
516 mult( surface_emission(iv,
joker), IR, B );
529 const Index& stokes_dim,
530 const Index& atmosphere_dim,
531 const Vector& specular_los,
533 const Vector& surface_scalar_reflectivity,
534 const Agenda& blackbody_radiation_agenda,
546 if( surface_scalar_reflectivity.
nelem() != nf &&
547 surface_scalar_reflectivity.
nelem() != 1 )
550 os <<
"The number of elements in *surface_scalar_reflectivity* should\n"
551 <<
"match length of *f_grid* or be 1."
552 <<
"\n length of *f_grid* : " << nf
553 <<
"\n length of *surface_scalar_reflectivity* : "
554 << surface_scalar_reflectivity.
nelem()
556 throw runtime_error( os.str() );
559 if(
min(surface_scalar_reflectivity) < 0 ||
560 max(surface_scalar_reflectivity) > 1 )
563 "All values in *surface_scalar_reflectivity* must be inside [0,1]." );
566 out2 <<
" Sets variables to model a flat surface\n";
567 out3 <<
" surface temperature: " << surface_skin_t <<
" K.\n";
570 surface_los(0,
joker) = specular_los;
572 surface_emission.
resize( nf, stokes_dim );
573 surface_rmatrix.
resize( 1, nf, stokes_dim, stokes_dim );
577 blackbody_radiation_agenda );
581 for(
Index iv=0; iv<nf; iv++ )
583 if( iv == 0 || surface_scalar_reflectivity.
nelem() > 1 )
584 { r = surface_scalar_reflectivity[iv]; }
586 surface_emission(iv,0) = (1.0-r) * b[iv];
587 surface_rmatrix(0,iv,0,0) = r;
600 const Index& stokes_dim,
601 const Index& atmosphere_dim,
604 const Vector& surface_scalar_reflectivity,
605 const Index& lambertian_nza,
606 const Agenda& blackbody_radiation_agenda,
617 if( surface_scalar_reflectivity.
nelem() != nf &&
618 surface_scalar_reflectivity.
nelem() != 1 )
621 os <<
"The number of elements in *surface_scalar_reflectivity* should\n"
622 <<
"match length of *f_grid* or be 1."
623 <<
"\n length of *f_grid* : " << nf
624 <<
"\n length of *surface_scalar_reflectivity* : "
625 << surface_scalar_reflectivity.
nelem()
627 throw runtime_error( os.str() );
630 if(
min(surface_scalar_reflectivity) < 0 ||
631 max(surface_scalar_reflectivity) > 1 )
634 "All values in *surface_scalar_reflectivity* must be inside [0,1]." );
639 surface_los.
resize( lambertian_nza, rtp_los.
nelem() );
640 surface_rmatrix.
resize( lambertian_nza, nf, stokes_dim, stokes_dim );
641 surface_emission.
resize( nf, stokes_dim );
644 surface_rmatrix = 0.0;
645 surface_emission = 0.0;
650 const Vector za_lims( 0.0, lambertian_nza+1, dza );
653 for(
Index ip=0; ip<lambertian_nza; ip++ )
654 { surface_los(ip,0) = za_lims[ip] + za_pos * dza; }
658 blackbody_radiation_agenda );
664 for(
Index iv=0; iv<nf; iv++ )
667 if( iv == 0 || surface_scalar_reflectivity.
nelem() > 1 )
668 { r = surface_scalar_reflectivity[iv]; }
678 for(
Index ip=0; ip<lambertian_nza; ip++ )
681 cos(2*
DEG2RAD*za_lims[ip+1]) );
682 surface_rmatrix(ip,iv,0,0) =
w;
686 surface_emission(iv,0) = (1-r) * b[iv];
695 const Index& atmosphere_dim,
704 Index gfield_fID = 0;
705 Index gfield_tID = 1;
706 Index gfield_compID = 2;
707 Index gfield_latID = 3;
708 Index gfield_lonID = 4;
728 if( nlat < 2 || nlon < 2 )
731 os <<
"The data in *complex_refr_index_field* must span a geographical "
732 <<
"region. That is,\nthe latitude and longitude grids must have a "
739 os <<
"The data in *complex_refr_index_field* must have exactly two "
740 <<
"pages. One page each\nfor the real and imaginary part of the "
741 <<
"complex refractive index.";
759 lon_shifted[nlon-1] );
762 surface_complex_refr_index.
resize( nf, nt, 2 );
764 surface_complex_refr_index.
set_grid( 0,
766 surface_complex_refr_index.
set_grid_name( 1,
"Temperature" );
767 surface_complex_refr_index.
set_grid( 1,
770 surface_complex_refr_index.
set_grid( 2,
776 gridpos( gp_lat, GFlat, lat[0] );
777 gridpos( gp_lon, lon_shifted, lon[0] );
781 for(
Index iv=0; iv<nf; iv++ )
783 for(
Index it=0; it<nt; it++ )
785 surface_complex_refr_index.
data(iv,it,0) =
interp( itw,
787 surface_complex_refr_index.
data(iv,it,1) =
interp( itw,
798 const Index& stokes_dim,
800 const Index& atmosphere_dim,
830 if( nlat < 2 || nlon < 2 )
833 os <<
"The data in *r_field* must span a geographical region. That is,\n"
834 <<
"the latitude and longitude grids must have a length >= 2.";
835 throw runtime_error( os.str() );
841 os <<
"The data in *r_field* must span a range of zenith angles. That\n"
842 <<
"is the zenith angle grid must have a length >= 2.";
843 throw runtime_error( os.str() );
846 if( ns1 < stokes_dim || ns2 < stokes_dim || ns1 > 4 || ns2 > 4 )
849 os <<
"The \"Stokes dimensions\" must have a size that is >= "
850 <<
"*stokes_dim* (but not exceeding 4).";
851 throw runtime_error( os.str() );
864 Tensor4 r_f_za( nf_in, stokes_dim, stokes_dim, nza );
869 lon_shifted, lon[0] );
872 gridpos( gp_lon, lon_shifted, lon[0] );
875 for(
Index iv=0; iv<nf_in; iv++ )
876 {
for(
Index iz=0; iz<nza; iz++ )
877 {
for(
Index is1=0; is1<stokes_dim; is1++ )
878 {
for(
Index is2=0; is2<stokes_dim; is2++ )
880 r_f_za(iv,is1,is2,iz) =
interp( itw,
885 Tensor3 r_f( nf_in, stokes_dim, stokes_dim );
890 Vector incang( 1, 180-rtp_los[0] );
899 for(
Index i=0; i<nf_in; i++ )
900 {
for(
Index is1=0; is1<stokes_dim; is1++ )
901 {
for(
Index is2=0; is2<stokes_dim; is2++ )
904 r_f(i,is1,is2) = tmp[0];
910 { surface_reflectivity = r_f; }
916 surface_reflectivity.
resize( nf_out, stokes_dim, stokes_dim );
922 for(
Index is1=0; is1<stokes_dim; is1++ )
923 {
for(
Index is2=0; is2<stokes_dim; is2++ )
926 r_f(
joker,is1,is2), gp );
934 Vector& surface_scalar_reflectivity,
935 const Index& stokes_dim,
937 const Index& atmosphere_dim,
963 if( nlat < 2 || nlon < 2 )
966 os <<
"The data in *r_field* must span a geographical region. That is,\n"
967 <<
"the latitude and longitude grids must have a length >= 2.";
968 throw runtime_error( os.str() );
975 os <<
"The data in *r_field* must span a range of zenith angles. That\n"
976 <<
"is the zenith angle grid must have a length >= 2.";
977 throw runtime_error( os.str() );
990 Matrix r_f_za( nf_in, nza );
995 lon_shifted, lon[0] );
998 gridpos( gp_lon, lon_shifted, lon[0] );
1001 for(
Index iv=0; iv<nf_in; iv++ )
1003 for(
Index iz=0; iz<nza; iz++ )
1018 Vector incang( 1, 180-rtp_los[0] );
1027 for(
Index i=0; i<nf_in; i++ )
1038 surface_scalar_reflectivity.
resize( 1 );
1039 surface_scalar_reflectivity[0] = r_f[0];
1046 surface_scalar_reflectivity.
resize( nf_out );
1052 interp( surface_scalar_reflectivity, itw, r_f, gp );