ARTS  2.0.49
montecarlo.cc
Go to the documentation of this file.
1 /* copyright (C) 2003-2010 Cory Davis <cory.davis@metservice.com>
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 
33 /*===========================================================================
34  === External declarations
35  ===========================================================================*/
36 
37 #include "auto_md.h"
38 #include "montecarlo.h"
39 #include "mc_interp.h"
40 
41 #ifdef HAVE_SSTREAM
42 #include <sstream>
43 #else
44 #include "sstream.h"
45 #endif
46 
48 
58  MatrixView ext_mat_mono,
59  VectorView abs_vec_mono,
60  Numeric& temperature,
61  const Agenda& opt_prop_gas_agenda,
62  const Agenda& abs_scalar_gas_agenda,
63  const Index f_index,
64  const GridPos& gp_p,
65  const GridPos& gp_lat,
66  const GridPos& gp_lon,
67  ConstVectorView p_grid,
68  ConstTensor3View t_field,
69  ConstTensor4View vmr_field)
70 {
71  const Index ns = vmr_field.nbooks();
72  Vector t_vec(1); //vectors are required by interp_atmfield_gp2itw etc.
73  Vector p_vec(1);//may not be efficient with unecessary vectors
74  Matrix itw_p(1,2);
75  ArrayOfGridPos ao_gp_p(1),ao_gp_lat(1),ao_gp_lon(1);
76  Matrix vmr_mat(ns,1), itw_field;
77 
78  //local versions of workspace variables
79  Matrix local_abs_scalar_gas,local_abs_vec;
80  Tensor3 local_ext_mat;
81  ao_gp_p[0]=gp_p;
82  ao_gp_lat[0]=gp_lat;
83  ao_gp_lon[0]=gp_lon;
84 
85  // Determine the pressure
86 
87  interpweights( itw_p, ao_gp_p );
88  itw2p( p_vec, p_grid, ao_gp_p, itw_p );
89 
90  // Determine the atmospheric temperature and species VMR
91  //
92  interp_atmfield_gp2itw( itw_field, 3, ao_gp_p, ao_gp_lat, ao_gp_lon );
93  //
94  interp_atmfield_by_itw( t_vec, 3, t_field, ao_gp_p, ao_gp_lat, ao_gp_lon,
95  itw_field );
96  //
97  for( Index is=0; is<ns; is++ )
98  {
99  interp_atmfield_by_itw( vmr_mat(is, joker), 3,
100  vmr_field(is, joker, joker, joker),
101  ao_gp_p, ao_gp_lat,
102  ao_gp_lon, itw_field );
103  }
104 
105 
106  temperature = t_vec[0];
107 
108  //calcualte absorption coefficient
109  abs_scalar_gas_agendaExecute( ws, local_abs_scalar_gas,f_index,0,p_vec[0],
110  temperature,vmr_mat(joker,0),abs_scalar_gas_agenda );
111  opt_prop_gas_agendaExecute( ws, local_ext_mat, local_abs_vec, f_index,
112  local_abs_scalar_gas, opt_prop_gas_agenda );
113  ext_mat_mono=local_ext_mat(0, Range(joker), Range(joker));
114  abs_vec_mono=local_abs_vec(0,Range(joker));
115 }
116 
117 
118 
120 
130  MatrixView ext_mat_mono,
131  VectorView abs_vec_mono,
132  VectorView pnd_vec,
133  Numeric& temperature,
134  const Agenda& opt_prop_gas_agenda,
135  const Agenda& abs_scalar_gas_agenda,
136  const Index stokes_dim,
137  const Index f_index,
138  const GridPos& gp_p,
139  const GridPos& gp_lat,
140  const GridPos& gp_lon,
141  ConstVectorView p_grid_cloud,
142  ConstTensor3View t_field_cloud,
143  ConstTensor4View vmr_field_cloud,
144  const Tensor4& pnd_field,
145  const ArrayOfSingleScatteringData& scat_data_mono,
146  const ArrayOfIndex& cloudbox_limits,
147  const Vector& rte_los,
148  const Verbosity& verbosity
149  )
150 
151 {
152  const Index ns = vmr_field_cloud.nbooks();
153  const Index N_pt = pnd_field.nbooks();
154  Matrix pnd_ppath(N_pt,1);
155  Vector t_ppath(1);
156  Vector p_ppath(1);//may not be efficient with unecessary vectors
157  Matrix itw_p(1,2);
158  ArrayOfGridPos ao_gp_p(1),ao_gp_lat(1),ao_gp_lon(1);
159  Matrix vmr_ppath(ns,1), itw_field;
160  Matrix ext_mat_part(stokes_dim, stokes_dim, 0.0);
161  Vector abs_vec_part(stokes_dim, 0.0);
162  Numeric scat_za,scat_aa;
163 
164  //local versions of workspace variables
165  Matrix local_abs_scalar_gas,local_abs_vec;
166  Tensor3 local_ext_mat;
167  //Numeric local_rte_pressure;
168  //Vector local_rte_vmrlist;
169 
170  ao_gp_p[0]=gp_p;
171  ao_gp_lat[0]=gp_lat;
172  ao_gp_lon[0]=gp_lon;
173 
174 
175  cloud_atm_vars_by_gp(p_ppath,t_ppath,vmr_ppath,pnd_ppath,ao_gp_p,
176  ao_gp_lat,ao_gp_lon,cloudbox_limits,p_grid_cloud,
177  t_field_cloud, vmr_field_cloud,pnd_field);
178 
179  //local_rte_pressure = p_ppath[0];
180  temperature = t_ppath[0];
181  //rte_vmr_list = vmr_ppath(joker,0);
182  abs_scalar_gas_agendaExecute( ws, local_abs_scalar_gas,f_index,0,p_ppath[0],
183  temperature,vmr_ppath(joker,0),abs_scalar_gas_agenda );
184  opt_prop_gas_agendaExecute( ws, local_ext_mat, local_abs_vec, f_index,
185  local_abs_scalar_gas, opt_prop_gas_agenda );
186  ext_mat_mono=local_ext_mat(0, Range(joker), Range(joker));
187  abs_vec_mono=local_abs_vec(0,Range(joker));
188  ext_mat_part=0.0;
189  abs_vec_part=0.0;
190  scat_za=180-rte_los[0];
191  scat_aa=rte_los[1]+180;
192  //Make sure scat_aa is between -180 and 180
193  if (scat_aa>180){scat_aa-=360;}
194  //
195  //opt_prop_part_agenda.execute( true );
196  //use pnd_ppath and ext_mat_spt to get extmat (and similar for abs_vec
197  pnd_vec=pnd_ppath(joker, 0);
198  opt_propCalc(ext_mat_part,abs_vec_part,scat_za,scat_aa,scat_data_mono,
199  stokes_dim, pnd_vec, temperature,verbosity);
200 
201  ext_mat_mono += ext_mat_part;
202  abs_vec_mono += abs_vec_part;
203 
204 }
205 
206 
207 
209 
232  VectorView pressure,
233  VectorView temperature,
234  MatrixView vmr,
235  MatrixView pnd,
236  const ArrayOfGridPos& gp_p,
237  const ArrayOfGridPos& gp_lat,
238  const ArrayOfGridPos& gp_lon,
239  const ArrayOfIndex& cloudbox_limits,
240  ConstVectorView p_grid_cloud,
241  ConstTensor3View t_field_cloud,
242  ConstTensor4View vmr_field_cloud,
243  ConstTensor4View pnd_field
244  )
245 {
246  Index np=gp_p.nelem();
247  assert(pressure.nelem()==np);
248  Index ns=vmr_field_cloud.nbooks();
249  Index N_pt=pnd_field.nbooks();
250  ArrayOfGridPos gp_p_cloud = gp_p;
251  ArrayOfGridPos gp_lat_cloud = gp_lat;
252  ArrayOfGridPos gp_lon_cloud = gp_lon;
253  Index atmosphere_dim=3;
254 
255  for (Index i = 0; i < np; i++ )
256  {
257  // Calculate grid positions inside the cloud.
258  gp_p_cloud[i].idx -= cloudbox_limits[0];
259  gp_lat_cloud[i].idx -= cloudbox_limits[2];
260  gp_lon_cloud[i].idx -= cloudbox_limits[4];
261  }
262 
263  const Index n1 = cloudbox_limits[1] - cloudbox_limits[0];
264  const Index n2 = cloudbox_limits[3] - cloudbox_limits[2];
265  const Index n3 = cloudbox_limits[5] - cloudbox_limits[4];
266  gridpos_upperend_check( gp_p_cloud[0], n1 );
267  gridpos_upperend_check( gp_p_cloud[np-1], n1 );
268  gridpos_upperend_check( gp_lat_cloud[0], n2 );
269  gridpos_upperend_check( gp_lat_cloud[np-1], n2);
270  gridpos_upperend_check( gp_lon_cloud[0], n3 );
271  gridpos_upperend_check( gp_lon_cloud[np-1], n3 );
272 
273  // Determine the pressure at each propagation path point
274  Matrix itw_p(np,2);
275  //
276  //interpweights( itw_p, ppath.gp_p );
277  interpweights( itw_p, gp_p_cloud );
278  itw2p( pressure, p_grid_cloud, gp_p_cloud, itw_p );
279 
280  // Determine the atmospheric temperature and species VMR at
281  // each propagation path point
282  Matrix itw_field;
283  //
284  interp_atmfield_gp2itw( itw_field, atmosphere_dim,
285  gp_p_cloud, gp_lat_cloud, gp_lon_cloud );
286  //
287  interp_atmfield_by_itw( temperature, atmosphere_dim, t_field_cloud,
288  gp_p_cloud, gp_lat_cloud, gp_lon_cloud,
289  itw_field );
290  //
291  for( Index is=0; is<ns; is++ )
292  {
293  interp_atmfield_by_itw( vmr(is, joker), atmosphere_dim,
294  vmr_field_cloud(is, joker, joker, joker),
295  gp_p_cloud, gp_lat_cloud,
296  gp_lon_cloud, itw_field );
297  }
298 
299  //Determine the particle number density for every particle type at
300  // each propagation path point
301  for( Index ip=0; ip<N_pt; ip++ )
302  {
303  // if grid positions still outside the range the propagation path step
304  // must be outside the cloudbox and pnd is set to zero
305  interp_atmfield_by_itw( pnd(ip, joker), atmosphere_dim,
306  pnd_field(ip, joker, joker, joker),
307  gp_p_cloud, gp_lat_cloud,
308  gp_lon_cloud, itw_field );
309  }
310 }
311 
312 
314 
326  Vector& cum_l_step,
327  const Ppath& ppath
328  )
329  {
330  cum_l_step.resize(ppath.np);
331  Numeric cumsum = 0.0;
332  cum_l_step[0] = 0.0;
333  for (Index i=0; i<ppath.np-1; i++)
334  {
335  cumsum += ppath.l_step[i];
336  cum_l_step[i+1] = cumsum;
337  }
338  }
339 
341 
351 void findZ11max(Vector& Z11maxvector,
352  const ArrayOfSingleScatteringData& scat_data_mono)
353 {
354  Index np=scat_data_mono.nelem();
355  Z11maxvector.resize(np);
356 
357  for(Index i = 0;i<np;i++)
358  {
359  switch(scat_data_mono[i].ptype){
361  {
362  Z11maxvector[i]=max(scat_data_mono[i].pha_mat_data(0,joker,joker,0,0,0,0));
363  }
365  {
366  Z11maxvector[i]=max(scat_data_mono[i].pha_mat_data(0,joker,joker,0,joker,0,0));
367  }
368  default:
369  Z11maxvector[i]=max(scat_data_mono[i].pha_mat_data(0,joker,joker,joker,joker,joker,0));
370  }
371  }
372 }
373 
374 
375 
376 
378 
388 bool is_anyptype30(const ArrayOfSingleScatteringData& scat_data_mono)
389 {
390  Index np=scat_data_mono.nelem();
391  bool anyptype30=false;
392  Index i=0;
393  while(i < np && anyptype30==false)
394  {
395  if(scat_data_mono[i].ptype==PARTICLE_TYPE_HORIZ_AL)
396  {
397  anyptype30=true;
398  }
399  i+=1;
400  }
401  return anyptype30;
402 }
403 
405 
418  Numeric& iwp,
419  Numeric& cloud_opt_path,
420  //input
421  const Vector& rte_pos,
422  const Vector& rte_los,
423  const Agenda& ppath_step_agenda,
424  const Vector& p_grid,
425  const Vector& lat_grid,
426  const Vector& lon_grid,
427  const Matrix& r_geoid,
428  const Matrix& z_surface,
429  const Tensor3& z_field,
430  const Tensor3& t_field,
431  const Tensor4& vmr_field,
432  const ArrayOfIndex& cloudbox_limits,
433  const Tensor4& pnd_field,
434  const ArrayOfSingleScatteringData& scat_data_mono,
435  const Vector& particle_masses,
436  const Verbosity& verbosity)
437 {
438  //internal declarations
439  Ppath ppath;
440  Vector local_rte_pos=rte_pos;
441  Vector local_rte_los=rte_los;
442  iwp=0;
443  cloud_opt_path=0;
444  //calculate ppath to cloudbox boundary
445  ppath_calc( ws, ppath, ppath_step_agenda, 3,
446  p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
447  1, cloudbox_limits, local_rte_pos, local_rte_los, 1,
448  verbosity );
449  //if this ppath hit a cloud, now take ppath inside cloud
450  if (ppath_what_background(ppath)>2)
451  {
452  //move to the intersection of the cloudbox boundary and the
453  //propagation path
454  local_rte_pos=ppath.pos(ppath.np-1,joker);
455  local_rte_los=ppath.los(ppath.np-1,joker);
456 
457  Range p_range(cloudbox_limits[0],
458  cloudbox_limits[1]-cloudbox_limits[0]+1);
459  Range lat_range(cloudbox_limits[2],
460  cloudbox_limits[3]-cloudbox_limits[2]+1);
461  Range lon_range(cloudbox_limits[4],
462  cloudbox_limits[5]-cloudbox_limits[4]+1);
463 
464  ppath_calc( ws, ppath, ppath_step_agenda, 3,
465  p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
466  1, cloudbox_limits, local_rte_pos, local_rte_los, 0,
467  verbosity );
468 
469  Matrix pnd_ppath(particle_masses.nelem(),ppath.np);
470  Vector t_ppath(ppath.np);
471  Vector p_ppath(ppath.np);
472  Matrix vmr_ppath(vmr_field.nbooks(),ppath.np);
473  Matrix ext_mat_part(1, 1, 0.0);
474  Vector abs_vec_part(1, 0.0);
475 
476  cloud_atm_vars_by_gp(p_ppath,t_ppath,vmr_ppath,pnd_ppath,ppath.gp_p,
477  ppath.gp_lat,ppath.gp_lon,cloudbox_limits,p_grid[p_range],
478  t_field(p_range,lat_range,lon_range),
479  vmr_field(joker,p_range,lat_range,lon_range),
480  pnd_field);
481 
482  Vector k_vec(ppath.np);
483  Vector iwc_vec(ppath.np);
484  //calculate integrands
485  for (Index i = 0; i < ppath.np ; ++i)
486  {
487  opt_propCalc(ext_mat_part,abs_vec_part,ppath.los(i,0),ppath.los(i,1),scat_data_mono,
488  1, pnd_ppath(joker, i), t_ppath[i], verbosity);
489  k_vec[i]=ext_mat_part(0,0);
490  Vector pnd_vec=pnd_ppath(joker, i);
491  assert(pnd_vec.nelem()==particle_masses.nelem());
492  iwc_vec[i]=pnd_vec*particle_masses;//hopefully this is the dot product
493  }
494  //integrate IWP and optical properties
495  for (Index i = 0; i < ppath.np-1 ; ++i)
496  {
497  //Add to path integrals
498  iwp+=0.5*(iwc_vec[i+1]+iwc_vec[i])*ppath.l_step[i];
499  cloud_opt_path+=0.5*(k_vec[i+1]+k_vec[i])*ppath.l_step[i];
500  }
501  }
502 }
503 
504 
506 
518  ConstMatrixView A)
519 {
520  Index m=A.nrows();
521  assert( A.ncols()==m );
522  M=0;
523  Numeric a=A(0,0);
524  Numeric b=A(0,1);
525  M(0,0)=cosh(b);
526  M(1,1)=cosh(b);
527  M(0,1)=sinh(b);
528  M(1,0)=sinh(b);
529  if ( m>2 )
530  {
531  Numeric c=A(2,3);
532  M(2,2)=cos(c);
533  if ( m > 3 )
534  {
535  M(2,3)=sin(c);
536  M(3,2)=-sin(c);
537  M(3,3)=cos(c); // Added by GH 2011-06-15 as per e-mail 2011-06-13
538  }
539  }
540  M*=exp(a);
541 }
542 
543 
544 
546 
558  MatrixView evol_op,
559  Vector& abs_vec_mono,
560  Numeric& temperature,
561  MatrixView ext_mat_mono,
562  Rng& rng,
563  Vector& rte_pos,
564  Vector& rte_los,
565  Vector& pnd_vec,
566  Numeric& g,
567  Ppath& ppath_step,
568  Index& termination_flag,
569  bool& inside_cloud,
570  //Numeric& rte_pressure,
571  //Vector& rte_vmr_list,
572  const Agenda& opt_prop_gas_agenda,
573  const Agenda& abs_scalar_gas_agenda,
574  const Index stokes_dim,
575  const Index f_index,
576  const Vector& p_grid,
577  const Vector& lat_grid,
578  const Vector& lon_grid,
579  const Tensor3& z_field,
580  const Matrix& r_geoid,
581  const Matrix& z_surface,
582  const Tensor3& t_field,
583  const Tensor4& vmr_field,
584  const ArrayOfIndex& cloudbox_limits,
585  const Tensor4& pnd_field,
586  const ArrayOfSingleScatteringData& scat_data_mono,
587  const Verbosity& verbosity)
588  // 2011-06-17 GH commented out, unused?
589  // const Index z_field_is_1D)
590 
591 {
592  ArrayOfMatrix evol_opArray(2);
593  ArrayOfMatrix ext_matArray(2);
594  ArrayOfVector abs_vecArray(2),pnd_vecArray(2);
595  Vector tArray(2);
596  Vector cum_l_step;
597  Matrix T(stokes_dim,stokes_dim);
598  Numeric k;
599  Numeric ds;
600  Index np=0;
601  Index istep = 0; // Counter for number of steps
602  Matrix opt_depth_mat(stokes_dim,stokes_dim),incT(stokes_dim,stokes_dim,0.0);
603  Matrix old_evol_op(stokes_dim,stokes_dim);
604  //g=0;k=0;ds=0;
605  //at the start of the path the evolution operator is the identity matrix
606  id_mat(evol_op);
607  evol_opArray[1]=evol_op;
608  //initialise Ppath with ppath_start_stepping
609  //Index rubbish=z_field_is_1D;rubbish+=1; // 2011-06-17 GH commented out, unused?
610  ppath_start_stepping( ppath_step, 3, p_grid, lat_grid,
611  lon_grid, z_field, r_geoid, z_surface,
612  0, cloudbox_limits, false,
613  rte_pos, rte_los, verbosity );
614  //Use cloudbox_ppath_start_stepping to avoid unnecessary z_at_latlon calls.
615  //cloudbox_ppath_start_stepping( ppath_step, 3, p_grid, lat_grid,
616  // lon_grid, z_field, r_geoid, z_surface, rte_pos,
617  // rte_los ,z_field_is_1D);
618  Range p_range(cloudbox_limits[0],
619  cloudbox_limits[1]-cloudbox_limits[0]+1);
620  Range lat_range(cloudbox_limits[2],
621  cloudbox_limits[3]-cloudbox_limits[2]+1);
622  Range lon_range(cloudbox_limits[4],
623  cloudbox_limits[5]-cloudbox_limits[4]+1);
624  termination_flag=0;
625 
626  inside_cloud=is_inside_cloudbox( ppath_step, cloudbox_limits,true );
627 
628  if (inside_cloud)
629  {
630  cloudy_rt_vars_at_gp(ws,ext_mat_mono,abs_vec_mono,pnd_vec,temperature,
631  opt_prop_gas_agenda,abs_scalar_gas_agenda,
632  stokes_dim, f_index, ppath_step.gp_p[0], ppath_step.gp_lat[0],
633  ppath_step.gp_lon[0],p_grid[p_range],
634  t_field(p_range,lat_range,lon_range),
635  vmr_field(joker,p_range,lat_range,lon_range),pnd_field,
636  scat_data_mono, cloudbox_limits,ppath_step.los(0,joker),
637  verbosity);
638  }
639  else
640  {
641  clear_rt_vars_at_gp( ws, ext_mat_mono, abs_vec_mono, temperature,
642  opt_prop_gas_agenda, abs_scalar_gas_agenda, f_index,
643  ppath_step.gp_p[0], ppath_step.gp_lat[0], ppath_step.gp_lon[0],
644  p_grid, t_field, vmr_field );
645  pnd_vec=0.0;
646  }
647  ext_matArray[1]=ext_mat_mono;
648  abs_vecArray[1]=abs_vec_mono;
649  tArray[1]=temperature;
650  pnd_vecArray[1]=pnd_vec;
651  //draw random number to determine end point
652  Numeric r = rng.draw();
653  while ((evol_op(0,0)>r)&(!termination_flag))
654  {
655  istep++;
656  //we consider more than 5000
657  // path points to be an indication on that the calcululations have
658  // got stuck in an infinite loop.
659  if( istep > 5000 )
660  {
661  throw runtime_error(
662  "5000 path points have been reached. Is this an infinite loop?" );
663  }
664  evol_opArray[0]=evol_opArray[1];
665  ext_matArray[0]=ext_matArray[1];
666  abs_vecArray[0]=abs_vecArray[1];
667  tArray[0]=tArray[1];
668  pnd_vecArray[0]=pnd_vecArray[1];
669  //perform single path step using ppath_step_geom_3d
670  ppath_step_geom_3d(ppath_step, p_grid, lat_grid, lon_grid, z_field,
671  r_geoid, z_surface, -1);
672  np=ppath_step.np;//I think this should always be 2.
673  cum_l_stepCalc(cum_l_step, ppath_step);
674  //path_step should now have two elements.
675  //calculate evol_op
676  inside_cloud=is_inside_cloudbox( ppath_step, cloudbox_limits, true );
677  if (inside_cloud)
678  {
679  cloudy_rt_vars_at_gp(ws,ext_mat_mono,abs_vec_mono,pnd_vec,temperature,
680  opt_prop_gas_agenda,abs_scalar_gas_agenda, stokes_dim, f_index,
681  ppath_step.gp_p[np-1],ppath_step.gp_lat[np-1],
682  ppath_step.gp_lon[np-1],p_grid[p_range],
683  t_field(p_range,lat_range,lon_range),
684  vmr_field(joker,p_range,lat_range,lon_range),pnd_field,
685  scat_data_mono, cloudbox_limits,ppath_step.los(np-1,joker),
686  verbosity);
687  }
688  else
689  {
690  clear_rt_vars_at_gp(ws, ext_mat_mono,abs_vec_mono,temperature,
691  opt_prop_gas_agenda, abs_scalar_gas_agenda, f_index,
692  ppath_step.gp_p[np-1], ppath_step.gp_lat[np-1],
693  ppath_step.gp_lon[np-1], p_grid, t_field, vmr_field);
694  pnd_vec=0.0;
695  }
696  ext_matArray[1]=ext_mat_mono;
697  abs_vecArray[1]=abs_vec_mono;
698  tArray[1]=temperature;
699  pnd_vecArray[1]=pnd_vec;
700  opt_depth_mat=ext_matArray[1];
701  opt_depth_mat+=ext_matArray[0];
702  opt_depth_mat*=-cum_l_step[np-1]/2;
703  incT=0;
704  if ( stokes_dim == 1 )
705  {
706  incT(0,0)=exp(opt_depth_mat(0,0));
707  }
708  else if ( is_diagonal( opt_depth_mat))
709  {
710  for ( Index j=0;j<stokes_dim;j++)
711  {
712  incT(j,j)=exp(opt_depth_mat(j,j));
713  }
714  }
715  else
716  {
717  //matrix_exp(incT,opt_depth_mat,10);
718  matrix_exp_p30(incT,opt_depth_mat);
719  }
720  mult(evol_op,evol_opArray[0],incT);
721  evol_opArray[1]=evol_op;
722 
723  //check whether hit ground or space
724  Index bg = ppath_what_background(ppath_step);
725  if ( bg==2 )
726  {
727  //we have hit the surface
728  termination_flag=2;
729 
730  }
731  //else if ( is_gridpos_at_index_i( ppath_step.gp_p[np-1], p_grid.nelem() - 1 ) )
732  else if (fractional_gp(ppath_step.gp_p[np-1])>=(Numeric)(p_grid.nelem() - 1)-1e-3)
733  {
734  //we have left the top of the atmosphere
735  termination_flag=1;
736 
737  }
738 
739 
740  }
741  if (termination_flag)
742  {//we must have reached the cloudbox boundary
743  //
744  rte_pos = ppath_step.pos(np-1,Range(0,3));
745  rte_los = ppath_step.los(np-1,joker);
746  g=evol_op(0,0);
747  }
748  else
749  {
750  //find position...and evol_op..and everything else required at the new
751  //scattering/emission point
752  // GH 2011-09-14:
753  // log(incT(0,0)) = log(exp(opt_depth_mat(0, 0))) = opt_depth_mat(0, 0)
754  // Avoid loss of precision, use opt_depth_mat directly
755  //k=-log(incT(0,0))/cum_l_step[np-1];//K=K11 only for diagonal ext_mat
756  k=-opt_depth_mat(0,0)/cum_l_step[np-1];//K=K11 only for diagonal ext_mat
757  ds=log(evol_opArray[0](0,0)/r)/k;
758  g=k*r;
759  Vector x(2,0.0);
760  //interpolate atmospheric variables required later
761  //length 2
762  ArrayOfGridPos gp(1);
763  x[1]=cum_l_step[np-1];
764  Vector itw(2);
765 
766  gridpos(gp, x, ds);
767  assert(gp[0].idx==0);
768  interpweights(itw,gp[0]);
769  interp(ext_mat_mono, itw, ext_matArray, gp[0]);
770  opt_depth_mat = ext_mat_mono;
771  opt_depth_mat+=ext_matArray[gp[0].idx];
772  opt_depth_mat*=-ds/2;
773  if ( stokes_dim == 1 )
774  {
775  incT(0,0)=exp(opt_depth_mat(0,0));
776  }
777  else if ( is_diagonal( opt_depth_mat))
778  {
779  for ( Index i=0;i<stokes_dim;i++)
780  {
781  incT(i,i)=exp(opt_depth_mat(i,i));
782  }
783  }
784  else
785  {
786  //matrix_exp(incT,opt_depth_mat,10);
787  matrix_exp_p30(incT,opt_depth_mat);
788  }
789  mult(evol_op,evol_opArray[gp[0].idx],incT);
790  interp(abs_vec_mono, itw, abs_vecArray,gp[0]);
791  temperature=interp(itw,tArray,gp[0]);
792  interp(pnd_vec, itw,pnd_vecArray,gp[0]);
793  if (np > 2)
794  {
795  gridpos(gp,cum_l_step,ds);
796  interpweights(itw,gp[0]);
797  }
798  for (Index i=0; i<2; i++)
799  {
800  rte_pos[i] = interp(itw,ppath_step.pos(Range(joker),i),gp[0]);
801  rte_los[i] = interp(itw,ppath_step.los(Range(joker),i),gp[0]);
802  }
803  rte_pos[2] = interp(itw,ppath_step.pos(Range(joker),2),gp[0]);
804  }
805  assert(isfinite(g));
806 }
807 
809 
822  MatrixView evol_op,
823  Vector& abs_vec_mono,
824  Numeric& temperature,
825  MatrixView ext_mat_mono,
826  Rng& rng,
827  Vector& rte_pos,
828  Vector& rte_los,
829  Vector& pnd_vec,
830  Numeric& g,
831  Index& termination_flag,
832  bool& inside_cloud,
833  const Agenda& opt_prop_gas_agenda,
834  const Agenda& abs_scalar_gas_agenda,
835  const Index stokes_dim,
836  const Index f_index,
837  const Vector& p_grid,
838  const Vector& lat_grid,
839  const Vector& lon_grid,
840  const Tensor3& z_field,
841  const Matrix& r_geoid,
842  const Matrix& z_surface,
843  const Tensor3& t_field,
844  const Tensor4& vmr_field,
845  const ArrayOfIndex& cloudbox_limits,
846  const Tensor4& pnd_field,
847  const ArrayOfSingleScatteringData& scat_data_mono,
848  const Index z_field_is_1D,
849  const Ppath& ppath,
850  const Verbosity& verbosity)
851 {
852 
853  //Internal declarations
854  ArrayOfMatrix evol_opArray(2);
855  ArrayOfMatrix ext_matArray(2);
856  ArrayOfVector abs_vecArray(2),pnd_vecArray(2);
857  GridPos gp_p,gp_lat,gp_lon;
858  Vector itw(4);
859  Vector tArray(2);
860  Vector cum_l_step;
861  Vector z_grid(p_grid.nelem());
862  Matrix T(stokes_dim,stokes_dim);
863  Numeric k;
864  Numeric x,y,z;
865  Numeric ds,lstep=0.,dx,dy,dz;
866  Index istep = 0; // Counter for number of steps
867  Matrix opt_depth_mat(stokes_dim,stokes_dim),incT(stokes_dim,stokes_dim,0.0);
868  Matrix old_evol_op(stokes_dim,stokes_dim);
869  Numeric rv_geoid=0.;
870  Numeric rv_surface=0.;
871  Numeric alt;
872  Numeric gpnum;
873  const Index np_ipa=ppath.np;
874  Index i_closest=0;
875  Numeric gp_diff;
876  Vector lon_iw(2),lat_iw(2);
877  Vector l_vec(2);
878  GridPos gp;
879  Vector itw1d(2);
880 
881  //Initialisations
882 
883  if (z_field_is_1D)
884  {
885  z_grid=z_field(joker,0,0);
886  rv_geoid=r_geoid(0,0);
887  rv_surface=rv_geoid+z_surface(0,0);
888  }
889 
890  id_mat(evol_op);
891  evol_opArray[1]=evol_op;
892  //initialise Ppath with ppath_start_stepping
893  //
894  Ppath ppath_step;
895  //
896  ppath_start_stepping( ppath_step, 3, p_grid, lat_grid,
897  lon_grid, z_field, r_geoid, z_surface,
898  0, cloudbox_limits, false,
899  rte_pos, rte_los, verbosity );
900 
901  gp_p=ppath_step.gp_p[0];
902  gp_lat=ppath_step.gp_lat[0];
903  gp_lon=ppath_step.gp_lon[0];
904  rte_pos=ppath_step.pos(0,joker);
905  rte_los=ppath_step.los(0,joker);
906 
907  Range p_range(cloudbox_limits[0],
908  cloudbox_limits[1]-cloudbox_limits[0]+1);
909  Range lat_range(cloudbox_limits[2],
910  cloudbox_limits[3]-cloudbox_limits[2]+1);
911  Range lon_range(cloudbox_limits[4],
912  cloudbox_limits[5]-cloudbox_limits[4]+1);
913  termination_flag=0;
914 
915  inside_cloud=is_inside_cloudbox( ppath_step, cloudbox_limits,false );
916 
917  if (inside_cloud)
918  {
919  cloudy_rt_vars_at_gp(ws, ext_mat_mono,abs_vec_mono,pnd_vec,temperature,
920  opt_prop_gas_agenda,abs_scalar_gas_agenda, stokes_dim, f_index,
921  gp_p, gp_lat, gp_lon,p_grid[p_range],
922  t_field(p_range,lat_range,lon_range),
923  vmr_field(joker,p_range,lat_range,lon_range),
924  pnd_field,scat_data_mono, cloudbox_limits,rte_los,
925  verbosity);
926  }
927  else
928  {
929  clear_rt_vars_at_gp( ws, ext_mat_mono,abs_vec_mono,temperature,
930  opt_prop_gas_agenda, abs_scalar_gas_agenda, f_index,
931  gp_p, gp_lat, gp_lon, p_grid, t_field, vmr_field);
932  pnd_vec=0.0;
933  }
934  ext_matArray[1]=ext_mat_mono;
935  abs_vecArray[1]=abs_vec_mono;
936  tArray[1]=temperature;
937  pnd_vecArray[1]=pnd_vec;
938  //draw random number to determine end point
939  Numeric r = rng.draw();
940  while ((evol_op(0,0)>r)&(!termination_flag))
941  {
942  //check we are not in an infinite loop (assert for ease of debugging
943  istep++;
944  assert(istep<=5000);
945 
946  //these array variables hold values from the two ends of a path step.
947  //Here we make the values for the last point of the previous step, the values
948  //for the first poinst of the current step.
949  evol_opArray[0]=evol_opArray[1];
950  ext_matArray[0]=ext_matArray[1];
951  abs_vecArray[0]=abs_vecArray[1];
952  tArray[0]=tArray[1];
953  pnd_vecArray[0]=pnd_vecArray[1];
954 
955  //Choose sensible path step length. This is done by considering the dimensions of the
956  //current grid cell and the LOS direction. The aim is to move only one grid cell.
957  //dy=cos(DEG2RAD*rte_los[1])*sin(DEG2RAD*rte_los[0])*
958  // (lat_grid[gp_lat.idx+1]-lat_grid[gp_lat.idx])*DEG2RAD*r_geoid(gp_lat.idx,gp_lon.idx);
959  //dx=sin(DEG2RAD*rte_los[1])*sin(DEG2RAD*rte_los[0])*
960  // (lon_grid[gp_lon.idx+1]-lon_grid[gp_lon.idx])*DEG2RAD*r_geoid(gp_lat.idx,gp_lon.idx)*
961  // cos(DEG2RAD*rte_pos[1]);
962  //dz=cos(DEG2RAD*rte_los[0])*(z_field(gp_p.idx+1,gp_lat.idx,gp_lon.idx)-
963  // z_field(gp_p.idx,gp_lat.idx,gp_lon.idx));
964  //lstep=sqrt(dx*dx+dy*dy+dz*dz);
965  //take the minimum grid dimension as the path step length
966  Numeric Dy=(lat_grid[gp_lat.idx+1]-lat_grid[gp_lat.idx])*DEG2RAD*
967  r_geoid(gp_lat.idx,gp_lon.idx);
968  Numeric Dx=(lon_grid[gp_lon.idx+1]-lon_grid[gp_lon.idx])*
969  DEG2RAD*r_geoid(gp_lat.idx,gp_lon.idx)*cos(DEG2RAD*rte_pos[1]);
970  Numeric Dz=z_field(gp_p.idx+1,gp_lat.idx,gp_lon.idx)-
971  z_field(gp_p.idx,gp_lat.idx,gp_lon.idx);
972  Numeric Dxy=sqrt(Dx*Dx+Dy*Dy);
973  if (Dxy/abs(tan(rte_los[0]*DEG2RAD))>Dz){dz=Dz;}
974  else {dz=Dxy/abs(tan(rte_los[0]*DEG2RAD));}
975  Numeric dxy;
976  if(dz*abs(tan(rte_los[0]*DEG2RAD))>Dxy){dxy=Dxy;}
977  else{dxy=dz*abs(tan(rte_los[0]*DEG2RAD));}
978  lstep=sqrt(dxy*dxy+dz*dz);
979  //calculate new position
980  //current position and direction vector
981  poslos2cart( x, y, z, dx, dy, dz, rte_pos[0], rte_pos[1], rte_pos[2],
982  rte_los[0], rte_los[1] );
983  //new_position
984  x+=lstep*dx;
985  y+=lstep*dy;
986  z+=lstep*dz;
987  //back to spherical coords
988  cart2poslos(rte_pos[0],rte_pos[1],rte_pos[2],rte_los[0],rte_los[1],
989  x,y,z,dx,dy,dz);
990  //get new grid_positions
991  gridpos( gp_lat, lat_grid, rte_pos[1] );
992  gridpos( gp_lon, lon_grid, rte_pos[2] );
993  if (!z_field_is_1D)
994  {
995  z_at_latlon( z_grid, p_grid, lat_grid, lon_grid, z_field, gp_lat, gp_lon );
996  interpweights( itw, gp_lat, gp_lon );
997  rv_geoid = interp( itw, r_geoid, gp_lat, gp_lon );
998  rv_surface = rv_geoid + interp( itw, z_surface, gp_lat, gp_lon );
999  }
1000  alt = rte_pos[0] - rv_geoid;
1001  //Have we left the top of the atmosphere?
1002  if ((alt>=z_grid[p_grid.nelem()-1])&(rte_los[0]<=90))
1003  {
1004  termination_flag=1;
1005  //shift relavent position variables to the appropriate point
1006  //z is linearly interpolated with respect to lat and lon
1007  //I don't think this is overly important. Just change gp_p and rte_pos
1008  alt=z_grid[p_grid.nelem()-1];
1009  rte_pos[0]=alt+rv_geoid;
1010  }
1011  //Have we hit the surface?
1012  if( (rte_pos[0] <= rv_surface)&(rte_los[0]>=90) )
1013  {
1014  termination_flag=2;
1015  rte_pos[0]=rv_surface;
1016  alt = rte_pos[0] - rv_geoid;
1017  }
1018  gridpos( gp_p, z_grid, alt );
1019 
1020  //now project the new point back to the original IPA path
1021  //find lat and lon gridpoints on reference ppath_ipa
1022  gpnum=fractional_gp(gp_p);
1023  //search through ppath_ipa to find the closest grid point
1024  gp_diff=abs(fractional_gp(ppath.gp_p[0])-gpnum);
1025  for (Index i=1;i<np_ipa;i++)
1026  {
1027  Numeric new_gp_diff=abs(fractional_gp(ppath.gp_p[i])-gpnum);
1028  if (new_gp_diff<=gp_diff)
1029  {
1030  gp_diff=new_gp_diff;
1031  i_closest=i;
1032  }
1033  else
1034  {
1035  //getting further away - can stop now
1036  break;
1037  }
1038  }
1039  gp_lat=ppath.gp_lat[i_closest];
1040  gp_lon=ppath.gp_lon[i_closest];
1041  interpweights(lon_iw,gp_lon);
1042  interpweights(lat_iw,gp_lat);
1043  //
1044  if (!z_field_is_1D)
1045  {
1046  interpweights( itw, gp_lat, gp_lon );
1047  rv_geoid = interp( itw, r_geoid, gp_lat, gp_lon );
1048  }
1049  rte_pos[0]=rv_geoid+interp_atmfield_by_gp(3,z_field,
1050  gp_p,gp_lat,gp_lon);
1051  rte_pos[1]=interp(lat_iw, lat_grid,gp_lat);
1052  rte_pos[2]=interp(lon_iw, lon_grid,gp_lon);
1053 
1054  //calculate evolution operator
1055  inside_cloud=is_gp_inside_cloudbox(gp_p,gp_lat,gp_lon,
1056  cloudbox_limits, false );
1057  //calculate RT variables at new point
1058  if (inside_cloud)
1059  {
1061  ext_mat_mono, abs_vec_mono, pnd_vec, temperature,
1062  opt_prop_gas_agenda, abs_scalar_gas_agenda, stokes_dim,
1063  f_index, gp_p,gp_lat, gp_lon, p_grid[p_range],
1064  t_field(p_range,lat_range,lon_range),
1065  vmr_field(joker,p_range,lat_range,lon_range),
1066  pnd_field, scat_data_mono, cloudbox_limits,rte_los,
1067  verbosity);
1068  }
1069  else
1070  {
1071  clear_rt_vars_at_gp( ws, ext_mat_mono, abs_vec_mono, temperature,
1072  opt_prop_gas_agenda, abs_scalar_gas_agenda, f_index,
1073  gp_p, gp_lat, gp_lon, p_grid, t_field, vmr_field);
1074  pnd_vec=0.0;
1075  }
1076  //put these variables in the last Array slot
1077  ext_matArray[1]=ext_mat_mono;
1078  abs_vecArray[1]=abs_vec_mono;
1079  tArray[1]=temperature;
1080  pnd_vecArray[1]=pnd_vec;
1081  opt_depth_mat=ext_matArray[1];
1082  //now calculate evolution operator
1083  opt_depth_mat+=ext_matArray[0];
1084  opt_depth_mat*=-lstep/2;
1085  incT=0;
1086  if ( stokes_dim == 1 )
1087  {
1088  incT(0,0)=exp(opt_depth_mat(0,0));
1089  }
1090  else if ( is_diagonal( opt_depth_mat))
1091  {
1092  for ( Index j=0;j<stokes_dim;j++)
1093  {
1094  incT(j,j)=exp(opt_depth_mat(j,j));
1095  }
1096  }
1097  else
1098  {
1099  matrix_exp_p30(incT,opt_depth_mat);
1100  }
1101  mult(evol_op,evol_opArray[0],incT);
1102  assert(incT(0,0)<1);
1103  assert(evol_op(0,0)<1);
1104  evol_opArray[1]=evol_op;
1105 
1106  }
1107  if (termination_flag)
1108  {
1109  //we must have reached the surface or the TOA
1110  g=evol_op(0,0);
1111  }
1112  else
1113  {
1114  //then we have met the monte carlo pathlength criteria somewhere inside
1115  //the atmosphere and between the two points corresponding to the *Array
1116  //variables.
1117 
1118  //find position corresponding to the pathlength criteria
1119  k=-log(incT(0,0))/lstep;
1120  //length of path segment required by critera
1121  ds=log(evol_opArray[0](0,0)/r)/k;
1122  g=k*r;
1123  l_vec=0.0;
1124  l_vec[1]=lstep;
1125  //gridpos and interpolations for required step length
1126  gridpos(gp, l_vec, ds);
1127  interpweights(itw1d,gp);
1128  //interpolate optical properties at required point
1129  interp(ext_mat_mono, itw1d, ext_matArray, gp);
1130  opt_depth_mat = ext_mat_mono;
1131  opt_depth_mat+=ext_matArray[gp.idx];
1132  opt_depth_mat*=-ds/2;
1133  if ( stokes_dim == 1 )
1134  {
1135  incT(0,0)=exp(opt_depth_mat(0,0));
1136  }
1137  else if ( is_diagonal( opt_depth_mat))
1138  {
1139  for ( Index i=0;i<stokes_dim;i++)
1140  {
1141  incT(i,i)=exp(opt_depth_mat(i,i));
1142  }
1143  }
1144  else
1145  {
1146  //matrix_exp(incT,opt_depth_mat,10);
1147  matrix_exp_p30(incT,opt_depth_mat);
1148  }
1149  mult(evol_op,evol_opArray[gp.idx],incT);
1150  interp(abs_vec_mono, itw1d, abs_vecArray,gp);
1151  temperature=interp(itw1d,tArray, gp);
1152  interp(pnd_vec, itw1d, pnd_vecArray, gp);
1153  //move cartesion coordinates back to required point.
1154  x+=(ds-lstep)*dx;
1155  y+=(ds-lstep)*dy;
1156  z+=(ds-lstep)*dz;
1157  //and convert back to spherical.
1158  cart2poslos(rte_pos[0],rte_pos[1],rte_pos[2],rte_los[0],rte_los[1],x,y,z,dx,dy,dz);
1159 
1160  }
1161 }
1162 
1164 
1181  MatrixView ext_mat_mono,
1182  VectorView abs_vec_mono,
1183  const Numeric za,
1184  const Numeric aa,
1185  const ArrayOfSingleScatteringData& scat_data_mono,
1186  const Index stokes_dim,
1187  ConstVectorView pnd_vec,
1188  const Numeric rte_temperature,
1189  const Verbosity& verbosity
1190  )
1191 {
1192  assert( stokes_dim>=1 && stokes_dim<=4 );
1193  assert( ext_mat_mono.nrows() == stokes_dim );
1194  assert( ext_mat_mono.ncols() == stokes_dim );
1195  assert( abs_vec_mono.nelem() == stokes_dim );
1196 
1197  const Index N_pt = scat_data_mono.nelem();
1198 
1199  Matrix ext_mat_mono_spt(stokes_dim,stokes_dim);
1200  Vector abs_vec_mono_spt(stokes_dim);
1201 
1202  ext_mat_mono=0.0;
1203  abs_vec_mono=0.0;
1204 
1205  // Loop over the included particle_types
1206  for (Index i_pt = 0; i_pt < N_pt; i_pt++)
1207  {
1208  if (pnd_vec[i_pt]>0)
1209  {
1210  opt_propExtract(ext_mat_mono_spt,abs_vec_mono_spt,scat_data_mono[i_pt],za,aa,
1211  rte_temperature,stokes_dim, verbosity);
1212  ext_mat_mono_spt*=pnd_vec[i_pt];
1213  abs_vec_mono_spt*=pnd_vec[i_pt];
1214  ext_mat_mono+=ext_mat_mono_spt;
1215  abs_vec_mono+=abs_vec_mono_spt;
1216  }
1217  }
1218 }
1219 
1220 /* PE 2011-07-07
1221 void opt_propCalc2(
1222  MatrixView ext_mat_mono,
1223  VectorView abs_vec_mono,
1224  const Numeric za,
1225  const Numeric aa,
1226  const ArrayOfSingleScatteringData& scat_data_mono,
1227  const Index stokes_dim,
1228  ConstVectorView pnd_vec,
1229  const Numeric rte_temperature
1230  )
1231 {
1232  const Index N_pt = scat_data_mono.nelem();
1233 
1234  if (stokes_dim > 4 || stokes_dim < 1){
1235  throw runtime_error("The dimension of the stokes vector \n"
1236  "must be 1,2,3 or 4");
1237  }
1238  Matrix ext_mat_mono_spt(stokes_dim,stokes_dim);
1239  Vector abs_vec_mono_spt(stokes_dim);
1240 
1241  ext_mat_mono=0.0;
1242  abs_vec_mono=0.0;
1243 
1244  // Loop over the included particle_types
1245  for (Index i_pt = 0; i_pt < N_pt; i_pt++)
1246  {
1247  if (pnd_vec[i_pt]>0)
1248  {
1249  opt_propExtract(ext_mat_mono_spt,abs_vec_mono_spt,scat_data_mono[i_pt],za,aa,
1250  rte_temperature,stokes_dim);
1251  ext_mat_mono_spt*=pnd_vec[i_pt];
1252  abs_vec_mono_spt*=pnd_vec[i_pt];
1253  ext_mat_mono+=ext_mat_mono_spt;
1254  abs_vec_mono+=abs_vec_mono_spt;
1255  }
1256  }
1257 }
1258 */
1260 
1280  MatrixView ext_mat_mono_spt,
1281  VectorView abs_vec_mono_spt,
1282  const SingleScatteringData& scat_data,
1283  const Numeric za,
1284  const Numeric aa _U_, // avoid warning until we use ptype=10
1285  const Numeric rte_temperature,
1286  const Index stokes_dim,
1287  const Verbosity& verbosity
1288  )
1289 {
1290 
1291  GridPos t_gp;
1292  //interpolate over temperature
1293  if( scat_data.T_grid.nelem() > 1)
1294  {
1295  gridpos(t_gp, scat_data.T_grid, rte_temperature);
1296  }
1297  switch (scat_data.ptype){
1298 
1299  case PARTICLE_TYPE_GENERAL:
1300  {
1301  // This is only included to remove warnings about unused variables
1302  // during compilation
1303  CREATE_OUT0
1304  out0 << "Case PARTICLE_TYPE_GENERAL not yet implemented. \n";
1305  break;
1306  }
1308  {
1309  assert (scat_data.ext_mat_data.ncols() == 1);
1310 
1311  Vector itw(2);
1312  //interpolate over temperature
1313  if( scat_data.T_grid.nelem() > 1)
1314  {
1315  interpweights(itw, t_gp);
1316  }
1317  // In the case of randomly oriented particles the extinction matrix is
1318  // diagonal. The value of each element of the diagonal is the
1319  // extinction cross section, which is stored in the database.
1320 
1321  ext_mat_mono_spt = 0.;
1322  abs_vec_mono_spt = 0;
1323 
1324  if( scat_data.T_grid.nelem() == 1)
1325  {
1326  ext_mat_mono_spt(0,0) = scat_data.ext_mat_data(0,0,0,0,0);
1327  abs_vec_mono_spt[0] = scat_data.abs_vec_data(0,0,0,0,0);
1328  }
1329  // Temperature interpolation
1330  else
1331  {
1332  ext_mat_mono_spt(0,0) = interp(itw,scat_data.ext_mat_data(0,joker,0,0,0),t_gp);
1333  abs_vec_mono_spt[0] = interp(itw,scat_data.abs_vec_data(0,joker,0,0,0),t_gp);
1334  }
1335 
1336  if( stokes_dim == 1 ){
1337  break;
1338  }
1339 
1340  ext_mat_mono_spt(1,1) = ext_mat_mono_spt(0,0);
1341 
1342  if( stokes_dim == 2 ){
1343  break;
1344  }
1345 
1346  ext_mat_mono_spt(2,2) = ext_mat_mono_spt(0,0);
1347 
1348  if( stokes_dim == 3 ){
1349  break;
1350  }
1351 
1352  ext_mat_mono_spt(3,3) = ext_mat_mono_spt(0,0);
1353  break;
1354  }
1355 
1356  case PARTICLE_TYPE_HORIZ_AL://Added by Cory Davis 9/12/03
1357  {
1358  assert (scat_data.ext_mat_data.ncols() == 3);
1359 
1360  // In the case of horizontally oriented particles the extinction matrix
1361  // has only 3 independent non-zero elements ext_mat_monojj, K12=K21, and K34=-K43.
1362  // These values are dependent on the zenith angle of propagation. The
1363  // data storage format also makes use of the fact that in this case
1364  //K(za_sca)=K(180-za_sca).
1365 
1366  // 1st interpolate data by za_sca
1367  GridPos za_gp;
1368  Vector itw(4);
1369  Numeric Kjj;
1370  Numeric K12;
1371  Numeric K34;
1372 
1373  if( scat_data.T_grid.nelem() == 1)
1374  {
1375  ostringstream os;
1376  os << "Given optical property data is for constant temperature only.\n"
1377  "MC with p30 requires temperature-dependent optical property data\n";
1378  throw runtime_error( os.str() );
1379  }
1380 
1381  if (za>90)
1382  {
1383  gridpos(za_gp,scat_data.za_grid,180-za);
1384  }
1385  else
1386  {
1387  gridpos(za_gp,scat_data.za_grid,za);
1388  }
1389 
1390  interpweights(itw,t_gp,za_gp);
1391 
1392  ext_mat_mono_spt=0.0;
1393  abs_vec_mono_spt=0.0;
1394  Kjj=interp(itw,scat_data.ext_mat_data(0,joker,joker,0,0),t_gp,za_gp);
1395  ext_mat_mono_spt(0,0)=Kjj;
1396  abs_vec_mono_spt[0] = interp(itw,scat_data.abs_vec_data(0,joker,joker,0,0),
1397  t_gp,za_gp);
1398  if( stokes_dim == 1 ){
1399  break;
1400  }
1401 
1402  K12=interp(itw,scat_data.ext_mat_data(0,joker,joker,0,1),t_gp,za_gp);
1403  ext_mat_mono_spt(1,1)=Kjj;
1404  ext_mat_mono_spt(0,1)=K12;
1405  ext_mat_mono_spt(1,0)=K12;
1406  abs_vec_mono_spt[1] = interp(itw,scat_data.abs_vec_data(0,joker,joker,0,1),
1407  t_gp,za_gp);
1408 
1409  if( stokes_dim == 2 ){
1410  break;
1411  }
1412 
1413  ext_mat_mono_spt(2,2)=Kjj;
1414 
1415  if( stokes_dim == 3 ){
1416  break;
1417  }
1418 
1419  K34=interp(itw,scat_data.ext_mat_data(0,joker,joker,0,2),t_gp,za_gp);
1420  ext_mat_mono_spt(2,3)=K34;
1421  ext_mat_mono_spt(3,2)=-K34;
1422  ext_mat_mono_spt(3,3)=Kjj;
1423  break;
1424 
1425  }
1426  default:
1427  {
1428  CREATE_OUT0
1429  out0 << "Not all particle type cases are implemented\n";
1430  }
1431 
1432  }
1433 
1434 
1435 }
1436 
1437 
1439 
1457  MatrixView Z,
1458  const Numeric za_sca,
1459  const Numeric aa_sca,
1460  const Numeric za_inc,
1461  const Numeric aa_inc,
1462  const ArrayOfSingleScatteringData& scat_data_mono,
1463  const Index stokes_dim,
1464  ConstVectorView pnd_vec,
1465  const Numeric rte_temperature,
1466  const Verbosity& verbosity
1467  )
1468 {
1469  Index N_pt=pnd_vec.nelem();
1470 
1471  assert(aa_inc>=-180 && aa_inc<=180);
1472  assert(aa_sca>=-180 && aa_sca<=180);
1473 
1474  Matrix Z_spt(stokes_dim, stokes_dim, 0.);
1475  Z=0.0;
1476  // this is a loop over the different particle types
1477  for (Index i_pt = 0; i_pt < N_pt; i_pt++)
1478  {
1479  if (pnd_vec[i_pt]>0)
1480  {
1481  pha_mat_singleExtract(Z_spt,scat_data_mono[i_pt],za_sca,aa_sca,za_inc,
1482  aa_inc,rte_temperature,stokes_dim,verbosity);
1483  Z_spt*=pnd_vec[i_pt];
1484  Z+=Z_spt;
1485  }
1486  }
1487 }
1488 
1490 
1508  MatrixView Z_spt,
1509  const SingleScatteringData& scat_data,
1510  const Numeric za_sca,
1511  const Numeric aa_sca,
1512  const Numeric za_inc,
1513  const Numeric aa_inc,
1514  const Numeric rte_temperature,
1515  const Index stokes_dim,
1516  const Verbosity& verbosity
1517  )
1518 {
1519  switch (scat_data.ptype){
1520 
1521  case PARTICLE_TYPE_GENERAL:
1522  {
1523  // to remove warnings during compilation.
1524  CREATE_OUT0
1525  out0 << "Case PARTICLE_TYPE_GENERAL not yet implemented. \n";
1526  break;
1527  }
1529  {
1530  // Calculate the scattering and interpolate the data on the scattering
1531  // angle:
1532 
1533  Vector pha_mat_int(6);
1534  Numeric theta_rad;
1535 
1536  // Interpolation of the data on the scattering angle:
1537  interp_scat_angle_temperature(pha_mat_int, theta_rad,
1538  scat_data, za_sca, aa_sca,
1539  za_inc, aa_inc, rte_temperature);
1540 
1541  // Caclulate the phase matrix in the laboratory frame:
1542  pha_mat_labCalc(Z_spt, pha_mat_int, za_sca, aa_sca, za_inc, aa_inc, theta_rad);
1543 
1544  break;
1545  }
1546 
1547  case PARTICLE_TYPE_HORIZ_AL://Added by Cory Davis
1548  //Data is already stored in the laboratory frame, but it is compressed
1549  //a little. Details elsewhere
1550  {
1551  assert (scat_data.pha_mat_data.ncols()==16);
1552  Numeric delta_aa=aa_sca-aa_inc+(aa_sca-aa_inc<-180)*360-
1553  (aa_sca-aa_inc>180)*360;//delta_aa corresponds to the "pages"
1554  //dimension of pha_mat_data
1555  GridPos t_gp;
1556  GridPos za_sca_gp;
1557  GridPos delta_aa_gp;
1558  GridPos za_inc_gp;
1559  Vector itw(16);
1560 
1561  if( scat_data.T_grid.nelem() == 1)
1562  {
1563  ostringstream os;
1564  os << "Given optical property data is for constant temperature only.\n"
1565  "MC with p30 requires temperature-dependent optical property data\n";
1566  throw runtime_error( os.str() );
1567  }
1568 
1569  gridpos(t_gp, scat_data.T_grid, rte_temperature);
1570  gridpos(delta_aa_gp,scat_data.aa_grid,abs(delta_aa));
1571  if (za_inc>90)
1572  {
1573  gridpos(za_inc_gp,scat_data.za_grid,180-za_inc);
1574  gridpos(za_sca_gp,scat_data.za_grid,180-za_sca);
1575  }
1576  else
1577  {
1578  gridpos(za_inc_gp,scat_data.za_grid,za_inc);
1579  gridpos(za_sca_gp,scat_data.za_grid,za_sca);
1580  }
1581 
1582  interpweights(itw,t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1583 
1584  Z_spt(0,0)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1585  Range(joker),0,0),
1586  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1587  if( stokes_dim == 1 ){
1588  break;
1589  }
1590  Z_spt(0,1)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1591  Range(joker),0,1),
1592  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1593  Z_spt(1,0)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1594  Range(joker),0,4),
1595  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1596  Z_spt(1,1)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1597  Range(joker),0,5),
1598  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1599  if( stokes_dim == 2 ){
1600  break;
1601  }
1602  if ((za_inc<=90 && delta_aa>=0)||(za_inc>90 && delta_aa<0))
1603  {
1604  Z_spt(0,2)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1605  Range(joker),0,2),
1606  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1607  Z_spt(1,2)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1608  Range(joker),0,6),
1609  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1610  Z_spt(2,0)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1611  Range(joker),0,8),
1612  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1613  Z_spt(2,1)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1614  Range(joker),0,9),
1615  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1616  }
1617  else
1618  {
1619  Z_spt(0,2)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1620  Range(joker),0,2),
1621  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1622  Z_spt(1,2)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1623  Range(joker),0,6),
1624  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1625  Z_spt(2,0)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1626  Range(joker),0,8),
1627  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1628  Z_spt(2,1)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1629  Range(joker),0,9),
1630  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1631  }
1632  Z_spt(2,2)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1633  Range(joker),0,10),
1634  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1635  if( stokes_dim == 3 ){
1636  break;
1637  }
1638  if ((za_inc<=90 && delta_aa>=0)||(za_inc>90 && delta_aa<0))
1639  {
1640  Z_spt(0,3)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1641  Range(joker),0,3),
1642  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1643  Z_spt(1,3)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1644  Range(joker),0,7),
1645  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1646  Z_spt(3,0)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1647  Range(joker),0,12),
1648  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1649  Z_spt(3,1)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1650  Range(joker),0,13),
1651  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1652  }
1653  else
1654  {
1655  Z_spt(0,3)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1656  Range(joker),0,3),
1657  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1658  Z_spt(1,3)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1659  Range(joker),0,7),
1660  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1661  Z_spt(3,0)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1662  Range(joker),0,12),
1663  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1664  Z_spt(3,1)=-interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1665  Range(joker),0,13),
1666  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1667  }
1668  Z_spt(2,3)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1669  Range(joker),0,11),
1670  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1671  Z_spt(3,2)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1672  Range(joker),0,14),
1673  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1674  Z_spt(3,3)=interp(itw,scat_data.pha_mat_data(0,joker,Range(joker),Range(joker),
1675  Range(joker),0,15),
1676  t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1677  break;
1678 
1679  }
1680  default:
1681  CREATE_OUT0
1682  out0 << "Not all particle type cases are implemented\n";
1683 
1684  }
1685 }
1686 
1687 
1689 
1713  VectorView new_rte_los,
1714  Numeric& g_los_csc_theta,
1715  MatrixView Z,
1716  Rng& rng,
1717  ConstVectorView rte_los,
1718  const ArrayOfSingleScatteringData& scat_data_mono,
1719  const Index stokes_dim,
1720  ConstVectorView pnd_vec,
1721  const bool anyptype30,
1722  ConstVectorView Z11maxvector,
1723  const Numeric Csca,
1724  const Numeric rte_temperature,
1725  const Verbosity& verbosity
1726  )
1727 {
1728  Numeric Z11max=0;
1729  bool tryagain=true;
1730  Numeric aa_scat = (rte_los[1]>=0) ?-180+rte_los[1]:180+rte_los[1];
1731 
1732  // Rejection method http://en.wikipedia.org/wiki/Rejection_sampling
1733  if(anyptype30)
1734  {
1735  Index np=pnd_vec.nelem();
1736  assert(scat_data_mono.nelem()==np);
1737  for(Index i=0;i<np;i++)
1738  {
1739  Z11max+=Z11maxvector[i]*pnd_vec[i];
1740  }
1741  }
1742  else
1743  {
1744  Matrix dummyZ(stokes_dim,stokes_dim);
1745  //The following is based on the assumption that the maximum value of the
1746  //phase matrix for a given scattered direction is for forward scattering
1747  pha_mat_singleCalc(dummyZ,180-rte_los[0],aa_scat,180-rte_los[0],
1748  aa_scat,scat_data_mono,stokes_dim,pnd_vec,rte_temperature,
1749  verbosity);
1750  Z11max=dummyZ(0,0);
1751  }
1753  while(tryagain)
1754  {
1755  new_rte_los[1] = rng.draw()*360-180;
1756  new_rte_los[0] = acos(1-2*rng.draw())*RAD2DEG;
1757  //Calculate Phase matrix////////////////////////////////
1758  Numeric aa_inc= (new_rte_los[1]>=0) ?
1759  -180+new_rte_los[1]:180+new_rte_los[1];
1760 
1761  pha_mat_singleCalc(Z,180-rte_los[0],aa_scat,180-new_rte_los[0],
1762  aa_inc,scat_data_mono,stokes_dim,pnd_vec,rte_temperature,
1763  verbosity);
1764 
1765  if (rng.draw()<=Z(0,0)/Z11max)//then new los is accepted
1766  {
1767  tryagain=false;
1768  }
1769  }
1770  g_los_csc_theta =Z(0,0)/Csca;
1771 }
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
cloudy_rt_vars_at_gp
void cloudy_rt_vars_at_gp(Workspace &ws, MatrixView ext_mat_mono, VectorView abs_vec_mono, VectorView pnd_vec, Numeric &temperature, const Agenda &opt_prop_gas_agenda, const Agenda &abs_scalar_gas_agenda, const Index stokes_dim, const Index f_index, const GridPos &gp_p, const GridPos &gp_lat, const GridPos &gp_lon, ConstVectorView p_grid_cloud, ConstTensor3View t_field_cloud, ConstTensor4View vmr_field_cloud, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_mono, const ArrayOfIndex &cloudbox_limits, const Vector &rte_los, const Verbosity &verbosity)
cloudy_rt_vars_at_gp
Definition: montecarlo.cc:129
SingleScatteringData::za_grid
Vector za_grid
Definition: optproperties.h:79
MatrixView
The MatrixView class.
Definition: matpackI.h:668
PARTICLE_TYPE_GENERAL
@ PARTICLE_TYPE_GENERAL
Definition: optproperties.h:56
ppath_start_stepping
void ppath_start_stepping(Ppath &ppath, const Index &atmosphere_dim, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstMatrixView r_geoid, ConstMatrixView z_surface, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const bool &outside_cloudbox, ConstVectorView rte_pos, ConstVectorView rte_los, const Verbosity &verbosity)
ppath_start_stepping
Definition: ppath.cc:5164
auto_md.h
matrix_exp_p30
void matrix_exp_p30(MatrixView M, ConstMatrixView A)
matrix_exp_p30
Definition: montecarlo.cc:517
opt_propCalc
void opt_propCalc(MatrixView ext_mat_mono, VectorView abs_vec_mono, const Numeric za, const Numeric aa, const ArrayOfSingleScatteringData &scat_data_mono, const Index stokes_dim, ConstVectorView pnd_vec, const Numeric rte_temperature, const Verbosity &verbosity)
opt_propCalc
Definition: montecarlo.cc:1180
gridpos
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
Definition: interpolation.cc:167
abs_scalar_gas_agendaExecute
void abs_scalar_gas_agendaExecute(Workspace &ws, Matrix &abs_scalar_gas, const Index f_index, const Numeric rte_doppler, const Numeric rte_pressure, const Numeric rte_temperature, const Vector &rte_vmr_list, const Agenda &input_agenda)
Definition: auto_md.cc:9032
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.
itw2p
void itw2p(VectorView p_values, ConstVectorView p_grid, const ArrayOfGridPos &gp, ConstMatrixView itw)
itw2p
Definition: special_interp.cc:763
ConstTensor5View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackV.cc:56
RAD2DEG
const Numeric RAD2DEG
Global constant, conversion from radians to degrees.
ConstTensor7View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackVII.cc:67
is_diagonal
bool is_diagonal(ConstMatrixView A)
Checks if a square matrix is diagonal.
Definition: logic.cc:387
joker
const Joker joker
interp
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
Definition: interpolation.cc:1000
poslos2cart
void poslos2cart(double &x, double &y, double &z, double &dx, double &dy, double &dz, const double &r, const double &lat, const double &lon, const double &za, const double &aa)
poslos2cart
Definition: ppath.cc:567
SingleScatteringData::ptype
ParticleType ptype
Definition: optproperties.h:75
opt_prop_gas_agendaExecute
void opt_prop_gas_agendaExecute(Workspace &ws, Tensor3 &ext_mat, Matrix &abs_vec, const Index f_index, const Matrix &abs_scalar_gas, const Agenda &input_agenda)
Definition: auto_md.cc:10073
z_at_latlon
void z_at_latlon(VectorView z, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, const GridPos &gp_lat, const GridPos &gp_lon)
z_at_latlon
Definition: special_interp.cc:934
interp_atmfield_by_itw
void interp_atmfield_by_itw(VectorView x, const Index &atmosphere_dim, ConstTensor3View x_field, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon, ConstMatrixView itw)
interp_atmfield_by_itw
Definition: special_interp.cc:159
is_gp_inside_cloudbox
bool is_gp_inside_cloudbox(const GridPos &gp_p, const GridPos &gp_lat, const GridPos &gp_lon, const ArrayOfIndex &cloudbox_limits, const bool include_boundaries)
Definition: cloudbox.cc:689
SingleScatteringData::aa_grid
Vector aa_grid
Definition: optproperties.h:80
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:771
PARTICLE_TYPE_MACROS_ISO
@ PARTICLE_TYPE_MACROS_ISO
Definition: optproperties.h:57
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
fractional_gp
Numeric fractional_gp(const GridPos &gp)
fractional_gp
Definition: interpolation.cc:504
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
DEG2RAD
const Numeric DEG2RAD
Global constant, conversion from degrees to radians.
montecarlo.h
Tensor4
The Tensor4 class.
Definition: matpackIV.h:375
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
Agenda
The Agenda class.
Definition: agenda_class.h:44
SingleScatteringData
Structure which describes the single scattering properties of a.
Definition: optproperties.h:74
dx
#define dx
Definition: continua.cc:14561
ConstTensor4View
A constant view of a Tensor4.
Definition: matpackIV.h:149
Array< GridPos >
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
CREATE_OUT0
#define CREATE_OUT0
Definition: messages.h:205
Ppath::gp_lat
ArrayOfGridPos gp_lat
Definition: ppath.h:67
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
gridpos_upperend_check
void gridpos_upperend_check(GridPos &gp, const Index &ie)
gridpos_upperend_check
Definition: interpolation.cc:608
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
_U_
#define _U_
Definition: config.h:158
abs
#define abs(x)
Definition: continua.cc:13094
Ppath::los
Matrix los
Definition: ppath.h:69
SingleScatteringData::ext_mat_data
Tensor5 ext_mat_data
Definition: optproperties.h:82
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
VectorView
The VectorView class.
Definition: matpackI.h:373
is_inside_cloudbox
bool is_inside_cloudbox(const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, const bool include_boundaries)
Definition: cloudbox.cc:764
ns
#define ns
Definition: continua.cc:14564
ppath_step_geom_3d
void ppath_step_geom_3d(Ppath &ppath, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstMatrixView r_geoid, ConstMatrixView z_surface, const double &lmax)
ppath_step_geom_3d
Definition: ppath.cc:3956
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Verbosity
Definition: messages.h:50
Ppath::l_step
Vector l_step
Definition: ppath.h:65
interp_scat_angle_temperature
void interp_scat_angle_temperature(VectorView pha_mat_int, Numeric &theta_rad, const SingleScatteringData &scat_data, const Numeric &za_sca, const Numeric &aa_sca, const Numeric &za_inc, const Numeric &aa_inc, const Numeric &rte_temperature)
Definition: mc_interp.cc:183
cart2poslos
void cart2poslos(double &r, double &lat, double &lon, double &za, double &aa, const double &x, const double &y, const double &z, const double &dx, const double &dy, const double &dz)
cart2poslos
Definition: ppath.cc:652
ConstTensor4View::nbooks
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:60
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
clear_rt_vars_at_gp
void clear_rt_vars_at_gp(Workspace &ws, MatrixView ext_mat_mono, VectorView abs_vec_mono, Numeric &temperature, const Agenda &opt_prop_gas_agenda, const Agenda &abs_scalar_gas_agenda, const Index f_index, const GridPos &gp_p, const GridPos &gp_lat, const GridPos &gp_lon, ConstVectorView p_grid, ConstTensor3View t_field, ConstTensor4View vmr_field)
clear_rt_vars_at_gp
Definition: montecarlo.cc:57
max
#define max(a, b)
Definition: continua.cc:13097
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:591
opt_propExtract
void opt_propExtract(MatrixView ext_mat_mono_spt, VectorView abs_vec_mono_spt, const SingleScatteringData &scat_data, const Numeric za, const Numeric aa, const Numeric rte_temperature, const Index stokes_dim, const Verbosity &verbosity)
Extract ext_mat_mono and abs_vec_mono from a monochromatic SingleScatteringData object.
Definition: montecarlo.cc:1279
Range
The range class.
Definition: matpackI.h:148
GridPos
Structure to store a grid position.
Definition: interpolation.h:74
interp_atmfield_gp2itw
void interp_atmfield_gp2itw(Matrix &itw, const Index &atmosphere_dim, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon)
interp_atmfield_gp2itw
Definition: special_interp.cc:99
pha_mat_singleExtract
void pha_mat_singleExtract(MatrixView Z_spt, const SingleScatteringData &scat_data, const Numeric za_sca, const Numeric aa_sca, const Numeric za_inc, const Numeric aa_inc, const Numeric rte_temperature, const Index stokes_dim, const Verbosity &verbosity)
Extract the phase matrix from a monochromatic SingleScatteringData object.
Definition: montecarlo.cc:1507
cloud_atm_vars_by_gp
void cloud_atm_vars_by_gp(VectorView pressure, VectorView temperature, MatrixView vmr, MatrixView pnd, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon, const ArrayOfIndex &cloudbox_limits, ConstVectorView p_grid_cloud, ConstTensor3View t_field_cloud, ConstTensor4View vmr_field_cloud, ConstTensor4View pnd_field)
cloud_atm_vars_by_gp
Definition: montecarlo.cc:231
interp_atmfield_by_gp
void interp_atmfield_by_gp(VectorView x, const Index &atmosphere_dim, ConstTensor3View x_field, const ArrayOfGridPos &gp_p, const ArrayOfGridPos &gp_lat, const ArrayOfGridPos &gp_lon)
interp_atmfield_by_gp
Definition: special_interp.cc:215
pha_mat_labCalc
void pha_mat_labCalc(MatrixView pha_mat_lab, ConstVectorView pha_mat_int, const Numeric &za_sca, const Numeric &aa_sca, const Numeric &za_inc, const Numeric &aa_inc, const Numeric &theta_rad)
Calculate phase matrix in laboratory coordinate system.
Definition: optproperties.cc:705
Rng
Definition: rng.h:569
Workspace
Workspace class.
Definition: workspace_ng.h:47
ConstTensor3View
A constant view of a Tensor3.
Definition: matpackIII.h:147
PARTICLE_TYPE_HORIZ_AL
@ PARTICLE_TYPE_HORIZ_AL
Definition: optproperties.h:58
SingleScatteringData::abs_vec_data
Tensor5 abs_vec_data
Definition: optproperties.h:83
findZ11max
void findZ11max(Vector &Z11maxvector, const ArrayOfSingleScatteringData &scat_data_mono)
findZ11max
Definition: montecarlo.cc:351
GridPos::idx
Index idx
Definition: interpolation.h:75
cum_l_stepCalc
void cum_l_stepCalc(Vector &cum_l_step, const Ppath &ppath)
cum_l_stepCalc
Definition: montecarlo.cc:325
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
M
#define M
Definition: rng.cc:196
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
ppath_what_background
Index ppath_what_background(const Ppath &ppath)
ppath_what_background
Definition: ppath.cc:2561
Vector
The Vector class.
Definition: matpackI.h:555
SingleScatteringData::pha_mat_data
Tensor7 pha_mat_data
Definition: optproperties.h:81
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
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:300
Ppath::pos
Matrix pos
Definition: ppath.h:63
SingleScatteringData::T_grid
Vector T_grid
Definition: optproperties.h:78
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
interpweights
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
Definition: interpolation.cc:756