ARTS  2.0.49
m_montecarlo.cc
Go to the documentation of this file.
1 /* Copyright (C) 2003-2008 Cory Davis <cory@met.ed.ac.uk>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
18 
19 
20 /*===========================================================================
21  === File description
22  ===========================================================================*/
23 
35 /*===========================================================================
36  === External declarations
37  ===========================================================================*/
38 
39 #include "messages.h"
40 #include "arts.h"
41 #include "ppath.h"
42 #include "matpackI.h"
43 #include "special_interp.h"
44 #include "check_input.h"
45 #include <stdexcept>
46 #include <cmath>
47 #include "rte.h"
48 #include "lin_alg.h"
49 #include "auto_md.h"
50 #include "logic.h"
51 #include "physics_funcs.h"
52 #include "xml_io.h"
53 #include "montecarlo.h"
54 #include "rng.h"
55 #include <ctime>
56 #include <fstream>
57 #include "mc_interp.h"
58 #include "math_funcs.h"
59 
60 extern const Numeric DEG2RAD;
61 extern const Numeric RAD2DEG;
62 extern const Numeric PI;
63 extern const Numeric BOLTZMAN_CONST;
64 extern const Numeric SPEED_OF_LIGHT;
65 
66 
67 /*===========================================================================
68  === The functions (in alphabetical order)
69  ===========================================================================*/
70 
71 
72 /* Workspace method: Doxygen documentation will be auto-generated */
74  //output
75  Numeric& mc_IWP,
76  Numeric& mc_cloud_opt_path,
77  Numeric& mc_IWP_error,
78  Numeric& mc_cloud_opt_path_error,
79  Index& mc_iteration_count,
80  //input
81  const MCAntenna& mc_antenna,
82  const Matrix& sensor_pos,
83  const Matrix& sensor_los,
84  const Agenda& ppath_step_agenda,
85  const Vector& p_grid,
86  const Vector& lat_grid,
87  const Vector& lon_grid,
88  const Matrix& r_geoid,
89  const Matrix& z_surface,
90  const Tensor3& z_field,
91  const Tensor3& t_field,
92  const Tensor4& vmr_field,
93  const ArrayOfIndex& cloudbox_limits,
94  const Tensor4& pnd_field,
95  const ArrayOfSingleScatteringData& scat_data_mono,
96  const Vector& particle_masses,
97  const Index& mc_seed,
98  //Keyword params
99  const Index& max_iter,
100  const Verbosity& verbosity)
101 {
102  //if antenna is pencil beam jsut need a single path integral, otherwise
103  //for now do monte carlo integration
104  if (mc_antenna.get_type()==ANTENNA_TYPE_PENCIL_BEAM)
105  {
106  iwp_cloud_opt_pathCalc(ws, mc_IWP,mc_cloud_opt_path,sensor_pos(0,joker),
107  sensor_los(0,joker),
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,
111  verbosity);
112  }
113  else
114  {
115  Numeric iwp,cloud_opt_path;
116  Numeric iwp_squared=0;
117  Numeric tau_squared=0;
118  mc_iteration_count=0;
119  mc_IWP=0;
120  mc_cloud_opt_path=0;
121  Vector local_rte_los(2);
122  Rng rng;
123  rng.seed(mc_seed, verbosity);
124  //Begin Main Loop
125  while (mc_iteration_count<max_iter)
126  {
127  mc_antenna.draw_los(local_rte_los,rng,sensor_los(0,joker));
128  mc_iteration_count+=1;
129  iwp_cloud_opt_pathCalc(ws, iwp,cloud_opt_path,sensor_pos(0,joker),
130  local_rte_los,
131  ppath_step_agenda,p_grid,lat_grid,lon_grid,
132  r_geoid,z_surface,z_field,t_field,vmr_field,
133  cloudbox_limits,
134  pnd_field,scat_data_mono,particle_masses,
135  verbosity);
136  mc_IWP+=iwp;
137  iwp_squared+=iwp*iwp;
138  mc_cloud_opt_path+=cloud_opt_path;
139  tau_squared+=cloud_opt_path*cloud_opt_path;
140  }
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)
144  /(Numeric)mc_iteration_count);
145  mc_cloud_opt_path_error=sqrt((tau_squared/(Numeric)mc_iteration_count-
146  mc_cloud_opt_path*mc_cloud_opt_path)
147  /(Numeric)mc_iteration_count);
148 
149  }
150 
151 }
152 
153 
154 /* Workspace method: Doxygen documentation will be auto-generated */
156  //keyword arguments
157  const Numeric& za_sigma,
158  const Numeric& aa_sigma,
159  const Verbosity&)
160 {
161  mc_antenna.set_gaussian(za_sigma,aa_sigma);
162 }
163 
164 
165 /* Workspace method: Doxygen documentation will be auto-generated */
167  //keyword arguments
168  const Numeric& za_fwhm,
169  const Numeric& aa_fwhm,
170  const Verbosity&)
171 {
172  mc_antenna.set_gaussian_fwhm(za_fwhm,aa_fwhm);
173 }
174 
175 
176 /* Workspace method: Doxygen documentation will be auto-generated */
178  const Verbosity&)
179 {
180  mc_antenna.set_pencil_beam();
181 }
182 
183 
184 /* Workspace method: Doxygen documentation will be auto-generated */
186  Vector& y,
187  Index& mc_iteration_count,
188  Vector& mc_error,
189  Tensor3& mc_points,
190  const MCAntenna& mc_antenna,
191  const Vector& f_grid,
192  const Index& f_index,
193  const Matrix& sensor_pos,
194  const Matrix& sensor_los,
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,
201  const Vector& p_grid,
202  const Vector& lat_grid,
203  const Vector& lon_grid,
204  const Tensor3& z_field,
205  const Matrix& r_geoid,
206  const Matrix& z_surface,
207  const Tensor3& t_field,
208  const Tensor4& vmr_field,
209  const Index& cloudbox_on,
210  const ArrayOfIndex& cloudbox_limits,
211  const Tensor4& pnd_field,
212  const ArrayOfSingleScatteringData& scat_data_mono,
213  const Index& basics_checked,
214  const Index& cloudbox_checked,
215  const Index& mc_seed,
216  const String& y_unit,
217  const Numeric& std_err,
218  const Index& max_time,
219  const Index& max_iter,
220  // GH commented out 2011-06-17 unused
221  // const Index& z_field_is_1D,
222  const Verbosity& verbosity)
223 {
224  // Basic checks
225  if( !cloudbox_on )
226  throw runtime_error(
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)." );
234 
235  //Check keyword input
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" );
238  }
239 
240  if( f_index < 0 )
241  {
242  throw runtime_error(
243  "The option of f_index < 0 is not handled by this method." );
244  }
245  if( f_index >= f_grid.nelem() )
246  {
247  throw runtime_error(
248  "*f_index* is outside the range of *f_grid*." );
249  }
250 
251  if (! (atmosphere_dim == 3))
252  {
253  ostringstream os;
254  os << "Expected atmosphere_dim: 3. ";
255  os << "Found: " << atmosphere_dim;
256  throw runtime_error(os.str());
257  }
258 
259  if (! (sensor_pos.ncols() == 3))
260  {
261  ostringstream os;
262  os << "Expected number of columns in sensor_pos: 3. ";
263  os << "Found: " << sensor_pos.ncols();
264  throw runtime_error(os.str());
265  }
266 
267  if (! (sensor_los.ncols() == 2))
268  {
269  ostringstream os;
270  os << "Expected number of columns in sensor_los: 2. ";
271  os << "Found: " << sensor_los.ncols();
272  throw runtime_error(os.str());
273  }
274 
275  if (pnd_field.nbooks() == 0)
276  {
277  ostringstream os;
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());
281  }
282 
284  Ppath ppath_step;
285  Rng rng; //Random Number generator
286  time_t start_time=time(NULL);
287  Index N_pt=pnd_field.nbooks();//Number of particle types
288  Vector pnd_vec(N_pt); //Vector of particle number densities used at each point
289  Vector Z11maxvector;//Vector holding the maximum phase function for each
290  bool anyptype30=is_anyptype30(scat_data_mono);
291  if (anyptype30)
292  {
293  findZ11max(Z11maxvector,scat_data_mono);
294  }
295  rng.seed(mc_seed, verbosity);
296  bool keepgoing,inside_cloud; // flag indicating whether to stop tracing a photons path
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),
299 
300  ext_mat_mono(stokes_dim,stokes_dim),q(stokes_dim,stokes_dim),newQ(stokes_dim,stokes_dim),
301  Z(stokes_dim,stokes_dim);
302  q=0.0;newQ=0.0;
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);
306  y.resize(stokes_dim);
307  y=0;
308  Index termination_flag=0;
309  mc_error.resize(stokes_dim);
310  //local versions of workspace
311  Matrix local_iy(1,stokes_dim),local_surface_emission(1,stokes_dim),local_surface_los;
312  Tensor4 local_surface_rmatrix;
313  Vector local_rte_pos(2);
314  Vector local_rte_los(2);
315  Vector new_rte_los(2);
316  Index np;
317  mc_points.resize(p_grid.nelem(),lat_grid.nelem(),lon_grid.nelem());
318  mc_points=0;
319  Isum=0.0;Isquaredsum=0.0;
320  Numeric std_err_i;
321  bool convert_to_rjbt=false;
322  if ( y_unit == "RJBT" )
323  {
324  std_err_i=f_grid[f_index]*f_grid[f_index]*2*BOLTZMAN_CONST/
326  convert_to_rjbt=true;
327  }
328  else if ( y_unit == "1" )
329  {
330  std_err_i=std_err;
331  }
332  else
333  {
334  ostringstream os;
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() );
338  }
339 
340 
341  //Begin Main Loop
342  while (true)
343  {
344  mc_iteration_count+=1;
345  keepgoing=true; //flag indicating whether to continue tracing a photon path
346  //Sample a FOV direction
347  mc_antenna.draw_los(local_rte_los,rng,sensor_los(0,joker));
348  id_mat(Q);
349  local_rte_pos=sensor_pos(0,joker);
350  I_i=0.0;
351 
352 
353  while (keepgoing)
354  {
355  mcPathTraceGeneral( ws,
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); //, z_field_is_1D ); // Unused?
363 
364  np=ppath_step.np;
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;
367  // GH 2011-09-08: if the lowest layer has large
368  // extent and a thick cloud, g may be 0 due to
369  // underflow, but then I_i should be 0 as well.
370  // Don't turn it into nan for no reason.
371  // If reaching underflow, no point in going on;
372  // hence new photon.
373  // GH 2011-09-14: moved this check to outside the different
374  // scenarios, as this goes wrong regardless of the scenario.
375  if (g==0)
376  {
377  out2 << "Warning: g=0. Very thick cloud near surface? Results still reliable or not?\n";
378  assert(I_i[0]==0);
379  keepgoing = false;
380  }
381  else if (termination_flag==1)
382  {
383  iy_space_agendaExecute(ws, local_iy,local_rte_pos,local_rte_los,
384  iy_space_agenda);
385  mult(vector1,evol_op,local_iy(f_index,joker));
386  mult(I_i,Q,vector1);
387  I_i/=g;
388  keepgoing=false; //stop here. New photon.
389  }
390  else if (termination_flag==2)
391  {
392  //Calculate surface properties
393  surface_prop_agendaExecute( ws, local_surface_emission,
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 );
398 
399  if( local_surface_los.nrows() > 1 )
400  {
401  throw runtime_error(
402  "The method handles only specular reflections." );
403  }
404 
405  //deal with blackbody case
406  if (local_surface_los.nrows()==0)
407  {
408  mult(vector1,evol_op,local_surface_emission(f_index,joker));
409  mult(I_i,Q,vector1);
410  I_i/=g;
411  keepgoing=false;
412  }
413  else
414  //decide between reflection and emission
415  {
416  Numeric R11=local_surface_rmatrix(0,f_index,0,0);
417  if (rng.draw()>R11)
418  {
419  //then we have emission
420  //Matrix oneminusR(stokes_dim,stokes_dim);
421  //id_mat(oneminusR);
422  //oneminusR-=local_surface_rmatrix(0,0,joker,joker);
423  //oneminusR/=1-R11;
424  //mult(vector1,oneminusR,local_surface_emission(0,joker));
425  mult(vector1,evol_op,local_surface_emission(f_index,joker));
426  mult(I_i,Q,vector1);
427  I_i/=g*(1-R11);
428  keepgoing=false;
429  }
430  else
431  {
432  //we have reflection
433  local_rte_los=local_surface_los(0,joker);
434 
435  mult(q,evol_op,local_surface_rmatrix(0,f_index,joker,joker));
436  mult(newQ,Q,q);
437  Q=newQ;
438  Q/=g*R11;
439  }
440  }
441  }
442  else if (inside_cloud)
443  {
444  //we have another scattering/emission point
445  //Estimate single scattering albedo
446  albedo=1-abs_vec_mono[0]/ext_mat_mono(0,0);
447  //cout<<"albedo = "<<albedo<<" ext_mat_mono(0,0) = "<<ext_mat_mono(0,0)<<" abs_vec_mono[0] = "<<abs_vec_mono[0]<<"\n";
448  //determine whether photon is emitted or scattered
449  if (rng.draw()>albedo)
450  {
451  //Calculate emission
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));//yuck!
458  mult(I_i,Q,emissioncontri);
459  keepgoing=false;
460  //cout << "emission contri" << I_i[0] << "\n";
461  }
462  else
463  {
464  //we have a scattering event
465  //Sample new line of sight.
466 
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,
470  verbosity);
471 
472  Z/=g*g_los_csc_theta*albedo;
473 
474  mult(q,evol_op,Z);
475  mult(newQ,Q,q);
476  Q=newQ;
477  //scattering_order+=1;
478  local_rte_los=new_rte_los;
479  //if (silent==0){cout <<"mc_iteration_count = "<<mc_iteration_count <<
480  // ", scattering_order = " <<scattering_order <<"\n";}
481  }
482  }
483  else
484  {
485  //Must be clear sky emission point
486  //Calculate emission
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);
492  emissioncontri/=g;
493  mult(I_i,Q,emissioncontri);
494  keepgoing=false;
495  //cout << "emission contri" << I_i[0] << "\n";
496  }
497  }
498  Isum += I_i;
499  for(Index j=0; j<stokes_dim; j++)
500  {
501  assert(!isnan(I_i[j]));
502  Isquaredsum[j] += I_i[j]*I_i[j];
503  }
504  y=Isum;
505  y/=(Numeric)mc_iteration_count;
506  for(Index j=0; j<stokes_dim; j++)
507  {
508  mc_error[j]=sqrt((Isquaredsum[j]/(Numeric)mc_iteration_count-y[j]*y[j])/(Numeric)mc_iteration_count);
509  }
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;}
513  }
514  if ( convert_to_rjbt )
515  {
516  for(Index j=0; j<stokes_dim; j++)
517  {
518  y[j]=invrayjean(y[j],f_grid[f_index]);
519  mc_error[j]=invrayjean(mc_error[j],f_grid[f_index]);
520  }
521  }
522 }
523 
524 
525 /* Workspace method: Doxygen documentation will be auto-generated */
526 void MCIPA(Workspace& ws,
527  Vector& y,
528  Index& mc_iteration_count,
529  Vector& mc_error,
530  Tensor3& mc_points,
531  const MCAntenna& mc_antenna,
532  const Vector& f_grid,
533  const Index& f_index,
534  const Matrix& sensor_pos,
535  const Matrix& sensor_los,
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,
543  const Vector& p_grid,
544  const Vector& lat_grid,
545  const Vector& lon_grid,
546  const Tensor3& z_field,
547  const Matrix& r_geoid,
548  const Matrix& z_surface,
549  const Tensor3& t_field,
550  const Tensor4& vmr_field,
551  const ArrayOfIndex& cloudbox_limits,
552  const Tensor4& pnd_field,
553  const ArrayOfSingleScatteringData& scat_data_mono,
554  const Index& mc_seed,
555  const String& y_unit,
556  //Keyword params
557  const Numeric& std_err,
558  const Index& max_time,
559  const Index& max_iter,
560  const Index& z_field_is_1D,
561  const Verbosity& verbosity)
562 {
563  //Check keyword input
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" );
566  }
567 
568  if (! (atmosphere_dim == 3))
569  {
570  throw runtime_error(
571  "For montecarlo, atmosphere_dim must be 3.");
572  }
573 
574  Ppath ppath_step;
575  Rng rng; //Random Nuimber generator
576  time_t start_time=time(NULL);
577  Index N_pt=pnd_field.nbooks();//Number of particle types
578  Vector pnd_vec(N_pt); //Vector of particle number densities used at each point
579  Vector Z11maxvector;//Vector holding the maximum phase function for each
580  bool anyptype30=is_anyptype30(scat_data_mono);
581  if (anyptype30)
582  {
583  findZ11max(Z11maxvector,scat_data_mono);
584  }
585  rng.seed(mc_seed, verbosity);
586  bool keepgoing,inside_cloud; // flag indicating whether to stop tracing a photons path
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);
591  q=0.0;newQ=0.0;
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);
595  y.resize(stokes_dim);
596  y=0;
597  Index termination_flag=0;
598  mc_error.resize(stokes_dim);
599  //local versions of workspace
600  Matrix local_iy(1,stokes_dim),local_surface_emission(1,stokes_dim),local_surface_los;
601  Tensor4 local_surface_rmatrix;
602  Vector local_rte_pos(2);
603  Vector local_rte_los(2);
604  Vector new_rte_los(2);
605  Index np;
606  mc_points.resize(p_grid.nelem(),lat_grid.nelem(),lon_grid.nelem());
607  mc_points=0;
608  Isum=0.0;Isquaredsum=0.0;
609  Numeric std_err_i;
610  bool convert_to_rjbt=false;
611  if ( y_unit == "RJBT" )
612  {
613  std_err_i=f_grid[0]*f_grid[0]*2*BOLTZMAN_CONST/SPEED_OF_LIGHT/SPEED_OF_LIGHT*
614  std_err;
615  convert_to_rjbt=true;
616  }
617  else if ( y_unit == "1" )
618  {
619  std_err_i=std_err;
620  }
621  else
622  {
623  ostringstream os;
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() );
627  }
628 
629  //Begin Main Loop
630  while (true)
631  {
632  mc_iteration_count+=1;
633  keepgoing=true; //flag indicating whether to continue tracing a photon path
634  //Sample a FOV direction
635  mc_antenna.draw_los(local_rte_los,rng,sensor_los(0,joker));
636  id_mat(Q);
637  local_rte_pos=sensor_pos(0,joker);
638  I_i=0.0;
639 
640  //Obtain a reference propagation path to use for obtaining optical properties
641  //for the IPA method.
642  Ppath ppath;
643  ppath_calc( ws, ppath, ppath_step_agenda, 3,
644  p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
645  0, cloudbox_limits, local_rte_pos, local_rte_los, 1,
646  verbosity );
647 
648  while (keepgoing)
649  {
650  //modified path tracing routine for independent pixel approximation
651  mcPathTraceIPA( ws,
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,
660  verbosity );
661 
662  np=ppath.np;
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)
666  {
667  iy_space_agendaExecute(ws, local_iy,local_rte_pos,local_rte_los,
668  iy_space_agenda);
669  mult(vector1,evol_op,local_iy(0,joker));
670  mult(I_i,Q,vector1);
671  I_i/=g;
672  keepgoing=false; //stop here. New photon.
673  }
674  else if (termination_flag==2)
675  {
676  //Choose appropriate lat and lon grid points for IPA
677  //if ppath (the reference ppath) hits the srface just take the last point.
678  GridPos latgp;
679  GridPos longp;
680  if (ppath.background=="surface")
681  {
682  latgp=ppath.gp_lat[ppath.np-1];
683  longp=ppath.gp_lon[ppath.np-1];
684  }
685  else
686  {
687  //Use the lat and lon of the geometric tangent point
688  gridpos(latgp,lat_grid,ppath.geom_tan_pos[1]);
689  gridpos(longp,lon_grid,ppath.geom_tan_pos[2]);
690  }
691  //decide whether we have reflection or emission
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);
696  //deal with blackbody case
697  if (local_surface_los.nrows()==0)
698  {
699  mult(vector1,evol_op,local_surface_emission(0,joker));
700  mult(I_i,Q,vector1);
701  I_i/=g;
702  keepgoing=false;
703  }
704  else
705  //decide between reflection and emission
706  {
707  Numeric R11=local_surface_rmatrix(0,0,0,0);
708  if (rng.draw()>R11)
709  {
710  //then we have emission
711  //Matrix oneminusR(stokes_dim,stokes_dim);
712  //id_mat(oneminusR);
713  //oneminusR-=local_surface_rmatrix(0,0,joker,joker);
714  //oneminusR/=1-R11;
715  //mult(vector1,oneminusR,local_surface_emission(0,joker));
716  mult(vector1,evol_op,local_surface_emission(0,joker));
717  mult(I_i,Q,vector1);
718  I_i/=g*(1-R11);
719  keepgoing=false;
720  }
721  else
722  {
723  //we have reflection
724  local_rte_los=local_surface_los(0,joker);
725 
726  mult(q,evol_op,local_surface_rmatrix(0,0,joker,joker));
727  mult(newQ,Q,q);
728  Q=newQ;
729  Q/=g*R11;
730  }
731  }
732  }
733  else if (inside_cloud)
734  {
735  //we have another scattering/emission point
736  //Estimate single scattering albedo
737  albedo=1-abs_vec_mono[0]/ext_mat_mono(0,0);
738  //cout<<"albedo = "<<albedo<<" ext_mat_mono(0,0) = "<<ext_mat_mono(0,0)<<" abs_vec_mono[0] = "<<abs_vec_mono[0]<<"\n";
739  //determine whether photon is emitted or scattered
740  if (rng.draw()>albedo)
741  {
742  //Calculate emission
743  Numeric planck_value = planck( f_grid[0], temperature );
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));//yuck!
749  mult(I_i,Q,emissioncontri);
750  keepgoing=false;
751  //cout << "emission contri" << I_i[0] << "\n";
752  }
753  else
754  {
755  //we have a scattering event
756  //Sample new line of sight.
757 
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,
761  verbosity);
762 
763  Z/=g*g_los_csc_theta*albedo;
764 
765  mult(q,evol_op,Z);
766  mult(newQ,Q,q);
767  Q=newQ;
768  //scattering_order+=1;
769  local_rte_los=new_rte_los;
770  //if (silent==0){cout <<"mc_iteration_count = "<<mc_iteration_count <<
771  // ", scattering_order = " <<scattering_order <<"\n";}
772  }
773  }
774  else
775  {
776  //Must be clear sky emission point
777  //Calculate emission
778  Numeric planck_value = planck( f_grid[0], temperature );
779  Vector emission=abs_vec_mono;
780  emission*=planck_value;
781  Vector emissioncontri(stokes_dim);
782  mult(emissioncontri,evol_op,emission);
783  emissioncontri/=g;
784  mult(I_i,Q,emissioncontri);
785  keepgoing=false;
786  //cout << "emission contri" << I_i[0] << "\n";
787  }
788  }
789  Isum += I_i;
790  for(Index j=0; j<stokes_dim; j++)
791  {
792  assert(!isnan(I_i[j]));
793  Isquaredsum[j] += I_i[j]*I_i[j];
794  }
795  y=Isum;
796  y/=(Numeric)mc_iteration_count;
797  for(Index j=0; j<stokes_dim; j++)
798  {
799  mc_error[j]=sqrt((Isquaredsum[j]/(Numeric)mc_iteration_count-y[j]*y[j])/(Numeric)mc_iteration_count);
800  }
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;}
804  }
805  if ( convert_to_rjbt )
806  {
807  for(Index j=0; j<stokes_dim; j++)
808  {
809  y[j]=invrayjean(y[j],f_grid[0]);
810  mc_error[j]=invrayjean(mc_error[j],f_grid[0]);
811  }
812  }
813 }
814 
815 
816 /* Workspace method: Doxygen documentation will be auto-generated */
817 void MCSetSeedFromTime(Index& mc_seed,
818  const Verbosity&)
819 {
820  mc_seed=(Index)time(NULL);
821 }
822 
823 
824 /* Workspace method: Doxygen documentation will be auto-generated */
826  const Vector& f_grid,
827  const Index& f_index,
828  const Index& stokes_dim,
829  const ArrayOfSingleScatteringData& scat_data_raw,
830  const Numeric& rte_temperature,
831  const Numeric& za_out,
832  const Numeric& aa_out,
833  const Numeric& za_in,
834  const Numeric& aa_in,
835  const Verbosity& verbosity)
836 {
837  if( scat_data_raw.nelem() > 1 )
838  throw runtime_error( "Only one element in *scat_data_raw* is allowed." );
839 
840  ArrayOfSingleScatteringData scat_data;
841  scat_data_monoCalc( scat_data, scat_data_raw, f_grid, f_index, verbosity);
842 
843  Vector pnd( 1, 1.0 );
844 
845  pha_mat.resize( stokes_dim, stokes_dim );
846 
847  pha_mat_singleCalc( pha_mat, za_out, aa_out, za_in, aa_in,
848  scat_data, stokes_dim, pnd, rte_temperature,
849  verbosity );
850 }
851 
Matrix
The Matrix class.
Definition: matpackI.h:767
ppath_calc
void ppath_calc(Workspace &ws, Ppath &ppath, const Agenda &ppath_step_agenda, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &r_geoid, const Matrix &z_surface, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Vector &rte_pos, const Vector &rte_los, const bool &outside_cloudbox, const Verbosity &verbosity)
ppath_calc
Definition: ppath.cc:6171
DEG2RAD
const Numeric DEG2RAD
auto_md.h
SPEED_OF_LIGHT
const Numeric SPEED_OF_LIGHT
gridpos
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
Definition: interpolation.cc:167
Tensor3
The Tensor3 class.
Definition: matpackIII.h:340
id_mat
void id_mat(MatrixView I)
Identity Matrix.
Definition: lin_alg.cc:298
mc_interp.h
Interpolation classes and functions created for use within Monte Carlo scattering simulations.
joker
const Joker joker
ANTENNA_TYPE_PENCIL_BEAM
@ ANTENNA_TYPE_PENCIL_BEAM
Definition: mc_antenna.h:48
Ppath::background
String background
Definition: ppath.h:70
mc_IWP_cloud_opt_pathCalc
void mc_IWP_cloud_opt_pathCalc(Workspace &ws, Numeric &mc_IWP, Numeric &mc_cloud_opt_path, Numeric &mc_IWP_error, Numeric &mc_cloud_opt_path_error, Index &mc_iteration_count, const MCAntenna &mc_antenna, const Matrix &sensor_pos, const Matrix &sensor_los, const Agenda &ppath_step_agenda, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Matrix &r_geoid, const Matrix &z_surface, const Tensor3 &z_field, const Tensor3 &t_field, const Tensor4 &vmr_field, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_mono, const Vector &particle_masses, const Index &mc_seed, const Index &max_iter, const Verbosity &verbosity)
WORKSPACE METHOD: mc_IWP_cloud_opt_pathCalc.
Definition: m_montecarlo.cc:73
mc_antennaSetPencilBeam
void mc_antennaSetPencilBeam(MCAntenna &mc_antenna, const Verbosity &)
WORKSPACE METHOD: mc_antennaSetPencilBeam.
Definition: m_montecarlo.cc:177
Rng::seed
void seed(unsigned long int n, const Verbosity &verbosity)
Definition: rng.cc:72
mc_antennaSetGaussianByFWHM
void mc_antennaSetGaussianByFWHM(MCAntenna &mc_antenna, const Numeric &za_fwhm, const Numeric &aa_fwhm, const Verbosity &)
WORKSPACE METHOD: mc_antennaSetGaussianByFWHM.
Definition: m_montecarlo.cc:166
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:771
mcPathTraceIPA
void mcPathTraceIPA(Workspace &ws, MatrixView evol_op, Vector &abs_vec_mono, Numeric &temperature, MatrixView ext_mat_mono, Rng &rng, Vector &rte_pos, Vector &rte_los, Vector &pnd_vec, Numeric &g, Index &termination_flag, bool &inside_cloud, const Agenda &opt_prop_gas_agenda, const Agenda &abs_scalar_gas_agenda, const Index stokes_dim, const Index f_index, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &r_geoid, const Matrix &z_surface, const Tensor3 &t_field, const Tensor4 &vmr_field, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_mono, const Index z_field_is_1D, const Ppath &ppath, const Verbosity &verbosity)
mcPathTraceIPA
Definition: montecarlo.cc:821
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
MCAntenna
An Antenna object used by MCGeneral.
Definition: mc_antenna.h:56
MCIPA
void MCIPA(Workspace &ws, Vector &y, Index &mc_iteration_count, Vector &mc_error, Tensor3 &mc_points, const MCAntenna &mc_antenna, const Vector &f_grid, const Index &f_index, const Matrix &sensor_pos, const Matrix &sensor_los, const Index &stokes_dim, const Index &atmosphere_dim, const Agenda &iy_space_agenda, const Agenda &surface_prop_agenda, const Agenda &opt_prop_gas_agenda, const Agenda &abs_scalar_gas_agenda, const Agenda &ppath_step_agenda, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &r_geoid, const Matrix &z_surface, const Tensor3 &t_field, const Tensor4 &vmr_field, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_mono, const Index &mc_seed, const String &y_unit, const Numeric &std_err, const Index &max_time, const Index &max_iter, const Index &z_field_is_1D, const Verbosity &verbosity)
WORKSPACE METHOD: MCIPA.
Definition: m_montecarlo.cc:526
surface_prop_agendaExecute
void surface_prop_agendaExecute(Workspace &ws, Matrix &surface_emission, Matrix &surface_los, Tensor4 &surface_rmatrix, const Vector &rte_pos, const Vector &rte_los, const GridPos &rte_gp_p, const GridPos &rte_gp_lat, const GridPos &rte_gp_lon, const Agenda &input_agenda)
Definition: auto_md.cc:10590
CREATE_OUT2
#define CREATE_OUT2
Definition: messages.h:207
MCAntenna::set_gaussian_fwhm
void set_gaussian_fwhm(const Numeric &za_fwhm, const Numeric &aa_fwhm)
makes the antenna pattern a 2D gaussian specified by za and aa FWHM
Definition: mc_antenna.cc:116
montecarlo.h
Tensor4
The Tensor4 class.
Definition: matpackIV.h:375
q
#define q
Definition: continua.cc:14103
Ppath
The structure to describe a propagation path and releated quantities.
Definition: ppath.h:59
Ppath::gp_p
ArrayOfGridPos gp_p
Definition: ppath.h:66
Tensor3::resize
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:863
Agenda
The Agenda class.
Definition: agenda_class.h:44
BOLTZMAN_CONST
const Numeric BOLTZMAN_CONST
invrayjean
Numeric invrayjean(const Numeric &i, const Numeric &f)
invrayjean
Definition: physics_funcs.cc:170
matpackI.h
rng.h
Defines the Rng random number generator class.
Array< Index >
MCAntenna::get_type
AntennaType get_type(void) const
returns the antenna type
Definition: mc_antenna.cc:150
Rng::draw
double draw()
Definition: rng.cc:120
mult
void mult(VectorView y, const ConstMatrixView &M, const ConstVectorView &x)
Matrix Vector multiplication.
Definition: matpackI.cc:1607
is_anyptype30
bool is_anyptype30(const ArrayOfSingleScatteringData &scat_data_mono)
is_anyptype30
Definition: montecarlo.cc:388
Ppath::gp_lat
ArrayOfGridPos gp_lat
Definition: ppath.h:67
messages.h
Declarations having to do with the four output streams.
Sample_los
void Sample_los(VectorView new_rte_los, Numeric &g_los_csc_theta, MatrixView Z, Rng &rng, ConstVectorView rte_los, const ArrayOfSingleScatteringData &scat_data_mono, const Index stokes_dim, ConstVectorView pnd_vec, const bool anyptype30, ConstVectorView Z11maxvector, const Numeric Csca, const Numeric rte_temperature, const Verbosity &verbosity)
Sample_los.
Definition: montecarlo.cc:1712
MCSetSeedFromTime
void MCSetSeedFromTime(Index &mc_seed, const Verbosity &)
WORKSPACE METHOD: MCSetSeedFromTime.
Definition: m_montecarlo.cc:817
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
my_basic_string
The implementation for String, the ARTS string class.
Definition: mystring.h:62
Ppath::gp_lon
ArrayOfGridPos gp_lon
Definition: ppath.h:68
Ppath::np
Index np
Definition: ppath.h:61
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:175
physics_funcs.h
MCAntenna::draw_los
void draw_los(VectorView &sampled_rte_los, Rng &rng, ConstVectorView bore_sight_los) const
draws a line of sight by sampling the antenna response function
Definition: mc_antenna.cc:167
MCGeneral
void MCGeneral(Workspace &ws, Vector &y, Index &mc_iteration_count, Vector &mc_error, Tensor3 &mc_points, const MCAntenna &mc_antenna, const Vector &f_grid, const Index &f_index, const Matrix &sensor_pos, const Matrix &sensor_los, const Index &stokes_dim, const Index &atmosphere_dim, const Agenda &iy_space_agenda, const Agenda &surface_prop_agenda, const Agenda &opt_prop_gas_agenda, const Agenda &abs_scalar_gas_agenda, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &r_geoid, const Matrix &z_surface, const Tensor3 &t_field, const Tensor4 &vmr_field, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_mono, const Index &basics_checked, const Index &cloudbox_checked, const Index &mc_seed, const String &y_unit, const Numeric &std_err, const Index &max_time, const Index &max_iter, const Verbosity &verbosity)
WORKSPACE METHOD: MCGeneral.
Definition: m_montecarlo.cc:185
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
lin_alg.h
Linear algebra functions.
Verbosity
Definition: messages.h:50
RAD2DEG
const Numeric RAD2DEG
ConstTensor4View::nbooks
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:60
math_funcs.h
mcPathTraceGeneral
void mcPathTraceGeneral(Workspace &ws, MatrixView evol_op, Vector &abs_vec_mono, Numeric &temperature, MatrixView ext_mat_mono, Rng &rng, Vector &rte_pos, Vector &rte_los, Vector &pnd_vec, Numeric &g, Ppath &ppath_step, Index &termination_flag, bool &inside_cloud, const Agenda &opt_prop_gas_agenda, const Agenda &abs_scalar_gas_agenda, const Index stokes_dim, const Index f_index, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &r_geoid, const Matrix &z_surface, const Tensor3 &t_field, const Tensor4 &vmr_field, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_mono, const Verbosity &verbosity)
mcPathTraceGeneral
Definition: montecarlo.cc:557
Matrix::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1549
iy_space_agendaExecute
void iy_space_agendaExecute(Workspace &ws, Matrix &iy, const Vector &rte_pos, const Vector &rte_los, const Agenda &input_agenda)
Definition: auto_md.cc:9744
scat_data_monoCalc
void scat_data_monoCalc(ArrayOfSingleScatteringData &scat_data_mono, const ArrayOfSingleScatteringData &scat_data_raw, const Vector &f_grid, const Index &f_index, const Verbosity &)
WORKSPACE METHOD: scat_data_monoCalc.
Definition: m_optproperties.cc:1035
planck
Numeric planck(const Numeric &f, const Numeric &t)
planck
Definition: physics_funcs.cc:219
GridPos
Structure to store a grid position.
Definition: interpolation.h:74
ppath.h
Propagation path structure and functions.
pha_matExtractManually
void pha_matExtractManually(Matrix &pha_mat, const Vector &f_grid, const Index &f_index, const Index &stokes_dim, const ArrayOfSingleScatteringData &scat_data_raw, const Numeric &rte_temperature, const Numeric &za_out, const Numeric &aa_out, const Numeric &za_in, const Numeric &aa_in, const Verbosity &verbosity)
WORKSPACE METHOD: pha_matExtractManually.
Definition: m_montecarlo.cc:825
logic.h
Header file for logic.cc.
MCAntenna::set_pencil_beam
void set_pencil_beam(void)
makes the antenna pattern a pencil beam
Definition: mc_antenna.cc:88
rte.h
Declaration of functions in rte.cc.
Rng
Definition: rng.h:569
Workspace
Workspace class.
Definition: workspace_ng.h:47
special_interp.h
Header file for special_interp.cc.
findZ11max
void findZ11max(Vector &Z11maxvector, const ArrayOfSingleScatteringData &scat_data_mono)
findZ11max
Definition: montecarlo.cc:351
Ppath::geom_tan_pos
Vector geom_tan_pos
Definition: ppath.h:72
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
mc_antennaSetGaussian
void mc_antennaSetGaussian(MCAntenna &mc_antenna, const Numeric &za_sigma, const Numeric &aa_sigma, const Verbosity &)
WORKSPACE METHOD: mc_antennaSetGaussian.
Definition: m_montecarlo.cc:155
check_input.h
iwp_cloud_opt_pathCalc
void iwp_cloud_opt_pathCalc(Workspace &ws, Numeric &iwp, Numeric &cloud_opt_path, const Vector &rte_pos, const Vector &rte_los, const Agenda &ppath_step_agenda, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Matrix &r_geoid, const Matrix &z_surface, const Tensor3 &z_field, const Tensor3 &t_field, const Tensor4 &vmr_field, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_mono, const Vector &particle_masses, const Verbosity &verbosity)
iwp_cloud_opt_pathCalc
Definition: montecarlo.cc:417
Vector
The Vector class.
Definition: matpackI.h:555
pha_mat_singleCalc
void pha_mat_singleCalc(MatrixView Z, const Numeric za_sca, const Numeric aa_sca, const Numeric za_inc, const Numeric aa_inc, const ArrayOfSingleScatteringData &scat_data_mono, const Index stokes_dim, ConstVectorView pnd_vec, const Numeric rte_temperature, const Verbosity &verbosity)
pha_mat_singleCalc
Definition: montecarlo.cc:1456
PI
const Numeric PI
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
MCAntenna::set_gaussian
void set_gaussian(const Numeric &za_sigma, const Numeric &aa_sigma)
makes the antenna pattern a 2D gaussian specified by za and aa standard deviations
Definition: mc_antenna.cc:100
arts.h
The global header file for ARTS.
xml_io.h
This file contains basic functions to handle XML data files.