116 const Numeric& rtp_planck_value,
117 const bool& trans_is_precalc )
123 assert(
is_size(trans_mat, stokes_dim, stokes_dim));
124 assert(
is_size(ext_mat_av, stokes_dim, stokes_dim));
125 assert(
is_size(abs_vec_av, stokes_dim));
126 assert(
is_size(sca_vec_av, stokes_dim));
127 assert( rtp_planck_value >= 0 );
128 assert( lstep >= 0 );
132 bool unpol_abs_vec =
true;
134 for (
Index i = 1; i < stokes_dim; i++)
135 if (abs_vec_av[i] != 0)
136 unpol_abs_vec =
false;
138 bool unpol_sca_vec =
true;
140 for (
Index i = 1; i < stokes_dim; i++)
141 if (sca_vec_av[i] != 0)
142 unpol_sca_vec =
false;
145 Index extmat_case = 0;
146 if( !trans_is_precalc )
147 {
ext2trans( trans_mat, extmat_case, ext_mat_av, lstep ); }
150 if( stokes_dim == 1 )
152 stokes_vec[0] = stokes_vec[0] * trans_mat(0,0) +
153 ( abs_vec_av[0] * rtp_planck_value + sca_vec_av[0] ) /
154 ext_mat_av(0,0) * (1 - trans_mat(0,0) );
165 else if( extmat_case==1 && unpol_abs_vec && unpol_sca_vec )
168 stokes_vec[0] = stokes_vec[0] * trans_mat(0,0) +
169 ( abs_vec_av[0] * rtp_planck_value + sca_vec_av[0] ) /
170 ext_mat_av(0,0) * (1 - trans_mat(0,0) );
173 for(
Index i=1; i<stokes_dim; i++ )
175 stokes_vec[i] = stokes_vec[i] * trans_mat(i,i) + sca_vec_av[i] /
176 ext_mat_av(i,i) * (1 - trans_mat(i,i));
187 Matrix LU(stokes_dim, stokes_dim);
191 Matrix I(stokes_dim, stokes_dim);
193 Vector B_abs_vec(stokes_dim);
194 B_abs_vec = abs_vec_av;
195 B_abs_vec *= rtp_planck_value;
197 for (
Index i=0; i<stokes_dim; i++)
198 b[i] = B_abs_vec[i] + sca_vec_av[i];
201 ludcmp(LU, indx, ext_mat_av);
204 Matrix ext_mat_ds(stokes_dim, stokes_dim);
205 ext_mat_ds = ext_mat_av;
206 ext_mat_ds *= -lstep;
212 for(
Index i=0; i<stokes_dim; i++)
214 for(
Index j=0; j<stokes_dim; j++)
215 LU(i,j) = I(i,j) - trans_mat(i,j);
221 mult( term1, trans_mat, stokes_vec );
223 for (
Index i=0; i<stokes_dim; i++)
224 stokes_vec[i] = term1[i] + term2[i];
262 const Agenda& spt_calc_agenda,
263 const Agenda& opt_prop_part_agenda,
264 const Index& scat_za_index,
265 const Index& scat_aa_index,
276 out3 <<
"Calculate scattering properties in cloudbox \n";
278 const Index atmosphere_dim = cloudbox_limits.
nelem()/2;
280 const Index stokes_dim = ext_mat_field.
ncols();
282 assert( atmosphere_dim == 1 || atmosphere_dim ==3 );
283 assert( ext_mat_field.
ncols() == ext_mat_field.
nrows() &&
284 ext_mat_field.
ncols() == abs_vec_field.
ncols());
286 const Index Np_cloud = cloudbox_limits[1]-cloudbox_limits[0]+1;
289 Index Nlat_cloud = 1;
290 Index Nlon_cloud = 1;
292 if (atmosphere_dim == 3)
294 Nlat_cloud = cloudbox_limits[3]-cloudbox_limits[2]+1;
295 Nlon_cloud = cloudbox_limits[5]-cloudbox_limits[4]+1;
301 Matrix abs_vec_spt_local(N_pt, stokes_dim, 0.);
302 Tensor3 ext_mat_spt_local(N_pt, stokes_dim, stokes_dim, 0.);
318 for(
Index scat_p_index_local = 0; scat_p_index_local < Np_cloud;
319 scat_p_index_local ++)
321 for(
Index scat_lat_index_local = 0; scat_lat_index_local < Nlat_cloud;
322 scat_lat_index_local ++)
324 for(
Index scat_lon_index_local = 0;
325 scat_lon_index_local < Nlon_cloud;
326 scat_lon_index_local ++)
328 if (atmosphere_dim == 1)
329 rtp_temperature_local =
330 t_field(scat_p_index_local + cloudbox_limits[0], 0, 0);
332 rtp_temperature_local =
333 t_field(scat_p_index_local + cloudbox_limits[0],
334 scat_lat_index_local + cloudbox_limits[2],
335 scat_lon_index_local + cloudbox_limits[4]);
342 scat_lat_index_local,
343 scat_lon_index_local,
344 rtp_temperature_local,
353 scat_lat_index_local,
354 scat_lon_index_local,
355 opt_prop_part_agenda);
358 abs_vec_field(scat_p_index_local, scat_lat_index_local,
359 scat_lon_index_local,
362 ext_mat_field(scat_p_index_local, scat_lat_index_local,
363 scat_lon_index_local,
420 const Index& p_index,
421 const Index& scat_za_index,
426 const Agenda& propmat_clearsky_agenda,
429 const Agenda& ppath_step_agenda,
430 const Numeric& ppath_lraytrace,
437 const Index& f_index,
441 const Agenda& surface_rtprop_agenda,
443 const Index& scat_za_interp,
460 ppath_step.
pos(0,0) = z_field(p_index,0,0);
461 ppath_step.
r[0] = refellipsoid[0] + z_field(p_index,0,0);
464 ppath_step.
los(0,0) = scat_za_grid[scat_za_index];
468 ppath_step.
gp_p[0].idx = p_index;
469 ppath_step.
gp_p[0].fd[0] = 0;
470 ppath_step.
gp_p[0].fd[1] = 1;
475 Vector(1,f_grid[f_index]), ppath_step_agenda );
482 if((cloudbox_limits[0] <= ppath_step.
gp_p[1].idx &&
483 cloudbox_limits[1] > ppath_step.
gp_p[1].idx) ||
484 (cloudbox_limits[1] == ppath_step.
gp_p[1].idx &&
485 abs(ppath_step.
gp_p[1].fd[0]) < 1e-6))
488 const Index stokes_dim = doit_i_field.
ncols();
499 Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.
np, 0.);
500 Matrix abs_vec_int(stokes_dim, ppath_step.
np, 0.);
501 Matrix sca_vec_int(stokes_dim, ppath_step.
np, 0.);
502 Matrix doit_i_field_int(stokes_dim, ppath_step.
np, 0.);
504 Matrix vmr_list_int(N_species, ppath_step.
np, 0.);
508 doit_i_field_int, t_int, vmr_list_int, p_int,
509 ext_mat_field, abs_vec_field, doit_scat_field,
510 doit_i_field, t_field, vmr_field, p_grid,
511 ppath_step, cloudbox_limits, scat_za_grid,
512 scat_za_interp, verbosity);
525 propmat_clearsky_agenda,
528 ext_mat_int, abs_vec_int, sca_vec_int,
530 p_int, cloudbox_limits,
531 f_grid, f_index, p_index, 0, 0,
532 scat_za_index, 0, verbosity);
539 doit_i_field, surface_rtprop_agenda, f_grid,
540 f_index, stokes_dim, ppath_step, cloudbox_limits,
541 scat_za_grid, scat_za_index);
560 const Index& p_index,
561 const Index& scat_za_index,
567 const Agenda& propmat_clearsky_agenda,
570 const Agenda& ppath_step_agenda,
571 const Numeric& ppath_lraytrace,
579 const Index& f_index,
583 const Agenda& surface_rtprop_agenda,
584 const Index& scat_za_interp,
601 ppath_step.
pos(0,0) = z_field(p_index,0,0);
602 ppath_step.
r[0] = refellipsoid[0] + z_field(p_index,0,0);
605 ppath_step.
los(0,0) = scat_za_grid[scat_za_index];
609 ppath_step.
gp_p[0].idx = p_index;
610 ppath_step.
gp_p[0].fd[0] = 0;
611 ppath_step.
gp_p[0].fd[1] = 1;
616 Vector(1,f_grid[f_index]), ppath_step_agenda );
623 if((cloudbox_limits[0] <= ppath_step.
gp_p[1].idx &&
624 cloudbox_limits[1] > ppath_step.
gp_p[1].idx) ||
625 (cloudbox_limits[1] == ppath_step.
gp_p[1].idx &&
626 abs(ppath_step.
gp_p[1].fd[0]) < 1e-6))
629 const Index stokes_dim = doit_i_field.
ncols();
640 Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.
np, 0.);
641 Matrix abs_vec_int(stokes_dim, ppath_step.
np, 0.);
642 Matrix sca_vec_int(stokes_dim, ppath_step.
np, 0.);
643 Matrix doit_i_field_int(stokes_dim, ppath_step.
np, 0.);
645 Matrix vmr_list_int(N_species, ppath_step.
np, 0.);
649 doit_i_field_int, t_int, vmr_list_int, p_int,
650 ext_mat_field, abs_vec_field, doit_scat_field,
651 doit_i_field_old, t_field, vmr_field, p_grid,
652 ppath_step, cloudbox_limits, scat_za_grid,
653 scat_za_interp, verbosity);
669 propmat_clearsky_agenda,
672 ext_mat_int, abs_vec_int, sca_vec_int,
674 p_int, cloudbox_limits,
675 f_grid, f_index, p_index, 0, 0,
676 scat_za_index, 0, verbosity);
681 doit_i_field, surface_rtprop_agenda, f_grid,
682 f_index, stokes_dim, ppath_step, cloudbox_limits,
683 scat_za_grid, scat_za_index);
741 const Index& p_index,
742 const Index& lat_index,
743 const Index& lon_index,
744 const Index& scat_za_index,
745 const Index& scat_aa_index,
751 const Agenda& propmat_clearsky_agenda,
754 const Agenda& ppath_step_agenda,
755 const Numeric& ppath_lraytrace,
764 const Index& f_index,
775 const Index stokes_dim = doit_i_field.
ncols();
777 Vector sca_vec_av(stokes_dim,0);
781 aa_grid[i] = scat_aa_grid[i]-180.;
794 ppath_step.
pos(0,2) = lon_grid[lon_index];
795 ppath_step.
pos(0,1) = lat_grid[lat_index];
796 ppath_step.
pos(0,0) = z_field( p_index, lat_index, lon_index );
798 ppath_step.
r[0] =
refell2r( refellipsoid, ppath_step.
pos(0,1) ) +
803 ppath_step.
los(0,0) = scat_za_grid[scat_za_index];
804 ppath_step.
los(0,1) = aa_grid[scat_aa_index];
807 ppath_step.
gp_p[0].idx = p_index;
808 ppath_step.
gp_p[0].fd[0] = 0.;
809 ppath_step.
gp_p[0].fd[1] = 1.;
811 ppath_step.
gp_lat[0].idx = lat_index;
812 ppath_step.
gp_lat[0].fd[0] = 0.;
813 ppath_step.
gp_lat[0].fd[1] = 1.;
815 ppath_step.
gp_lon[0].idx = lon_index;
816 ppath_step.
gp_lon[0].fd[0] = 0.;
817 ppath_step.
gp_lon[0].fd[1] = 1.;
822 Vector(1,f_grid[f_index]), ppath_step_agenda);
839 for(
Index i = 0; i<ppath_step.
np; i++ )
841 cloud_gp_p[i].idx -= cloudbox_limits[0];
842 cloud_gp_lat[i].idx -= cloudbox_limits[2];
843 cloud_gp_lon[i].idx -= cloudbox_limits[4];
845 const Index n1 = cloudbox_limits[1] - cloudbox_limits[0];
846 const Index n2 = cloudbox_limits[3] - cloudbox_limits[2];
847 const Index n3 = cloudbox_limits[5] - cloudbox_limits[4];
869 los_grid_aa[i] = los_grid_aa[i] + 180.;
872 gridpos(gp_za, scat_za_grid, los_grid_za);
875 gridpos(gp_aa, scat_aa_grid, los_grid_aa);
878 interpweights(itw_p_za, cloud_gp_p, cloud_gp_lat, cloud_gp_lon,
887 Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.
np);
888 Matrix abs_vec_int(stokes_dim, ppath_step.
np);
889 Matrix sca_vec_int(stokes_dim, ppath_step.
np, 0.);
890 Matrix doit_i_field_int(stokes_dim, ppath_step.
np, 0.);
894 Vector stokes_vec(stokes_dim);
902 for (
Index i = 0; i < stokes_dim; i++)
906 out3 <<
"Interpolate ext_mat:\n";
907 for (
Index j = 0; j < stokes_dim; j++)
914 cloud_gp_lat, cloud_gp_lon);
922 cloud_gp_p, cloud_gp_lat, cloud_gp_lon);
928 out3 <<
"Interpolate doit_scat_field:\n";
932 cloud_gp_lat, cloud_gp_lon, gp_za, gp_aa);
933 out3 <<
"Interpolate doit_i_field:\n";
937 cloud_gp_lat, cloud_gp_lon, gp_za, gp_aa);
944 out3 <<
"Interpolate temperature field\n";
958 Matrix vmr_list_int(N_species, ppath_step.
np);
960 for (
Index i = 0; i < N_species; i++)
962 out3 <<
"Interpolate vmr field\n";
967 vmr_list_int(i,
joker) = vmr_int;
971 itw2p( p_int, p_grid, ppath_step.
gp_p, itw_p);
973 out3 <<
"Calculate radiative transfer inside cloudbox.\n";
975 propmat_clearsky_agenda,
978 ext_mat_int, abs_vec_int, sca_vec_int,
980 p_int, cloudbox_limits,
981 f_grid, f_index, p_index, lat_index, lon_index,
982 scat_za_index, scat_aa_index, verbosity);
1020 const Agenda& propmat_clearsky_agenda,
1021 const Ppath& ppath_step,
1031 const Index& f_index,
1032 const Index& p_index,
1033 const Index& lat_index,
1034 const Index& lon_index,
1035 const Index& scat_za_index,
1036 const Index& scat_aa_index,
1041 const Index N_species = vmr_list_int.
nrows();
1042 const Index stokes_dim = doit_i_field.
ncols();
1043 const Index atmosphere_dim = cloudbox_limits.
nelem()/2;
1045 Vector sca_vec_av(stokes_dim,0);
1046 Vector stokes_vec(stokes_dim, 0.);
1047 Vector rtp_vmr_local(N_species,0.);
1051 Tensor4 prev_propmat_clearsky;
1057 stokes_vec = doit_i_field_int(
joker, ppath_step.
np-1);
1059 for(
Index k = ppath_step.
np-1; k >= 0; k--)
1063 swap(cur_propmat_clearsky, prev_propmat_clearsky);
1068 const Vector rtp_mag_dummy(3,0);
1069 const Vector ppath_los_dummy;
1072 f_grid[
Range(f_index, 1)],
1073 rtp_mag_dummy, ppath_los_dummy,
1076 vmr_list_int(
joker,k),
1077 propmat_clearsky_agenda );
1081 if (k == ppath_step.
np-1)
1085 prev_propmat_clearsky += cur_propmat_clearsky;
1086 prev_propmat_clearsky *= 0.5;
1089 prev_propmat_clearsky);
1094 for (
Index i = 0; i < stokes_dim; i++)
1096 for (
Index j = 0; j < stokes_dim; j++)
1098 ext_mat_local(0,i,j) += 0.5 *
1099 (ext_mat_int(i,j,k) + ext_mat_int(i,j,k+1));
1104 abs_vec_local(0,i) += 0.5 *
1105 (abs_vec_int(i,k) + abs_vec_int(i,k+1));
1110 sca_vec_av[i] = 0.5 *
1111 (sca_vec_int(i, k) + sca_vec_int(i, k+1));
1119 Numeric rte_planck_value =
planck(f, 0.5 * (t_int[k] + t_int[k+1]));
1125 out3 <<
"-----------------------------------------\n";
1126 out3 <<
"Input for radiative transfer step \n"
1127 <<
"calculation inside"
1128 <<
" the cloudbox:" <<
"\n";
1129 out3 <<
"Stokes vector at intersection point: \n"
1132 out3 <<
"lstep: ..." << lstep <<
"\n";
1133 out3 <<
"------------------------------------------\n";
1134 out3 <<
"Averaged coefficients: \n";
1135 out3 <<
"Planck function: " << rte_planck_value <<
"\n";
1136 out3 <<
"Scattering vector: " << sca_vec_av <<
"\n";
1137 out3 <<
"Absorption vector: " << abs_vec_local(0,
joker) <<
"\n";
1138 out3 <<
"Extinction matrix: " << ext_mat_local(0,
joker,
joker) <<
"\n";
1147 sca_vec_av, lstep, rte_planck_value);
1151 if (atmosphere_dim == 1)
1152 doit_i_field(p_index - cloudbox_limits[0], 0, 0, scat_za_index, 0,
joker)
1154 else if (atmosphere_dim == 3)
1155 doit_i_field(p_index - cloudbox_limits[0],
1156 lat_index - cloudbox_limits[2],
1157 lon_index - cloudbox_limits[4],
1158 scat_za_index, scat_aa_index,
1159 joker) = stokes_vec;
1179 const Agenda& surface_rtprop_agenda,
1181 const Index& f_index,
1182 const Index& stokes_dim,
1183 const Ppath& ppath_step,
1186 const Index& scat_za_index
1189 chk_not_empty(
"surface_rtprop_agenda", surface_rtprop_agenda );
1205 rte_pos = ppath_step.
pos(np-1,
Range(0,ppath_step.
dim));
1209 rte_los = ppath_step.
los(np-1,
joker);
1215 surface_rmatrix,
Vector(1,f_grid[f_index]),
1216 rte_pos, rte_los, surface_rtprop_agenda );
1218 iy = surface_emission;
1226 for(
Index ilos=0; ilos<nlos; ilos++ )
1233 doit_i_field( cloudbox_limits[0], 0, 0,
1234 (scat_za_grid.
nelem() -1 - scat_za_index), 0,
joker) );
1235 iy(0,
joker) += rtmp;
1237 doit_i_field( cloudbox_limits[0], 0, 0, scat_za_index, 0,
joker ) =
1269 const Ppath& ppath_step,
1272 const Index& scat_za_interp,
1278 const Index stokes_dim = doit_i_field.
ncols();
1286 for(
Index i = 0; i < ppath_step.
np; i++ )
1287 cloud_gp_p[i].idx -= cloudbox_limits[0];
1290 const Index n1 = cloudbox_limits[1] - cloudbox_limits[0];
1304 gridpos(gp_za, scat_za_grid, los_grid);
1313 for (
Index i = 0; i < stokes_dim; i++)
1317 out3 <<
"Interpolate ext_mat:\n";
1318 for (
Index j = 0; j < stokes_dim; j++)
1324 ext_mat_field(
joker, 0, 0, i, j), cloud_gp_p );
1330 out3 <<
"Interpolate abs_vec:\n";
1332 abs_vec_field(
joker, 0, 0, i), cloud_gp_p );
1338 out3 <<
"Interpolate doit_scat_field and doit_i_field:\n";
1339 if(scat_za_interp == 0)
1345 doit_i_field(
joker, 0, 0,
joker, 0, i), cloud_gp_p, gp_za);
1347 else if (scat_za_interp == 1)
1352 Tensor3 sca_vec_int_za(stokes_dim, ppath_step.
np,
1353 scat_za_grid.
nelem(), 0.);
1354 Tensor3 doit_i_field_int_za(stokes_dim, ppath_step.
np,
1355 scat_za_grid.
nelem(), 0.);
1356 for (
Index za = 0; za < scat_za_grid.
nelem(); za++)
1359 doit_scat_field(
joker, 0, 0, za, 0, i), cloud_gp_p);
1360 out3 <<
"Interpolate doit_i_field:\n";
1362 doit_i_field(
joker, 0, 0, za, 0, i), cloud_gp_p);
1364 for (
Index ip = 0; ip < ppath_step.
np; ip ++)
1366 sca_vec_int(i, ip) =
1368 los_grid[ip], gp_za[ip]);
1369 doit_i_field_int(i, ip) =
1371 los_grid[ip], gp_za[ip]);
1380 out3 <<
"Interpolate temperature field\n";
1393 for (
Index i_sp = 0; i_sp < N_species; i_sp ++)
1395 out3 <<
"Interpolate vmr field\n";
1396 interp( vmr_int, itw, vmr_field(i_sp,
joker, 0, 0), ppath_step.
gp_p );
1397 vmr_list_int(i_sp,
joker) = vmr_int;
1402 itw2p( p_int, p_grid, ppath_step.
gp_p, itw);
1448 const Index& p_index,
1449 const Index& scat_za_index,
1454 const Agenda& propmat_clearsky_agenda,
1462 const Index& f_index,
1471 const Index stokes_dim = doit_i_field.
ncols();
1472 const Index atmosphere_dim = 1;
1476 Vector rtp_vmr(N_species,0.);
1477 Vector sca_vec_av(stokes_dim,0);
1482 Vector stokes_vec(stokes_dim);
1484 if((p_index == 0) && (scat_za_grid[scat_za_index] > 90))
1496 if(scat_za_grid[scat_za_index] <= 90.0)
1498 stokes_vec = doit_i_field(p_index-cloudbox_limits[0] +1, 0, 0, scat_za_index, 0,
joker);
1499 Numeric z_field_above = z_field(p_index +1, 0, 0);
1500 Numeric z_field_0 = z_field(p_index, 0, 0);
1503 if (scat_za_grid[scat_za_index] == 90.0)
1512 cos_theta = cos(scat_za_grid[scat_za_index]*
PI/180.0);
1514 Numeric dz = (z_field_above - z_field_0);
1516 lstep =
abs(dz/cos_theta) ;
1519 Numeric rtp_temperature = 0.5 * (t_field(p_index,0,0)
1520 + t_field(p_index + 1,0,0));
1523 Numeric rtp_pressure = 0.5 * (p_grid[p_index]
1524 + p_grid[p_index + 1]);
1527 for (
Index j = 0; j < N_species; j++)
1528 rtp_vmr[j] = 0.5 * (vmr_field(j,p_index,0,0) +
1529 vmr_field(j,p_index + 1,0,0));
1535 const Vector rtp_mag_dummy(3,0);
1536 const Vector ppath_los_dummy;
1539 f_grid[
Range(f_index, 1)],
1540 rtp_mag_dummy,ppath_los_dummy,
1544 propmat_clearsky_agenda);
1551 for (
Index k = 0; k < stokes_dim; k++)
1553 for (
Index j = 0; j < stokes_dim; j++)
1556 ext_mat(0,k,j) += 0.5 *
1557 (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) +
1558 ext_mat_field(p_index - cloudbox_limits[0]+ 1,0,0,k,j));
1563 abs_vec(0,k) += 0.5 *
1564 (abs_vec_field(p_index- cloudbox_limits[0],0,0,k) +
1565 abs_vec_field(p_index - cloudbox_limits[0]+ 1,0,0,k));
1570 sca_vec_av[k] += 0.5 *
1571 (doit_scat_field(p_index- cloudbox_limits[0],0,0,scat_za_index,0, k) +
1572 doit_scat_field(p_index - cloudbox_limits[0]+ 1,0,0,scat_za_index,0,k));
1583 out3 <<
"-----------------------------------------\n";
1584 out3 <<
"Input for radiative transfer step \n"
1585 <<
"calculation inside"
1586 <<
" the cloudbox:" <<
"\n";
1587 out3 <<
"Stokes vector at intersection point: \n"
1590 out3 <<
"lstep: ..." << lstep <<
"\n";
1591 out3 <<
"------------------------------------------\n";
1592 out3 <<
"Averaged coefficients: \n";
1593 out3 <<
"Planck function: " << rte_planck_value <<
"\n";
1594 out3 <<
"Scattering vector: " << sca_vec_av <<
"\n";
1595 out3 <<
"Absorption vector: " << abs_vec(0,
joker) <<
"\n";
1596 out3 <<
"Extinction matrix: " << ext_mat(0,
joker,
joker) <<
"\n";
1605 sca_vec_av, lstep, rte_planck_value);
1608 doit_i_field(p_index - cloudbox_limits[0],
1611 joker) = stokes_vec;
1613 if(scat_za_grid[scat_za_index] > 90)
1615 stokes_vec = doit_i_field(p_index-cloudbox_limits[0] -1, 0, 0, scat_za_index, 0,
joker);
1616 Numeric z_field_below = z_field(p_index -1, 0, 0);
1617 Numeric z_field_0 = z_field(p_index, 0, 0);
1620 if (scat_za_grid[scat_za_index] == 90.0)
1622 cos_theta = cos((scat_za_grid[scat_za_index] -1)*
PI/180.);
1628 cos_theta = cos(scat_za_grid[scat_za_index]*
PI/180.0);
1630 Numeric dz = ( z_field_0 - z_field_below);
1631 lstep =
abs(dz/cos_theta) ;
1634 Numeric rtp_temperature = 0.5 * (t_field(p_index,0,0)
1635 + t_field(p_index - 1,0,0));
1638 Numeric rtp_pressure = 0.5 * (p_grid[p_index]
1639 + p_grid[p_index - 1]);
1643 for (
Index k = 0; k < N_species; k++)
1644 rtp_vmr[k] = 0.5 * (vmr_field(k,p_index,0,0) +
1645 vmr_field(k,p_index - 1,0,0));
1651 const Vector rtp_mag_dummy(3,0);
1652 const Vector ppath_los_dummy;
1655 f_grid[
Range(f_index, 1)],
1656 rtp_mag_dummy,ppath_los_dummy,
1660 propmat_clearsky_agenda );
1670 for (
Index k = 0; k < stokes_dim; k++)
1672 for (
Index j = 0; j < stokes_dim; j++)
1675 ext_mat(0,k,j) += 0.5 *
1676 (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) +
1677 ext_mat_field(p_index - cloudbox_limits[0]- 1,0,0,k,j));
1682 abs_vec(0,k) += 0.5 *
1683 (abs_vec_field(p_index - cloudbox_limits[0],0,0,k) +
1684 abs_vec_field(p_index - cloudbox_limits[0]- 1,0,0,k));
1689 sca_vec_av[k] += 0.5 *
1690 (doit_scat_field(p_index- cloudbox_limits[0],0,0,scat_za_index,0, k) +
1691 doit_scat_field(p_index - cloudbox_limits[0]- 1,0,0,scat_za_index,0,k));
1702 out3 <<
"-----------------------------------------\n";
1703 out3 <<
"Input for radiative transfer step \n"
1704 <<
"calculation inside"
1705 <<
" the cloudbox:" <<
"\n";
1706 out3 <<
"Stokes vector at intersection point: \n"
1709 out3 <<
"lstep: ..." << lstep <<
"\n";
1710 out3 <<
"------------------------------------------\n";
1711 out3 <<
"Averaged coefficients: \n";
1712 out3 <<
"Planck function: " << rte_planck_value <<
"\n";
1713 out3 <<
"Scattering vector: " << sca_vec_av <<
"\n";
1714 out3 <<
"Absorption vector: " << abs_vec(0,
joker) <<
"\n";
1715 out3 <<
"Extinction matrix: " << ext_mat(0,
joker,
joker) <<
"\n";
1724 sca_vec_av, lstep, rte_planck_value);
1727 doit_i_field(p_index - cloudbox_limits[0],
1730 joker) = stokes_vec;
1742 Vector rte_pos( atmosphere_dim );
1743 Numeric z_field_0 = z_field(0, 0, 0);
1744 rte_pos = z_field_0;
1747 rte_los = scat_za_grid[scat_za_index];
1758 throw runtime_error(
1759 "Surface reflections inside cloud box not yet handled." );
1946 Matrix& doit_i_field_opt,
1951 const Index& scat_za_interp)
1955 assert(doit_i_field.
npages() == N_za);
1959 Vector i_approx_interp(N_za);
1964 idx.push_back(N_za-1);
1979 while( max_diff > acc )
1988 for(
Index i_p = 0; i_p < N_p; i_p++ )
1990 for(
Index i_za_red = 0; i_za_red < idx.
nelem(); i_za_red ++)
1992 za_reduced[i_za_red] = za_grid_fine[idx[i_za_red]];
1993 doit_i_field_opt(i_p, i_za_red) = doit_i_field(i_p, 0, 0, idx[i_za_red],
1997 gridpos(gp_za, za_reduced, za_grid_fine);
1999 if(scat_za_interp == 0 || idx.
nelem() < 3)
2002 interp(i_approx_interp, itw, doit_i_field_opt(i_p,
joker), gp_za);
2004 else if(scat_za_interp == 1)
2006 for(
Index i_za = 0; i_za < N_za; i_za ++)
2008 i_approx_interp[i_za] =
2020 for (
Index i_za = 0; i_za < N_za; i_za ++)
2022 diff_vec[i_za] =
abs( doit_i_field(i_p, 0, 0, i_za, 0 ,0)
2023 - i_approx_interp[i_za]);
2024 if( diff_vec[i_za] > max_diff_za[i_p] )
2026 max_diff_za[i_p] = diff_vec[i_za];
2031 if( max_diff_za[i_p] > max_diff_p )
2033 max_diff_p = max_diff_za[i_p];
2040 max_diff = max_diff_p/doit_i_field(ind_p, 0, 0, ind_za[ind_p], 0, 0)*100.;
2042 idx.push_back(ind_za[ind_p]);
2045 i_sort.resize(idx_unsorted.
nelem());
2048 for (
Index i = 0; i<idx_unsorted.
nelem(); i++)
2049 idx[i] = idx_unsorted[i_sort[i]];
2058 za_grid_opt[i] = za_grid_fine[idx[i]];
2059 doit_i_field_opt(
joker, i) = doit_i_field(
joker, 0, 0, idx[i], 0, 0);
2098 const Tensor4& doit_i_field1D_spectrum,
2103 const Index& cloudbox_on,
2105 const Index& atmosphere_dim,
2106 const Index& stokes_dim,
2107 const Vector& scat_za_grid,
2108 const Vector& scat_aa_grid,
2110 const String& interpmeth,
2111 const Index& rigorous,
2118 if( !(atmosphere_dim == 1 || atmosphere_dim == 3) )
2119 throw runtime_error(
"The atmospheric dimensionality must be 1 or 3.");
2121 throw runtime_error(
"The cloud box is not activated and no outgoing "
2122 "field can be returned." );
2123 if ( cloudbox_limits.
nelem() != 2*atmosphere_dim )
2124 throw runtime_error(
2125 "*cloudbox_limits* is a vector which contains the upper and lower\n"
2126 "limit of the cloud for all atmospheric dimensions.\n"
2127 "So its length must be 2 x *atmosphere_dim*" );
2128 if( scat_za_grid.
nelem() == 0 )
2129 throw runtime_error(
"The variable *scat_za_grid* is empty. Are dummy "
2130 "values from *cloudboxOff used?" );
2131 if( !( interpmeth ==
"linear" || interpmeth ==
"polynomial" ) )
2132 throw runtime_error(
"Unknown interpolation method. Possible choices are "
2133 "\"linear\" and \"polynomial\"." );
2134 if( interpmeth ==
"polynomial" && atmosphere_dim != 1 )
2135 throw runtime_error(
"Polynomial interpolation method is only available "
2136 "for *atmosphere_dim* = 1." );
2138 throw runtime_error(
"Inconsistency in size between f_grid and scat_i_p! "
2139 "(This method does not yet handle dispersion type calculations.)" );
2155 if( atmosphere_dim == 3 && border > 100 )
2178 if( fgp <
Numeric(cloudbox_limits[0]) ||
2179 fgp >
Numeric(cloudbox_limits[1]) )
2183 if( atmosphere_dim == 3 && inside )
2186 if( fgp <
Numeric(cloudbox_limits[2]) ||
2187 fgp >
Numeric(cloudbox_limits[3]) )
2190 if( fgp <
Numeric(cloudbox_limits[4]) ||
2191 fgp >
Numeric(cloudbox_limits[5]) )
2202 throw runtime_error(
2203 "Given position has been found to be outside the cloudbox." );
2208 DEBUG_ONLY (
const Index np = cloudbox_limits[1] - cloudbox_limits[0] + 1);
2212 iy.
resize( nf, stokes_dim );
2218 if (atmosphere_dim == 3)
2220 throw runtime_error(
2221 "3D DOIT calculations are not implemented\n"
2222 "for observations from inside the cloudbox.\n"
2227 assert(atmosphere_dim == 1);
2230 assert(
is_size(doit_i_field1D_spectrum, nf, np, nza, stokes_dim) );
2232 out3 <<
" Interpolating outgoing field:\n";
2233 out3 <<
" zenith_angle: " << rte_los[0] <<
"\n";
2234 out3 <<
" Sensor inside cloudbox at position: " <<
2239 gridpos( gp_za, scat_za_grid, rte_los[0] );
2249 gp_p.
idx = rte_gp_p.idx - cloudbox_limits[0];
2251 cloudbox_limits[0] );
2260 if( interpmeth ==
"linear" )
2262 for(
Index is = 0; is < stokes_dim; is++ )
2264 for(
Index iv = 0; iv < nf; iv++ )
2266 for (
Index i_za = 0; i_za < nza; i_za++)
2269 (itw_p, doit_i_field1D_spectrum(iv,
joker, i_za, is),
2272 iy(iv,is) =
interp( itw_za, iy_p, gp_za);
2278 for(
Index is = 0; is < stokes_dim; is++ )
2280 for(
Index iv = 0; iv < nf; iv++ )
2282 for (
Index i_za = 0; i_za < nza; i_za++)
2285 (itw_p, doit_i_field1D_spectrum(iv,
joker, i_za, is),
2288 iy(iv,is) =
interp_poly( scat_za_grid, iy_p, rte_los[0],
2301 else if( atmosphere_dim == 1 )
2303 out3 <<
" Interpolating outgoing field:\n";
2304 out3 <<
" zenith_angle: " << rte_los[0] <<
"\n";
2306 out3 <<
" top side\n";
2308 out3 <<
" bottom side\n";
2312 gridpos( gp, scat_za_grid, rte_los[0] );
2318 if( interpmeth ==
"linear" )
2320 for(
Index is = 0; is < stokes_dim; is++ )
2322 if( is==0 && rigorous )
2324 for(
Index iv = 0; iv < nf; iv++ )
2328 if( scat_i_p(iv,border,0,0,gp.
idx,0,is)/
2329 scat_i_p(iv,border,0,0,gp.
idx+1,0,is) > 1/maxratio &&
2330 scat_i_p(iv,border,0,0,gp.
idx,0,is)/
2331 scat_i_p(iv,border,0,0,gp.
idx+1,0,is) < maxratio )
2334 scat_i_p( iv, border, 0, 0,
joker, 0, is ),
2340 os <<
"ERROR: Radiance difference between interpolation\n"
2341 <<
"points is too large (factor " << maxratio <<
") to\n"
2342 <<
"safely interpolate. This might be due to za_grid\n"
2343 <<
"being too coarse or the radiance field being a\n"
2344 <<
"step-like function.\n";
2345 os <<
"Happens at boundary " << border <<
" between zenith\n"
2346 <<
"angels " << scat_za_grid[gp.
idx] <<
" and "
2347 << scat_za_grid[gp.
idx+1] <<
"deg for frequency"
2348 <<
"#" << iv <<
", where radiances are "
2349 << scat_i_p(iv,border,0,0,gp.
idx,0,0)
2350 <<
" and " << scat_i_p(iv,border,0,0,gp.
idx+1,0,0)
2351 <<
" W/(sr m2 Hz).";
2352 throw runtime_error(os.str());
2358 for(
Index iv = 0; iv < nf; iv++ )
2361 scat_i_p( iv, border, 0, 0,
joker, 0, is ),
2369 for(
Index is = 0; is < stokes_dim; is++ )
2371 for(
Index iv = 0; iv < nf; iv++ )
2374 scat_i_p( iv, border, 0, 0,
joker, 0, is ) , rte_los[0],
2388 scat_aa_grid.
nelem(), stokes_dim ));
2392 scat_aa_grid.
nelem(), stokes_dim ));
2395 scat_aa_grid.
nelem(), stokes_dim ));
2397 out3 <<
" Interpolating outgoing field:\n";
2398 out3 <<
" zenith angle : " << rte_los[0] <<
"\n";
2399 out3 <<
" azimuth angle: " << rte_los[1]+180. <<
"\n";
2404 gridpos( gp_za, scat_za_grid, rte_los[0] );
2405 gridpos( gp_aa, scat_aa_grid, rte_los[1]+180. );
2415 cb_gp_lat = rte_gp_lat;
2416 cb_gp_lon = rte_gp_lon;
2417 cb_gp_lat.
idx -= cloudbox_limits[2];
2418 cb_gp_lon.
idx -= cloudbox_limits[4];
2421 cloudbox_limits[2] );
2423 cloudbox_limits[4] );
2427 for(
Index is = 0; is < stokes_dim; is++ )
2429 for(
Index iv = 0; iv < nf; iv++ )
2433 cb_gp_lat, cb_gp_lon, gp_za, gp_aa );
2439 else if( border <= 3 )
2444 cb_gp_lon = rte_gp_lon;
2445 cb_gp_p.
idx -= cloudbox_limits[0];
2446 cb_gp_lon.
idx -= cloudbox_limits[4];
2449 cloudbox_limits[0] );
2451 cloudbox_limits[4] );
2455 for(
Index is = 0; is < stokes_dim; is++ )
2457 for(
Index iv = 0; iv < nf; iv++ )
2461 cb_gp_p, cb_gp_lon, gp_za, gp_aa );
2472 cb_gp_lat = rte_gp_lat;
2473 cb_gp_p.
idx -= cloudbox_limits[0];
2474 cb_gp_lat.
idx -= cloudbox_limits[2];
2477 cloudbox_limits[0] );
2479 cloudbox_limits[2] );
2483 for(
Index is = 0; is < stokes_dim; is++ )
2485 for(
Index iv = 0; iv < nf; iv++ )
2489 cb_gp_p, cb_gp_lat, gp_za, gp_aa );
2525 const Agenda& spt_calc_agenda,
2526 const Index& atmosphere_dim,
2527 const Vector& scat_za_grid,
2528 const Vector& scat_aa_grid,
2530 const Agenda& opt_prop_part_agenda,
2532 const Numeric& norm_error_threshold,
2533 const Index& norm_debug,
2536 if (atmosphere_dim != 1)
2537 throw runtime_error(
"Only 1D is supported here for now");
2545 if (scat_za_grid[0] != 0. || scat_za_grid[Nza-1] != 180.)
2546 throw runtime_error(
"The range of *scat_za_grid* must [0 180].");
2551 if (scat_aa_grid[0] != 0. || scat_aa_grid[Naa-1] != 360.)
2552 throw runtime_error(
"The range of *scat_aa_grid* must [0 360].");
2555 const Index stokes_dim = doit_scat_field.
ncols();
2556 assert(stokes_dim > 0 || stokes_dim < 5);
2560 Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
2561 stokes_dim, stokes_dim, 0.);
2562 Tensor4 abs_vec_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
2569 doit_scat_field.
nbooks(),
2570 doit_scat_field.
npages(),
2571 doit_scat_field.
nrows(),
2574 Index scat_aa_index_local = 0;
2577 for(
Index scat_za_index_local = 0; scat_za_index_local < Nza;
2578 scat_za_index_local ++)
2586 spt_calc_agenda, opt_prop_part_agenda,
2587 scat_za_index_local, scat_aa_index_local,
2588 cloudbox_limits, t_field, pnd_field, verbosity);
2590 for(
Index p_index = 0;
2591 p_index <= (cloudbox_limits[1] - cloudbox_limits[0]);
2598 for (
Index i = 0; i < stokes_dim; i++)
2600 doit_scat_ext_field(p_index, 0, 0, scat_za_index_local, 0)
2601 += doit_i_field(p_index, 0, 0, scat_za_index_local, 0, i)
2602 * (ext_mat_field(p_index, 0, 0, 0, i) - abs_vec_field(p_index, 0, 0, i));
2608 Index corr_max_p_index = -1;
2610 for (
Index p_index = 0; p_index < Np; p_index++)
2623 const Numeric corr_factor = scat_ext_int / scat_int;
2627 if (!isnan(corr_factor) && !isinf(corr_factor))
2629 if (
abs(corr_factor) >
abs(corr_max))
2631 corr_max = corr_factor;
2632 corr_max_p_index = p_index;
2634 if (
abs(1.-corr_factor) > norm_error_threshold)
2637 os <<
"ERROR: DOIT correction factor exceeds threshold: "
2638 << setprecision(4) << 1.-corr_factor <<
" at p_index " << p_index <<
"\n";
2639 throw runtime_error(os.str());
2641 else if (
abs(1.-corr_factor) > norm_error_threshold/2.)
2643 out0 <<
" WARNING: DOIT correction factor above threshold/2: "
2644 << 1.-corr_factor <<
" at p_index " << p_index <<
"\n";
2648 doit_scat_field(p_index, 0, 0,
joker, 0,
joker) *= corr_factor;
2654 if (norm_debug) norm_out = out0;
2656 if (corr_max_p_index != -1)
2658 norm_out <<
" Max. DOIT correction factor in this iteration: " << 1.-corr_max
2659 <<
" at p_index " << corr_max_p_index <<
"\n";
2663 norm_out <<
" No DOIT correction performed in this iteration.\n";