00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00035
00036
00037
00038
00039 #include "messages.h"
00040 #include "arts.h"
00041 #include "ppath.h"
00042 #include "matpackI.h"
00043 #include "special_interp.h"
00044 #include "check_input.h"
00045 #include <stdexcept>
00046 #include <cmath>
00047 #include "rte.h"
00048 #include "lin_alg.h"
00049 #include "auto_md.h"
00050 #include "logic.h"
00051 #include "physics_funcs.h"
00052 #include "xml_io.h"
00053 #include "montecarlo.h"
00054 #include "rng.h"
00055 #include <ctime>
00056 #include <fstream>
00057 #include "mc_interp.h"
00058 #include "math_funcs.h"
00059
00060 extern const Numeric DEG2RAD;
00061 extern const Numeric RAD2DEG;
00062 extern const Numeric PI;
00063 extern const Numeric BOLTZMAN_CONST;
00064 extern const Numeric SPEED_OF_LIGHT;
00065
00066
00067
00068
00069
00070
00071
00072
00073 void mc_IWP_cloud_opt_pathCalc(
00074 Workspace& ws,
00075
00076 Numeric& mc_IWP,
00077 Numeric& mc_cloud_opt_path,
00078 Numeric& mc_IWP_error,
00079 Numeric& mc_cloud_opt_path_error,
00080 Index& mc_iteration_count,
00081
00082 const MCAntenna& mc_antenna,
00083 const Matrix& sensor_pos,
00084 const Matrix& sensor_los,
00085 const Agenda& ppath_step_agenda,
00086 const Vector& p_grid,
00087 const Vector& lat_grid,
00088 const Vector& lon_grid,
00089 const Matrix& r_geoid,
00090 const Matrix& z_surface,
00091 const Tensor3& z_field,
00092 const Tensor3& t_field,
00093 const Tensor4& vmr_field,
00094 const ArrayOfIndex& cloudbox_limits,
00095 const Tensor4& pnd_field,
00096 const ArrayOfSingleScatteringData& scat_data_mono,
00097 const Vector& particle_masses,
00098 const Index& mc_seed,
00099
00100 const Index& max_iter
00101 )
00102 {
00103
00104
00105 if (mc_antenna.get_type()==ATYPE_PENCIL_BEAM)
00106 {
00107 iwp_cloud_opt_pathCalc(ws, mc_IWP,mc_cloud_opt_path,sensor_pos(0,joker),
00108 sensor_los(0,joker),
00109 ppath_step_agenda,p_grid,lat_grid,lon_grid,
00110 r_geoid,z_surface,z_field,t_field,vmr_field,cloudbox_limits,
00111 pnd_field,scat_data_mono,particle_masses);
00112 }
00113 else
00114 {
00115 Numeric iwp,cloud_opt_path;
00116 Numeric iwp_squared=0;
00117 Numeric tau_squared=0;
00118 mc_iteration_count=0;
00119 mc_IWP=0;
00120 mc_cloud_opt_path=0;
00121 Vector local_rte_los(2);
00122 Rng rng;
00123 rng.seed(mc_seed);
00124
00125 while (mc_iteration_count<max_iter)
00126 {
00127 mc_antenna.draw_los(local_rte_los,rng,sensor_los(0,joker));
00128 mc_iteration_count+=1;
00129 iwp_cloud_opt_pathCalc(ws, iwp,cloud_opt_path,sensor_pos(0,joker),
00130 local_rte_los,
00131 ppath_step_agenda,p_grid,lat_grid,lon_grid,
00132 r_geoid,z_surface,z_field,t_field,vmr_field,
00133 cloudbox_limits,
00134 pnd_field,scat_data_mono,particle_masses);
00135 mc_IWP+=iwp;
00136 iwp_squared+=iwp*iwp;
00137 mc_cloud_opt_path+=cloud_opt_path;
00138 tau_squared+=cloud_opt_path*cloud_opt_path;
00139 }
00140 mc_IWP/=(Numeric)mc_iteration_count;
00141 mc_cloud_opt_path/=(Numeric)mc_iteration_count;
00142 mc_IWP_error=sqrt((iwp_squared/(Numeric)mc_iteration_count-mc_IWP*mc_IWP)
00143 /(Numeric)mc_iteration_count);
00144 mc_cloud_opt_path_error=sqrt((tau_squared/(Numeric)mc_iteration_count-
00145 mc_cloud_opt_path*mc_cloud_opt_path)
00146 /(Numeric)mc_iteration_count);
00147
00148 }
00149
00150 }
00151
00152
00153
00154 void mc_antennaSetGaussian(
00155 MCAntenna& mc_antenna,
00156
00157 const Numeric& za_sigma,
00158 const Numeric& aa_sigma
00159 )
00160 {
00161 mc_antenna.set_gaussian(za_sigma,aa_sigma);
00162 }
00163
00164
00165
00166 void mc_antennaSetGaussianByFWHM(
00167 MCAntenna& mc_antenna,
00168
00169 const Numeric& za_fwhm,
00170 const Numeric& aa_fwhm
00171 )
00172 {
00173 mc_antenna.set_gaussian_fwhm(za_fwhm,aa_fwhm);
00174 }
00175
00176
00177
00178 void mc_antennaSetPencilBeam(
00179 MCAntenna& mc_antenna
00180 )
00181 {
00182 mc_antenna.set_pencil_beam();
00183 }
00184
00185
00186
00187 void MCGeneral(Workspace& ws,
00188 Vector& y,
00189 Index& mc_iteration_count,
00190 Vector& mc_error,
00191 Tensor3& mc_points,
00192 const MCAntenna& mc_antenna,
00193 const Vector& f_grid,
00194 const Index& f_index,
00195 const Matrix& sensor_pos,
00196 const Matrix& sensor_los,
00197 const Index& stokes_dim,
00198 const Agenda& iy_space_agenda,
00199 const Agenda& surface_prop_agenda,
00200 const Agenda& opt_prop_gas_agenda,
00201 const Agenda& abs_scalar_gas_agenda,
00202 const Vector& p_grid,
00203 const Vector& lat_grid,
00204 const Vector& lon_grid,
00205 const Tensor3& z_field,
00206 const Matrix& r_geoid,
00207 const Matrix& z_surface,
00208 const Tensor3& t_field,
00209 const Tensor4& vmr_field,
00210 const ArrayOfIndex& cloudbox_limits,
00211 const Tensor4& pnd_field,
00212 const ArrayOfSingleScatteringData& scat_data_mono,
00213 const Index& mc_seed,
00214 const String& y_unit,
00215 const Numeric& std_err,
00216 const Index& max_time,
00217 const Index& max_iter,
00218 const Index& z_field_is_1D
00219 )
00220 {
00221
00222 if (max_time<0 && max_iter<0 && std_err<0){
00223 throw runtime_error( "At least one of std_err, max_time, and max_iter must be positive" );
00224 }
00225 Ppath ppath_step;
00226 Rng rng;
00227 time_t start_time=time(NULL);
00228 Index N_pt=pnd_field.nbooks();
00229 Vector pnd_vec(N_pt);
00230 Vector Z11maxvector;
00231 bool anyptype30=is_anyptype30(scat_data_mono);
00232 if (anyptype30)
00233 {
00234 findZ11max(Z11maxvector,scat_data_mono);
00235 }
00236 rng.seed(mc_seed);
00237 bool keepgoing,inside_cloud;
00238 Numeric g,temperature,albedo,g_los_csc_theta;
00239 Matrix A(stokes_dim,stokes_dim),Q(stokes_dim,stokes_dim),evol_op(stokes_dim,stokes_dim),
00240
00241 ext_mat_mono(stokes_dim,stokes_dim),q(stokes_dim,stokes_dim),newQ(stokes_dim,stokes_dim),
00242 Z(stokes_dim,stokes_dim);
00243 q=0.0;newQ=0.0;
00244 mc_iteration_count=0;
00245 Vector vector1(stokes_dim),abs_vec_mono(stokes_dim),I_i(stokes_dim),Isum(stokes_dim),
00246 Isquaredsum(stokes_dim);
00247 y.resize(stokes_dim);
00248 y=0;
00249 Index termination_flag=0;
00250 mc_error.resize(stokes_dim);
00251
00252 Matrix local_iy(1,stokes_dim),local_surface_emission(1,stokes_dim),local_surface_los;
00253 Tensor4 local_surface_rmatrix;
00254 Vector local_rte_pos(2);
00255 Vector local_rte_los(2);
00256 Vector new_rte_los(2);
00257 Index np;
00258 mc_points.resize(p_grid.nelem(),lat_grid.nelem(),lon_grid.nelem());
00259 mc_points=0;
00260 Isum=0.0;Isquaredsum=0.0;
00261 Numeric std_err_i;
00262 bool convert_to_rjbt=false;
00263 if ( y_unit == "RJBT" )
00264 {
00265 std_err_i=f_grid[0]*f_grid[0]*2*BOLTZMAN_CONST/SPEED_OF_LIGHT/SPEED_OF_LIGHT*
00266 std_err;
00267 convert_to_rjbt=true;
00268 }
00269 else if ( y_unit == "1" )
00270 {
00271 std_err_i=std_err;
00272 }
00273 else
00274 {
00275 ostringstream os;
00276 os << "Invalid value for *y_unit*:" << y_unit <<".\n"
00277 << "This method allows only the options \"RJBT\" and \"1\".";
00278 throw runtime_error( os.str() );
00279 }
00280
00281
00282
00283 while (true)
00284 {
00285 mc_iteration_count+=1;
00286 keepgoing=true;
00287
00288 mc_antenna.draw_los(local_rte_los,rng,sensor_los(0,joker));
00289 id_mat(Q);
00290 local_rte_pos=sensor_pos(0,joker);
00291 I_i=0.0;
00292
00293
00294 while (keepgoing)
00295 {
00296 mcPathTraceGeneral( ws,
00297 evol_op, abs_vec_mono, temperature, ext_mat_mono,
00298 rng, local_rte_pos, local_rte_los, pnd_vec, g,ppath_step,
00299 termination_flag, inside_cloud, opt_prop_gas_agenda,
00300 abs_scalar_gas_agenda, stokes_dim, f_index, p_grid,
00301 lat_grid, lon_grid, z_field, r_geoid, z_surface,
00302 t_field, vmr_field, cloudbox_limits, pnd_field,
00303 scat_data_mono, z_field_is_1D );
00304
00305 np=ppath_step.np;
00306 mc_points(ppath_step.gp_p[np-1].idx,ppath_step.gp_lat[np-1].idx,
00307 ppath_step.gp_lon[np-1].idx)+=1;
00308 if (termination_flag==1)
00309 {
00310 iy_space_agendaExecute(ws, local_iy,local_rte_pos,local_rte_los,
00311 iy_space_agenda);
00312 mult(vector1,evol_op,local_iy(0,joker));
00313 mult(I_i,Q,vector1);
00314 I_i/=g;
00315 keepgoing=false;
00316 }
00317 else if (termination_flag==2)
00318 {
00319
00320 surface_prop_agendaExecute( ws, local_surface_emission,
00321 local_surface_los, local_surface_rmatrix,
00322 local_rte_pos, local_rte_los, ppath_step.gp_p[np-1],
00323 ppath_step.gp_lat[np-1],ppath_step.gp_lon[np-1],
00324 surface_prop_agenda );
00325
00326 if (local_surface_los.nrows()==0)
00327 {
00328 mult(vector1,evol_op,local_surface_emission(0,joker));
00329 mult(I_i,Q,vector1);
00330 I_i/=g;
00331 keepgoing=false;
00332 }
00333 else
00334
00335 {
00336 Numeric R11=local_surface_rmatrix(0,0,0,0);
00337 if (rng.draw()>R11)
00338 {
00339
00340
00341
00342
00343
00344
00345 mult(vector1,evol_op,local_surface_emission(0,joker));
00346 mult(I_i,Q,vector1);
00347 I_i/=g*(1-R11);
00348 keepgoing=false;
00349 }
00350 else
00351 {
00352
00353 local_rte_los=local_surface_los(0,joker);
00354
00355 mult(q,evol_op,local_surface_rmatrix(0,0,joker,joker));
00356 mult(newQ,Q,q);
00357 Q=newQ;
00358 Q/=g*R11;
00359 }
00360 }
00361 }
00362 else if (inside_cloud)
00363 {
00364
00365
00366 albedo=1-abs_vec_mono[0]/ext_mat_mono(0,0);
00367
00368
00369 if (rng.draw()>albedo)
00370 {
00371
00372 Numeric planck_value = planck( f_grid[0], temperature );
00373 Vector emission=abs_vec_mono;
00374 emission*=planck_value;
00375 Vector emissioncontri(stokes_dim);
00376 mult(emissioncontri,evol_op,emission);
00377 emissioncontri/=(g*(1-albedo));
00378 mult(I_i,Q,emissioncontri);
00379 keepgoing=false;
00380
00381 }
00382 else
00383 {
00384
00385
00386
00387 Sample_los (new_rte_los,g_los_csc_theta,Z,rng,local_rte_los,
00388 scat_data_mono,stokes_dim,
00389 pnd_vec,anyptype30,Z11maxvector,ext_mat_mono(0,0)-abs_vec_mono[0],temperature);
00390
00391 Z/=g*g_los_csc_theta*albedo;
00392
00393 mult(q,evol_op,Z);
00394 mult(newQ,Q,q);
00395 Q=newQ;
00396
00397 local_rte_los=new_rte_los;
00398
00399
00400 }
00401 }
00402 else
00403 {
00404
00405
00406 Numeric planck_value = planck( f_grid[0], temperature );
00407 Vector emission=abs_vec_mono;
00408 emission*=planck_value;
00409 Vector emissioncontri(stokes_dim);
00410 mult(emissioncontri,evol_op,emission);
00411 emissioncontri/=g;
00412 mult(I_i,Q,emissioncontri);
00413 keepgoing=false;
00414
00415 }
00416 }
00417 Isum += I_i;
00418 for(Index j=0; j<stokes_dim; j++)
00419 {
00420 assert(!isnan(I_i[j]));
00421 Isquaredsum[j] += I_i[j]*I_i[j];
00422 }
00423 y=Isum;
00424 y/=(Numeric)mc_iteration_count;
00425 for(Index j=0; j<stokes_dim; j++)
00426 {
00427 mc_error[j]=sqrt((Isquaredsum[j]/(Numeric)mc_iteration_count-y[j]*y[j])/(Numeric)mc_iteration_count);
00428 }
00429 if (std_err>0 && mc_iteration_count>=100 && mc_error[0]<std_err_i){break;}
00430 if (max_time>0 && (Index)(time(NULL)-start_time)>=max_time){break;}
00431 if (max_iter>0 && mc_iteration_count>=max_iter){break;}
00432 }
00433 if ( convert_to_rjbt )
00434 {
00435 for(Index j=0; j<stokes_dim; j++)
00436 {
00437 y[j]=invrayjean(y[j],f_grid[0]);
00438 mc_error[j]=invrayjean(mc_error[j],f_grid[0]);
00439 }
00440 }
00441 }
00442
00443
00444
00445 void MCIPA(Workspace& ws,
00446 Vector& y,
00447 Index& mc_iteration_count,
00448 Vector& mc_error,
00449 Tensor3& mc_points,
00450 const MCAntenna& mc_antenna,
00451 const Vector& f_grid,
00452 const Index& f_index,
00453 const Matrix& sensor_pos,
00454 const Matrix& sensor_los,
00455 const Index& stokes_dim,
00456 const Agenda& iy_space_agenda,
00457 const Agenda& surface_prop_agenda,
00458 const Agenda& opt_prop_gas_agenda,
00459 const Agenda& abs_scalar_gas_agenda,
00460 const Agenda& ppath_step_agenda,
00461 const Vector& p_grid,
00462 const Vector& lat_grid,
00463 const Vector& lon_grid,
00464 const Tensor3& z_field,
00465 const Matrix& r_geoid,
00466 const Matrix& z_surface,
00467 const Tensor3& t_field,
00468 const Tensor4& vmr_field,
00469 const ArrayOfIndex& cloudbox_limits,
00470 const Tensor4& pnd_field,
00471 const ArrayOfSingleScatteringData& scat_data_mono,
00472 const Index& mc_seed,
00473 const String& y_unit,
00474
00475 const Numeric& std_err,
00476 const Index& max_time,
00477 const Index& max_iter,
00478 const Index& z_field_is_1D
00479 )
00480 {
00481
00482 if (max_time<0 && max_iter<0 && std_err<0){
00483 throw runtime_error( "At least one of std_err, max_time, and max_iter must be positive" );
00484 }
00485 Ppath ppath_step;
00486 Rng rng;
00487 time_t start_time=time(NULL);
00488 Index N_pt=pnd_field.nbooks();
00489 Vector pnd_vec(N_pt);
00490 Vector Z11maxvector;
00491 bool anyptype30=is_anyptype30(scat_data_mono);
00492 if (anyptype30)
00493 {
00494 findZ11max(Z11maxvector,scat_data_mono);
00495 }
00496 rng.seed(mc_seed);
00497 bool keepgoing,inside_cloud;
00498 Numeric g,temperature,albedo,g_los_csc_theta;
00499 Matrix A(stokes_dim,stokes_dim),Q(stokes_dim,stokes_dim),evol_op(stokes_dim,stokes_dim),
00500 ext_mat_mono(stokes_dim,stokes_dim),q(stokes_dim,stokes_dim),newQ(stokes_dim,stokes_dim),
00501 Z(stokes_dim,stokes_dim);
00502 q=0.0;newQ=0.0;
00503 mc_iteration_count=0;
00504 Vector vector1(stokes_dim),abs_vec_mono(stokes_dim),I_i(stokes_dim),Isum(stokes_dim),
00505 Isquaredsum(stokes_dim);
00506 y.resize(stokes_dim);
00507 y=0;
00508 Index termination_flag=0;
00509 mc_error.resize(stokes_dim);
00510
00511 Matrix local_iy(1,stokes_dim),local_surface_emission(1,stokes_dim),local_surface_los;
00512 Tensor4 local_surface_rmatrix;
00513 Vector local_rte_pos(2);
00514 Vector local_rte_los(2);
00515 Vector new_rte_los(2);
00516 Index np;
00517 mc_points.resize(p_grid.nelem(),lat_grid.nelem(),lon_grid.nelem());
00518 mc_points=0;
00519 Isum=0.0;Isquaredsum=0.0;
00520 Numeric std_err_i;
00521 bool convert_to_rjbt=false;
00522 if ( y_unit == "RJBT" )
00523 {
00524 std_err_i=f_grid[0]*f_grid[0]*2*BOLTZMAN_CONST/SPEED_OF_LIGHT/SPEED_OF_LIGHT*
00525 std_err;
00526 convert_to_rjbt=true;
00527 }
00528 else if ( y_unit == "1" )
00529 {
00530 std_err_i=std_err;
00531 }
00532 else
00533 {
00534 ostringstream os;
00535 os << "Invalid value for *y_unit*:" << y_unit <<".\n"
00536 << "This method allows only the options \"RJBT\" and \"1\".";
00537 throw runtime_error( os.str() );
00538 }
00539
00540
00541 while (true)
00542 {
00543 mc_iteration_count+=1;
00544 keepgoing=true;
00545
00546 mc_antenna.draw_los(local_rte_los,rng,sensor_los(0,joker));
00547 id_mat(Q);
00548 local_rte_pos=sensor_pos(0,joker);
00549 I_i=0.0;
00550
00551
00552
00553 Ppath ppath;
00554 ppath_calc( ws, ppath, ppath_step_agenda, 3,
00555 p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
00556 0, cloudbox_limits, local_rte_pos, local_rte_los, 1 );
00557
00558 while (keepgoing)
00559 {
00560
00561 mcPathTraceIPA( ws,
00562 evol_op, abs_vec_mono, temperature, ext_mat_mono, rng,
00563 local_rte_pos, local_rte_los, pnd_vec, g,
00564 termination_flag, inside_cloud,
00565 opt_prop_gas_agenda,abs_scalar_gas_agenda,
00566 stokes_dim, f_index, p_grid,
00567 lat_grid, lon_grid, z_field, r_geoid, z_surface,
00568 t_field, vmr_field, cloudbox_limits, pnd_field,
00569 scat_data_mono, z_field_is_1D, ppath );
00570
00571 np=ppath.np;
00572 mc_points(ppath.gp_p[np-1].idx,ppath.gp_lat[np-1].idx,
00573 ppath.gp_lon[np-1].idx)+=1;
00574 if (termination_flag==1)
00575 {
00576 iy_space_agendaExecute(ws, local_iy,local_rte_pos,local_rte_los,
00577 iy_space_agenda);
00578 mult(vector1,evol_op,local_iy(0,joker));
00579 mult(I_i,Q,vector1);
00580 I_i/=g;
00581 keepgoing=false;
00582 }
00583 else if (termination_flag==2)
00584 {
00585
00586
00587 GridPos latgp;
00588 GridPos longp;
00589 if (ppath.background=="surface")
00590 {
00591 latgp=ppath.gp_lat[ppath.np-1];
00592 longp=ppath.gp_lon[ppath.np-1];
00593 }
00594 else
00595 {
00596
00597 gridpos(latgp,lat_grid,ppath.geom_tan_pos[1]);
00598 gridpos(longp,lon_grid,ppath.geom_tan_pos[2]);
00599 }
00600
00601 surface_prop_agendaExecute(ws,
00602 local_surface_emission, local_surface_los,
00603 local_surface_rmatrix, local_rte_pos, local_rte_los,
00604 ppath.gp_p[np-1],latgp,longp, surface_prop_agenda);
00605
00606 if (local_surface_los.nrows()==0)
00607 {
00608 mult(vector1,evol_op,local_surface_emission(0,joker));
00609 mult(I_i,Q,vector1);
00610 I_i/=g;
00611 keepgoing=false;
00612 }
00613 else
00614
00615 {
00616 Numeric R11=local_surface_rmatrix(0,0,0,0);
00617 if (rng.draw()>R11)
00618 {
00619
00620
00621
00622
00623
00624
00625 mult(vector1,evol_op,local_surface_emission(0,joker));
00626 mult(I_i,Q,vector1);
00627 I_i/=g*(1-R11);
00628 keepgoing=false;
00629 }
00630 else
00631 {
00632
00633 local_rte_los=local_surface_los(0,joker);
00634
00635 mult(q,evol_op,local_surface_rmatrix(0,0,joker,joker));
00636 mult(newQ,Q,q);
00637 Q=newQ;
00638 Q/=g*R11;
00639 }
00640 }
00641 }
00642 else if (inside_cloud)
00643 {
00644
00645
00646 albedo=1-abs_vec_mono[0]/ext_mat_mono(0,0);
00647
00648
00649 if (rng.draw()>albedo)
00650 {
00651
00652 Numeric planck_value = planck( f_grid[0], temperature );
00653 Vector emission=abs_vec_mono;
00654 emission*=planck_value;
00655 Vector emissioncontri(stokes_dim);
00656 mult(emissioncontri,evol_op,emission);
00657 emissioncontri/=(g*(1-albedo));
00658 mult(I_i,Q,emissioncontri);
00659 keepgoing=false;
00660
00661 }
00662 else
00663 {
00664
00665
00666
00667 Sample_los (new_rte_los,g_los_csc_theta,Z,rng,local_rte_los,
00668 scat_data_mono,stokes_dim,
00669 pnd_vec,anyptype30,Z11maxvector,ext_mat_mono(0,0)-abs_vec_mono[0],temperature);
00670
00671 Z/=g*g_los_csc_theta*albedo;
00672
00673 mult(q,evol_op,Z);
00674 mult(newQ,Q,q);
00675 Q=newQ;
00676
00677 local_rte_los=new_rte_los;
00678
00679
00680 }
00681 }
00682 else
00683 {
00684
00685
00686 Numeric planck_value = planck( f_grid[0], temperature );
00687 Vector emission=abs_vec_mono;
00688 emission*=planck_value;
00689 Vector emissioncontri(stokes_dim);
00690 mult(emissioncontri,evol_op,emission);
00691 emissioncontri/=g;
00692 mult(I_i,Q,emissioncontri);
00693 keepgoing=false;
00694
00695 }
00696 }
00697 Isum += I_i;
00698 for(Index j=0; j<stokes_dim; j++)
00699 {
00700 assert(!isnan(I_i[j]));
00701 Isquaredsum[j] += I_i[j]*I_i[j];
00702 }
00703 y=Isum;
00704 y/=(Numeric)mc_iteration_count;
00705 for(Index j=0; j<stokes_dim; j++)
00706 {
00707 mc_error[j]=sqrt((Isquaredsum[j]/(Numeric)mc_iteration_count-y[j]*y[j])/(Numeric)mc_iteration_count);
00708 }
00709 if (std_err>0 && mc_iteration_count>=100 && mc_error[0]<std_err_i){break;}
00710 if (max_time>0 && (Index)(time(NULL)-start_time)>=max_time){break;}
00711 if (max_iter>0 && mc_iteration_count>=max_iter){break;}
00712 }
00713 if ( convert_to_rjbt )
00714 {
00715 for(Index j=0; j<stokes_dim; j++)
00716 {
00717 y[j]=invrayjean(y[j],f_grid[0]);
00718 mc_error[j]=invrayjean(mc_error[j],f_grid[0]);
00719 }
00720 }
00721 }
00722
00723
00724
00725 void MCSetIncomingEmpty(
00726 SLIData2& mc_incoming
00727 )
00728
00729 {
00730 mc_incoming.x1a.resize(0);
00731 mc_incoming.x2a.resize(0);
00732 mc_incoming.ya.resize(0);
00733 }
00734
00735
00736
00737 void MCSetSeedFromTime(
00738 Index& mc_seed
00739 )
00740 {
00741 mc_seed=(Index)time(NULL);
00742 }
00743
00744
00745
00746 void ScatteringMonteCarlo (Workspace& ws,
00747
00748 Ppath& ppath,
00749 Ppath& ppath_step,
00750
00751
00752
00753 Vector& mc_error,
00754 Index& mc_iteration_count,
00755 Vector& rte_pos,
00756 Vector& rte_los,
00757
00758 Matrix& iy,
00759 Numeric& rte_pressure,
00760 Numeric& rte_temperature,
00761 Vector& rte_vmr_list,
00762
00763 Tensor3& ext_mat,
00764 Matrix& abs_vec,
00765
00766 const Agenda& ppath_step_agenda,
00767 const Index& atmosphere_dim,
00768 const Vector& p_grid,
00769 const Vector& lat_grid,
00770 const Vector& lon_grid,
00771 const Tensor3& z_field,
00772 const Matrix& r_geoid,
00773 const Matrix& z_surface,
00774 const ArrayOfIndex& cloudbox_limits,
00775 const Index& stokes_dim,
00776
00777 const Agenda& rte_agenda,
00778 const Agenda& iy_space_agenda,
00779 const Agenda& surface_prop_agenda,
00780 const Tensor3& t_field,
00781 const Vector& f_grid,
00782
00783 const Agenda& opt_prop_gas_agenda,
00784 const Agenda& abs_scalar_gas_agenda,
00785 const Tensor4& vmr_field,
00786
00787 const ArrayOfSingleScatteringData& scat_data_mono,
00788 const Tensor4& pnd_field,
00789 const Index& mc_seed,
00790 const Index& f_index,
00791 const SLIData2& mc_incoming,
00792
00793 const Numeric& std_err,
00794 const Index& max_time,
00795 const Index& max_iter,
00796 const Index& incoming_lookup,
00797 const Index& z_field_is_1D
00798 )
00799
00800 {
00801
00802
00803
00804 const Index& record_ppathcloud=0;
00805 const Index& record_ppath=0;
00806 const Index& silent=1;
00807 const Index& record_histdata=0;
00808 const String& histdata_filename="";
00809
00810
00811 if (max_time<0 && max_iter<0 && std_err<0){
00812 throw runtime_error( "At least one of std_err, max_time, and max_iter must be positive" );
00813 }
00814
00815
00816
00817
00818
00819
00820
00821 Matrix identity(stokes_dim,stokes_dim,0.0);
00822 for (Index i=0; i<stokes_dim; i++){identity(i,i)=1.0;}
00823
00824 Matrix Q(stokes_dim,stokes_dim);
00825 Matrix evol_op(stokes_dim,stokes_dim);
00826 Matrix K(stokes_dim,stokes_dim);
00827 bool keepgoing;
00828 Index scattering_order;
00829 Vector new_rte_los(2);
00830 Ppath ppathLOS;
00831 Ppath ppathcloud;
00832 Numeric g;
00833 Numeric pathlength;
00834 ArrayOfMatrix TArrayLOS;
00835
00836 ArrayOfMatrix TArray;
00837
00838 ArrayOfMatrix ext_matArray;
00839
00840 ArrayOfMatrix ext_matArrayLOS;
00841
00842 ArrayOfVector abs_vecArray;
00843
00844 ArrayOfVector abs_vecArrayLOS;
00845
00846 Vector Isum(stokes_dim,0.0);
00847 Vector Isquaredsum(stokes_dim,0.0);
00848 Vector Iboundary(stokes_dim,0.0);
00849 Vector IboundaryLOScontri(stokes_dim,0.0);
00850 Matrix Z(stokes_dim,stokes_dim,0.0);
00851 Matrix q(stokes_dim,stokes_dim,0.0);
00852 Matrix newQ(stokes_dim,stokes_dim,0.0);
00853 Vector cum_l_step;
00854 Vector cum_l_stepLOS;
00855 Vector t_ppath;
00856 Vector t_ppathLOS;
00857 Matrix pnd_ppath;
00858 Matrix pnd_ppathLOS;
00859 ArrayOfGridPos pathlength_gp(1);
00860
00861 Vector K_abs(stokes_dim);
00862 Vector I(stokes_dim);
00863 mc_error.resize(stokes_dim);
00864 Rng rng;
00865 Vector I_i(stokes_dim);
00866 Vector boundarycontri(stokes_dim);
00867 Numeric g_los_csc_theta;
00868 Numeric albedo;
00869 Index N_pt=pnd_field.nbooks();
00870 Vector pnd_vec(N_pt);
00871 time_t start_time=time(NULL);
00872 Vector Z11maxvector;
00873
00874 bool left_cloudbox;
00876
00877
00878 Numeric transmittance= exp(-opt_depth_calc(ws, ext_mat, abs_vec, rte_pressure, rte_temperature,
00879 rte_vmr_list, ppath, opt_prop_gas_agenda,
00880 abs_scalar_gas_agenda, f_index, p_grid,
00881 lat_grid, lon_grid, t_field, vmr_field,
00882 atmosphere_dim));
00883 Numeric std_err_i=f_grid[0]*f_grid[0]*2*BOLTZMAN_CONST/SPEED_OF_LIGHT/SPEED_OF_LIGHT*
00884 std_err/transmittance;
00885
00886 bool anyptype30=is_anyptype30(scat_data_mono);
00887 if (anyptype30)
00888 {
00889 findZ11max(Z11maxvector,scat_data_mono);
00890 }
00891
00892 ofstream histfile;
00893 if (record_histdata==1)
00894 {
00895 const char* p = histdata_filename.c_str();
00896 histfile.open(p,ios::out);
00897 }
00898
00899
00900 rng.seed(mc_seed);
00901 Agenda iy_cloudbox_agenda;
00902 Cloudbox_ppath_rteCalc(ws, ppathLOS, ppath, ppath_step,
00903
00904 rte_pos, rte_los,
00905 cum_l_stepLOS, TArrayLOS, ext_matArrayLOS,
00906 abs_vecArrayLOS,t_ppathLOS, ext_mat, abs_vec, rte_pressure,
00907 rte_temperature, rte_vmr_list, iy, pnd_ppathLOS,
00908 ppath_step_agenda, atmosphere_dim,
00909 p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
00910 cloudbox_limits, record_ppathcloud, record_ppath,
00911 opt_prop_gas_agenda,
00912 abs_scalar_gas_agenda, f_index,
00913 stokes_dim, t_field, vmr_field, rte_agenda,
00914 iy_space_agenda,
00915 surface_prop_agenda, iy_cloudbox_agenda,f_grid, 0, 0,
00916 pnd_field,scat_data_mono, z_field_is_1D );
00917
00918 mult(IboundaryLOScontri,TArrayLOS[TArrayLOS.nelem()-1],iy(0,joker));
00919
00920
00921
00922
00923
00924 for (Index i = 0;i<stokes_dim;i++){assert(!isnan(IboundaryLOScontri[i]));}
00925
00926 mc_iteration_count=0;
00927
00928 while (true)
00929 {
00930 mc_iteration_count+=1;
00931 left_cloudbox=false;
00932 keepgoing=true;
00933 scattering_order=0;
00934 Q=identity;
00935 I_i=0.0;
00936 boundarycontri=0.0;
00937
00938
00939 TArray=TArrayLOS;
00940 ext_matArray=ext_matArrayLOS;
00941 abs_vecArray=abs_vecArrayLOS;
00942 ppathcloud=ppathLOS;
00943 cum_l_step=cum_l_stepLOS;
00944 t_ppath=t_ppathLOS;
00945 pnd_ppath=pnd_ppathLOS;
00946
00947 if (silent==0){cout<<"mc_iteration_count = "<<mc_iteration_count<<"\n";}
00948 while (keepgoing)
00949 {
00950 if (scattering_order>0)
00951 {
00952 mcPathTrace(ws, evol_op, K_abs, rte_temperature, K, rng, rte_pos,
00953 rte_los, pnd_vec, g,left_cloudbox, opt_prop_gas_agenda,
00954 abs_scalar_gas_agenda, stokes_dim, f_index, p_grid,
00955 lat_grid, lon_grid, z_field, r_geoid, z_surface,
00956 t_field, vmr_field, cloudbox_limits, pnd_field,
00957 scat_data_mono,z_field_is_1D);
00958 }
00959 else
00960 {
00961 Sample_ppathlengthLOS (pathlength,g,rng,TArray,cum_l_step);
00962
00963 interpTArray(evol_op, K_abs, rte_temperature, K, rte_pos, rte_los,
00964 pnd_vec, TArray, ext_matArray,
00965 abs_vecArray, t_ppath, pnd_ppath, cum_l_step,
00966 pathlength, stokes_dim, ppathcloud);
00967 }
00968 assert(cum_l_step.nelem()==ppathcloud.np);
00969 assert(TArray.nelem()==ppathcloud.np);
00970 if ( left_cloudbox )
00971
00972 {
00973
00974 if ( incoming_lookup )
00975 {
00976 Iboundary=0;
00977
00978 Iboundary[0]=mc_incoming.interpolate(rte_pos[0],rte_los[0]);
00979 }
00980 else
00981 {
00982 montecarloGetIncoming(ws, iy,rte_pos,rte_los,ppath,
00983
00984 ppath_step_agenda,
00985 rte_agenda,iy_space_agenda,surface_prop_agenda,
00986 iy_cloudbox_agenda,
00987 p_grid,lat_grid,lon_grid,z_field,
00988 t_field, vmr_field, r_geoid,
00989 z_surface,cloudbox_limits, atmosphere_dim,
00990 f_grid,stokes_dim);
00991
00992 Iboundary=iy(0,joker);
00993 }
00995 mult(boundarycontri,evol_op,Iboundary);
00996 mult(I_i,Q,boundarycontri);
00997 I_i/=g;
00998
00999 keepgoing=false;
01000 }
01001 else
01002 {
01003
01004
01005 albedo=1-K_abs[0]/K(0,0);
01006
01007
01008 if (rng.draw()>albedo)
01009 {
01010
01011 Numeric planck_value = planck( f_grid[f_index], rte_temperature );
01012 Vector emission=K_abs;
01013 emission*=planck_value;
01014 Vector emissioncontri(stokes_dim);
01015 mult(emissioncontri,evol_op,emission);
01016 emissioncontri/=(g*(1-albedo));
01017 mult(I_i,Q,emissioncontri);
01018 keepgoing=false;
01019
01020 }
01021 else
01022 {
01023
01024
01025 Sample_los (new_rte_los,g_los_csc_theta,Z,rng,rte_los,
01026 scat_data_mono,stokes_dim,
01027 pnd_vec,anyptype30,Z11maxvector,K(0,0)-K_abs[0],rte_temperature);
01028
01029 Z/=g*g_los_csc_theta*albedo;
01030
01031 mult(q,evol_op,Z);
01032 mult(newQ,Q,q);
01033 Q=newQ;
01034 scattering_order+=1;
01035 rte_los=new_rte_los;
01036 if (silent==0){cout <<"mc_iteration_count = "<<mc_iteration_count <<
01037 ", scattering_order = " <<scattering_order <<"\n";}
01038 }
01039
01040 }
01041
01042 }
01043 Isum += I_i;
01044 if (record_histdata==1){histfile << I_i << "\n";}
01045 for(Index j=0; j<stokes_dim; j++)
01046 {
01047 assert(!isnan(I_i[j]));
01048 Isquaredsum[j] += I_i[j]*I_i[j];
01049 }
01050 I=Isum;
01051 I/=(Numeric)mc_iteration_count;
01052 for(Index j=0; j<stokes_dim; j++)
01053 {
01054 mc_error[j]=sqrt((Isquaredsum[j]/(Numeric)mc_iteration_count-I[j]*I[j])/(Numeric)mc_iteration_count);
01055 }
01056 if (std_err>0 && mc_iteration_count>=100 && mc_error[0]<std_err_i){break;}
01057 if (max_time>0 && (Index)(time(NULL)-start_time)>=max_time){break;}
01058 if (max_iter>0 && mc_iteration_count>=max_iter){break;}
01059 }
01060
01061 I+=IboundaryLOScontri;
01062 iy(0,joker)=I;
01063 mc_error*=transmittance;
01064 }
01065
01066
01067
01068 void rte_posShift(
01069 Vector& rte_pos,
01070 Vector& rte_los,
01071 GridPos& rte_gp_p,
01072 GridPos& rte_gp_lat,
01073 GridPos& rte_gp_lon,
01074 const Ppath& ppath,
01075 const Index& atmosphere_dim)
01076 {
01077 const Index np = ppath.np;
01078
01079 rte_pos.resize( atmosphere_dim );
01080 rte_pos = ppath.pos(np-1,Range(0,atmosphere_dim));
01081 rte_los.resize( ppath.los.ncols() );
01082 rte_los = ppath.los(np-1,joker);
01083 gridpos_copy( rte_gp_p, ppath.gp_p[np-1] );
01084 if( atmosphere_dim > 1 )
01085 { gridpos_copy( rte_gp_lat, ppath.gp_lat[np-1] ); }
01086 if( atmosphere_dim > 2 )
01087 { gridpos_copy( rte_gp_lon, ppath.gp_lon[np-1] ); }
01088 }
01089