78 Numeric& mc_cloud_opt_path_error,
79 Index& mc_iteration_count,
84 const Agenda& ppath_step_agenda,
96 const Vector& particle_masses,
99 const Index& max_iter,
108 ppath_step_agenda,p_grid,lat_grid,lon_grid,
109 r_geoid,z_surface,z_field,t_field,vmr_field,cloudbox_limits,
110 pnd_field,scat_data_mono,particle_masses,
118 mc_iteration_count=0;
123 rng.
seed(mc_seed, verbosity);
125 while (mc_iteration_count<max_iter)
128 mc_iteration_count+=1;
131 ppath_step_agenda,p_grid,lat_grid,lon_grid,
132 r_geoid,z_surface,z_field,t_field,vmr_field,
134 pnd_field,scat_data_mono,particle_masses,
137 iwp_squared+=iwp*iwp;
138 mc_cloud_opt_path+=cloud_opt_path;
139 tau_squared+=cloud_opt_path*cloud_opt_path;
141 mc_IWP/=(
Numeric)mc_iteration_count;
142 mc_cloud_opt_path/=(
Numeric)mc_iteration_count;
143 mc_IWP_error=sqrt((iwp_squared/(
Numeric)mc_iteration_count-mc_IWP*mc_IWP)
145 mc_cloud_opt_path_error=sqrt((tau_squared/(
Numeric)mc_iteration_count-
146 mc_cloud_opt_path*mc_cloud_opt_path)
187 Index& mc_iteration_count,
192 const Index& f_index,
195 const Index& stokes_dim,
196 const Index& atmosphere_dim,
197 const Agenda& iy_space_agenda,
198 const Agenda& surface_prop_agenda,
199 const Agenda& opt_prop_gas_agenda,
200 const Agenda& abs_scalar_gas_agenda,
209 const Index& cloudbox_on,
213 const Index& basics_checked,
214 const Index& cloudbox_checked,
215 const Index& mc_seed,
218 const Index& max_time,
219 const Index& max_iter,
227 "The cloudbox must be activated (cloudbox_on must be 1)" );
228 if( !basics_checked )
229 throw runtime_error(
"The atmosphere and basic control varaibles must be "
230 "flagged to have passed a consistency check (basics_checked=1)." );
231 if( !cloudbox_checked )
232 throw runtime_error(
"The cloudbox must be flagged to have passed a "
233 "consistency check (cloudbox_checked=1)." );
236 if (max_time<0 && max_iter<0 && std_err<0){
237 throw runtime_error(
"At least one of std_err, max_time, and max_iter must be positive" );
243 "The option of f_index < 0 is not handled by this method." );
245 if( f_index >= f_grid.
nelem() )
248 "*f_index* is outside the range of *f_grid*." );
251 if (! (atmosphere_dim == 3))
254 os <<
"Expected atmosphere_dim: 3. ";
255 os <<
"Found: " << atmosphere_dim;
256 throw runtime_error(os.str());
259 if (! (sensor_pos.
ncols() == 3))
262 os <<
"Expected number of columns in sensor_pos: 3. ";
263 os <<
"Found: " << sensor_pos.
ncols();
264 throw runtime_error(os.str());
267 if (! (sensor_los.
ncols() == 2))
270 os <<
"Expected number of columns in sensor_los: 2. ";
271 os <<
"Found: " << sensor_los.
ncols();
272 throw runtime_error(os.str());
275 if (pnd_field.
nbooks() == 0)
278 os <<
"No scattering particles found! "
279 <<
"Maybe you calculated the pnd_field before you set up the cloudbox?";
280 throw runtime_error(os.str());
286 time_t start_time=time(NULL);
295 rng.
seed(mc_seed, verbosity);
296 bool keepgoing,inside_cloud;
297 Numeric g,temperature,albedo,g_los_csc_theta;
298 Matrix A(stokes_dim,stokes_dim),Q(stokes_dim,stokes_dim),evol_op(stokes_dim,stokes_dim),
300 ext_mat_mono(stokes_dim,stokes_dim),
q(stokes_dim,stokes_dim),newQ(stokes_dim,stokes_dim),
301 Z(stokes_dim,stokes_dim);
303 mc_iteration_count=0;
304 Vector vector1(stokes_dim),abs_vec_mono(stokes_dim),I_i(stokes_dim),Isum(stokes_dim),
305 Isquaredsum(stokes_dim);
308 Index termination_flag=0;
309 mc_error.
resize(stokes_dim);
311 Matrix local_iy(1,stokes_dim),local_surface_emission(1,stokes_dim),local_surface_los;
319 Isum=0.0;Isquaredsum=0.0;
321 bool convert_to_rjbt=
false;
322 if ( y_unit ==
"RJBT" )
326 convert_to_rjbt=
true;
328 else if ( y_unit ==
"1" )
335 os <<
"Invalid value for *y_unit*:" << y_unit <<
".\n"
336 <<
"This method allows only the options \"RJBT\" and \"1\".";
337 throw runtime_error( os.str() );
344 mc_iteration_count+=1;
349 local_rte_pos=sensor_pos(0,
joker);
356 evol_op, abs_vec_mono, temperature, ext_mat_mono,
357 rng, local_rte_pos, local_rte_los, pnd_vec, g,ppath_step,
358 termination_flag, inside_cloud, opt_prop_gas_agenda,
359 abs_scalar_gas_agenda, stokes_dim, f_index, p_grid,
360 lat_grid, lon_grid, z_field, r_geoid, z_surface,
361 t_field, vmr_field, cloudbox_limits, pnd_field,
362 scat_data_mono, verbosity);
365 mc_points(ppath_step.gp_p[np-1].idx,ppath_step.gp_lat[np-1].idx,
366 ppath_step.gp_lon[np-1].idx)+=1;
377 out2 <<
"Warning: g=0. Very thick cloud near surface? Results still reliable or not?\n";
381 else if (termination_flag==1)
385 mult(vector1,evol_op,local_iy(f_index,
joker));
390 else if (termination_flag==2)
394 local_surface_los, local_surface_rmatrix,
395 local_rte_pos, local_rte_los, ppath_step.gp_p[np-1],
396 ppath_step.gp_lat[np-1],ppath_step.gp_lon[np-1],
397 surface_prop_agenda );
399 if( local_surface_los.
nrows() > 1 )
402 "The method handles only specular reflections." );
406 if (local_surface_los.
nrows()==0)
408 mult(vector1,evol_op,local_surface_emission(f_index,
joker));
416 Numeric R11=local_surface_rmatrix(0,f_index,0,0);
425 mult(vector1,evol_op,local_surface_emission(f_index,
joker));
433 local_rte_los=local_surface_los(0,
joker);
442 else if (inside_cloud)
446 albedo=1-abs_vec_mono[0]/ext_mat_mono(0,0);
449 if (rng.
draw()>albedo)
452 Numeric planck_value =
planck( f_grid[f_index], temperature );
453 Vector emission=abs_vec_mono;
454 emission*=planck_value;
455 Vector emissioncontri(stokes_dim);
456 mult(emissioncontri,evol_op,emission);
457 emissioncontri/=(g*(1-albedo));
458 mult(I_i,Q,emissioncontri);
467 Sample_los (new_rte_los,g_los_csc_theta,Z,rng,local_rte_los,
468 scat_data_mono,stokes_dim,
469 pnd_vec,anyptype30,Z11maxvector,ext_mat_mono(0,0)-abs_vec_mono[0],temperature,
472 Z/=g*g_los_csc_theta*albedo;
478 local_rte_los=new_rte_los;
487 Numeric planck_value =
planck( f_grid[f_index], temperature );
488 Vector emission=abs_vec_mono;
489 emission*=planck_value;
490 Vector emissioncontri(stokes_dim);
491 mult(emissioncontri,evol_op,emission);
493 mult(I_i,Q,emissioncontri);
499 for(
Index j=0; j<stokes_dim; j++)
501 assert(!isnan(I_i[j]));
502 Isquaredsum[j] += I_i[j]*I_i[j];
505 y/=(
Numeric)mc_iteration_count;
506 for(
Index j=0; j<stokes_dim; j++)
508 mc_error[j]=sqrt((Isquaredsum[j]/(
Numeric)mc_iteration_count-y[j]*y[j])/(
Numeric)mc_iteration_count);
510 if (std_err>0 && mc_iteration_count>=100 && mc_error[0]<std_err_i){
break;}
511 if (max_time>0 && (
Index)(time(NULL)-start_time)>=max_time){
break;}
512 if (max_iter>0 && mc_iteration_count>=max_iter){
break;}
514 if ( convert_to_rjbt )
516 for(
Index j=0; j<stokes_dim; j++)
519 mc_error[j]=
invrayjean(mc_error[j],f_grid[f_index]);
528 Index& mc_iteration_count,
533 const Index& f_index,
536 const Index& stokes_dim,
537 const Index& atmosphere_dim,
538 const Agenda& iy_space_agenda,
539 const Agenda& surface_prop_agenda,
540 const Agenda& opt_prop_gas_agenda,
541 const Agenda& abs_scalar_gas_agenda,
542 const Agenda& ppath_step_agenda,
554 const Index& mc_seed,
558 const Index& max_time,
559 const Index& max_iter,
560 const Index& z_field_is_1D,
564 if (max_time<0 && max_iter<0 && std_err<0){
565 throw runtime_error(
"At least one of std_err, max_time, and max_iter must be positive" );
568 if (! (atmosphere_dim == 3))
571 "For montecarlo, atmosphere_dim must be 3.");
576 time_t start_time=time(NULL);
585 rng.
seed(mc_seed, verbosity);
586 bool keepgoing,inside_cloud;
587 Numeric g,temperature,albedo,g_los_csc_theta;
588 Matrix A(stokes_dim,stokes_dim),Q(stokes_dim,stokes_dim),evol_op(stokes_dim,stokes_dim),
589 ext_mat_mono(stokes_dim,stokes_dim),
q(stokes_dim,stokes_dim),newQ(stokes_dim,stokes_dim),
590 Z(stokes_dim,stokes_dim);
592 mc_iteration_count=0;
593 Vector vector1(stokes_dim),abs_vec_mono(stokes_dim),I_i(stokes_dim),Isum(stokes_dim),
594 Isquaredsum(stokes_dim);
597 Index termination_flag=0;
598 mc_error.
resize(stokes_dim);
600 Matrix local_iy(1,stokes_dim),local_surface_emission(1,stokes_dim),local_surface_los;
608 Isum=0.0;Isquaredsum=0.0;
610 bool convert_to_rjbt=
false;
611 if ( y_unit ==
"RJBT" )
615 convert_to_rjbt=
true;
617 else if ( y_unit ==
"1" )
624 os <<
"Invalid value for *y_unit*:" << y_unit <<
".\n"
625 <<
"This method allows only the options \"RJBT\" and \"1\".";
626 throw runtime_error( os.str() );
632 mc_iteration_count+=1;
637 local_rte_pos=sensor_pos(0,
joker);
644 p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
645 0, cloudbox_limits, local_rte_pos, local_rte_los, 1,
652 evol_op, abs_vec_mono, temperature, ext_mat_mono, rng,
653 local_rte_pos, local_rte_los, pnd_vec, g,
654 termination_flag, inside_cloud,
655 opt_prop_gas_agenda,abs_scalar_gas_agenda,
656 stokes_dim, f_index, p_grid,
657 lat_grid, lon_grid, z_field, r_geoid, z_surface,
658 t_field, vmr_field, cloudbox_limits, pnd_field,
659 scat_data_mono, z_field_is_1D, ppath,
663 mc_points(ppath.
gp_p[np-1].idx,ppath.
gp_lat[np-1].idx,
664 ppath.
gp_lon[np-1].idx)+=1;
665 if (termination_flag==1)
674 else if (termination_flag==2)
693 local_surface_emission, local_surface_los,
694 local_surface_rmatrix, local_rte_pos, local_rte_los,
695 ppath.
gp_p[np-1],latgp,longp, surface_prop_agenda);
697 if (local_surface_los.
nrows()==0)
699 mult(vector1,evol_op,local_surface_emission(0,
joker));
707 Numeric R11=local_surface_rmatrix(0,0,0,0);
716 mult(vector1,evol_op,local_surface_emission(0,
joker));
724 local_rte_los=local_surface_los(0,
joker);
733 else if (inside_cloud)
737 albedo=1-abs_vec_mono[0]/ext_mat_mono(0,0);
740 if (rng.
draw()>albedo)
744 Vector emission=abs_vec_mono;
745 emission*=planck_value;
746 Vector emissioncontri(stokes_dim);
747 mult(emissioncontri,evol_op,emission);
748 emissioncontri/=(g*(1-albedo));
749 mult(I_i,Q,emissioncontri);
758 Sample_los (new_rte_los,g_los_csc_theta,Z,rng,local_rte_los,
759 scat_data_mono,stokes_dim,
760 pnd_vec,anyptype30,Z11maxvector,ext_mat_mono(0,0)-abs_vec_mono[0],temperature,
763 Z/=g*g_los_csc_theta*albedo;
769 local_rte_los=new_rte_los;
779 Vector emission=abs_vec_mono;
780 emission*=planck_value;
781 Vector emissioncontri(stokes_dim);
782 mult(emissioncontri,evol_op,emission);
784 mult(I_i,Q,emissioncontri);
790 for(
Index j=0; j<stokes_dim; j++)
792 assert(!isnan(I_i[j]));
793 Isquaredsum[j] += I_i[j]*I_i[j];
796 y/=(
Numeric)mc_iteration_count;
797 for(
Index j=0; j<stokes_dim; j++)
799 mc_error[j]=sqrt((Isquaredsum[j]/(
Numeric)mc_iteration_count-y[j]*y[j])/(
Numeric)mc_iteration_count);
801 if (std_err>0 && mc_iteration_count>=100 && mc_error[0]<std_err_i){
break;}
802 if (max_time>0 && (
Index)(time(NULL)-start_time)>=max_time){
break;}
803 if (max_iter>0 && mc_iteration_count>=max_iter){
break;}
805 if ( convert_to_rjbt )
807 for(
Index j=0; j<stokes_dim; j++)
810 mc_error[j]=
invrayjean(mc_error[j],f_grid[0]);
820 mc_seed=(
Index)time(NULL);
827 const Index& f_index,
828 const Index& stokes_dim,
830 const Numeric& rte_temperature,
837 if( scat_data_raw.
nelem() > 1 )
838 throw runtime_error(
"Only one element in *scat_data_raw* is allowed." );
845 pha_mat.
resize( stokes_dim, stokes_dim );
848 scat_data, stokes_dim, pnd, rte_temperature,