105 Index& mc_iteration_count,
110 const Index& f_index,
113 const Index& stokes_dim,
114 const Index& atmosphere_dim,
115 const Agenda& ppath_step_agenda,
116 const Numeric& ppath_lraytrace,
117 const Agenda& iy_space_agenda,
118 const Agenda& surface_rtprop_agenda,
119 const Agenda& propmat_clearsky_agenda,
124 const Vector& refellipsoid,
128 const Index& cloudbox_on,
132 const Index& atmfields_checked,
133 const Index& atmgeom_checked,
134 const Index& cloudbox_checked,
135 const Index& mc_seed,
138 const Index& max_time,
139 const Index& max_iter,
140 const Index& min_iter,
146 if( atmfields_checked != 1 )
147 throw runtime_error(
"The atmospheric fields must be flagged to have "
148 "passed a consistency check (atmfields_checked=1)." );
149 if( atmgeom_checked != 1 )
150 throw runtime_error(
"The atmospheric geometry must be flagged to have "
151 "passed a consistency check (atmgeom_checked=1)." );
152 if( cloudbox_checked != 1 )
153 throw runtime_error(
"The cloudbox must be flagged to have "
154 "passed a consistency check (cloudbox_checked=1)." );
156 throw runtime_error(
"The cloudbox must be activated (cloudbox_on=1)." );
159 throw runtime_error(
"*mc_min_iter* must be >= 100." );
161 if( max_time < 0 && max_iter < 0 && std_err < 0 )
162 throw runtime_error(
"At least one of std_err, max_time, and max_iter "
163 "must be positive." );
166 throw runtime_error(
"The option of f_index < 0 is not handled by this "
168 if( f_index >= f_grid.
nelem() )
169 throw runtime_error(
"*f_index* is outside the range of *f_grid*." );
171 if( atmosphere_dim != 3 )
172 throw runtime_error(
"Only 3D atmospheres are handled. " );
174 if( sensor_pos.
ncols() != 3 )
177 os <<
"Expected number of columns in sensor_pos: 3.\n";
178 os <<
"Found: " << sensor_pos.
ncols();
179 throw runtime_error(os.str());
182 if (! (sensor_los.
ncols() == 2))
185 os <<
"Expected number of columns in sensor_los: 2.\n";
186 os <<
"Found: " << sensor_los.
ncols();
187 throw runtime_error(os.str());
192 time_t start_time=time(NULL);
198 {
findZ11max(Z11maxvector,scat_data_array_mono); }
199 rng.
seed(mc_seed, verbosity);
200 Numeric g,temperature,albedo,g_los_csc_theta;
201 Matrix A(stokes_dim,stokes_dim), Q(stokes_dim,stokes_dim);
202 Matrix evol_op(stokes_dim,stokes_dim), ext_mat_mono(stokes_dim,stokes_dim);
203 Matrix q(stokes_dim,stokes_dim), newQ(stokes_dim,stokes_dim);
204 Matrix Z(stokes_dim,stokes_dim);
207 Vector vector1(stokes_dim), abs_vec_mono(stokes_dim), I_i(stokes_dim);
208 Vector Isum(stokes_dim), Isquaredsum(stokes_dim);
209 Index termination_flag = 0;
210 const Numeric f_mono = f_grid[f_index];
217 mc_iteration_count = 0;
218 mc_error.
resize(stokes_dim);
223 Matrix local_iy(1,stokes_dim), local_surface_emission(1,stokes_dim);
230 Isum=0.0;Isquaredsum=0.0;
232 bool convert_to_rjbt =
false;
233 if ( y_unit ==
"RJBT" )
237 convert_to_rjbt =
true;
239 else if ( y_unit ==
"1" )
240 { std_err_i = std_err; }
244 os <<
"Invalid value for *y_unit*:" << y_unit <<
".\n"
245 <<
"This method allows only the options \"RJBT\" and \"1\".";
246 throw runtime_error( os.str() );
252 bool keepgoing, oksampling;
258 mc_iteration_count += 1;
266 local_rte_pos=sensor_pos(0,
joker);
272 ext_mat_mono, rng, local_rte_pos, local_rte_los,
273 pnd_vec, g,ppath_step, termination_flag,
274 inside_cloud, ppath_step_agenda, ppath_lraytrace,
275 propmat_clearsky_agenda, stokes_dim, f_mono,
276 p_grid, lat_grid, lon_grid, z_field, refellipsoid,
277 z_surface, t_field, vmr_field,
278 cloudbox_limits, pnd_field, scat_data_array_mono,
282 mc_points(ppath_step.
gp_p[np-1].idx,ppath_step.
gp_lat[np-1].idx,
283 ppath_step.
gp_lon[np-1].idx) += 1;
297 mc_iteration_count -= 1;
298 out0 <<
"WARNING: A rejected path sampling (g=0)!\n(if this"
299 <<
"happens repeatedly, try to decrease *ppath_lmax*)";
301 else if( termination_flag == 1 )
304 local_rte_pos, local_rte_los,
306 mult( vector1, evol_op, local_iy(0,
joker) );
307 mult( I_i, Q, vector1 );
311 else if( termination_flag == 2 )
316 local_surface_rmatrix,
318 local_rte_pos, local_rte_los,
319 surface_rtprop_agenda );
321 if( local_surface_los.
nrows() > 1 )
323 "The method handles only specular reflections." );
326 if( local_surface_los.
nrows() == 0 )
328 mult( vector1, evol_op, local_surface_emission(0,
joker) );
329 mult( I_i, Q, vector1);
336 Numeric R11 = local_surface_rmatrix(0,0,0,0);
337 if( rng.
draw() > R11 )
340 mult( vector1, evol_op, local_surface_emission(0,
joker) );
341 mult( I_i, Q, vector1 );
348 local_rte_los = local_surface_los( 0,
joker );
357 else if (inside_cloud)
361 albedo = 1 - abs_vec_mono[0]/ext_mat_mono(0,0);
364 if( rng.
draw() > albedo )
368 Vector emission = abs_vec_mono;
369 emission *= planck_value;
370 Vector emissioncontri(stokes_dim);
371 mult( emissioncontri, evol_op, emission );
372 emissioncontri /= (g*(1-albedo));
373 mult( I_i, Q, emissioncontri );
379 Sample_los( new_rte_los, g_los_csc_theta, Z, rng,
380 local_rte_los, scat_data_array_mono, stokes_dim,
381 pnd_vec, anyptype30, Z11maxvector,
382 ext_mat_mono(0,0)-abs_vec_mono[0], temperature,
385 Z /= g * g_los_csc_theta * albedo;
387 mult(
q, evol_op, Z );
391 local_rte_los = new_rte_los;
399 Vector emission = abs_vec_mono;
400 emission *= planck_value;
401 Vector emissioncontri(stokes_dim);
402 mult( emissioncontri, evol_op, emission );
404 mult( I_i, Q, emissioncontri );
413 for(
Index j=0; j<stokes_dim; j++ )
415 assert( !isnan(I_i[j]) );
416 Isquaredsum[j] += I_i[j]*I_i[j];
419 y /= (
Numeric)mc_iteration_count;
420 for(
Index j=0; j<stokes_dim; j++)
422 mc_error[j] = sqrt( ( Isquaredsum[j] /
423 (
Numeric)mc_iteration_count - y[j]*y[j] ) /
426 if( std_err > 0 && mc_iteration_count >= min_iter &&
427 mc_error[0] < std_err_i )
429 if( max_time > 0 && (
Index)(time(NULL)-start_time) >= max_time )
431 if( max_iter > 0 && mc_iteration_count >= max_iter )
436 if( convert_to_rjbt )
438 for(
Index j=0; j<stokes_dim; j++)
441 mc_error[j] =
invrayjean( mc_error[j], f_mono );
451 mc_seed=(
Index)time(NULL);