61 const Agenda& opt_prop_gas_agenda,
62 const Agenda& abs_scalar_gas_agenda,
79 Matrix local_abs_scalar_gas,local_abs_vec;
88 itw2p( p_vec, p_grid, ao_gp_p, itw_p );
102 ao_gp_lon, itw_field );
106 temperature = t_vec[0];
110 temperature,vmr_mat(
joker,0),abs_scalar_gas_agenda );
112 local_abs_scalar_gas, opt_prop_gas_agenda );
134 const Agenda& opt_prop_gas_agenda,
135 const Agenda& abs_scalar_gas_agenda,
136 const Index stokes_dim,
160 Matrix ext_mat_part(stokes_dim, stokes_dim, 0.0);
161 Vector abs_vec_part(stokes_dim, 0.0);
165 Matrix local_abs_scalar_gas,local_abs_vec;
176 ao_gp_lat,ao_gp_lon,cloudbox_limits,p_grid_cloud,
177 t_field_cloud, vmr_field_cloud,pnd_field);
180 temperature = t_ppath[0];
183 temperature,vmr_ppath(
joker,0),abs_scalar_gas_agenda );
185 local_abs_scalar_gas, opt_prop_gas_agenda );
190 scat_za=180-rte_los[0];
191 scat_aa=rte_los[1]+180;
193 if (scat_aa>180){scat_aa-=360;}
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);
201 ext_mat_mono += ext_mat_part;
202 abs_vec_mono += abs_vec_part;
247 assert(pressure.
nelem()==np);
253 Index atmosphere_dim=3;
255 for (
Index i = 0; i < np; i++ )
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];
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];
278 itw2p( pressure, p_grid_cloud, gp_p_cloud, itw_p );
285 gp_p_cloud, gp_lat_cloud, gp_lon_cloud );
288 gp_p_cloud, gp_lat_cloud, gp_lon_cloud,
295 gp_p_cloud, gp_lat_cloud,
296 gp_lon_cloud, itw_field );
301 for(
Index ip=0; ip<N_pt; ip++ )
307 gp_p_cloud, gp_lat_cloud,
308 gp_lon_cloud, itw_field );
333 for (
Index i=0; i<ppath.
np-1; i++)
335 cumsum += ppath.
l_step[i];
336 cum_l_step[i+1] = cumsum;
357 for(
Index i = 0;i<np;i++)
359 switch(scat_data_mono[i].ptype){
362 Z11maxvector[i]=
max(scat_data_mono[i].pha_mat_data(0,
joker,
joker,0,0,0,0));
391 bool anyptype30=
false;
393 while(i < np && anyptype30==
false)
423 const Agenda& ppath_step_agenda,
435 const Vector& particle_masses,
440 Vector local_rte_pos=rte_pos;
441 Vector local_rte_los=rte_los;
446 p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
447 1, cloudbox_limits, local_rte_pos, local_rte_los, 1,
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);
465 p_grid, lat_grid, lon_grid, z_field, r_geoid, z_surface,
466 1, cloudbox_limits, local_rte_pos, local_rte_los, 0,
473 Matrix ext_mat_part(1, 1, 0.0);
474 Vector abs_vec_part(1, 0.0);
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),
485 for (
Index i = 0; i < ppath.
np ; ++i)
488 1, pnd_ppath(
joker, i), t_ppath[i], verbosity);
489 k_vec[i]=ext_mat_part(0,0);
491 assert(pnd_vec.
nelem()==particle_masses.
nelem());
492 iwc_vec[i]=pnd_vec*particle_masses;
495 for (
Index i = 0; i < ppath.
np-1 ; ++i)
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];
521 assert( A.
ncols()==m );
568 Index& termination_flag,
572 const Agenda& opt_prop_gas_agenda,
573 const Agenda& abs_scalar_gas_agenda,
574 const Index stokes_dim,
597 Matrix T(stokes_dim,stokes_dim);
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);
607 evol_opArray[1]=evol_op;
611 lon_grid, z_field, r_geoid, z_surface,
612 0, cloudbox_limits,
false,
613 rte_pos, rte_los, verbosity );
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);
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),
642 opt_prop_gas_agenda, abs_scalar_gas_agenda, f_index,
644 p_grid, t_field, vmr_field );
647 ext_matArray[1]=ext_mat_mono;
648 abs_vecArray[1]=abs_vec_mono;
649 tArray[1]=temperature;
650 pnd_vecArray[1]=pnd_vec;
653 while ((evol_op(0,0)>r)&(!termination_flag))
662 "5000 path points have been reached. Is this an infinite loop?" );
664 evol_opArray[0]=evol_opArray[1];
665 ext_matArray[0]=ext_matArray[1];
666 abs_vecArray[0]=abs_vecArray[1];
668 pnd_vecArray[0]=pnd_vecArray[1];
671 r_geoid, z_surface, -1);
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),
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);
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;
704 if ( stokes_dim == 1 )
706 incT(0,0)=exp(opt_depth_mat(0,0));
710 for (
Index j=0;j<stokes_dim;j++)
712 incT(j,j)=exp(opt_depth_mat(j,j));
720 mult(evol_op,evol_opArray[0],incT);
721 evol_opArray[1]=evol_op;
741 if (termination_flag)
744 rte_pos = ppath_step.
pos(np-1,
Range(0,3));
745 rte_los = ppath_step.
los(np-1,
joker);
756 k=-opt_depth_mat(0,0)/cum_l_step[np-1];
757 ds=log(evol_opArray[0](0,0)/r)/k;
763 x[1]=cum_l_step[np-1];
767 assert(gp[0].idx==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 )
775 incT(0,0)=exp(opt_depth_mat(0,0));
779 for (
Index i=0;i<stokes_dim;i++)
781 incT(i,i)=exp(opt_depth_mat(i,i));
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]);
798 for (
Index i=0; i<2; i++)
831 Index& termination_flag,
833 const Agenda& opt_prop_gas_agenda,
834 const Agenda& abs_scalar_gas_agenda,
835 const Index stokes_dim,
848 const Index z_field_is_1D,
862 Matrix T(stokes_dim,stokes_dim);
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);
876 Vector lon_iw(2),lat_iw(2);
885 z_grid=z_field(
joker,0,0);
886 rv_geoid=r_geoid(0,0);
887 rv_surface=rv_geoid+z_surface(0,0);
891 evol_opArray[1]=evol_op;
897 lon_grid, z_field, r_geoid, z_surface,
898 0, cloudbox_limits,
false,
899 rte_pos, rte_los, verbosity );
901 gp_p=ppath_step.
gp_p[0];
902 gp_lat=ppath_step.
gp_lat[0];
903 gp_lon=ppath_step.
gp_lon[0];
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);
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,
930 opt_prop_gas_agenda, abs_scalar_gas_agenda, f_index,
931 gp_p, gp_lat, gp_lon, p_grid, t_field, vmr_field);
934 ext_matArray[1]=ext_mat_mono;
935 abs_vecArray[1]=abs_vec_mono;
936 tArray[1]=temperature;
937 pnd_vecArray[1]=pnd_vec;
940 while ((evol_op(0,0)>r)&(!termination_flag))
949 evol_opArray[0]=evol_opArray[1];
950 ext_matArray[0]=ext_matArray[1];
951 abs_vecArray[0]=abs_vecArray[1];
953 pnd_vecArray[0]=pnd_vecArray[1];
967 r_geoid(gp_lat.
idx,gp_lon.
idx);
973 if (Dxy/
abs(tan(rte_los[0]*
DEG2RAD))>Dz){dz=Dz;}
976 if(dz*
abs(tan(rte_los[0]*
DEG2RAD))>Dxy){dxy=Dxy;}
978 lstep=sqrt(dxy*dxy+dz*dz);
981 poslos2cart( x, y, z,
dx, dy, dz, rte_pos[0], rte_pos[1], rte_pos[2],
982 rte_los[0], rte_los[1] );
988 cart2poslos(rte_pos[0],rte_pos[1],rte_pos[2],rte_los[0],rte_los[1],
991 gridpos( gp_lat, lat_grid, rte_pos[1] );
992 gridpos( gp_lon, lon_grid, rte_pos[2] );
995 z_at_latlon( z_grid, p_grid, lat_grid, lon_grid, z_field, 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 );
1000 alt = rte_pos[0] - rv_geoid;
1002 if ((alt>=z_grid[p_grid.
nelem()-1])&(rte_los[0]<=90))
1008 alt=z_grid[p_grid.
nelem()-1];
1009 rte_pos[0]=alt+rv_geoid;
1012 if( (rte_pos[0] <= rv_surface)&(rte_los[0]>=90) )
1015 rte_pos[0]=rv_surface;
1016 alt = rte_pos[0] - rv_geoid;
1025 for (
Index i=1;i<np_ipa;i++)
1028 if (new_gp_diff<=gp_diff)
1030 gp_diff=new_gp_diff;
1039 gp_lat=ppath.
gp_lat[i_closest];
1040 gp_lon=ppath.
gp_lon[i_closest];
1047 rv_geoid =
interp( itw, r_geoid, gp_lat, gp_lon );
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);
1056 cloudbox_limits,
false );
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,
1072 opt_prop_gas_agenda, abs_scalar_gas_agenda, f_index,
1073 gp_p, gp_lat, gp_lon, p_grid, t_field, vmr_field);
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];
1083 opt_depth_mat+=ext_matArray[0];
1084 opt_depth_mat*=-lstep/2;
1086 if ( stokes_dim == 1 )
1088 incT(0,0)=exp(opt_depth_mat(0,0));
1092 for (
Index j=0;j<stokes_dim;j++)
1094 incT(j,j)=exp(opt_depth_mat(j,j));
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;
1107 if (termination_flag)
1119 k=-log(incT(0,0))/lstep;
1121 ds=log(evol_opArray[0](0,0)/r)/k;
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 )
1135 incT(0,0)=exp(opt_depth_mat(0,0));
1139 for (
Index i=0;i<stokes_dim;i++)
1141 incT(i,i)=exp(opt_depth_mat(i,i));
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);
1158 cart2poslos(rte_pos[0],rte_pos[1],rte_pos[2],rte_los[0],rte_los[1],x,y,z,
dx,dy,dz);
1186 const Index stokes_dim,
1188 const Numeric rte_temperature,
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 );
1199 Matrix ext_mat_mono_spt(stokes_dim,stokes_dim);
1200 Vector abs_vec_mono_spt(stokes_dim);
1206 for (
Index i_pt = 0; i_pt < N_pt; i_pt++)
1208 if (pnd_vec[i_pt]>0)
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;
1285 const Numeric rte_temperature,
1286 const Index stokes_dim,
1297 switch (scat_data.
ptype){
1304 out0 <<
"Case PARTICLE_TYPE_GENERAL not yet implemented. \n";
1321 ext_mat_mono_spt = 0.;
1322 abs_vec_mono_spt = 0;
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);
1336 if( stokes_dim == 1 ){
1340 ext_mat_mono_spt(1,1) = ext_mat_mono_spt(0,0);
1342 if( stokes_dim == 2 ){
1346 ext_mat_mono_spt(2,2) = ext_mat_mono_spt(0,0);
1348 if( stokes_dim == 3 ){
1352 ext_mat_mono_spt(3,3) = ext_mat_mono_spt(0,0);
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() );
1392 ext_mat_mono_spt=0.0;
1393 abs_vec_mono_spt=0.0;
1395 ext_mat_mono_spt(0,0)=Kjj;
1398 if( stokes_dim == 1 ){
1403 ext_mat_mono_spt(1,1)=Kjj;
1404 ext_mat_mono_spt(0,1)=K12;
1405 ext_mat_mono_spt(1,0)=K12;
1409 if( stokes_dim == 2 ){
1413 ext_mat_mono_spt(2,2)=Kjj;
1415 if( stokes_dim == 3 ){
1420 ext_mat_mono_spt(2,3)=K34;
1421 ext_mat_mono_spt(3,2)=-K34;
1422 ext_mat_mono_spt(3,3)=Kjj;
1429 out0 <<
"Not all particle type cases are implemented\n";
1463 const Index stokes_dim,
1465 const Numeric rte_temperature,
1471 assert(aa_inc>=-180 && aa_inc<=180);
1472 assert(aa_sca>=-180 && aa_sca<=180);
1474 Matrix Z_spt(stokes_dim, stokes_dim, 0.);
1477 for (
Index i_pt = 0; i_pt < N_pt; i_pt++)
1479 if (pnd_vec[i_pt]>0)
1482 aa_inc,rte_temperature,stokes_dim,verbosity);
1483 Z_spt*=pnd_vec[i_pt];
1514 const Numeric rte_temperature,
1515 const Index stokes_dim,
1519 switch (scat_data.
ptype){
1525 out0 <<
"Case PARTICLE_TYPE_GENERAL not yet implemented. \n";
1538 scat_data, za_sca, aa_sca,
1539 za_inc, aa_inc, rte_temperature);
1542 pha_mat_labCalc(Z_spt, pha_mat_int, za_sca, aa_sca, za_inc, aa_inc, theta_rad);
1552 Numeric delta_aa=aa_sca-aa_inc+(aa_sca-aa_inc<-180)*360-
1553 (aa_sca-aa_inc>180)*360;
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() );
1586 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1587 if( stokes_dim == 1 ){
1592 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1595 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1598 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1599 if( stokes_dim == 2 ){
1602 if ((za_inc<=90 && delta_aa>=0)||(za_inc>90 && delta_aa<0))
1606 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1609 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1612 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1615 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1621 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1624 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1627 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1630 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1634 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1635 if( stokes_dim == 3 ){
1638 if ((za_inc<=90 && delta_aa>=0)||(za_inc>90 && delta_aa<0))
1642 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1645 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1648 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1651 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1657 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1660 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1663 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1666 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1670 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1673 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1676 t_gp,za_sca_gp,delta_aa_gp,za_inc_gp);
1682 out0 <<
"Not all particle type cases are implemented\n";
1719 const Index stokes_dim,
1721 const bool anyptype30,
1724 const Numeric rte_temperature,
1730 Numeric aa_scat = (rte_los[1]>=0) ?-180+rte_los[1]:180+rte_los[1];
1736 assert(scat_data_mono.
nelem()==np);
1737 for(
Index i=0;i<np;i++)
1739 Z11max+=Z11maxvector[i]*pnd_vec[i];
1744 Matrix dummyZ(stokes_dim,stokes_dim);
1748 aa_scat,scat_data_mono,stokes_dim,pnd_vec,rte_temperature,
1755 new_rte_los[1] = rng.
draw()*360-180;
1758 Numeric aa_inc= (new_rte_los[1]>=0) ?
1759 -180+new_rte_los[1]:180+new_rte_los[1];
1762 aa_inc,scat_data_mono,stokes_dim,pnd_vec,rte_temperature,
1765 if (rng.
draw()<=Z(0,0)/Z11max)
1770 g_los_csc_theta =Z(0,0)/Csca;