00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00033
00034
00035
00036 #include "mc_interp.h"
00037 #include "logic.h"
00038 #include "montecarlo.h"
00039
00040
00042
00052 Numeric SLIData2::interpolate(Numeric x1, Numeric x2) const
00053 {
00054 GridPos gp1,gpl,gpr;
00055 Vector itw1(2),itwl(2),itwr(2);
00056 Numeric yl,yr;
00057
00058 gridpos(gp1,this->x1a,x1);
00059 interpweights(itw1,gp1);
00060
00061 gridpos(gpl,this->x2a[gp1.idx],x2);
00062 interpweights(itwl,gpl);
00063 gridpos(gpr,this->x2a[gp1.idx+1],x2);
00064 interpweights(itwr,gpr);
00065 yl=interp(itwl,this->ya[gp1.idx],gpl);
00066 yr=interp(itwr,this->ya[gp1.idx+1],gpr);
00067
00068 return itw1[0]*yl+itw1[1]*yr;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078 ostream& operator<< (ostream& os, const SLIData2& )
00079 {
00080 os << "SLIData2 : Output operator not implemented";
00081 return os;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00094
00111 Matrix interp( ConstVectorView itw,
00112 ArrayOfMatrix a,
00113 const GridPos& tc )
00114 {
00115 DEBUG_ONLY (const Numeric sum_check_epsilon = 1e-6);
00116
00117 assert(is_size(itw,2));
00118
00119
00120
00121
00122 assert( is_same_within_epsilon( itw.sum(),
00123 1,
00124 sum_check_epsilon ) );
00125
00126
00127 Matrix tia(a[0].nrows(),a[0].ncols(),0.0);
00128 Matrix b(a[0].nrows(),a[0].ncols(),0.0);
00129 Index iti = 0;
00130 for ( Index c=0; c<2; ++c )
00131 {
00132 b=a[tc.idx+c];
00133 b*=itw[iti];
00134 tia += b;
00135 ++iti;
00136 }
00137
00138 return tia;
00139 }
00140
00141
00143
00160 Vector interp( ConstVectorView itw,
00161 ArrayOfVector a,
00162 const GridPos& tc )
00163 {
00164 DEBUG_ONLY (const Numeric sum_check_epsilon = 1e-6);
00165
00166 assert(is_size(itw,2));
00167
00168
00169
00170
00171 assert( is_same_within_epsilon( itw.sum(),
00172 1,
00173 sum_check_epsilon ) );
00174
00175
00176 Vector tia(a[0].nelem(),0.0);
00177 Vector b(a[0].nelem(),0.0);
00178 Index iti = 0;
00179 for ( Index c=0; c<2; ++c )
00180 {
00181 b=a[tc.idx+c];
00182 b*=itw[iti];
00183 tia += b;
00184 ++iti;
00185 }
00186
00187 return tia;
00188 }
00189
00190 void interp_scat_angle_temperature(
00191 VectorView pha_mat_int,
00192 Numeric& theta_rad,
00193
00194 const SingleScatteringData& scat_data,
00195 const Numeric& za_sca,
00196 const Numeric& aa_sca,
00197 const Numeric& za_inc,
00198 const Numeric& aa_inc,
00199 const Numeric& rte_temperature
00200 )
00201 {
00202 Numeric ANG_TOL=1e-7;
00203
00204
00205
00206
00207
00208
00209 if(abs(aa_sca-aa_inc)<ANG_TOL)
00210 {
00211 theta_rad=DEG2RAD*abs(za_sca-za_inc);
00212 }
00213 else if (abs(abs(aa_sca-aa_inc)-180)<ANG_TOL)
00214 {
00215 theta_rad=DEG2RAD*(za_sca+za_inc);
00216 if (theta_rad>PI){theta_rad=2*PI-theta_rad;}
00217 }
00218 else
00219 {
00220 const Numeric za_sca_rad = za_sca * DEG2RAD;
00221 const Numeric za_inc_rad = za_inc * DEG2RAD;
00222 const Numeric aa_sca_rad = aa_sca * DEG2RAD;
00223 const Numeric aa_inc_rad = aa_inc * DEG2RAD;
00224
00225
00226 assert (scat_data.pha_mat_data.ncols() == 6);
00227
00228 theta_rad = acos(cos(za_sca_rad) * cos(za_inc_rad) +
00229 sin(za_sca_rad) * sin(za_inc_rad) *
00230 cos(aa_sca_rad - aa_inc_rad));
00231 }
00232 const Numeric theta = RAD2DEG * theta_rad;
00233
00234
00235
00236 GridPos thet_gp;
00237 gridpos(thet_gp, scat_data.za_grid, theta);
00238 GridPos t_gp;
00239 gridpos(t_gp, scat_data.T_grid, rte_temperature);
00240
00241 Vector itw(4);
00242 interpweights(itw, t_gp,thet_gp);
00243
00244 for (Index i = 0; i < 6; i++)
00245 {
00246 pha_mat_int[i] = interp(itw, scat_data.pha_mat_data(0,joker,joker, 0, 0, 0, i),
00247 t_gp,thet_gp);
00248 }
00249 }
00250
00251
00252
00254
00282
00283 void interpTArray(Matrix& T,
00284 Vector& K_abs,
00285 Numeric& temperature,
00286 MatrixView& K,
00287 Vector& rte_pos,
00288 Vector& rte_los,
00289 VectorView& pnd_vec,
00290 const ArrayOfMatrix& TArray,
00291 const ArrayOfMatrix& ext_matArray,
00292 const ArrayOfVector& abs_vecArray,
00293 const Vector& t_ppath,
00294 const Matrix& pnd_ppath,
00295 const Vector& cum_l_step,
00296 const Numeric& pathlength,
00297 const Index& stokes_dim,
00298 const Ppath& ppath
00299 )
00300 {
00301
00302 Matrix incT(stokes_dim,stokes_dim,0.0);
00303 Matrix opt_depth_mat(stokes_dim,stokes_dim);
00304 Vector itw(2);
00305 Numeric delta_s;
00306 Index N_pt=pnd_vec.nelem();
00307 ArrayOfGridPos gp(1);
00308
00309
00310 gridpos(gp, cum_l_step, pathlength);
00311 interpweights(itw,gp[0]);
00312 K = interp(itw,ext_matArray,gp[0]);
00313 delta_s = pathlength - cum_l_step[gp[0].idx];
00314 opt_depth_mat = K;
00315 opt_depth_mat+=ext_matArray[gp[0].idx];
00316 opt_depth_mat*=-delta_s/2;
00317 if ( stokes_dim == 1 )
00318 {
00319 incT(0,0)=exp(opt_depth_mat(0,0));
00320 }
00321 else if ( is_diagonal( opt_depth_mat))
00322 {
00323 for ( Index i=0;i<stokes_dim;i++)
00324 {
00325 incT(i,i)=exp(opt_depth_mat(i,i));
00326 }
00327 }
00328 else
00329 {
00330
00331 matrix_exp_p30(incT,opt_depth_mat);
00332 }
00333 mult(T,TArray[gp[0].idx],incT);
00334
00335 K_abs = interp(itw, abs_vecArray,gp[0]);
00336
00337 temperature=interp(itw,t_ppath,gp[0]);
00338
00339 for (Index i=0;i<N_pt;i++)
00340 {
00341 pnd_vec[i]=interp(itw,pnd_ppath(i,Range(joker)),gp[0]);
00342 }
00343
00344 for (Index i=0; i<2; i++)
00345 {
00346 rte_pos[i] = interp(itw,ppath.pos(Range(joker),i),gp[0]);
00347 rte_los[i] = interp(itw,ppath.los(Range(joker),i),gp[0]);
00348 }
00349 rte_pos[2] = interp(itw,ppath.pos(Range(joker),2),gp[0]);
00350 }