72 Index& doit_za_grid_size,
76 const Index& N_za_grid,
77 const Index& N_aa_grid,
78 const String& za_grid_opt_file,
87 throw runtime_error(
"N_za_grid must be greater than 15 for accurate results");
88 else if (N_za_grid > 100)
91 out1 <<
"Warning: N_za_grid is very large which means that the \n"
92 <<
"calculation will be very slow. The recommended value is 19.\n";
96 throw runtime_error(
"N_aa_grid must be greater than 5 for accurate results");
97 else if (N_aa_grid > 100)
100 out1 <<
"Warning: N_aa_grid is very large which means that the \n"
101 <<
"calculation will be very slow. The recommended value is 10.\n";
106 nlinspace(scat_aa_grid, 0, 360, N_aa_grid);
110 doit_za_grid_size = N_za_grid;
112 if( za_grid_opt_file ==
"" )
113 nlinspace(scat_za_grid, 0, 180, N_za_grid);
122 Index& doit_conv_flag,
123 Index& doit_iteration_counter,
126 const Tensor6& doit_i_field_old,
135 if( doit_conv_flag != 0 )
136 throw runtime_error(
"Convergence flag is non-zero, which means that this\n"
137 "WSM is not used correctly. *doit_conv_flagAbs* should\n"
138 "be used only in *doit_conv_test_agenda*\n");
141 if (doit_iteration_counter > 100)
143 out1 <<
"Warning in DOIT calculation:"
144 <<
"Method does not converge (number of iterations \n"
145 <<
"is > 100). Either the cloud particle number density \n"
146 <<
"is too large or the numerical setup for the DOIT \n"
147 <<
"calculation is not correct. In case of limb \n"
148 <<
"simulations please make sure that you use an \n"
149 <<
"optimized zenith angle grid. \n"
150 <<
"*doit_i_field* might be wrong.\n";
159 const Index stokes_dim = doit_i_field.
ncols();
162 if ( epsilon.
nelem() != stokes_dim )
164 "You have to specify limiting values for the "
165 "convergence test for each Stokes component "
166 "separately. That means that *epsilon* must "
167 "have *stokes_dim* elements!"
172 N_p, N_lat, N_lon, N_za, N_aa, stokes_dim))
173 throw runtime_error(
"The fields (Tensor6) *doit_i_field* and \n"
174 "*doit_i_field_old* which are compared in the \n"
175 "convergence test do not have the same size.\n");
180 out2 <<
" Number of DOIT iteration: " << doit_iteration_counter <<
"\n";
181 doit_iteration_counter +=1;
184 for (
Index p_index = 0; p_index < N_p; p_index++)
186 for (
Index lat_index = 0; lat_index < N_lat; lat_index++)
188 for (
Index lon_index = 0; lon_index <N_lon; lon_index++)
190 for (
Index scat_za_index = 0; scat_za_index < N_za;
193 for (
Index scat_aa_index = 0; scat_aa_index < N_aa;
196 for (
Index stokes_index = 0; stokes_index <
197 stokes_dim; stokes_index ++)
200 (doit_i_field(p_index, lat_index, lon_index,
201 scat_za_index, scat_aa_index,
203 doit_i_field_old(p_index, lat_index,
204 lon_index, scat_za_index,
212 if(
abs(diff) > epsilon[stokes_index])
214 out1 <<
"difference: " << diff <<
"\n";
228 out2 <<
" Number of DOIT-iterations: " << doit_iteration_counter <<
"\n";
234 Index& doit_conv_flag,
235 Index& doit_iteration_counter,
238 const Tensor6& doit_i_field_old,
240 const Index& f_index,
250 if( doit_conv_flag != 0 )
251 throw runtime_error(
"Convergence flag is non-zero, which means that this \n"
252 "WSM is not used correctly. *doit_conv_flagAbs* should\n"
253 "be used only in *doit_conv_test_agenda*\n");
255 if (doit_iteration_counter > 100)
257 out1 <<
"Warning in DOIT calculation at frequency" << f_grid[f_index]
259 <<
"Method does not converge (number of iterations \n"
260 <<
"is > 100). Either the cloud particle number density \n"
261 <<
"is too large or the numerical setup for the DOIT \n"
262 <<
"calculation is not correct. In case of limb \n"
263 <<
"simulations please make sure that you use an \n"
264 <<
"optimized zenith angle grid. \n"
265 <<
"*doit_i_field* might be wrong.\n";
274 const Index stokes_dim = doit_i_field.
ncols();
277 if ( epsilon.
nelem() != stokes_dim )
279 "You have to specify limiting values for the "
280 "convergence test for each Stokes component "
281 "separately. That means that *epsilon* must "
282 "have *stokes_dim* elements!"
287 N_p, N_lat, N_lon, N_za, N_aa, stokes_dim))
288 throw runtime_error(
"The fields (Tensor6) *doit_i_field* and \n"
289 "*doit_i_field_old* which are compared in the \n"
290 "convergence test do not have the same size.\n");
294 if( f_grid.
nelem() == 0 )
295 throw runtime_error(
"The frequency grid is empty." );
299 if ( f_index >= f_grid.
nelem() )
300 throw runtime_error(
"*f_index* is greater than number of elements in the\n"
301 "frequency grid.\n");
305 out2 <<
" Number of DOIT iteration: " << doit_iteration_counter <<
"\n";
306 doit_iteration_counter +=1;
308 for (
Index p_index = 0; p_index < N_p; p_index++)
310 for (
Index lat_index = 0; lat_index < N_lat; lat_index++)
312 for (
Index lon_index = 0; lon_index <N_lon; lon_index++)
314 for (
Index scat_za_index = 0; scat_za_index < N_za;
317 for (
Index scat_aa_index = 0; scat_aa_index < N_aa;
320 for (
Index stokes_index = 0; stokes_index <
321 stokes_dim; stokes_index ++)
324 abs( doit_i_field(p_index, lat_index, lon_index,
325 scat_za_index, scat_aa_index,
327 doit_i_field_old(p_index, lat_index,
328 lon_index, scat_za_index,
336 if( diff_bt > epsilon[stokes_index])
338 out1 <<
"BT difference: " << diff_bt <<
"\n";
350 out1 <<
"Number of DOIT-iterations:" << doit_iteration_counter <<
"\n";
356 Index& doit_conv_flag,
357 Index& doit_iteration_counter,
360 const Tensor6& doit_i_field_old,
362 const Index& f_index,
372 if( doit_conv_flag != 0 )
373 throw runtime_error(
"Convergence flag is non-zero, which means that this \n"
374 "WSM is not used correctly. *doit_conv_flagAbs* should\n"
375 "be used only in *doit_conv_test_agenda*\n");
378 if (doit_iteration_counter > 100)
379 throw runtime_error(
"Error in DOIT calculation: \n"
380 "Method does not converge (number of iterations \n"
381 "is > 100). Either the cloud particle number density \n"
382 "is too large or the numerical setup for the DOIT \n"
383 "calculation is not correct. In case of limb \n"
384 "simulations please make sure that you use an \n"
385 "optimized zenith angle grid. \n");
392 const Index stokes_dim = doit_i_field.
ncols();
395 if ( epsilon.
nelem() != stokes_dim )
397 "You have to specify limiting values for the "
398 "convergence test for each Stokes component "
399 "separately. That means that *epsilon* must "
400 "have *stokes_dim* elements!"
405 N_p, N_lat, N_lon, N_za, N_aa, stokes_dim))
406 throw runtime_error(
"The fields (Tensor6) *doit_i_field* and \n"
407 "*doit_i_field_old* which are compared in the \n"
408 "convergence test do not have the same size.\n");
412 if( f_grid.
nelem() == 0 )
413 throw runtime_error(
"The frequency grid is empty." );
417 if ( f_index >= f_grid.
nelem() )
418 throw runtime_error(
"*f_index* is greater than number of elements in the\n"
419 "frequency grid.\n");
424 out2 <<
" Number of DOIT iteration: " << doit_iteration_counter <<
"\n";
425 doit_iteration_counter +=1;
433 for (
Index p_index = 0; p_index < N_p; p_index++)
435 for (
Index lat_index = 0; lat_index < N_lat; lat_index++)
437 for (
Index lon_index = 0; lon_index <N_lon; lon_index++)
439 for (
Index scat_za_index = 0; scat_za_index < N_za;
442 for (
Index scat_aa_index = 0; scat_aa_index < N_aa;
447 doit_i_field(p_index, lat_index,
449 scat_za_index, scat_aa_index, i) -
450 doit_i_field_old(p_index, lat_index,
451 lon_index, scat_za_index,
460 lqs[i] = sqrt(lqs[i]);
461 lqs[i] /= (
Numeric)(N_p*N_lat*N_lon*N_za*N_aa);
466 if (lqs[i] >= epsilon[i] )
470 out1 <<
"lqs [I]: " << lqs[0] <<
"\n";
472 if (doit_conv_flag == 1)
475 out1 <<
"Number of DOIT-iterations: " << doit_iteration_counter
486 const Agenda& doit_scat_field_agenda,
487 const Agenda& doit_rte_agenda,
488 const Agenda& doit_conv_test_agenda,
494 chk_not_empty(
"doit_scat_field_agenda", doit_scat_field_agenda);
496 chk_not_empty(
"doit_conv_test_agenda", doit_conv_test_agenda);
503 Tensor6 doit_i_field_old_local;
504 Index doit_conv_flag_local;
505 Index doit_iteration_counter_local;
512 doit_i_field.
nrows(), doit_i_field.
ncols(), 0.);
514 doit_conv_flag_local = 0;
515 doit_iteration_counter_local = 0;
517 while(doit_conv_flag_local == 0) {
520 doit_i_field_old_local = doit_i_field;
525 out2 <<
" Execute doit_scat_field_agenda. \n";
528 doit_scat_field_agenda);
531 out2 <<
" Execute doit_rte_agenda. \n";
537 doit_iteration_counter_local,
539 doit_i_field_old_local,
540 doit_conv_test_agenda);
552 const Tensor6& doit_i_field_old,
553 const Tensor6& doit_scat_field,
556 const Agenda& abs_scalar_gas_agenda,
559 const Agenda& spt_calc_agenda,
560 const Vector& scat_za_grid,
563 const Agenda& opt_prop_part_agenda,
564 const Agenda& opt_prop_gas_agenda,
566 const Agenda& ppath_step_agenda,
574 const Index& f_index,
575 const Agenda& surface_prop_agenda,
576 const Index& doit_za_interp,
583 out2 <<
" doit_i_fieldUpdate1D: Radiative transfer calculation in cloudbox\n";
584 out2 <<
" ------------------------------------------------------------- \n";
590 chk_not_empty(
"opt_prop_part_agenda", opt_prop_part_agenda);
594 if (cloudbox_limits.
nelem() != 2)
596 "The cloudbox dimension is not 1D! \n"
597 "Do you really want to do a 1D calculation? \n"
598 "If not, use *doit_i_fieldUpdateSeq3D*.\n"
604 if (scat_za_grid[0] != 0. || scat_za_grid[N_scat_za-1] != 180.)
605 throw runtime_error(
"The range of *scat_za_grid* must [0 180].");
607 if( p_grid.
nelem() < 2 )
608 throw runtime_error(
"The length of *p_grid* must be >= 2." );
620 if( f_grid.
nelem() == 0 )
621 throw runtime_error(
"The frequency grid is empty." );
625 if ( f_index >= f_grid.
nelem() )
626 throw runtime_error(
"*f_index* is greater than number of elements in the\n"
627 "frequency grid.\n");
629 if( !(doit_za_interp == 0 || doit_za_interp == 1 ) )
630 throw runtime_error(
"Interpolation method is not defined. Use \n"
631 "*doit_za_interpSet*.\n");
633 const Index stokes_dim = doit_scat_field.
ncols();
634 assert(stokes_dim > 0 || stokes_dim < 5);
639 (cloudbox_limits[1] - cloudbox_limits[0]) + 1, 1, 1,
640 N_scat_za, 1, stokes_dim));
642 assert(
is_size( doit_i_field_old,
643 (cloudbox_limits[1] - cloudbox_limits[0]) + 1, 1, 1,
644 scat_za_grid.
nelem(), 1, stokes_dim));
646 assert(
is_size( doit_scat_field,
647 (cloudbox_limits[1] - cloudbox_limits[0]) + 1, 1, 1,
648 N_scat_za, 1, stokes_dim));
658 out3 <<
"Calculate single particle properties \n";
668 Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
669 stokes_dim, stokes_dim, 0.);
670 Tensor4 abs_vec_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
674 Index scat_aa_index_local = 0;
677 for(
Index scat_za_index_local = 0; scat_za_index_local < N_scat_za;
678 scat_za_index_local ++)
687 opt_prop_part_agenda, scat_za_index_local,
689 cloudbox_limits, t_field, pnd_field, verbosity);
695 for(
Index p_index = cloudbox_limits[0]; p_index
696 <= cloudbox_limits[1]; p_index ++)
698 if ( (p_index!=0) || (scat_za_grid[scat_za_index_local] <= 90.))
701 p_index, scat_za_index_local,
703 cloudbox_limits, doit_i_field_old,
705 abs_scalar_gas_agenda, vmr_field,
706 opt_prop_gas_agenda, ppath_step_agenda,
707 p_grid, z_field, r_geoid, z_surface,
708 t_field, f_grid, f_index, ext_mat_field,
710 surface_prop_agenda, doit_za_interp,
724 const Tensor6& doit_scat_field,
727 const Agenda& abs_scalar_gas_agenda,
730 const Agenda& spt_calc_agenda,
731 const Vector& scat_za_grid,
734 const Agenda& opt_prop_part_agenda,
735 const Agenda& opt_prop_gas_agenda,
737 const Agenda& ppath_step_agenda,
745 const Index& f_index,
746 const Agenda& surface_prop_agenda,
747 const Index& doit_za_interp,
753 out2<<
" doit_i_fieldUpdateSeq1D: Radiative transfer calculation in cloudbox\n";
754 out2 <<
" ------------------------------------------------------------- \n";
759 chk_not_empty(
"abs_scalar_gas_agenda", abs_scalar_gas_agenda);
761 chk_not_empty(
"opt_prop_part_agenda", opt_prop_part_agenda);
765 if (cloudbox_limits.
nelem() != 2)
767 "The cloudbox dimension is not 1D! \n"
768 "Do you really want to do a 1D calculation? \n"
769 "For 3D use *doit_i_fieldUpdateSeq3D*.\n"
775 if (scat_za_grid[0] != 0. || scat_za_grid[N_scat_za-1] != 180.)
776 throw runtime_error(
"The range of *scat_za_grid* must [0 180].");
778 if( p_grid.
nelem() < 2 )
779 throw runtime_error(
"The length of *p_grid* must be >= 2." );
791 if( f_grid.
nelem() == 0 )
792 throw runtime_error(
"The frequency grid is empty." );
796 if ( f_index >= f_grid.
nelem() )
797 throw runtime_error(
"*f_index* is greater than number of elements in the\n"
798 "frequency grid.\n");
800 if( !(doit_za_interp == 0 || doit_za_interp == 1 ) )
801 throw runtime_error(
"Interpolation method is not defined. Use \n"
802 "*doit_za_interpSet*.\n");
804 const Index stokes_dim = doit_scat_field.
ncols();
805 assert(stokes_dim > 0 || stokes_dim < 5);
810 (cloudbox_limits[1] - cloudbox_limits[0]) + 1, 1, 1,
811 N_scat_za, 1, stokes_dim));
813 assert(
is_size( doit_scat_field,
814 (cloudbox_limits[1] - cloudbox_limits[0]) + 1, 1, 1,
815 N_scat_za, 1, stokes_dim));
825 out3 <<
"Calculate single particle properties \n";
835 Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
836 stokes_dim, stokes_dim, 0.);
837 Tensor4 abs_vec_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
843 Numeric theta_lim = 180. - asin((r_geoid(0,0)+
844 z_field(cloudbox_limits[0],0,0))/
846 z_field(cloudbox_limits[1],0,0)))*
RAD2DEG;
848 Index scat_aa_index_local = 0;
851 for(
Index scat_za_index_local = 0; scat_za_index_local < N_scat_za;
852 scat_za_index_local ++)
860 spt_calc_agenda, opt_prop_part_agenda,
861 scat_za_index_local, scat_aa_index_local,
862 cloudbox_limits, t_field, pnd_field, verbosity);
875 if ( scat_za_grid[scat_za_index_local] <= 90.)
882 for(
Index p_index = cloudbox_limits[1]-1; p_index
883 >= cloudbox_limits[0]; p_index --)
886 p_index, scat_za_index_local, scat_za_grid,
887 cloudbox_limits, doit_scat_field,
888 abs_scalar_gas_agenda, vmr_field,
889 opt_prop_gas_agenda, ppath_step_agenda,
890 p_grid, z_field, r_geoid, z_surface,
891 t_field, f_grid, f_index, ext_mat_field,
893 surface_prop_agenda, doit_za_interp,
897 else if ( scat_za_grid[scat_za_index_local] >= theta_lim)
902 for(
Index p_index = cloudbox_limits[0]+1; p_index
903 <= cloudbox_limits[1]; p_index ++)
906 p_index, scat_za_index_local, scat_za_grid,
907 cloudbox_limits, doit_scat_field,
908 abs_scalar_gas_agenda, vmr_field,
909 opt_prop_gas_agenda, ppath_step_agenda,
910 p_grid, z_field, r_geoid, z_surface,
911 t_field, f_grid, f_index, ext_mat_field,
913 surface_prop_agenda, doit_za_interp,
925 else if ( scat_za_grid[scat_za_index_local] > 90. &&
926 scat_za_grid[scat_za_index_local] < theta_lim )
928 for(
Index p_index = cloudbox_limits[0]; p_index
929 <= cloudbox_limits[1]; p_index ++)
935 if (!(p_index == 0 && scat_za_grid[scat_za_index_local] > 90.))
938 p_index, scat_za_index_local,
940 cloudbox_limits, doit_scat_field,
941 abs_scalar_gas_agenda, vmr_field,
942 opt_prop_gas_agenda, ppath_step_agenda,
943 p_grid, z_field, r_geoid, z_surface,
944 t_field, f_grid, f_index, ext_mat_field,
946 surface_prop_agenda, doit_za_interp,
961 const Tensor6& doit_scat_field,
964 const Agenda& abs_scalar_gas_agenda,
967 const Agenda& spt_calc_agenda,
968 const Vector& scat_za_grid,
969 const Vector& scat_aa_grid,
972 const Agenda& opt_prop_part_agenda,
973 const Agenda& opt_prop_gas_agenda,
975 const Agenda& ppath_step_agenda,
985 const Index& f_index,
986 const Index& doit_za_interp,
992 out2<<
" doit_i_fieldUpdateSeq3D: Radiative transfer calculatiuon in cloudbox.\n";
993 out2 <<
" ------------------------------------------------------------- \n";
998 chk_not_empty(
"abs_scalar_gas_agenda", abs_scalar_gas_agenda);
1000 chk_not_empty(
"opt_prop_part_agenda", opt_prop_part_agenda);
1004 if (cloudbox_limits.
nelem() != 6)
1005 throw runtime_error(
1006 "The cloudbox dimension is not 3D! \n"
1007 "Do you really want to do a 3D calculation? \n"
1008 "For 1D use *doit_i_fieldUpdateSeq1D*.\n"
1012 const Index N_scat_za = scat_za_grid.
nelem();
1014 if (scat_za_grid[0] != 0. || scat_za_grid[N_scat_za-1] != 180.)
1015 throw runtime_error(
"The range of *scat_za_grid* must [0 180].");
1018 const Index N_scat_aa = scat_aa_grid.
nelem();
1020 if (scat_aa_grid[0] != 0. || scat_aa_grid[N_scat_aa-1] != 360.)
1021 throw runtime_error(
"The range of *scat_za_grid* must [0 360].");
1037 if( f_grid.
nelem() == 0 )
1038 throw runtime_error(
"The frequency grid is empty." );
1042 if ( f_index >= f_grid.
nelem() )
1043 throw runtime_error(
"*f_index* is greater than number of elements in the\n"
1044 "frequency grid.\n");
1046 if( !(doit_za_interp == 0 || doit_za_interp == 1 ) )
1047 throw runtime_error(
"Interpolation method is not defined. Use \n"
1048 "*doit_za_interpSet*.\n");
1050 const Index stokes_dim = doit_scat_field.
ncols();
1051 assert(stokes_dim > 0 || stokes_dim < 5);
1054 assert(
is_size( doit_i_field,
1055 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1056 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
1057 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
1062 assert(
is_size( doit_scat_field,
1063 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1064 (cloudbox_limits[3] - cloudbox_limits[2]) + 1,
1065 (cloudbox_limits[5] - cloudbox_limits[4]) + 1,
1078 out3 <<
"Calculate single particle properties \n";
1088 const Index p_low = cloudbox_limits[0];
1089 const Index p_up = cloudbox_limits[1];
1090 const Index lat_low = cloudbox_limits[2];
1091 const Index lat_up = cloudbox_limits[3];
1092 const Index lon_low = cloudbox_limits[4];
1093 const Index lon_up = cloudbox_limits[5];
1097 Tensor5 ext_mat_field(p_up-p_low+1, lat_up-lat_low+1, lon_up-lon_low+1,
1098 stokes_dim, stokes_dim, 0.);
1099 Tensor4 abs_vec_field(p_up-p_low+1, lat_up-lat_low+1, lon_up-lon_low+1,
1104 for(
Index scat_za_index = 0; scat_za_index < N_scat_za; scat_za_index ++)
1108 for(
Index scat_aa_index = 1; scat_aa_index < N_scat_aa; scat_aa_index ++)
1119 opt_prop_part_agenda, scat_za_index,
1120 scat_aa_index, cloudbox_limits, t_field,
1121 pnd_field, verbosity);
1124 Vector stokes_vec(stokes_dim,0.);
1126 Numeric theta_lim = 180. - asin((r_geoid(0,0)+z_field(p_low,0,0))
1127 /(r_geoid(0,0)+z_field(p_up,0,0)))
1131 if ( scat_za_grid[scat_za_index] <= 90.)
1138 for(
Index p_index = p_up-1; p_index >= p_low; p_index --)
1140 for(
Index lat_index = lat_low; lat_index <= lat_up;
1143 for(
Index lon_index = lon_low; lon_index <= lon_up;
1148 lon_index, scat_za_index,
1149 scat_aa_index, scat_za_grid,
1150 scat_aa_grid, cloudbox_limits,
1152 abs_scalar_gas_agenda,
1154 opt_prop_gas_agenda,
1155 ppath_step_agenda, p_grid,
1156 lat_grid, lon_grid, z_field,
1157 r_geoid, z_surface, t_field,
1159 ext_mat_field, abs_vec_field,
1166 else if ( scat_za_grid[scat_za_index] > theta_lim)
1171 for(
Index p_index = p_low+1; p_index <= p_up; p_index ++)
1173 for(
Index lat_index = lat_low; lat_index <= lat_up;
1176 for(
Index lon_index = lon_low; lon_index <= lon_up;
1181 lon_index, scat_za_index,
1182 scat_aa_index, scat_za_grid,
1183 scat_aa_grid, cloudbox_limits,
1185 abs_scalar_gas_agenda,
1187 opt_prop_gas_agenda,
1188 ppath_step_agenda, p_grid,
1189 lat_grid, lon_grid, z_field,
1190 r_geoid, z_surface, t_field,
1192 ext_mat_field, abs_vec_field,
1207 else if ( scat_za_grid[scat_za_index] > 90. &&
1208 scat_za_grid[scat_za_index] < theta_lim )
1210 for(
Index p_index = p_low; p_index <= p_up; p_index ++)
1216 if (!(p_index == 0 && scat_za_grid[scat_za_index] > 90.))
1218 for(
Index lat_index = lat_low; lat_index <= lat_up;
1221 for(
Index lon_index = lon_low; lon_index <= lon_up;
1227 lon_index, scat_za_index,
1233 abs_scalar_gas_agenda,
1235 opt_prop_gas_agenda,
1236 ppath_step_agenda, p_grid,
1266 Index& scat_za_index ,
1268 const Tensor6& doit_scat_field,
1271 const Agenda& abs_scalar_gas_agenda,
1274 const Agenda& spt_calc_agenda,
1275 const Vector& scat_za_grid,
1278 const Agenda& opt_prop_part_agenda,
1279 const Agenda& opt_prop_gas_agenda,
1281 const Agenda& ppath_step_agenda,
1288 const Index& f_index,
1294 out2 <<
" doit_i_fieldUpdateSeq1DPP: Radiative transfer calculation in cloudbox.\n";
1295 out2 <<
" --------------------------------------------------------------------- \n";
1297 const Index stokes_dim = doit_scat_field.
ncols();
1302 if (stokes_dim < 0 || stokes_dim > 4)
1303 throw runtime_error(
1304 "The dimension of stokes vector must be"
1307 assert(
is_size( doit_i_field,
1308 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1311 scat_za_grid.
nelem(),
1315 assert(
is_size( doit_scat_field,
1316 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
1319 scat_za_grid.
nelem(),
1324 assert( f_index <= f_grid.
nelem() );
1331 const Index N_scat_za = scat_za_grid.
nelem();
1338 out3 <<
"Calculate single particle properties \n";
1349 Tensor5 ext_mat_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
1350 stokes_dim, stokes_dim, 0.);
1351 Tensor4 abs_vec_field(cloudbox_limits[1] - cloudbox_limits[0] + 1, 1, 1,
1355 for(scat_za_index = 0; scat_za_index < N_scat_za; scat_za_index ++)
1359 Index scat_aa_index = 0;
1363 opt_prop_part_agenda, scat_za_index, scat_aa_index,
1364 cloudbox_limits, t_field,
1365 pnd_field, verbosity);
1371 Vector stokes_vec(stokes_dim,0.);
1373 if ( scat_za_grid[scat_za_index] <= 90)
1383 for(
Index p_index = cloudbox_limits[1] -1; p_index
1384 >= cloudbox_limits[0]; p_index --)
1387 p_index, scat_za_index,
1391 abs_scalar_gas_agenda,
1393 opt_prop_gas_agenda,
1395 p_grid, z_field, r_geoid,
1403 else if ( scat_za_grid[scat_za_index] > 90)
1408 for(
Index p_index = cloudbox_limits[0]+1; p_index
1409 <= cloudbox_limits[1]; p_index ++)
1412 p_index, scat_za_index,
1416 abs_scalar_gas_agenda,
1418 opt_prop_gas_agenda,
1420 p_grid, z_field, r_geoid,
1435 Index& scat_p_index,
1436 Index& scat_lat_index,
1437 Index& scat_lon_index,
1438 Index& scat_za_index,
1439 Index& scat_aa_index,
1442 Index& doit_is_initialized,
1444 const Index& stokes_dim,
1445 const Index& atmosphere_dim,
1446 const Vector& scat_za_grid,
1447 const Vector& scat_aa_grid,
1448 const Index& doit_za_grid_size,
1449 const Index& cloudbox_on,
1457 doit_is_initialized = 0;
1458 out0 <<
" Cloudbox is off, DOIT calculation will be skipped.\n";
1464 if (stokes_dim < 0 || stokes_dim > 4)
1465 throw runtime_error(
1466 "The dimension of stokes vector must be"
1472 const Index N_scat_za = scat_za_grid.
nelem();
1474 if (scat_za_grid[0] != 0. || scat_za_grid[N_scat_za-1] != 180.)
1475 throw runtime_error(
"The range of *scat_za_grid* must [0 180].");
1478 const Index N_scat_aa = scat_aa_grid.
nelem();
1480 if (scat_aa_grid[0] != 0. || scat_aa_grid[N_scat_aa-1] != 360.)
1481 throw runtime_error(
"The range of *scat_za_grid* must [0 360].");
1483 if (doit_za_grid_size < 16)
1484 throw runtime_error(
1485 "*doit_za_grid_size* must be greater than 15 for accurate results");
1486 else if (doit_za_grid_size > 100)
1489 out1 <<
"Warning: doit_za_grid_size is very large which means that the \n"
1490 <<
"calculation will be very slow. The recommended value is 19.\n";
1493 if ( cloudbox_limits.
nelem()!= 2*atmosphere_dim)
1494 throw runtime_error(
1495 "*cloudbox_limits* is a vector which contains the"
1496 "upper and lower limit of the cloud for all "
1497 "atmospheric dimensions. So its dimension must"
1498 "be 2 x *atmosphere_dim*");
1500 if (scat_data_raw.
nelem() == 0)
1501 throw runtime_error(
1502 "No scattering data files have been added.\n"
1503 "Please use the WSM *ParticleTypeAdd* or \n"
1504 "*ParticleTypeAddAll* to define the cloud \n"
1505 "properties for the scattering calculation.\n"
1521 if (atmosphere_dim == 1)
1523 doit_i_field.
resize((cloudbox_limits[1] - cloudbox_limits[0]) +1,
1526 scat_za_grid.
nelem(),
1530 doit_scat_field.
resize((cloudbox_limits[1] - cloudbox_limits[0]) +1,
1533 scat_za_grid.
nelem(),
1537 else if (atmosphere_dim == 3)
1539 doit_i_field.
resize((cloudbox_limits[1] - cloudbox_limits[0]) +1,
1540 (cloudbox_limits[3] - cloudbox_limits[2]) +1,
1541 (cloudbox_limits[5] - cloudbox_limits[4]) +1,
1542 scat_za_grid.
nelem(),
1543 scat_aa_grid.
nelem(),
1546 doit_scat_field.
resize((cloudbox_limits[1] - cloudbox_limits[0]) +1,
1547 (cloudbox_limits[3] - cloudbox_limits[2]) +1,
1548 (cloudbox_limits[5] - cloudbox_limits[4]) +1,
1549 scat_za_grid.
nelem(),
1550 scat_aa_grid.
nelem(),
1555 throw runtime_error(
1556 "Scattering calculations are not possible for a 2D"
1557 "atmosphere. If you want to do scattering calculations"
1558 "*atmosphere_dim* has to be either 1 or 3"
1563 doit_scat_field = 0.;
1564 doit_is_initialized = 1;
1570 const Index& doit_iteration_counter,
1583 os << doit_iteration_counter;
1586 if( iterations[0] == 0 )
1597 if (doit_iteration_counter == iterations[i])
1611 const Agenda& pha_mat_spt_agenda,
1615 const Index& atmosphere_dim,
1617 const Vector& scat_za_grid,
1618 const Vector& scat_aa_grid,
1619 const Index& doit_za_grid_size,
1634 if (scat_za_grid[0] != 0. || scat_za_grid[Nza-1] != 180.)
1635 throw runtime_error(
"The range of *scat_za_grid* must [0 180].");
1640 if (scat_aa_grid[0] != 0. || scat_aa_grid[Naa-1] != 360.)
1641 throw runtime_error(
"The range of *scat_za_grid* must [0 360].");
1644 const Index stokes_dim = doit_scat_field.
ncols();
1645 assert(stokes_dim > 0 || stokes_dim < 5);
1655 if (atmosphere_dim == 1)
1658 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1659 1, 1, Nza, 1, stokes_dim));
1660 assert(
is_size(doit_scat_field,
1661 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1662 1, 1, scat_za_grid.
nelem(), 1, stokes_dim));
1664 else if (atmosphere_dim == 3)
1666 assert (
is_size( doit_i_field,
1667 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1668 (cloudbox_limits[3] - cloudbox_limits[2]) +1,
1669 (cloudbox_limits[5] - cloudbox_limits[4]) +1,
1670 Nza, Naa, stokes_dim));
1671 assert (
is_size( doit_scat_field,
1672 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1673 (cloudbox_limits[3] - cloudbox_limits[2]) +1,
1674 (cloudbox_limits[5] - cloudbox_limits[4]) +1,
1675 Nza, Naa, stokes_dim));
1680 os <<
"The atmospheric dimension must be 1D or 3D \n"
1681 <<
"for scattering calculations using the DOIT\n"
1682 <<
"module, but it is not. The value of *atmosphere_dim*\n"
1683 <<
"is " << atmosphere_dim <<
".";
1684 throw runtime_error( os.str() );
1687 if ( cloudbox_limits.
nelem()!= 2*atmosphere_dim)
1688 throw runtime_error(
1689 "*cloudbox_limits* is a vector which contains the"
1690 "upper and lower limit of the cloud for all "
1691 "atmospheric dimensions. So its dimension must"
1692 "be 2 x *atmosphere_dim*");
1696 if (doit_za_grid_size != Nza)
1697 throw runtime_error(
1698 "The zenith angle grids for the computation of\n"
1699 "the scattering integral and the RT part must \n"
1700 "be equal. Check definitions in \n"
1701 "*DoitAngularGridsSet*. The keyword \n"
1702 "'za_grid_opt_file' should be empty. \n"
1708 Tensor4 pha_mat_local(doit_za_grid_size, scat_aa_grid.
nelem(),
1709 stokes_dim, stokes_dim, 0.);
1711 Tensor5 pha_mat_spt_local(pnd_field.
nbooks(), doit_za_grid_size,
1712 scat_aa_grid.
nelem(), stokes_dim, stokes_dim, 0.);
1716 grid_stepsize[0] = 180./(
Numeric)(doit_za_grid_size - 1);
1717 grid_stepsize[1] = 360./(
Numeric)(Naa - 1);
1719 Tensor3 product_field(Nza, Naa, stokes_dim, 0);
1721 out2 <<
" Calculate the scattered field\n";
1723 if ( atmosphere_dim == 1 )
1725 Index scat_aa_index_local = 0;
1729 for (
Index p_index = 0; p_index<=cloudbox_limits[1]-cloudbox_limits[0] ;
1732 Numeric rte_temperature_local =
1733 t_field(p_index + cloudbox_limits[0], 0, 0);
1735 for (
Index scat_za_index_local = 0;
1736 scat_za_index_local < Nza; scat_za_index_local ++)
1739 Index index_zero = 0;
1742 out3 <<
"Calculate the phase matrix \n";
1744 scat_za_index_local,
1748 scat_aa_index_local,
1749 rte_temperature_local,
1750 pha_mat_spt_agenda);
1753 pha_matCalc(pha_mat_local, pha_mat_spt_local, pnd_field,
1754 atmosphere_dim, p_index, 0,
1757 out3 <<
"Multiplication of phase matrix with incoming" <<
1764 for (
Index za_in = 0; za_in < Nza; ++ za_in)
1766 for (
Index aa_in = 0; aa_in < Naa; ++ aa_in)
1771 for (
Index i = 0; i < stokes_dim; i++)
1773 for (
Index j = 0; j< stokes_dim; j++)
1775 product_field(za_in, aa_in, i) +=
1776 pha_mat_local(za_in, aa_in, i, j) *
1777 doit_i_field(p_index, 0, 0, za_in, 0, j);
1785 for (
Index i = 0; i < stokes_dim; i++)
1787 doit_scat_field( p_index, 0, 0, scat_za_index_local, 0, i)
1801 else if( atmosphere_dim == 3 )
1807 for (
Index p_index = 0; p_index <=
1808 cloudbox_limits[1] - cloudbox_limits[0];
1811 for (
Index lat_index = 0; lat_index <=
1812 cloudbox_limits[3] - cloudbox_limits[2]; lat_index++)
1814 for (
Index lon_index = 0; lon_index <=
1815 cloudbox_limits[5]-cloudbox_limits[4]; lon_index++)
1817 Numeric rte_temperature_local =
1818 t_field(p_index + cloudbox_limits[0],
1819 lat_index + cloudbox_limits[2],
1820 lon_index + cloudbox_limits[4]);
1822 for (
Index scat_aa_index_local = 1;
1823 scat_aa_index_local < Naa;
1824 scat_aa_index_local++)
1826 for (
Index scat_za_index_local = 0;
1827 scat_za_index_local < Nza;
1828 scat_za_index_local ++)
1830 out3 <<
"Calculate phase matrix \n";
1832 scat_za_index_local,
1836 scat_aa_index_local,
1837 rte_temperature_local,
1838 pha_mat_spt_agenda);
1852 for (
Index za_in = 0; za_in < Nza; ++ za_in)
1854 for (
Index aa_in = 0; aa_in < Naa; ++ aa_in)
1858 for (
Index i = 0; i < stokes_dim; i++)
1860 for (
Index j = 0; j< stokes_dim; j++)
1862 product_field(za_in, aa_in, i) +=
1864 (za_in, aa_in, i, j) *
1865 doit_i_field(p_index, lat_index,
1867 scat_za_index_local,
1868 scat_aa_index_local,
1878 for (
Index i = 0; i < stokes_dim; i++)
1880 doit_scat_field( p_index,
1883 scat_za_index_local,
1884 scat_aa_index_local,
1911 const Agenda& pha_mat_spt_agenda,
1915 const Index& atmosphere_dim,
1917 const Vector& scat_za_grid,
1918 const Vector& scat_aa_grid,
1919 const Index& doit_za_grid_size,
1920 const Index& doit_za_interp,
1934 if (scat_za_grid[0] != 0. || scat_za_grid[Nza-1] != 180.)
1935 throw runtime_error(
"The range of *scat_za_grid* must [0 180].");
1940 if (scat_aa_grid[0] != 0. || scat_aa_grid[Naa-1] != 360.)
1941 throw runtime_error(
"The range of *scat_za_grid* must [0 360].");
1944 const Index stokes_dim = doit_scat_field.
ncols();
1945 assert(stokes_dim > 0 || stokes_dim < 5);
1955 if (atmosphere_dim == 1)
1958 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1959 1, 1, Nza, 1, stokes_dim));
1960 assert(
is_size(doit_scat_field,
1961 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1962 1, 1, scat_za_grid.
nelem(), 1, stokes_dim));
1964 else if (atmosphere_dim == 3)
1966 assert (
is_size( doit_i_field,
1967 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1968 (cloudbox_limits[3] - cloudbox_limits[2]) +1,
1969 (cloudbox_limits[5] - cloudbox_limits[4]) +1,
1970 Nza, Naa, stokes_dim));
1971 assert (
is_size( doit_scat_field,
1972 (cloudbox_limits[1] - cloudbox_limits[0]) +1,
1973 (cloudbox_limits[3] - cloudbox_limits[2]) +1,
1974 (cloudbox_limits[5] - cloudbox_limits[4]) +1,
1975 Nza, Naa, stokes_dim));
1980 os <<
"The atmospheric dimension must be 1D or 3D \n"
1981 <<
"for scattering calculations using the DOIT\n"
1982 <<
"module, but it is not. The value of *atmosphere_dim*\n"
1983 <<
"is " << atmosphere_dim <<
".";
1984 throw runtime_error( os.str() );
1987 if( !(doit_za_interp == 0 || doit_za_interp == 1 ) )
1988 throw runtime_error(
"Interpolation method is not defined. Use \n"
1989 "*doit_za_interpSet*.\n");
1991 if ( cloudbox_limits.
nelem()!= 2*atmosphere_dim)
1992 throw runtime_error(
1993 "*cloudbox_limits* is a vector which contains the"
1994 "upper and lower limit of the cloud for all "
1995 "atmospheric dimensions. So its dimension must"
1996 "be 2 x *atmosphere_dim*");
1998 if (doit_za_grid_size < 16)
1999 throw runtime_error(
2000 "*doit_za_grid_size* must be greater than 15 for"
2001 "accurate results");
2002 else if (doit_za_grid_size > 100)
2005 out1 <<
"Warning: doit_za_grid_size is very large which means that the \n"
2006 <<
"calculation will be very slow. The recommended value is 19.\n";
2012 Tensor4 pha_mat_local(doit_za_grid_size, scat_aa_grid.
nelem(),
2013 stokes_dim, stokes_dim, 0.);
2015 Tensor5 pha_mat_spt_local(pnd_field.
nbooks(), doit_za_grid_size,
2016 scat_aa_grid.
nelem(), stokes_dim, stokes_dim, 0.);
2021 nlinspace(za_grid, 0, 180, doit_za_grid_size);
2026 gridpos(gp_za_i, scat_za_grid, za_grid);
2028 Matrix itw_za_i(doit_za_grid_size, 2);
2032 Matrix doit_i_field_int(doit_za_grid_size, stokes_dim, 0);
2037 gridpos(gp_za, za_grid, scat_za_grid);
2043 Matrix doit_scat_field_org(doit_za_grid_size, stokes_dim, 0);
2048 grid_stepsize[0] = 180./(
Numeric)(doit_za_grid_size - 1);
2049 grid_stepsize[1] = 360./(
Numeric)(Naa - 1);
2051 Tensor3 product_field(doit_za_grid_size, Naa, stokes_dim, 0);
2053 if ( atmosphere_dim == 1 )
2055 Index scat_aa_index_local = 0;
2059 for (
Index p_index = 0;
2060 p_index <= cloudbox_limits[1]-cloudbox_limits[0];
2063 Numeric rte_temperature_local =
2064 t_field(p_index + cloudbox_limits[0], 0, 0);
2066 for (
Index i = 0; i < stokes_dim; i++)
2068 if (doit_za_interp == 0)
2071 doit_i_field(p_index, 0, 0,
joker, 0, i), gp_za_i);
2073 else if (doit_za_interp == 1)
2076 for(
Index za = 0; za < za_grid.
nelem(); za++)
2078 doit_i_field_int(za, i) =
2080 doit_i_field(p_index, 0, 0,
joker, 0, i),
2090 for(
Index scat_za_index_local = 0;
2091 scat_za_index_local < doit_za_grid_size;
2092 scat_za_index_local++)
2095 Index index_zero = 0;
2098 out3 <<
"Calculate the phase matrix \n";
2100 scat_za_index_local,
2104 scat_aa_index_local,
2105 rte_temperature_local,
2106 pha_mat_spt_agenda);
2109 pha_matCalc(pha_mat_local, pha_mat_spt_local, pnd_field,
2110 atmosphere_dim, p_index, 0,
2113 out3 <<
"Multiplication of phase matrix with incoming" <<
2120 for(
Index za_in = 0; za_in < doit_za_grid_size; za_in ++)
2122 for (
Index aa_in = 0; aa_in < Naa; ++ aa_in)
2127 for (
Index i = 0; i < stokes_dim; i++)
2129 for (
Index j = 0; j< stokes_dim; j++)
2131 product_field(za_in, aa_in, i) +=
2132 pha_mat_local(za_in, aa_in, i, j) *
2133 doit_i_field_int(za_in, j);
2140 out3 <<
"Compute integral. \n";
2141 for (
Index i = 0; i < stokes_dim; i++)
2143 doit_scat_field_org(scat_za_index_local, i)=
2153 for (
Index i = 0; i < stokes_dim; i++)
2155 if(doit_za_interp == 0)
2157 interp(doit_scat_field(p_index,
2164 doit_scat_field_org(
joker, i),
2169 for(
Index za = 0; za < scat_za_grid.
nelem(); za++)
2171 doit_scat_field(p_index, 0, 0, za, 0, i) =
2173 doit_scat_field_org(
joker, i),
2184 else if( atmosphere_dim == 3 ){
2186 for (
Index p_index = 0; p_index <= cloudbox_limits[1] - cloudbox_limits[0];
2189 for (
Index lat_index = 0; lat_index <=
2190 cloudbox_limits[3] - cloudbox_limits[2]; lat_index++)
2192 for (
Index lon_index = 0; lon_index <=
2193 cloudbox_limits[5] - cloudbox_limits[4]; lon_index++)
2196 Numeric rte_temperature_local =
2197 t_field(p_index + cloudbox_limits[0],
2198 lat_index + cloudbox_limits[2],
2199 lon_index + cloudbox_limits[4]);
2202 for (
Index scat_aa_index_local = 1;
2203 scat_aa_index_local < Naa;
2204 scat_aa_index_local++)
2207 for (
Index i = 0; i < stokes_dim; i++)
2210 doit_i_field(p_index, lat_index, lon_index,
2211 joker, scat_aa_index_local, i), gp_za_i);
2214 for (
Index scat_za_index_local = 0;
2215 scat_za_index_local < doit_za_grid_size;
2216 scat_za_index_local++)
2219 out3 <<
"Calculate phase matrix \n";
2221 scat_za_index_local,
2225 scat_aa_index_local,
2226 rte_temperature_local,
2227 pha_mat_spt_agenda);
2242 out3 <<
"Multiplication of phase matrix with" <<
2243 "incoming intensity \n";
2245 for(
Index za_in = 0; za_in < doit_za_grid_size; za_in ++)
2247 for (
Index aa_in = 0; aa_in < Naa; ++ aa_in)
2251 for (
Index i = 0; i < stokes_dim; i++)
2253 for (
Index j = 0; j< stokes_dim; j++)
2255 product_field(za_in, aa_in, i) +=
2256 pha_mat_local(za_in, aa_in, i, j) *
2257 doit_i_field_int(za_in, j);
2263 out3 <<
"Compute the integral \n";
2265 for (
Index i = 0; i < stokes_dim; i++)
2267 doit_scat_field_org(scat_za_index_local, i) =
2279 for (
Index i = 0; i < stokes_dim; i++)
2281 interp(doit_scat_field(p_index,
2285 scat_aa_index_local,
2288 doit_scat_field_org(
joker, i),
2298 out2 <<
" Finished scattered field.\n";
2304 Vector& doit_za_grid_opt,
2307 const Vector& scat_za_grid,
2308 const Index& doit_za_interp,
2318 chk_size(
"doit_i_field", doit_i_field,
2320 doit_i_field.
ncols());
2322 if(doit_i_field.
ncols()<1 || doit_i_field.
ncols()>4)
2323 throw runtime_error(
"The last dimension of *doit_i_field* corresponds\n"
2324 "to the Stokes dimension, therefore the number of\n"
2325 "columns in *doit_i_field* must be a number between\n"
2326 "1 and 4, but it is not!");
2328 if(scat_za_grid.
nelem() < 500)
2329 throw runtime_error(
"The fine grid (*scat_za_grid*) has less than \n"
2330 "500 grid points which is not sufficient for \n"
2331 "grid_optimization");
2333 if( !(doit_za_interp == 0 || doit_za_interp == 1 ) )
2334 throw runtime_error(
"Interpolation method is not defined. Use \n"
2335 "*doit_za_interpSet*.\n");
2340 Matrix doit_i_field_opt_mat;
2341 doit_i_field_opt_mat = 0.;
2344 za_gridOpt(doit_za_grid_opt, doit_i_field_opt_mat,
2345 scat_za_grid, doit_i_field, acc,
2352 const Index& atmosphere_dim,
2359 if (atmosphere_dim != 1 && method ==
"polynomial")
2360 throw runtime_error(
2361 "Polynomial interpolation is only implemented for\n"
2362 "1D DOIT calculations as \n"
2363 "in 3D there can be numerical problems.\n"
2364 "Please use 'linear' interpolation method."
2367 if(method ==
"linear")
2369 else if (method ==
"polynomial")
2372 throw runtime_error(
"Possible interpolation methods are 'linear' "
2373 "and 'polynomial'.\n");
2383 Tensor4& doit_i_field1D_spectrum,
2384 const Index& cloudbox_on,
2386 const Agenda& doit_mono_agenda,
2387 const Index& doit_is_initialized,
2396 if (!cloudbox_on)
return;
2402 if( f_grid.
nelem() == 0 )
2403 throw runtime_error(
"The frequency grid is empty." );
2407 if (!doit_is_initialized)
2408 throw runtime_error(
2409 "Initialization method *DoitInit* has to be "
2411 "start of *ScatteringDoit*");
2419 Agenda l_doit_mono_agenda(doit_mono_agenda);
2433 for (
Index f_index = 0; f_index < nf; f_index ++)
2436 os <<
"Frequency: " << f_grid[f_index]/1e9 <<
" GHz \n" ;
2440 scat_i_lon, doit_i_field1D_spectrum,
2441 f_index, l_doit_mono_agenda);
2451 Tensor4& doit_i_field1D_spectrum,
2455 const Index& f_index,
2459 const Vector& scat_za_grid,
2460 const Vector& scat_aa_grid,
2461 const Index& stokes_dim,
2462 const Index& atmosphere_dim,
2464 const Matrix& sensor_pos,
2472 Index N_p = cloudbox_limits[1] - cloudbox_limits[0] +1;
2476 assert( f_index < f_grid.
nelem() );
2481 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
2484 if (stokes_dim < 0 || stokes_dim > 4)
2485 throw runtime_error(
2486 "The dimension of stokes vector must be"
2489 if ( cloudbox_limits.nelem()!= 2*atmosphere_dim)
2490 throw runtime_error(
2491 "*cloudbox_limits* is a vector which contains the"
2492 "upper and lower limit of the cloud for all "
2493 "atmospheric dimensions. So its dimension must"
2494 "be 2 x *atmosphere_dim*");
2498 doit_i_field1D_spectrum.
resize(N_f, N_p, N_za, stokes_dim);
2499 doit_i_field1D_spectrum = 0;
2503 if(atmosphere_dim == 1)
2505 bool in_cloudbox =
false;
2508 for (
Index i = 0; i < sensor_pos.
ncols(); i++)
2511 if(sensor_pos(i, 0) >= z_field(cloudbox_limits[0], 0, 0) &&
2512 sensor_pos(i, 0) <= z_field(cloudbox_limits[1], 0, 0) )
2516 out2 <<
" Sensor position in cloudbox, store radiation field\n"
2517 <<
" in cloudbox for all frequencies. \n";
2522 assert (
is_size( doit_i_field,
2523 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
2531 N_f, 2, 1, 1, N_za, 1, stokes_dim ));
2533 for (
Index za = 0; za < N_za; za++)
2535 for (
Index i = 0; i < stokes_dim; i++)
2539 scat_i_p(f_index, 0, 0, 0,
2541 doit_i_field(0, 0, 0, za, 0, i);
2543 scat_i_p(f_index, 1, 0, 0,
2545 doit_i_field(cloudbox_limits[1] - cloudbox_limits[0],
2552 doit_i_field1D_spectrum(f_index,
joker, za, i) =
2553 doit_i_field(
joker, 0, 0, za, 0, i);
2562 if(atmosphere_dim == 3)
2565 Index N_lat = cloudbox_limits[3] - cloudbox_limits[2] + 1;
2566 Index N_lon = cloudbox_limits[5] - cloudbox_limits[4] + 1;
2569 assert (
is_size( doit_i_field,
2570 cloudbox_limits[1] - cloudbox_limits[0] + 1,
2578 scat_i_p.
resize(N_f, 2, N_lat, N_lon, N_za, N_aa, stokes_dim);
2579 scat_i_lat.
resize(N_f, N_p, 2, N_lon, N_za, N_aa, stokes_dim);
2580 scat_i_lon.
resize(N_f, N_p, N_lat, 2, N_za, N_aa, stokes_dim);
2582 for (
Index za = 0; za < N_za; za++)
2584 for (
Index aa = 0; aa < N_aa; aa++)
2586 for (
Index i = 0; i < stokes_dim; i++)
2591 for (
Index lat = 0; lat < N_lat; lat++)
2593 for (
Index lon = 0; lon < N_lon; lon++)
2596 scat_i_p(f_index, 0, lat, lon,
2598 doit_i_field(0, lat, lon, za, aa, i);
2600 scat_i_p(f_index, 1, lat, lon,
2602 doit_i_field(cloudbox_limits[1]-cloudbox_limits[0],
2603 lat, lon, za, aa, i);
2609 for (
Index p = 0; p < N_p; p++)
2611 for (
Index lon = 0; lon < N_lon; lon++)
2614 scat_i_lat(f_index, p, 0, lon,
2616 doit_i_field(p, 0, lon, za, aa, i);
2618 scat_i_lat(f_index, p, 1, lon,
2620 doit_i_field(p, cloudbox_limits[3]-
2626 for (
Index lat = 0; lat < N_lat; lat++)
2629 scat_i_lon(f_index, p, lat, 0,
2631 doit_i_field(p, lat, 0, za, aa, i);
2633 scat_i_lon(f_index, p, lat, 1,
2635 doit_i_field(p, lat, cloudbox_limits[5]-
2636 cloudbox_limits[4], za, aa, i);
2652 const Agenda& iy_clearsky_basic_agenda,
2653 const Index& atmosphere_dim,
2658 const Index& cloudbox_on,
2661 const Index& stokes_dim,
2662 const Vector& scat_za_grid,
2663 const Vector& scat_aa_grid,
2667 if (!cloudbox_on)
return;
2670 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
2672 Index Ni = stokes_dim;
2677 if( !(atmosphere_dim == 1 || atmosphere_dim == 3) )
2678 throw runtime_error(
"The atmospheric dimensionality must be 1 or 3.");
2679 if( scat_za_grid[0] != 0. || scat_za_grid[Nza-1] != 180. )
2680 throw runtime_error(
2681 "*scat_za_grid* must include 0 and 180 degrees as endpoints." );
2685 if( atmosphere_dim == 1 )
2688 scat_i_p.
resize( Nf, 2, 1, 1, Nza, 1, Ni );
2689 scat_i_lat.
resize( 0, 0, 0, 0, 0, 0, 0 );
2690 scat_i_lon.
resize( 0, 0, 0, 0, 0, 0, 0 );
2697 for (
Index boundary = 0; boundary <= 1; boundary++)
2699 pos[0] = r_geoid(0,0) + z_field( cloudbox_limits[boundary], 0, 0 );
2701 for (
Index scat_za_index = 0; scat_za_index < Nza; scat_za_index ++)
2703 los[0] = scat_za_grid[scat_za_index];
2706 iy_clearsky_basic_agenda );
2708 scat_i_p(
joker, boundary, 0, 0, scat_za_index, 0,
joker ) = iy;
2719 if( scat_aa_grid[0] != 0. || scat_aa_grid[Naa-1] != 360. )
2720 throw runtime_error(
2721 "*scat_aa_grid* must include 0 and 360 degrees as endpoints." );
2723 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
2724 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
2730 for(
Index i = 0; i<Naa; i++)
2731 aa_grid[i] = scat_aa_grid[i] - 180;
2734 scat_i_p.
resize( Nf, 2, Nlat_cloud, Nlon_cloud, Nza, Naa, Ni );
2735 scat_i_lat.
resize( Nf, Np_cloud, 2, Nlon_cloud, Nza, Naa, Ni );
2736 scat_i_lon.
resize( Nf, Np_cloud, Nlat_cloud, 2, Nza, Naa, Ni );
2744 for (
Index boundary = 0; boundary <= 1; boundary++)
2746 for (
Index lat_index = 0; lat_index < Nlat_cloud; lat_index++ )
2748 for (
Index lon_index = 0; lon_index < Nlon_cloud; lon_index++ )
2750 pos[0] = r_geoid(lat_index + cloudbox_limits[2],
2751 lon_index + cloudbox_limits[4])
2752 + z_field(cloudbox_limits[boundary],
2753 lat_index + cloudbox_limits[2],
2754 lon_index + cloudbox_limits[4]);
2755 pos[1] = lat_grid[lat_index + cloudbox_limits[2]];
2756 pos[2] = lon_grid[lon_index + cloudbox_limits[4]];
2758 for (
Index scat_za_index = 0; scat_za_index < Nza;
2761 for (
Index scat_aa_index = 0; scat_aa_index < Naa;
2764 los[0] = scat_za_grid[scat_za_index];
2765 los[1] = aa_grid[scat_aa_index];
2773 if( ( scat_za_index != 0 &&
2774 scat_za_index != (Nza-1) ) ||
2775 scat_aa_index == 0 )
2778 0, iy_clearsky_basic_agenda );
2781 scat_i_p(
joker, boundary, lat_index, lon_index,
2782 scat_za_index, scat_aa_index,
joker) = iy;
2790 for (
Index boundary = 0; boundary <= 1; boundary++)
2792 for (
Index p_index = 0; p_index < Np_cloud; p_index++ )
2794 for (
Index lon_index = 0; lon_index < Nlon_cloud; lon_index++ )
2796 pos[0] = r_geoid(cloudbox_limits[boundary+2],
2797 lon_index + cloudbox_limits[4])
2798 + z_field(p_index + cloudbox_limits[0],
2799 cloudbox_limits[boundary+2],
2800 lon_index + cloudbox_limits[4]);
2801 pos[1] = lat_grid[cloudbox_limits[boundary+2]];
2802 pos[2] = lon_grid[lon_index + cloudbox_limits[4]];
2804 for (
Index scat_za_index = 0; scat_za_index < Nza;
2807 for (
Index scat_aa_index = 0; scat_aa_index < Naa;
2810 los[0] = scat_za_grid[scat_za_index];
2811 los[1] = aa_grid[scat_aa_index];
2815 if( !( ( scat_za_index == 0 ||
2816 scat_za_index == (Nza-1) ) &&
2817 scat_aa_index == 0 ) )
2820 0, iy_clearsky_basic_agenda );
2823 scat_i_lat(
joker, p_index, boundary, lon_index,
2824 scat_za_index, scat_aa_index,
joker) = iy;
2832 for (
Index boundary = 0; boundary <= 1; boundary++)
2834 for (
Index p_index = 0; p_index < Np_cloud; p_index++ )
2836 for (
Index lat_index = 0; lat_index < Nlat_cloud; lat_index++ )
2838 pos[0] = r_geoid(lat_index + cloudbox_limits[2],
2839 cloudbox_limits[boundary+4])
2840 + z_field(p_index + cloudbox_limits[0],
2841 lat_index + cloudbox_limits[2],
2842 cloudbox_limits[boundary+4]);
2843 pos[1] = lat_grid[lat_index + cloudbox_limits[2]];
2844 pos[2] = lon_grid[cloudbox_limits[boundary+4]];
2846 for (
Index scat_za_index = 0; scat_za_index < Nza;
2849 for (
Index scat_aa_index = 0; scat_aa_index < Naa;
2852 los[0] = scat_za_grid[scat_za_index];
2853 los[1] = aa_grid[scat_aa_index];
2857 if( !( ( scat_za_index == 0 ||
2858 scat_za_index == (Nza-1) ) &&
2859 scat_aa_index == 0 ) )
2862 0, iy_clearsky_basic_agenda );
2865 scat_i_lon(
joker, p_index, lat_index, boundary,
2866 scat_za_index, scat_aa_index,
joker) = iy;
2882 const Agenda& iy_clearsky_basic_agenda,
2883 const Index& atmosphere_dim,
2890 const Index& stokes_dim,
2891 const Vector& scat_za_grid,
2892 const Vector& scat_aa_grid,
2896 if (!cloudbox_on)
return;
2899 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
2900 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
2901 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
2904 Index Ni = stokes_dim;
2910 if( atmosphere_dim != 3 )
2911 throw runtime_error(
"The atmospheric dimensionality must be 3.");
2914 if( scat_za_grid[0] != 0. || scat_za_grid[Nza-1] != 180. )
2915 throw runtime_error(
2916 "*scat_za_grid* must include 0 and 180 degrees as endpoints." );
2917 if( scat_aa_grid[0] != 0. || scat_aa_grid[Naa-1] != 360. )
2918 throw runtime_error(
2919 "*scat_aa_grid* must include 0 and 360 degrees as endpoints." );
2931 for(
Index i = 0; i<Naa; i++)
2932 aa_grid[i] = scat_aa_grid[i] - 180;
2939 scat_i_p.
resize(Nf, 2, Nlat_cloud, Nlon_cloud, Nza, Naa, Ni);
2940 scat_i_lat.
resize(Nf, Np_cloud, 2, Nlon_cloud, Nza, Naa, Ni);
2941 scat_i_lon.
resize(Nf, Np_cloud, Nlat_cloud, 2, Nza, Naa, Ni);
2947 pos[1] = lat_grid[cloudbox_limits[2]];
2948 pos[2] = lon_grid[cloudbox_limits[4]];
2949 los[1] = aa_grid[aa_index];
2952 for (
Index p_index = 0; p_index < Np_cloud; p_index++ )
2954 pos[0] = r_geoid(cloudbox_limits[2], cloudbox_limits[4])
2955 + z_field(cloudbox_limits[0] + p_index, cloudbox_limits[2],
2956 cloudbox_limits[4]);
2958 for (
Index scat_za_index = 0; scat_za_index < Nza; scat_za_index++ )
2960 los[0] = scat_za_grid[scat_za_index];
2963 iy_clearsky_basic_agenda );
2965 for (
Index aa = 0; aa < Naa; aa ++)
2970 for (
Index lat = 0; lat < Nlat_cloud; lat ++)
2972 for (
Index lon = 0; lon < Nlon_cloud; lon ++)
2974 scat_i_p(
joker, 0, lat, lon, scat_za_index, aa,
2981 else if (p_index == Np_cloud-1)
2982 for (
Index lat = 0; lat < Nlat_cloud; lat ++)
2984 for (
Index lon = 0; lon < Nlon_cloud; lon ++)
2986 scat_i_p(
joker, 1, lat, lon, scat_za_index, aa,
2993 for (
Index lat = 0; lat < 2; lat ++)
2995 for (
Index lon = 0; lon < Nlon_cloud; lon ++)
2997 scat_i_lat(
joker, p_index, lat, lon,
2998 scat_za_index, aa,
joker)
3004 for (
Index lat = 0; lat < Nlat_cloud; lat ++)
3006 for (
Index lon = 0; lon < 2; lon ++)
3008 scat_i_lon(
joker, p_index, lat, lon,
3009 scat_za_index, aa,
joker)
3023 Index& iy_error_type,
3026 const Tensor3& iy_transmission,
3030 const Tensor4& doit_i_field1D_spectrum,
3035 const Index& jacobian_do,
3036 const Index& cloudbox_on,
3038 const Index& atmosphere_dim,
3039 const Index& stokes_dim,
3040 const Vector& scat_za_grid,
3041 const Vector& scat_aa_grid,
3047 throw runtime_error(
3048 "This method does not provide any jacobians (jacobian_do must be 0)" );
3055 doit_i_field1D_spectrum, rte_gp_p,
3056 rte_gp_lat, rte_gp_lon, rte_los, cloudbox_on,
3057 cloudbox_limits, atmosphere_dim, stokes_dim,
3058 scat_za_grid, scat_aa_grid, f_grid,
"linear",
3070 iy_aux.
resize( nf, stokes_dim );
3071 iy_error.
resize( nf, stokes_dim );
3074 for(
Index iv=0; iv<nf; iv++ )
3076 for(
Index is=0; is<stokes_dim; is++ )
3078 iy_aux( iv, is ) = iy_transmission( iv, is, is );
3079 iy_error( iv, is ) = iy_aux( iv, is ) * eps[is];
3088 Index& iy_error_type,
3091 const Tensor3& iy_transmission,
3095 const Tensor4& doit_i_field1D_spectrum,
3100 const Index& jacobian_do,
3101 const Index& cloudbox_on,
3103 const Index& atmosphere_dim,
3104 const Index& stokes_dim,
3105 const Vector& scat_za_grid,
3106 const Vector& scat_aa_grid,
3112 throw runtime_error(
3113 "This method does not provide any jacobians (jacobian_do must be 0)" );
3120 doit_i_field1D_spectrum, rte_gp_p,
3121 rte_gp_lat, rte_gp_lon, rte_los, cloudbox_on,
3122 cloudbox_limits, atmosphere_dim, stokes_dim,
3123 scat_za_grid, scat_aa_grid, f_grid,
"polynomial",
3135 iy_aux.
resize( nf, stokes_dim );
3136 iy_error.
resize( nf, stokes_dim );
3139 for(
Index iv=0; iv<nf; iv++ )
3141 for(
Index is=0; is<stokes_dim; is++ )
3143 iy_aux( iv, is ) = iy_transmission( iv, is, is );
3144 iy_error( iv, is ) = iy_aux( iv, is ) * eps[is];
3155 const Index& f_index,
3160 const Index& atmosphere_dim,
3162 const Index& all_frequencies,
3167 out2 <<
" Interpolate boundary clearsky field to obtain the initial field.\n";
3172 if(atmosphere_dim == 1)
3174 if(f_index == 0 || all_frequencies ==
true){
3176 if (f_grid.
nelem() != N_f){
3178 throw runtime_error(
" scat_i_p should have same frequency "
3179 " dimension as f_grid");
3183 throw runtime_error(
"scat_i_p should have exactly two elements "
3184 "in pressure dimension which correspond to the "
3185 "two cloudbox bounding pressure levels");
3195 doit_i_field.
resize((cloudbox_limits[1]- cloudbox_limits[0])+1,
3211 p_grid[
Range(cloudbox_limits[0],
3213 (cloudbox_limits[1]- cloudbox_limits[0]))],
3214 p_grid[
Range(cloudbox_limits[0],
3215 (cloudbox_limits[1]- cloudbox_limits[0])+1)]);
3217 Matrix itw((cloudbox_limits[1]- cloudbox_limits[0])+1, 2);
3222 for (
Index za_index = 0; za_index < N_za ; ++ za_index)
3224 for (
Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
3226 for (
Index i = 0 ; i < N_i ; ++ i)
3264 else if(atmosphere_dim == 3)
3266 if (all_frequencies ==
false)
3267 throw runtime_error(
"Error in doit_i_fieldSetClearsky: For 3D "
3268 "all_frequencies option is not implemented \n");
3274 throw runtime_error(
" scat_i_p, scat_i_lat, scat_i_lon should have "
3275 "same frequency dimension");
3277 Index N_p = cloudbox_limits[1] - cloudbox_limits[0] + 1;
3280 throw runtime_error(
"scat_i_lat and scat_i_lon should have "
3281 "same pressure grid dimension as p_grid");
3284 Index N_lat = cloudbox_limits[3] - cloudbox_limits[2] + 1;
3286 if(scat_i_lon.
nshelves() != N_lat ||
3288 throw runtime_error(
"scat_i_p and scat_i_lon should have "
3289 "same latitude grid dimension as lat_grid");
3292 Index N_lon = cloudbox_limits[5] - cloudbox_limits[4] + 1;
3293 if(scat_i_lat.
nbooks() != N_lon ||
3294 scat_i_p.
nbooks() != N_lon ){
3295 throw runtime_error(
"scat_i_p and scat_i_lat should have "
3296 "same longitude grid dimension as lon_grid");
3299 throw runtime_error(
"scat_i_p should have exactly two elements "
3300 "in pressure dimension which correspond to the "
3301 "two cloudbox bounding pressure levels");
3305 throw runtime_error(
"scat_i_lat should have exactly two elements "
3306 "in latitude dimension which correspond to the "
3307 "two cloudbox bounding latitude levels");
3309 if(scat_i_lon.
nbooks() != 2){
3310 throw runtime_error(
"scat_i_lon should have exactly two elements "
3311 "in longitude dimension which correspond to the "
3312 "two cloudbox bounding longitude levels");
3315 if (scat_i_lat.
npages() != N_za ||
3316 scat_i_lon.
npages() != N_za){
3318 throw runtime_error(
" scat_i_p, scat_i_lat, scat_i_lon should have "
3319 "same zenith angle dimension");
3322 if (scat_i_lat.
nrows() != N_aa ||
3323 scat_i_lon.
nrows() != N_aa){
3325 throw runtime_error(
" scat_i_p, scat_i_lat, scat_i_lon should have "
3326 "same azimuth angle dimension");
3329 if (scat_i_lat.
ncols() != N_i ||
3330 scat_i_lon.
ncols() != N_i){
3332 throw runtime_error(
" scat_i_p, scat_i_lat, scat_i_lon should have "
3333 "same value for stokes_dim and can take only"
3334 "values 1,2,3 or 4");
3341 doit_i_field.
resize((cloudbox_limits[1]- cloudbox_limits[0])+1,
3342 (cloudbox_limits[3]- cloudbox_limits[2])+1,
3343 (cloudbox_limits[5]- cloudbox_limits[4])+1,
3351 ArrayOfGridPos lat_gp((cloudbox_limits[3]- cloudbox_limits[2])+1);
3352 ArrayOfGridPos lon_gp((cloudbox_limits[5]- cloudbox_limits[4])+1);
3359 p_grid[
Range(cloudbox_limits[0],
3361 (cloudbox_limits[1]- cloudbox_limits[0]))],
3362 p_grid[
Range(cloudbox_limits[0],
3363 (cloudbox_limits[1]- cloudbox_limits[0])+1)]);
3365 lat_grid[
Range(cloudbox_limits[2],
3367 (cloudbox_limits[3]- cloudbox_limits[2]))],
3368 lat_grid[
Range(cloudbox_limits[2],
3369 (cloudbox_limits[3]- cloudbox_limits[2])+1)]);
3371 lon_grid[
Range(cloudbox_limits[4],
3373 (cloudbox_limits[5]- cloudbox_limits[4]))],
3374 lon_grid[
Range(cloudbox_limits[4],
3375 (cloudbox_limits[5]- cloudbox_limits[4])+1)]);
3381 Matrix itw_p((cloudbox_limits[1]- cloudbox_limits[0])+1, 2);
3382 Matrix itw_lat((cloudbox_limits[3]- cloudbox_limits[2])+1, 2);
3383 Matrix itw_lon((cloudbox_limits[5]- cloudbox_limits[4])+1, 2);
3390 for (
Index lat_index = 0;
3391 lat_index <= (cloudbox_limits[3]-cloudbox_limits[2]); ++ lat_index)
3393 for (
Index lon_index = 0;
3394 lon_index <= (cloudbox_limits[5]-cloudbox_limits[4]);
3397 for (
Index za_index = 0; za_index < N_za ; ++ za_index)
3399 for (
Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
3401 for (
Index i = 0 ; i < N_i ; ++ i)
3429 for (
Index p_index = 0;
3430 p_index <= (cloudbox_limits[1]-cloudbox_limits[0]) ; ++ p_index)
3432 for (
Index lon_index = 0;
3433 lon_index <= (cloudbox_limits[5]-cloudbox_limits[4]) ;
3436 for (
Index za_index = 0; za_index < N_za ; ++ za_index)
3438 for (
Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
3440 for (
Index i = 0 ; i < N_i ; ++ i)
3445 za_index, aa_index, i);
3449 lon_index, za_index, aa_index, i);
3461 for (
Index p_index = 0;
3462 p_index <= (cloudbox_limits[1]-cloudbox_limits[0]); ++ p_index)
3464 for (
Index lat_index = 0;
3465 lat_index <= (cloudbox_limits[3]-cloudbox_limits[2]);
3468 for (
Index za_index = 0; za_index < N_za ; ++ za_index)
3470 for (
Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
3472 for (
Index i = 0 ; i < N_i ; ++ i)
3475 VectorView target_field = doit_i_field(p_index,
3515 const Index& atmosphere_dim,
3516 const Index& stokes_dim,
3518 const Vector& doit_i_field_values,
3524 out2 <<
" Set initial field to constant values: " << doit_i_field_values <<
"\n";
3530 Index N_i = stokes_dim;
3531 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
3532 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
3533 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
3538 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
3541 if (stokes_dim < 0 || stokes_dim > 4)
3542 throw runtime_error(
3543 "The dimension of stokes vector must be"
3546 if ( cloudbox_limits.nelem()!= 2*atmosphere_dim)
3547 throw runtime_error(
3548 "*cloudbox_limits* is a vector which contains the"
3549 "upper and lower limit of the cloud for all "
3550 "atmospheric dimensions. So its dimension must"
3551 "be 2 x *atmosphere_dim*");
3555 if(atmosphere_dim == 1)
3557 out3 <<
" atm_dim = 1\n";
3560 doit_i_field.
resize((cloudbox_limits[1] - cloudbox_limits[0])+1, 1, 1, N_za,
3565 for (
Index za_index = 0; za_index < N_za; za_index++)
3567 for (
Index i = 0; i < stokes_dim; i++)
3570 doit_i_field(cloudbox_limits[1]-cloudbox_limits[0], 0, 0, za_index,
3572 scat_i_p(0, 1, 0, 0, za_index, 0, i);
3574 doit_i_field(0, 0, 0, za_index, 0, i) =
3575 scat_i_p(0, 0, 0, 0, za_index, 0, i);
3576 for (
Index scat_p_index = 1; scat_p_index < cloudbox_limits[1] -
3577 cloudbox_limits[0]; scat_p_index++ )
3579 doit_i_field(scat_p_index, 0, 0, za_index, 0, i) = doit_i_field_values[i];
3585 if ( !
is_size(scat_i_p, 1, 2, Nlat_cloud,
3586 Nlon_cloud, N_za, N_aa, stokes_dim)
3587 || !
is_size(scat_i_lat, 1, Np_cloud, 2,
3588 Nlon_cloud, N_za, N_aa, stokes_dim)
3589 || !
is_size(scat_i_lon, 1, Np_cloud,
3590 Nlat_cloud, 2, N_za, N_aa, stokes_dim) )
3591 throw runtime_error(
3592 "One of the interface variables (*scat_i_p*, "
3593 "*scat_i_lat* or *scat_i_lon*) does not have "
3594 "the right dimensions. \n Probably you have "
3595 "calculated them before for another value of "
3601 out3 <<
"atm_dim = 3\n";
3602 doit_i_field.
resize((cloudbox_limits[1]- cloudbox_limits[0])+1,
3603 (cloudbox_limits[3]- cloudbox_limits[2])+1,
3604 (cloudbox_limits[5]- cloudbox_limits[4])+1,
3613 for (
Index za_index = 0; za_index < N_za; za_index++)
3615 for (
Index aa_index = 0; aa_index < N_aa; aa_index++)
3617 for (
Index i = 0; i < stokes_dim; i++)
3621 for (
Index lat_index = cloudbox_limits[2];
3622 lat_index <= cloudbox_limits[3]; lat_index++)
3624 for (
Index lon_index = cloudbox_limits[4];
3625 lon_index <= cloudbox_limits[5]; lon_index++)
3628 doit_i_field(cloudbox_limits[1]-cloudbox_limits[0],
3629 lat_index-cloudbox_limits[2],
3630 lon_index-cloudbox_limits[4],
3631 za_index, aa_index, i) =
3632 scat_i_p(0, 1, lat_index-cloudbox_limits[2],
3633 lon_index-cloudbox_limits[4],
3634 za_index, aa_index, i);
3636 doit_i_field(0, lat_index-cloudbox_limits[2],
3637 lon_index-cloudbox_limits[4],
3638 za_index, aa_index, i) =
3639 scat_i_p(0, 0, lat_index-cloudbox_limits[2],
3640 lon_index-cloudbox_limits[4],
3641 za_index, aa_index, i);
3645 for (
Index p_index = cloudbox_limits[0];
3646 p_index <= cloudbox_limits[1]; p_index++)
3650 for (
Index lon_index = cloudbox_limits[4];
3651 lon_index <= cloudbox_limits[5]; lon_index++)
3654 doit_i_field(p_index-cloudbox_limits[0],
3655 cloudbox_limits[3]-cloudbox_limits[2],
3656 lon_index-cloudbox_limits[4],
3657 za_index, aa_index, i) =
3658 scat_i_lat(0, p_index-cloudbox_limits[0],
3659 1, lon_index-cloudbox_limits[4],
3660 za_index, aa_index, i);
3662 doit_i_field(p_index-cloudbox_limits[0], 0,
3663 lon_index-cloudbox_limits[4],
3664 za_index, aa_index, i) =
3665 scat_i_lat(0, p_index-cloudbox_limits[0], 0,
3666 lon_index-cloudbox_limits[4],
3667 za_index, aa_index, i);
3671 for (
Index lat_index = cloudbox_limits[2];
3672 lat_index <= cloudbox_limits[3]; lat_index++)
3675 doit_i_field(p_index-cloudbox_limits[0],
3676 lat_index-cloudbox_limits[2],
3677 cloudbox_limits[5]-cloudbox_limits[4],
3678 za_index, aa_index, i) =
3679 scat_i_lon(0, p_index-cloudbox_limits[0],
3680 lat_index-cloudbox_limits[2], 1,
3681 za_index, aa_index, i);
3683 doit_i_field(p_index-cloudbox_limits[0],
3684 lat_index-cloudbox_limits[2],
3686 za_index, aa_index, i) =
3687 scat_i_lon(0, p_index-cloudbox_limits[0],
3688 lat_index-cloudbox_limits[2], 0,
3689 za_index, aa_index, i);
3696 for(
Index p_index = (cloudbox_limits[0]+1);
3697 p_index < cloudbox_limits[1] ;
3700 for (
Index lat_index = (cloudbox_limits[2]+1);
3701 lat_index < cloudbox_limits[3];
3704 for (
Index lon_index = (cloudbox_limits[4]+1);
3705 lon_index < cloudbox_limits[5];
3708 doit_i_field(p_index-cloudbox_limits[0],
3709 lat_index-cloudbox_limits[2],
3710 lon_index-cloudbox_limits[4],
3711 za_index, aa_index, i) =
3712 doit_i_field_values[i];