00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00035
00036
00037
00038
00039 #include <cmath>
00040 #include "arts.h"
00041 #include "exceptions.h"
00042 #include "array.h"
00043 #include "matpackIII.h"
00044 #include "matpackVII.h"
00045 #include "logic.h"
00046 #include "interpolation.h"
00047 #include "messages.h"
00048 #include "xml_io.h"
00049 #include "optproperties.h"
00050 #include "math_funcs.h"
00051 #include "sorting.h"
00052 #include "check_input.h"
00053 #include "auto_md.h"
00054
00055 extern const Numeric PI;
00056 extern const Numeric DEG2RAD;
00057 extern const Numeric RAD2DEG;
00058
00059 #define part_type scat_data_raw[i_pt].ptype
00060 #define f_datagrid scat_data_raw[i_pt].f_grid
00061 #define T_datagrid scat_data_raw[i_pt].T_grid
00062 #define za_datagrid scat_data_raw[i_pt].za_grid
00063 #define aa_datagrid scat_data_raw[i_pt].aa_grid
00064 #define pha_mat_data_raw scat_data_raw[i_pt].pha_mat_data //CPD: changed from pha_mat_data
00065 #define ext_mat_data_raw scat_data_raw[i_pt].ext_mat_data //which wouldn't let me play with
00066 #define abs_vec_data_raw scat_data_raw[i_pt].abs_vec_data //scat_data_mono.
00067 #define pnd_limit 1e-12 // If particle number density is below this value,
00068
00069
00070
00071
00072 void pha_mat_sptFromData(
00073 Tensor5& pha_mat_spt,
00074
00075 const ArrayOfSingleScatteringData& scat_data_raw,
00076 const Vector& scat_za_grid,
00077 const Vector& scat_aa_grid,
00078 const Index& scat_za_index,
00079 const Index& scat_aa_index,
00080 const Index& f_index,
00081 const Vector& f_grid,
00082 const Numeric& rte_temperature,
00083 const Tensor4& pnd_field,
00084 const Index& scat_p_index,
00085 const Index& scat_lat_index,
00086 const Index& scat_lon_index
00087 )
00088 {
00089 out3 << "Calculate *pha_mat_spt* from database\n";
00090
00091 const Index N_pt = scat_data_raw.nelem();
00092 const Index stokes_dim = pha_mat_spt.ncols();
00093
00094 if (stokes_dim > 4 || stokes_dim < 1){
00095 throw runtime_error("The dimension of the stokes vector \n"
00096 "must be 1,2,3 or 4");
00097 }
00098
00099 assert( pha_mat_spt.nshelves() == N_pt );
00100
00101
00102
00103 Tensor5 pha_mat_data_int;
00104
00105
00106
00107 for (Index i_pt = 0; i_pt < N_pt; i_pt++)
00108 {
00109
00110
00111 if (pnd_field(i_pt, scat_p_index, scat_lat_index, scat_lon_index) > pnd_limit)
00112 {
00113
00114
00115
00116
00117
00118
00119
00120
00121 pha_mat_data_int.resize(pha_mat_data_raw.nshelves(), pha_mat_data_raw.nbooks(),
00122 pha_mat_data_raw.npages(), pha_mat_data_raw.nrows(),
00123 pha_mat_data_raw.ncols());
00124
00125
00126
00127 GridPos freq_gp;
00128 gridpos(freq_gp, f_datagrid, f_grid[f_index]);
00129
00130 GridPos t_gp;
00131 gridpos(t_gp, T_datagrid, rte_temperature);
00132
00133
00134 Vector itw(4);
00135 interpweights(itw, freq_gp, t_gp);
00136
00137 for (Index i_za_sca = 0; i_za_sca < pha_mat_data_raw.nshelves() ; i_za_sca++)
00138 {
00139 for (Index i_aa_sca = 0; i_aa_sca < pha_mat_data_raw.nbooks(); i_aa_sca++)
00140 {
00141 for (Index i_za_inc = 0; i_za_inc < pha_mat_data_raw.npages();
00142 i_za_inc++)
00143 {
00144 for (Index i_aa_inc = 0; i_aa_inc < pha_mat_data_raw.nrows();
00145 i_aa_inc++)
00146 {
00147 for (Index i = 0; i < pha_mat_data_raw.ncols(); i++)
00148 {
00149 pha_mat_data_int(i_za_sca,
00150 i_aa_sca, i_za_inc,
00151 i_aa_inc, i) =
00152 interp(itw,
00153 pha_mat_data_raw(joker, joker, i_za_sca,
00154 i_aa_sca, i_za_inc,
00155 i_aa_inc, i),
00156 freq_gp, t_gp);
00157 }
00158 }
00159 }
00160 }
00161 }
00162
00163
00164 for (Index za_inc_idx = 0; za_inc_idx < scat_za_grid.nelem();
00165 za_inc_idx ++)
00166 {
00167 for (Index aa_inc_idx = 0; aa_inc_idx < scat_aa_grid.nelem();
00168 aa_inc_idx ++)
00169 {
00170 pha_matTransform(pha_mat_spt
00171 (i_pt, za_inc_idx, aa_inc_idx, joker, joker),
00172 pha_mat_data_int,
00173 za_datagrid, aa_datagrid,
00174 part_type, scat_za_index, scat_aa_index,
00175 za_inc_idx,
00176 aa_inc_idx, scat_za_grid, scat_aa_grid);
00177 }
00178 }
00179 }
00180 }
00181 }
00182
00183
00184
00185 void pha_mat_sptFromDataDOITOpt(
00186 Tensor5& pha_mat_spt,
00187
00188 const ArrayOfTensor7& pha_mat_sptDOITOpt,
00189 const ArrayOfSingleScatteringData& scat_data_mono,
00190 const Index& doit_za_grid_size,
00191 const Vector& scat_aa_grid,
00192 const Index& scat_za_index,
00193 const Index& scat_aa_index,
00194 const Numeric& rte_temperature,
00195 const Tensor4& pnd_field,
00196 const Index& scat_p_index,
00197 const Index& scat_lat_index,
00198 const Index& scat_lon_index
00199 )
00200 {
00201
00202 if (pnd_field.ncols() > 1)
00203 {
00204 assert(pha_mat_sptDOITOpt.nelem() == scat_data_mono.nelem());
00205
00206
00207 assert(pha_mat_sptDOITOpt[0].nlibraries() == scat_data_mono[0].T_grid.nelem());
00208 assert(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
00209 assert(pha_mat_sptDOITOpt[0].nshelves() == scat_aa_grid.nelem() );
00210 assert(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
00211 assert(pha_mat_sptDOITOpt[0].npages() == scat_aa_grid.nelem());
00212 }
00213
00214
00215 else if ( pnd_field.ncols() == 1 )
00216 {
00217
00218
00219
00220 assert(pha_mat_sptDOITOpt.nelem() == scat_data_mono.nelem());
00221
00222
00223 assert(pha_mat_sptDOITOpt[0].nlibraries() == scat_data_mono[0].T_grid.nelem());
00224 assert(pha_mat_sptDOITOpt[0].nvitrines() == doit_za_grid_size);
00225 assert(pha_mat_sptDOITOpt[0].nshelves() == 1);
00226 assert(pha_mat_sptDOITOpt[0].nbooks() == doit_za_grid_size);
00227 assert(pha_mat_sptDOITOpt[0].npages() == scat_aa_grid.nelem());
00228 }
00229
00230 assert(doit_za_grid_size > 0);
00231
00232
00233 Vector za_grid;
00234 nlinspace(za_grid, 0, 180, doit_za_grid_size);
00235
00236 const Index N_pt = scat_data_mono.nelem();
00237 const Index stokes_dim = pha_mat_spt.ncols();
00238
00239 if (stokes_dim > 4 || stokes_dim < 1){
00240 throw runtime_error("The dimension of the stokes vector \n"
00241 "must be 1,2,3 or 4");
00242 }
00243
00244 assert( pha_mat_spt.nshelves() == N_pt );
00245
00246 GridPos T_gp;
00247 Vector itw(2);
00248
00249
00250
00251 pha_mat_spt = 0.;
00252
00253
00254 for (Index i_pt = 0; i_pt < N_pt; i_pt ++)
00255 {
00256
00257
00258
00259 if (pnd_field(i_pt, scat_p_index, scat_lat_index, scat_lon_index) > pnd_limit)
00260 {
00261 if( scat_data_mono[i_pt].T_grid.nelem() > 1)
00262 {
00263
00264
00265
00266
00267
00268
00269 gridpos(T_gp, scat_data_mono[i_pt].T_grid, rte_temperature);
00270
00271 interpweights(itw, T_gp);
00272 }
00273
00274
00275
00276 for (Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
00277 za_inc_idx ++)
00278 {
00279 for (Index aa_inc_idx = 0; aa_inc_idx < scat_aa_grid.nelem();
00280 aa_inc_idx ++)
00281 {
00282 if( scat_data_mono[i_pt].T_grid.nelem() == 1)
00283 {
00284 pha_mat_spt(i_pt, za_inc_idx, aa_inc_idx, joker, joker) =
00285 pha_mat_sptDOITOpt[i_pt](0, scat_za_index,
00286 scat_aa_index, za_inc_idx,
00287 aa_inc_idx, joker, joker);
00288 }
00289
00290
00291 else
00292 {
00293 for (Index i = 0; i< stokes_dim; i++)
00294 {
00295 for (Index j = 0; j< stokes_dim; j++)
00296 {
00297 pha_mat_spt(i_pt, za_inc_idx, aa_inc_idx, i, j)=
00298 interp(itw,pha_mat_sptDOITOpt[i_pt]
00299 (joker, scat_za_index,
00300 scat_aa_index, za_inc_idx,
00301 aa_inc_idx, i, j) , T_gp);
00302 }
00303 }
00304 }
00305 }
00306 }
00307 }
00308 }
00309 }
00310
00311
00312
00313 void opt_prop_sptFromData(
00314 Tensor3& ext_mat_spt,
00315 Matrix& abs_vec_spt,
00316
00317 const ArrayOfSingleScatteringData& scat_data_raw,
00318 const Vector& scat_za_grid,
00319 const Vector& scat_aa_grid,
00320 const Index& scat_za_index,
00321 const Index& scat_aa_index,
00322 const Index& f_index,
00323 const Vector& f_grid,
00324 const Numeric& rte_temperature,
00325 const Tensor4& pnd_field,
00326 const Index& scat_p_index,
00327 const Index& scat_lat_index,
00328 const Index& scat_lon_index
00329 )
00330 {
00331
00332 const Index N_pt = scat_data_raw.nelem();
00333 const Index stokes_dim = ext_mat_spt.ncols();
00334 const Numeric za_sca = scat_za_grid[scat_za_index];
00335 const Numeric aa_sca = scat_aa_grid[scat_aa_index];
00336
00337 if (stokes_dim > 4 || stokes_dim < 1){
00338 throw runtime_error("The dimension of the stokes vector \n"
00339 "must be 1,2,3 or 4");
00340 }
00341
00342 assert( ext_mat_spt.npages() == N_pt );
00343 assert( abs_vec_spt.nrows() == N_pt );
00344
00345
00346
00347 Tensor3 ext_mat_data_int;
00348 Tensor3 abs_vec_data_int;
00349
00350
00351 ext_mat_spt = 0.;
00352 abs_vec_spt = 0.;
00353
00354
00355
00356 for (Index i_pt = 0; i_pt < N_pt; i_pt++)
00357 {
00358
00359
00360
00361 if (pnd_field(i_pt, scat_p_index, scat_lat_index, scat_lon_index) > pnd_limit)
00362 {
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 ext_mat_data_int.resize(ext_mat_data_raw.npages(),
00376 ext_mat_data_raw.nrows(),
00377 ext_mat_data_raw.ncols());
00378
00379 abs_vec_data_int.resize(abs_vec_data_raw.npages(),
00380 abs_vec_data_raw.nrows(),
00381 abs_vec_data_raw.ncols());
00382
00383
00384
00385 GridPos freq_gp;
00386 gridpos(freq_gp, f_datagrid, f_grid[f_index]);
00387 GridPos t_gp;
00388 Vector itw;
00389
00390 if ( T_datagrid.nelem() > 1)
00391 {
00392 gridpos(t_gp, T_datagrid, rte_temperature);
00393
00394
00395 itw.resize(4);
00396 interpweights(itw, freq_gp, t_gp);
00397
00398 for (Index i_za_sca = 0; i_za_sca < ext_mat_data_raw.npages();
00399 i_za_sca++)
00400 {
00401 for(Index i_aa_sca = 0; i_aa_sca < ext_mat_data_raw.nrows();
00402 i_aa_sca++)
00403 {
00404
00405
00406
00407 for (Index i = 0; i < ext_mat_data_raw.ncols(); i++)
00408 {
00409 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
00410 interp(itw, ext_mat_data_raw(joker, joker,
00411 i_za_sca, i_aa_sca, i),
00412 freq_gp, t_gp);
00413 }
00414 }
00415 }
00416
00417 for (Index i_za_sca = 0; i_za_sca < abs_vec_data_raw.npages();
00418 i_za_sca++)
00419 {
00420 for(Index i_aa_sca = 0; i_aa_sca < abs_vec_data_raw.nrows();
00421 i_aa_sca++)
00422 {
00423
00424
00425
00426 for (Index i = 0; i < abs_vec_data_raw.ncols(); i++)
00427 {
00428 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
00429 interp(itw, abs_vec_data_raw(joker, joker, i_za_sca,
00430 i_aa_sca, i),
00431 freq_gp, t_gp);
00432 }
00433 }
00434 }
00435 }
00436 else
00437 {
00438
00439 itw.resize(2);
00440 interpweights(itw, freq_gp);
00441
00442 for (Index i_za_sca = 0; i_za_sca < ext_mat_data_raw.npages();
00443 i_za_sca++)
00444 {
00445 for(Index i_aa_sca = 0; i_aa_sca < ext_mat_data_raw.nrows();
00446 i_aa_sca++)
00447 {
00448
00449
00450
00451 for (Index i = 0; i < ext_mat_data_raw.ncols(); i++)
00452 {
00453 ext_mat_data_int(i_za_sca, i_aa_sca, i) =
00454 interp(itw, ext_mat_data_raw(joker, 0,
00455 i_za_sca, i_aa_sca, i),
00456 freq_gp);
00457 }
00458 }
00459 }
00460
00461 for (Index i_za_sca = 0; i_za_sca < abs_vec_data_raw.npages();
00462 i_za_sca++)
00463 {
00464 for(Index i_aa_sca = 0; i_aa_sca < abs_vec_data_raw.nrows();
00465 i_aa_sca++)
00466 {
00467
00468
00469
00470 for (Index i = 0; i < abs_vec_data_raw.ncols(); i++)
00471 {
00472 abs_vec_data_int(i_za_sca, i_aa_sca, i) =
00473 interp(itw, abs_vec_data_raw(joker, 0, i_za_sca,
00474 i_aa_sca, i),
00475 freq_gp);
00476 }
00477 }
00478 }
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 ext_matTransform(ext_mat_spt(i_pt, joker, joker),
00490 ext_mat_data_int,
00491 za_datagrid, aa_datagrid, part_type,
00492 za_sca, aa_sca);
00493
00494
00495
00496 abs_vecTransform(abs_vec_spt(i_pt, joker),
00497 abs_vec_data_int,
00498 za_datagrid, aa_datagrid, part_type,
00499 za_sca, aa_sca);
00500 }
00501
00502 }
00503 }
00504
00505
00506
00507 void ext_matAddPart(
00508 Tensor3& ext_mat,
00509 const Tensor3& ext_mat_spt,
00510 const Tensor4& pnd_field,
00511 const Index& atmosphere_dim,
00512 const Index& scat_p_index,
00513 const Index& scat_lat_index,
00514 const Index& scat_lon_index)
00515
00516 {
00517 Index N_pt = ext_mat_spt.npages();
00518 Index stokes_dim = ext_mat_spt.nrows();
00519
00520 Matrix ext_mat_part(stokes_dim, stokes_dim, 0.0);
00521
00522
00523 if (stokes_dim > 4 || stokes_dim < 1){
00524 throw runtime_error(
00525 "The dimension of stokes vector can be "
00526 "only 1,2,3, or 4");
00527 }
00528 if ( ext_mat_spt.ncols() != stokes_dim){
00529
00530 throw runtime_error(" The columns of ext_mat_spt should "
00531 "agree to stokes_dim");
00532 }
00533
00534 if (atmosphere_dim == 1)
00535 {
00536
00537 for (Index l = 0; l < N_pt; l++)
00538 {
00539
00540
00541 for (Index m = 0; m < stokes_dim; m++)
00542 {
00543 for (Index n = 0; n < stokes_dim; n++)
00544
00545
00546 ext_mat_part(m, n) +=
00547 (ext_mat_spt(l, m, n) * pnd_field(l, scat_p_index, 0, 0));
00548 }
00549 }
00550
00551
00552 ext_mat(0, Range(joker), Range(joker)) += ext_mat_part;
00553 }
00554
00555 if (atmosphere_dim == 3)
00556 {
00557
00558
00559 for (Index l = 0; l < N_pt; l++)
00560 {
00561
00562
00563 for (Index m = 0; m < stokes_dim; m++)
00564 {
00565 for (Index n = 0; n < stokes_dim; n++)
00566
00567
00568 ext_mat_part(m, n) += (ext_mat_spt(l, m, n) *
00569 pnd_field(l, scat_p_index,
00570 scat_lat_index,
00571 scat_lon_index));
00572
00573 }
00574 }
00575
00576
00577 ext_mat(0, Range(joker), Range(joker)) += ext_mat_part;
00578
00579 }
00580
00581 }
00582
00583
00584
00585 void abs_vecAddPart(
00586 Matrix& abs_vec,
00587 const Matrix& abs_vec_spt,
00588 const Tensor4& pnd_field,
00589 const Index& atmosphere_dim,
00590 const Index& scat_p_index,
00591 const Index& scat_lat_index,
00592 const Index& scat_lon_index)
00593
00594 {
00595 Index N_pt = abs_vec_spt.nrows();
00596 Index stokes_dim = abs_vec_spt.ncols();
00597
00598 Vector abs_vec_part(stokes_dim, 0.0);
00599
00600 if ((stokes_dim > 4) || (stokes_dim <1)){
00601 throw runtime_error("The dimension of stokes vector "
00602 "can be only 1,2,3, or 4");
00603 }
00604
00605 if (atmosphere_dim == 1)
00606 {
00607
00608 for (Index l = 0; l < N_pt ; ++l)
00609 {
00610
00611
00612 for (Index m = 0; m < stokes_dim; ++m)
00613
00614
00615 abs_vec_part[m] +=
00616 (abs_vec_spt(l, m) * pnd_field(l, scat_p_index, 0, 0));
00617
00618 }
00619
00620 abs_vec(0, Range(joker)) += abs_vec_part;
00621 }
00622
00623 if (atmosphere_dim == 3)
00624 {
00625
00626 for (Index l = 0; l < N_pt ; ++l)
00627 {
00628
00629
00630 for (Index m = 0; m < stokes_dim; ++m)
00631
00632
00633 abs_vec_part[m] += (abs_vec_spt(l, m) *
00634 pnd_field(l, scat_p_index,
00635 scat_lat_index,
00636 scat_lon_index));
00637
00638 }
00639
00640 abs_vec(0,Range(joker)) += abs_vec_part;
00641 }
00642 }
00643
00644
00645
00646 void ext_matInit( Tensor3& ext_mat,
00647 const Vector& f_grid,
00648 const Index& stokes_dim,
00649 const Index& f_index)
00650 {
00651 Index freq_dim;
00652
00653 if( f_index < 0 )
00654 freq_dim = f_grid.nelem();
00655 else
00656 freq_dim = 1;
00657
00658 ext_mat.resize( freq_dim,
00659 stokes_dim,
00660 stokes_dim );
00661 ext_mat = 0;
00662
00663 out2 << "Set dimensions of ext_mat as ["
00664 << freq_dim << ","
00665 << stokes_dim << ","
00666 << stokes_dim << "] and initialized to 0.\n";
00667 }
00668
00669
00670
00671 void ext_matAddGas( Tensor3& ext_mat,
00672 const Matrix& abs_scalar_gas )
00673 {
00674
00675 const Index stokes_dim = ext_mat.ncols();
00676
00677
00678
00679 if ( stokes_dim != ext_mat.nrows() )
00680 throw runtime_error("Row dimension of ext_mat inconsistent with "
00681 "column dimension.");
00682
00683
00684 const Index f_dim = ext_mat.npages();
00685
00686
00687
00688 if ( f_dim != abs_scalar_gas.nrows() )
00689 throw runtime_error("Frequency dimension of ext_mat and abs_scalar_gas\n"
00690 "are inconsistent in ext_matAddGas.");
00691
00692
00693
00694
00695 Vector abs_total(f_dim);
00696 for ( Index i=0; i<f_dim; ++i )
00697 abs_total[i] = abs_scalar_gas(i,joker).sum();
00698
00699 for ( Index i=0; i<stokes_dim; ++i )
00700 {
00701
00702 ext_mat(joker,i,i) += abs_total[joker];
00703
00704
00705
00706 }
00707 }
00708
00709
00710
00711 void abs_vecInit( Matrix& abs_vec,
00712 const Vector& f_grid,
00713 const Index& stokes_dim,
00714 const Index& f_index)
00715 {
00716 Index freq_dim;
00717
00718 if( f_index < 0 )
00719 freq_dim = f_grid.nelem();
00720 else
00721 freq_dim = 1;
00722
00723 abs_vec.resize( freq_dim,
00724 stokes_dim );
00725 abs_vec = 0;
00726
00727 out2 << "Set dimensions of abs_vec as ["
00728 << freq_dim << ","
00729 << stokes_dim << "] and initialized to 0.\n";
00730 }
00731
00732
00733
00734 void abs_vecAddGas( Matrix& abs_vec,
00735 const Matrix& abs_scalar_gas )
00736 {
00737
00738 const Index f_dim = abs_vec.nrows();
00739
00740
00741
00742 if ( f_dim != abs_scalar_gas.nrows() )
00743 throw runtime_error("Frequency dimension of abs_vec and abs_scalar_gas\n"
00744 "are inconsistent in abs_vecAddGas.");
00745
00746
00747
00748 for ( Index i=0; i<f_dim; ++i )
00749 {
00750
00751
00752 abs_vec(i,0) += abs_scalar_gas(i,joker).sum();
00753 }
00754
00755
00756
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 void pha_matCalc(
00805 Tensor4& pha_mat,
00806 const Tensor5& pha_mat_spt,
00807 const Tensor4& pnd_field,
00808 const Index& atmosphere_dim,
00809 const Index& scat_p_index,
00810 const Index& scat_lat_index,
00811 const Index& scat_lon_index)
00812
00813 {
00814
00815 Index N_pt = pha_mat_spt.nshelves();
00816 Index Nza = pha_mat_spt.nbooks();
00817 Index Naa = pha_mat_spt.npages();
00818 Index stokes_dim = pha_mat_spt.nrows();
00819
00820 pha_mat.resize(Nza, Naa, stokes_dim, stokes_dim);
00821
00822
00823 pha_mat = 0.0;
00824
00825 if (atmosphere_dim == 1)
00826 {
00827
00828 for (Index pt_index = 0; pt_index < N_pt; ++ pt_index)
00829 {
00830
00831 for (Index za_index = 0; za_index < Nza; ++ za_index)
00832 {
00833 for (Index aa_index = 0; aa_index < Naa; ++ aa_index)
00834 {
00835
00836
00837 for (Index stokes_index_1 = 0; stokes_index_1 < stokes_dim;
00838 ++ stokes_index_1)
00839 {
00840 for (Index stokes_index_2 = 0; stokes_index_2 < stokes_dim;
00841 ++ stokes_index_2)
00842
00843
00844 pha_mat(za_index, aa_index,
00845 stokes_index_1, stokes_index_2) +=
00846
00847 (pha_mat_spt(pt_index, za_index, aa_index,
00848 stokes_index_1, stokes_index_2) *
00849 pnd_field(pt_index,scat_p_index, 0, 0));
00850 }
00851 }
00852 }
00853 }
00854 }
00855
00856 if (atmosphere_dim == 3)
00857 {
00858
00859 for (Index pt_index = 0; pt_index < N_pt; ++ pt_index)
00860 {
00861
00862
00863 for (Index za_index = 0; za_index < Nza; ++ za_index)
00864 {
00865 for (Index aa_index = 0; aa_index < Naa; ++ aa_index)
00866 {
00867
00868
00869 for (Index i = 0; i < stokes_dim; ++ i)
00870 {
00871 for (Index j = 0; j < stokes_dim; ++ j)
00872 {
00873
00874
00875 pha_mat(za_index, aa_index, i,j ) +=
00876 (pha_mat_spt(pt_index, za_index, aa_index, i, j) *
00877 pnd_field(pt_index, scat_p_index,
00878 scat_lat_index, scat_lon_index));
00879
00880
00881 }
00882 }
00883 }
00884 }
00885 }
00886 }
00887 }
00888
00889
00890
00891 void scat_data_rawCheck(
00892 const ArrayOfSingleScatteringData& scat_data_raw
00893 )
00894 {
00895
00896 xml_write_to_file("SingleScatteringData", scat_data_raw);
00897
00898 const Index N_pt = scat_data_raw.nelem();
00899
00900
00901 for (Index i_pt = 0; i_pt < N_pt; i_pt++)
00902 {
00903 Numeric Csca = AngIntegrate_trapezoid
00904 (pha_mat_data_raw(0, 0, joker, 0, 0, 0, 0), za_datagrid);
00905
00906 Numeric Cext = ext_mat_data_raw(0,0,0,0,0);
00907
00908 Numeric Cabs = Cext - Csca;
00909
00910 Numeric Cabs_data = abs_vec_data_raw(0,0,0,0,0);
00911
00912 Numeric Csca_data = Cext - Cabs_data;
00913
00914 out1 << " Coefficients in database: \n"
00915 << "Cext: " << Cext << " Cabs: " << Cabs_data << " Csca: " << Csca_data
00916 << " \n Calculated absorption cooefficient: \n"
00917 << "Cabs calculated: " << Cabs
00918 << " Csca: " << Csca << "\n";
00919
00920 }
00921 }
00922
00923
00924
00925 void DoitScatteringDataPrepare(
00926 ArrayOfTensor7& pha_mat_sptDOITOpt,
00927 ArrayOfSingleScatteringData& scat_data_mono,
00928
00929 const Index& doit_za_grid_size,
00930 const Vector& scat_aa_grid,
00931 const ArrayOfSingleScatteringData&
00932 scat_data_raw,
00933 const Vector& f_grid,
00934 const Index& f_index,
00935 const Index& atmosphere_dim,
00936 const Index& stokes_dim
00937 )
00938 {
00939
00940
00941 for (Index i = 0; i<scat_data_raw.nelem(); i++)
00942 {
00943 if (scat_data_raw[i].f_grid[0] > f_grid[f_index] ||
00944 scat_data_raw[i].f_grid[scat_data_raw[i].f_grid.nelem()-1]
00945 < f_grid[f_index])
00946 {
00947 ostringstream os;
00948 os << "Frequency of the scattering calculation " << f_grid[f_index]
00949 << " GHz is not contained \n in the frequency grid of the " << i+1
00950 << "the single scattering data file \n(*ParticleTypeAdd*). "
00951 << "Range:" << scat_data_raw[i].f_grid[0]/1e9 <<" - "
00952 << scat_data_raw[i].f_grid[scat_data_raw[i].f_grid.nelem()-1]/1e9
00953 <<" GHz \n";
00954 throw runtime_error( os.str() );
00955 }
00956 }
00957
00958
00959 scat_data_monoCalc(scat_data_mono, scat_data_raw, f_grid, f_index);
00960
00961
00962 Index N_aa_sca;
00963 if(atmosphere_dim == 1)
00964 N_aa_sca = 1;
00965 else
00966 N_aa_sca = scat_aa_grid.nelem();
00967
00968 Vector za_grid;
00969 nlinspace(za_grid, 0, 180, doit_za_grid_size);
00970
00971 assert( scat_data_raw.nelem() == scat_data_mono.nelem() );
00972
00973 Index N_pt = scat_data_raw.nelem();
00974
00975 pha_mat_sptDOITOpt.resize(N_pt);
00976
00977 for (Index i_pt = 0; i_pt < N_pt; i_pt++)
00978 {
00979 Index N_T = scat_data_mono[i_pt].T_grid.nelem();
00980 pha_mat_sptDOITOpt[i_pt].resize(N_T, doit_za_grid_size, N_aa_sca,
00981 doit_za_grid_size, scat_aa_grid.nelem(),
00982 stokes_dim, stokes_dim);
00983
00984
00985 pha_mat_sptDOITOpt[i_pt]= 0.;
00986
00987
00988
00989 for (Index t_idx = 0; t_idx < N_T; t_idx ++)
00990 {
00991
00992 for (Index za_sca_idx = 0; za_sca_idx < doit_za_grid_size; za_sca_idx ++)
00993 {
00994 for (Index aa_sca_idx = 0; aa_sca_idx < N_aa_sca; aa_sca_idx ++)
00995 {
00996
00997 for (Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
00998 za_inc_idx ++)
00999 {
01000 for (Index aa_inc_idx = 0; aa_inc_idx <
01001 scat_aa_grid.nelem();
01002 aa_inc_idx ++)
01003 {
01004 pha_matTransform(pha_mat_sptDOITOpt[i_pt]
01005 (t_idx, za_sca_idx,
01006 aa_sca_idx, za_inc_idx, aa_inc_idx,
01007 joker, joker),
01008 scat_data_mono[i_pt].
01009 pha_mat_data
01010 (0,t_idx,joker,joker,joker,
01011 joker,joker),
01012 scat_data_mono[i_pt].za_grid,
01013 scat_data_mono[i_pt].aa_grid,
01014 scat_data_mono[i_pt].ptype,
01015 za_sca_idx,
01016 aa_sca_idx,
01017 za_inc_idx,
01018 aa_inc_idx,
01019 za_grid,
01020 scat_aa_grid);
01021 }
01022 }
01023 }
01024 }
01025 }
01026 }
01027 }
01028
01029
01030
01031 void scat_data_monoCalc(
01032 ArrayOfSingleScatteringData& scat_data_mono,
01033 const ArrayOfSingleScatteringData& scat_data_raw,
01034 const Vector& f_grid,
01035 const Index& f_index
01036 )
01037 {
01038
01039 for (Index i = 0; i<scat_data_raw.nelem(); i++)
01040 {
01041 if (scat_data_raw[i].f_grid[0] > f_grid[f_index] ||
01042 scat_data_raw[i].f_grid[scat_data_raw[i].f_grid.nelem()-1]
01043 < f_grid[f_index])
01044 {
01045 ostringstream os;
01046 os << "Frequency of the scattering calculation " << f_grid[f_index]
01047 << " GHz is not contained \nin the frequency grid of the " << i+1
01048 << "the single scattering data file \n(*ParticleTypeAdd*). "
01049 << "Range:" << scat_data_raw[i].f_grid[0]/1e9 <<" - "
01050 << scat_data_raw[i].f_grid[scat_data_raw[i].f_grid.nelem()-1]/1e9
01051 <<" GHz \n";
01052 throw runtime_error( os.str() );
01053 }
01054 }
01055
01056 const Index N_pt = scat_data_raw.nelem();
01057
01058
01059 scat_data_mono.resize(N_pt);
01060
01061
01062 for (Index i_pt = 0; i_pt < N_pt; i_pt++)
01063 {
01064
01065 GridPos freq_gp;
01066 gridpos(freq_gp, f_datagrid, f_grid[f_index]);
01067
01068
01069 Vector itw(2);
01070 interpweights(itw, freq_gp);
01071
01072
01073 scat_data_mono[i_pt].ptype=part_type;
01074 scat_data_mono[i_pt].f_grid.resize(1);
01075 scat_data_mono[i_pt].f_grid=f_grid[f_index];
01076 scat_data_mono[i_pt].T_grid=scat_data_raw[i_pt].T_grid;
01077 scat_data_mono[i_pt].za_grid=za_datagrid;
01078 scat_data_mono[i_pt].aa_grid=aa_datagrid;
01079
01080
01081 scat_data_mono[i_pt].pha_mat_data.resize(1,
01082 pha_mat_data_raw.nvitrines(),
01083 pha_mat_data_raw.nshelves(),
01084 pha_mat_data_raw.nbooks(),
01085 pha_mat_data_raw.npages(),
01086 pha_mat_data_raw.nrows(),
01087 pha_mat_data_raw.ncols());
01088
01089 for (Index t_index = 0; t_index < pha_mat_data_raw.nvitrines(); t_index ++)
01090 {
01091 for (Index i_za_sca = 0; i_za_sca < pha_mat_data_raw.nshelves();
01092 i_za_sca++)
01093 {
01094 for (Index i_aa_sca = 0; i_aa_sca < pha_mat_data_raw.nbooks();
01095 i_aa_sca++)
01096 {
01097 for (Index i_za_inc = 0; i_za_inc <
01098 pha_mat_data_raw.npages();
01099 i_za_inc++)
01100 {
01101 for (Index i_aa_inc = 0;
01102 i_aa_inc < pha_mat_data_raw.nrows();
01103 i_aa_inc++)
01104 {
01105 for (Index i = 0; i < pha_mat_data_raw.ncols(); i++)
01106 {
01107 scat_data_mono[i_pt].pha_mat_data(0, t_index,
01108 i_za_sca,
01109 i_aa_sca,
01110 i_za_inc,
01111 i_aa_inc, i) =
01112 interp(itw,
01113 pha_mat_data_raw(joker, t_index,
01114 i_za_sca,
01115 i_aa_sca, i_za_inc,
01116 i_aa_inc, i),
01117 freq_gp);
01118 }
01119 }
01120 }
01121 }
01122 }
01123
01124 scat_data_mono[i_pt].ext_mat_data.resize(1, T_datagrid.nelem(),
01125 ext_mat_data_raw.npages(),
01126 ext_mat_data_raw.nrows(),
01127 ext_mat_data_raw.ncols());
01128 for (Index i_za_sca = 0; i_za_sca < ext_mat_data_raw.npages();
01129 i_za_sca++)
01130 {
01131 for(Index i_aa_sca = 0; i_aa_sca < ext_mat_data_raw.nrows();
01132 i_aa_sca++)
01133 {
01134
01135
01136
01137 for (Index i = 0; i < ext_mat_data_raw.ncols(); i++)
01138 {
01139 scat_data_mono[i_pt].ext_mat_data(0, t_index,
01140 i_za_sca, i_aa_sca, i)
01141 = interp(itw, ext_mat_data_raw(joker, t_index, i_za_sca,
01142 i_aa_sca, i),
01143 freq_gp);
01144 }
01145 }
01146 }
01147
01148 scat_data_mono[i_pt].abs_vec_data.resize(1, T_datagrid.nelem(),
01149 abs_vec_data_raw.npages(),
01150 abs_vec_data_raw.nrows(),
01151 abs_vec_data_raw.ncols());
01152 for (Index i_za_sca = 0; i_za_sca < abs_vec_data_raw.npages() ;
01153 i_za_sca++)
01154 {
01155 for(Index i_aa_sca = 0; i_aa_sca < abs_vec_data_raw.nrows();
01156 i_aa_sca++)
01157 {
01158
01159
01160
01161 for (Index i = 0; i < abs_vec_data_raw.ncols(); i++)
01162 {
01163 scat_data_mono[i_pt].abs_vec_data(0, t_index, i_za_sca,
01164 i_aa_sca, i) =
01165 interp(itw, abs_vec_data_raw(joker, t_index, i_za_sca,
01166 i_aa_sca, i),
01167 freq_gp);
01168 }
01169 }
01170 }
01171 }
01172 }
01173 }
01174
01175
01176
01177 void opt_prop_sptFromMonoData(
01178 Tensor3& ext_mat_spt,
01179 Matrix& abs_vec_spt,
01180
01181 const ArrayOfSingleScatteringData& scat_data_mono,
01182 const Vector& scat_za_grid,
01183 const Vector& scat_aa_grid,
01184 const Index& scat_za_index,
01185 const Index& scat_aa_index,
01186 const Numeric& rte_temperature,
01187 const Tensor4& pnd_field,
01188 const Index& scat_p_index,
01189 const Index& scat_lat_index,
01190 const Index& scat_lon_index
01191 )
01192 {
01193 const Index N_pt = scat_data_mono.nelem();
01194 const Index stokes_dim = ext_mat_spt.ncols();
01195 const Numeric za_sca = scat_za_grid[scat_za_index];
01196 const Numeric aa_sca = scat_aa_grid[scat_aa_index];
01197
01198 if (stokes_dim > 4 || stokes_dim < 1){
01199 throw runtime_error("The dimension of the stokes vector \n"
01200 "must be 1,2,3 or 4");
01201 }
01202
01203 assert( ext_mat_spt.npages() == N_pt );
01204 assert( abs_vec_spt.nrows() == N_pt );
01205
01206
01207 ext_mat_spt = 0.;
01208 abs_vec_spt = 0.;
01209
01210 GridPos t_gp;
01211
01212 Vector itw(2);
01213
01214
01215 for (Index i_pt = 0; i_pt < N_pt; i_pt++)
01216 {
01217
01218
01219 if (pnd_field(i_pt, scat_p_index, scat_lat_index, scat_lon_index) > pnd_limit)
01220 {
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231 Index ext_npages = scat_data_mono[i_pt].ext_mat_data.npages();
01232 Index ext_nrows = scat_data_mono[i_pt].ext_mat_data.nrows();
01233 Index ext_ncols = scat_data_mono[i_pt].ext_mat_data.ncols();
01234 Index abs_npages = scat_data_mono[i_pt].abs_vec_data.npages();
01235 Index abs_nrows = scat_data_mono[i_pt].abs_vec_data.nrows();
01236 Index abs_ncols = scat_data_mono[i_pt].abs_vec_data.ncols();
01237 Tensor3 ext_mat_data1temp(ext_npages,ext_nrows,ext_ncols,0.0);
01238 Tensor3 abs_vec_data1temp(abs_npages,abs_nrows,abs_ncols,0.0);
01239
01240
01241 ConstVectorView t_grid = scat_data_mono[i_pt].T_grid;
01242
01243 if (t_grid.nelem() > 1)
01244 {
01245
01246
01247
01248
01249
01250
01251 gridpos(t_gp, scat_data_mono[i_pt].T_grid, rte_temperature);
01252 interpweights(itw, t_gp);
01253 for (Index i_p = 0; i_p < ext_npages ; i_p++)
01254 {
01255 for (Index i_r = 0; i_r < ext_nrows ; i_r++)
01256 {
01257 for (Index i_c = 0; i_c < ext_ncols ; i_c++)
01258 {
01259 ext_mat_data1temp(i_p,i_r,i_c)=interp(itw,
01260 scat_data_mono[i_pt].ext_mat_data(0,joker,i_p,i_r,i_c),t_gp);
01261 }
01262 }
01263 }
01264 }
01265 else
01266 {
01267 ext_mat_data1temp =
01268 scat_data_mono[i_pt].ext_mat_data(0,0,joker,joker,joker);
01269 }
01270
01271 ext_matTransform(ext_mat_spt(i_pt, joker, joker),
01272 ext_mat_data1temp,
01273 scat_data_mono[i_pt].za_grid,
01274 scat_data_mono[i_pt].aa_grid,
01275 scat_data_mono[i_pt].ptype,
01276 za_sca, aa_sca);
01277
01278
01279
01280
01281 if (t_grid.nelem() > 1)
01282 {
01283
01284 for (Index i_p = 0; i_p < abs_npages ; i_p++)
01285 {
01286 for (Index i_r = 0; i_r < abs_nrows ; i_r++)
01287 {
01288 for (Index i_c = 0; i_c < abs_ncols ; i_c++)
01289 {
01290 abs_vec_data1temp(i_p,i_r,i_c)=interp(itw,
01291 scat_data_mono[i_pt].abs_vec_data(0,joker,i_p,i_r,i_c),t_gp);
01292 }
01293 }
01294 }
01295 }
01296 else
01297 {
01298 abs_vec_data1temp =
01299 scat_data_mono[i_pt].abs_vec_data(0,0,joker,joker,joker);
01300 }
01301
01302 abs_vecTransform(abs_vec_spt(i_pt, joker),
01303 abs_vec_data1temp,
01304 scat_data_mono[i_pt].za_grid,
01305 scat_data_mono[i_pt].aa_grid,
01306 scat_data_mono[i_pt].ptype,
01307 za_sca, aa_sca);
01308 }
01309
01310 }
01311 }
01312
01313
01314
01315 void pha_mat_sptFromMonoData(
01316 Tensor5& pha_mat_spt,
01317
01318 const ArrayOfSingleScatteringData& scat_data_mono,
01319 const Index& doit_za_grid_size,
01320 const Vector& scat_aa_grid,
01321 const Index& scat_za_index,
01322 const Index& scat_aa_index,
01323 const Numeric& rte_temperature,
01324 const Tensor4& pnd_field,
01325 const Index& scat_p_index,
01326 const Index& scat_lat_index,
01327 const Index& scat_lon_index
01328 )
01329 {
01330 out3 << "Calculate *pha_mat_spt* from scat_data_mono. \n";
01331
01332 Vector za_grid;
01333 nlinspace(za_grid, 0, 180, doit_za_grid_size);
01334
01335 const Index N_pt = scat_data_mono.nelem();
01336 const Index stokes_dim = pha_mat_spt.ncols();
01337
01338
01339
01340 if (stokes_dim > 4 || stokes_dim < 1){
01341 throw runtime_error("The dimension of the stokes vector \n"
01342 "must be 1,2,3 or 4");
01343 }
01344
01345 assert( pha_mat_spt.nshelves() == N_pt );
01346
01347 GridPos T_gp;
01348 Vector itw(2);
01349
01350
01351 pha_mat_spt = 0.;
01352
01353 for (Index i_pt = 0; i_pt < N_pt; i_pt ++)
01354 {
01355
01356
01357
01358 if (pnd_field(i_pt, scat_p_index, scat_lat_index, scat_lon_index) >
01359 pnd_limit)
01360 {
01361
01362
01363 Tensor3 pha_mat_spt_tmp(scat_data_mono[i_pt].T_grid.nelem(),
01364 pha_mat_spt.nrows(), pha_mat_spt.ncols());
01365
01366 pha_mat_spt_tmp = 0.;
01367
01368 if( scat_data_mono[i_pt].T_grid.nelem() > 1)
01369 {
01370
01371
01372
01373
01374
01375
01376 gridpos(T_gp, scat_data_mono[i_pt].T_grid, rte_temperature);
01377
01378 interpweights(itw, T_gp);
01379 }
01380
01381
01382 for (Index za_inc_idx = 0; za_inc_idx < doit_za_grid_size;
01383 za_inc_idx ++)
01384 {
01385 for (Index aa_inc_idx = 0; aa_inc_idx < scat_aa_grid.nelem();
01386 aa_inc_idx ++)
01387 {
01388 for (Index t_idx = 0; t_idx <
01389 scat_data_mono[i_pt].T_grid.nelem();
01390 t_idx ++)
01391 {
01392 pha_matTransform( pha_mat_spt_tmp(t_idx, joker, joker),
01393 scat_data_mono[i_pt].
01394 pha_mat_data
01395 (0,0,joker,joker,joker,
01396 joker,joker),
01397 scat_data_mono[i_pt].za_grid,
01398 scat_data_mono[i_pt].aa_grid,
01399 scat_data_mono[i_pt].ptype,
01400 scat_za_index, scat_aa_index,
01401 za_inc_idx,
01402 aa_inc_idx, za_grid, scat_aa_grid);
01403 }
01404
01405 if( scat_data_mono[i_pt].T_grid.nelem() > 1)
01406 {
01407 for (Index i = 0; i< stokes_dim; i++)
01408 {
01409 for (Index j = 0; j< stokes_dim; j++)
01410 {
01411 pha_mat_spt(i_pt, za_inc_idx, aa_inc_idx, i, j)=
01412 interp(itw, pha_mat_spt_tmp(joker, i, j), T_gp);
01413 }
01414 }
01415 }
01416 else
01417 {
01418 pha_mat_spt(i_pt, za_inc_idx, aa_inc_idx, joker, joker) =
01419 pha_mat_spt_tmp(0, joker, joker);
01420 }
01421 }
01422 }
01423 }
01424 }
01425 }
01426