00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00040
00041
00042
00043
00044 #include <stdexcept>
00045 #include <cstdlib>
00046 #include <cmath>
00047
00048 #include "arts.h"
00049 #include "array.h"
00050 #include "check_input.h"
00051 #include "xml_io.h"
00052 #include "messages.h"
00053 #include "gridded_fields.h"
00054 #include "logic.h"
00055 #include "rte.h"
00056 #include "interpolation.h"
00057 #include "special_interp.h"
00058 #include "cloudbox.h"
00059 #include "optproperties.h"
00060 #include "math_funcs.h"
00061 #include "physics_funcs.h"
00062
00063 extern const Index GFIELD3_P_GRID;
00064 extern const Index GFIELD3_LAT_GRID;
00065 extern const Index GFIELD3_LON_GRID;
00066
00067
00068
00069
00070
00071
00072
00073 void cloudboxOff(
00074
00075 Index& cloudbox_on,
00076 ArrayOfIndex& cloudbox_limits,
00077 Agenda& iy_cloudbox_agenda )
00078 {
00079 cloudbox_on = 0;
00080 cloudbox_limits.resize(0);
00081 iy_cloudbox_agenda = Agenda();
00082 iy_cloudbox_agenda.set_name( "iy_cloudbox_agenda" );
00083 }
00084
00085
00086
00087 void cloudboxSetEmpty(
00088 Tensor4& pnd_field,
00089 ArrayOfSingleScatteringData& scat_data_raw,
00090
00091 const Vector& p_grid,
00092 const Vector& lat_grid,
00093 const Vector& lon_grid)
00094 {
00095
00096 if (lat_grid.nelem()>0)
00097 {
00098
00099 pnd_field.resize(1, p_grid.nelem(), lat_grid.nelem(), lon_grid.nelem());
00100 pnd_field = 0.;
00101 }
00102 else
00103 {
00104
00105 pnd_field.resize(1, p_grid.nelem(), 1, 1);
00106 pnd_field = 0.;
00107 }
00108
00109
00110
00111 scat_data_raw.resize(1);
00112 scat_data_raw[0].ptype = PTYPE_MACROS_ISO;
00113 scat_data_raw[0].description = " ";
00114
00115 nlinspace(scat_data_raw[0].f_grid, 1e9, 3.848043e+13 , 5);
00116 nlinspace(scat_data_raw[0].T_grid, 0, 400, 5);
00117 nlinspace(scat_data_raw[0].za_grid, 0, 180, 5);
00118 nlinspace(scat_data_raw[0].aa_grid, 0, 360, 5);
00119
00120 scat_data_raw[0].pha_mat_data.resize(5,5,5,1,1,1,6);
00121 scat_data_raw[0].pha_mat_data = 0.;
00122 scat_data_raw[0].ext_mat_data.resize(5,5,1,1,1);
00123 scat_data_raw[0].ext_mat_data = 0.;
00124 scat_data_raw[0].abs_vec_data.resize(5,5,1,1,1);
00125 scat_data_raw[0].abs_vec_data = 0.;
00126 }
00127
00128
00129
00130 void cloudboxSetManually(
00131
00132 Index& cloudbox_on,
00133 ArrayOfIndex& cloudbox_limits,
00134
00135 const Index& atmosphere_dim,
00136 const Vector& p_grid,
00137 const Vector& lat_grid,
00138 const Vector& lon_grid,
00139
00140 const Numeric& p1,
00141 const Numeric& p2,
00142 const Numeric& lat1,
00143 const Numeric& lat2,
00144 const Numeric& lon1,
00145 const Numeric& lon2 )
00146 {
00147
00148 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
00149 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
00150
00151 if( atmosphere_dim == 2 )
00152 { throw runtime_error( "The cloud box is not defined for 2D." ); }
00153
00154
00155 if( p1 <= p2 )
00156 throw runtime_error(
00157 "The pressure in *p1* must be bigger than the pressure in *p2*." );
00158 if( p1 <= p_grid[p_grid.nelem()-1] )
00159 throw runtime_error( "The pressure in *p1* must be larger than the "
00160 "last value in *p_grid*." );
00161 if( p2 >= p_grid[0] )
00162 throw runtime_error( "The pressure in *p2* must be smaller than the "
00163 "first value in *p_grid*." );
00164 if( atmosphere_dim >= 2 )
00165 {
00166 if( lat2 <= lat1 )
00167 throw runtime_error(
00168 "The latitude in *lat2* must be bigger than the latitude in *lat1*.");
00169 if( lat1 < lat_grid[1] )
00170 throw runtime_error( "The latitude in *lat1* must be >= than the "
00171 "second value in *lat_grid*." );
00172 if( lat2 > lat_grid[lat_grid.nelem()-2] )
00173 throw runtime_error( "The latitude in *lat2* must be <= than the "
00174 "next to last value in *lat_grid*." );
00175 }
00176 if( atmosphere_dim == 3 )
00177 {
00178 if( lon2 <= lon1 )
00179 throw runtime_error(
00180 "The longitude in *lon2* must be bigger than the longitude in *lon1*.");
00181 if( lon1 < lon_grid[1] )
00182 throw runtime_error( "The longitude in *lon1* must be >= than the "
00183 "second value in *lon_grid*." );
00184 if( lon2 > lon_grid[lon_grid.nelem()-2] )
00185 throw runtime_error( "The longitude in *lon2* must be <= than the "
00186 "next to last value in *lon_grid*." );
00187 }
00188
00189
00190 cloudbox_on = 1;
00191
00192
00193 cloudbox_limits.resize( atmosphere_dim*2 );
00194
00195
00196 if( p1 > p_grid[1] )
00197 {
00198 cloudbox_limits[0] = 0;
00199 }
00200 else
00201 {
00202 for( cloudbox_limits[0]=1; p_grid[cloudbox_limits[0]+1]>=p1;
00203 cloudbox_limits[0]++ ) {}
00204 }
00205 if( p2 < p_grid[p_grid.nelem()-2] )
00206 {
00207 cloudbox_limits[1] = p_grid.nelem() - 1;
00208 }
00209 else
00210 {
00211 for( cloudbox_limits[1]=p_grid.nelem()-2;
00212 p_grid[cloudbox_limits[1]-1]<=p2; cloudbox_limits[1]-- ) {}
00213 }
00214
00215
00216 if( atmosphere_dim >= 2 )
00217 {
00218 for( cloudbox_limits[2]=1; lat_grid[cloudbox_limits[2]+1]<=lat1;
00219 cloudbox_limits[2]++ ) {}
00220 for( cloudbox_limits[3]=lat_grid.nelem()-2;
00221 lat_grid[cloudbox_limits[3]-1]>=lat2; cloudbox_limits[3]-- ) {}
00222 }
00223
00224
00225 if( atmosphere_dim == 3 )
00226 {
00227 for( cloudbox_limits[4]=1; lon_grid[cloudbox_limits[4]+1]<=lon1;
00228 cloudbox_limits[4]++ ) {}
00229 for( cloudbox_limits[5]=lon_grid.nelem()-2;
00230 lon_grid[cloudbox_limits[5]-1]>=lon2; cloudbox_limits[5]-- ) {}
00231 }
00232 }
00233
00234
00235
00236 void cloudboxSetManuallyAltitude(
00237
00238 Index& cloudbox_on,
00239 ArrayOfIndex& cloudbox_limits,
00240
00241 const Index& atmosphere_dim,
00242 const Tensor3& z_field,
00243 const Vector& lat_grid,
00244 const Vector& lon_grid,
00245
00246 const Numeric& z1,
00247 const Numeric& z2,
00248 const Numeric& lat1,
00249 const Numeric& lat2,
00250 const Numeric& lon1,
00251 const Numeric& lon2 )
00252 {
00253
00254 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
00255
00256 if( atmosphere_dim == 2 )
00257 { throw runtime_error( "The cloud box is not defined for 2D." ); }
00258
00259
00260 if( z1 >= z2 )
00261 throw runtime_error(
00262 "The altitude in *z1* must be smaller than the altitude in *z2*." );
00263
00264
00265
00266
00267
00268
00269
00270
00271 if( atmosphere_dim == 3 )
00272 {
00273 if( lat2 <= lat1 )
00274 throw runtime_error(
00275 "The latitude in *lat2* must be bigger than the latitude in *lat1*.");
00276 if( lat1 < lat_grid[1] )
00277 throw runtime_error( "The latitude in *lat1* must be >= than the "
00278 "second value in *lat_grid*." );
00279 if( lat2 > lat_grid[lat_grid.nelem()-2] )
00280 throw runtime_error( "The latitude in *lat2* must be <= than the "
00281 "next to last value in *lat_grid*." );
00282 if( lon2 <= lon1 )
00283 throw runtime_error
00284 ("The longitude in *lon2* must be bigger than the longitude in *lon1*.");
00285 if( lon1 < lon_grid[1] )
00286 throw runtime_error( "The longitude in *lon1* must be >= than the "
00287 "second value in *lon_grid*." );
00288 if( lon2 > lon_grid[lon_grid.nelem()-2] )
00289 throw runtime_error( "The longitude in *lon2* must be <= than the "
00290 "next to last value in *lon_grid*." );
00291 }
00292
00293
00294 cloudbox_on = 1;
00295
00296
00297 cloudbox_limits.resize( atmosphere_dim*2 );
00298
00299
00300 if( z1 < z_field(1, 0, 0) )
00301 {
00302 cloudbox_limits[0] = 0;
00303 }
00304 else
00305 {
00306 for( cloudbox_limits[0]=1; z_field(cloudbox_limits[0]+1, 0, 0) <= z1;
00307 cloudbox_limits[0]++ ) {}
00308 }
00309 if( z2 > z_field(z_field.npages()-2, 0, 0) )
00310 {
00311 cloudbox_limits[1] = z_field.npages() - 1;
00312 }
00313 else
00314 {
00315 for( cloudbox_limits[1]=z_field.npages()- 2;
00316 z_field(cloudbox_limits[1]-1, 0, 0) >= z2; cloudbox_limits[1]-- ) {}
00317 }
00318
00319
00320 if( atmosphere_dim >= 2 )
00321 {
00322 for( cloudbox_limits[2]=1; lat_grid[cloudbox_limits[2]+1]<=lat1;
00323 cloudbox_limits[2]++ ) {}
00324 for( cloudbox_limits[3]=lat_grid.nelem()-2;
00325 lat_grid[cloudbox_limits[3]-1]>=lat2; cloudbox_limits[3]-- ) {}
00326 }
00327
00328
00329 if( atmosphere_dim == 3 )
00330 {
00331 for( cloudbox_limits[4]=1; lon_grid[cloudbox_limits[4]+1]<=lon1;
00332 cloudbox_limits[4]++ ) {}
00333 for( cloudbox_limits[5]=lon_grid.nelem()-2;
00334 lon_grid[cloudbox_limits[5]-1]>=lon2; cloudbox_limits[5]-- ) {}
00335 }
00336 }
00337
00338
00339
00340 void doit_i_fieldSetClearsky(Tensor6& doit_i_field,
00341 const Tensor7& scat_i_p,
00342 const Tensor7& scat_i_lat,
00343 const Tensor7& scat_i_lon,
00344 const Vector& f_grid,
00345 const Index& f_index,
00346 const Vector& p_grid,
00347 const Vector& lat_grid,
00348 const Vector& lon_grid,
00349 const ArrayOfIndex& cloudbox_limits,
00350 const Index& atmosphere_dim,
00351
00352 const Index& all_frequencies
00353 )
00354 {
00355
00356 out2 << " Interpolate boundary clearsky field to obtain the initial field.\n";
00357
00358
00359
00360
00361 if(atmosphere_dim == 1)
00362 {
00363 if(f_index == 0 || all_frequencies == true){
00364 Index N_f = scat_i_p.nlibraries();
00365 if (f_grid.nelem() != N_f){
00366
00367 throw runtime_error(" scat_i_p should have same frequency "
00368 " dimension as f_grid");
00369 }
00370
00371 if(scat_i_p.nvitrines() != 2){
00372 throw runtime_error("scat_i_p should have only two elements "
00373 "in pressure grid which corresponds "
00374 "to the two pressure surfaces");
00375 }
00376
00377
00378 Index N_za = scat_i_p.npages() ;
00379 Index N_aa = scat_i_p.nrows();
00380 Index N_i = scat_i_p.ncols();
00381
00382
00383
00384 doit_i_field.resize((cloudbox_limits[1]- cloudbox_limits[0])+1,
00385 1,
00386 1,
00387 N_za,
00388 N_aa,
00389 N_i);
00390
00391 doit_i_field = 0.;
00392
00393
00394
00395
00396
00397 ArrayOfGridPos p_gp((cloudbox_limits[1]- cloudbox_limits[0])+1);
00398
00399 p2gridpos(p_gp,
00400 p_grid[Range(cloudbox_limits[0],
00401 2,
00402 (cloudbox_limits[1]- cloudbox_limits[0]))],
00403 p_grid[Range(cloudbox_limits[0],
00404 (cloudbox_limits[1]- cloudbox_limits[0])+1)]);
00405
00406 Matrix itw((cloudbox_limits[1]- cloudbox_limits[0])+1, 2);
00407 interpweights ( itw, p_gp );
00408
00409
00410
00411 for (Index za_index = 0; za_index < N_za ; ++ za_index)
00412 {
00413 for (Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
00414 {
00415 for (Index i = 0 ; i < N_i ; ++ i)
00416 {
00417
00418 VectorView target_field = doit_i_field(Range(joker),
00419 0,
00420 0,
00421 za_index,
00422 aa_index,
00423 i);
00424
00425 ConstVectorView source_field = scat_i_p(f_index,
00426 Range(joker),
00427 0,
00428 0,
00429 za_index,
00430 aa_index,
00431 i);
00432
00433 interp(target_field,
00434 itw,
00435 source_field,
00436 p_gp);
00437 }
00438
00439 }
00440 }
00441 }
00442 else{
00443
00444 doit_i_field(0, 0, 0, Range(joker), Range(joker), Range(joker))=
00445 scat_i_p(f_index, 0, 0, 0, Range(joker), Range(joker),
00446 Range(joker));
00447 doit_i_field(doit_i_field.nvitrines()-1, 0, 0, Range(joker),
00448 Range(joker), Range(joker))=
00449 scat_i_p(f_index, 1, 0, 0, Range(joker), Range(joker),
00450 Range(joker));
00451 }
00452 }
00453 else if(atmosphere_dim == 3)
00454 {
00455 if (all_frequencies == false)
00456 throw runtime_error("Error in doit_i_fieldSetClearsky: For 3D "
00457 "all_frequencies option is not implemented \n");
00458
00459 Index N_f = scat_i_p.nlibraries();
00460 if (scat_i_lat.nlibraries() != N_f ||
00461 scat_i_lon.nlibraries() != N_f){
00462
00463 throw runtime_error(" scat_i_p, scat_i_lat, scat_i_lon should have "
00464 "same frequency dimension");
00465 }
00466 Index N_p = cloudbox_limits[1] - cloudbox_limits[0] + 1;
00467 if(scat_i_lon.nvitrines() != N_p ||
00468 scat_i_lat.nvitrines() != N_p ){
00469 throw runtime_error("scat_i_lat and scat_i_lon should have "
00470 "same pressure grid dimension as p_grid");
00471 }
00472
00473 Index N_lat = cloudbox_limits[3] - cloudbox_limits[2] + 1;
00474
00475 if(scat_i_lon.nshelves() != N_lat ||
00476 scat_i_p.nshelves() != N_lat){
00477 throw runtime_error("scat_i_p and scat_i_lon should have "
00478 "same latitude grid dimension as lat_grid");
00479 }
00480
00481 Index N_lon = cloudbox_limits[5] - cloudbox_limits[4] + 1;
00482 if(scat_i_lat.nbooks() != N_lon ||
00483 scat_i_p.nbooks() != N_lon ){
00484 throw runtime_error("scat_i_p and scat_i_lat should have "
00485 "same longitude grid dimension as lon_grid");
00486 }
00487 if(scat_i_p.nvitrines() != 2){
00488 throw runtime_error("scat_i_p should have only two elements "
00489 "in pressure grid which corresponds "
00490 "to the two pressure surfaces");
00491 }
00492
00493 if(scat_i_lat.nshelves() != 2){
00494 throw runtime_error("scat_i_lat should have only two elements "
00495 "in latitude grid which corresponds "
00496 "to the two latitude surfaces");
00497
00498 }
00499 if(scat_i_lon.nbooks() != 2){
00500 throw runtime_error("scat_i_lon should have only two elements "
00501 "in longitude grid which corresponds "
00502 "to the two longitude surfaces");
00503
00504 }
00505 Index N_za = scat_i_p.npages() ;
00506 if (scat_i_lat.npages() != N_za ||
00507 scat_i_lon.npages() != N_za){
00508
00509 throw runtime_error(" scat_i_p, scat_i_lat, scat_i_lon should have "
00510 "same dimension for zenith angles");
00511 }
00512 Index N_aa = scat_i_p.nrows();
00513 if (scat_i_lat.nrows() != N_aa ||
00514 scat_i_lon.nrows() != N_aa){
00515
00516 throw runtime_error(" scat_i_p, scat_i_lat, scat_i_lon should have "
00517 "same dimension for azimuth angles");
00518 }
00519 Index N_i = scat_i_p.ncols();
00520 if (scat_i_lat.ncols() != N_i ||
00521 scat_i_lon.ncols() != N_i){
00522
00523 throw runtime_error(" scat_i_p, scat_i_lat, scat_i_lon should have "
00524 "same value for stokes_dim and can take only"
00525 "values 1,2,3 or 4");
00526 }
00527
00528
00529
00530
00531
00532 doit_i_field.resize((cloudbox_limits[1]- cloudbox_limits[0])+1,
00533 (cloudbox_limits[3]- cloudbox_limits[2])+1,
00534 (cloudbox_limits[5]- cloudbox_limits[4])+1,
00535 N_za,
00536 N_aa,
00537 N_i);
00538
00539
00540
00541 ArrayOfGridPos p_gp((cloudbox_limits[1]- cloudbox_limits[0])+1);
00542 ArrayOfGridPos lat_gp((cloudbox_limits[3]- cloudbox_limits[2])+1);
00543 ArrayOfGridPos lon_gp((cloudbox_limits[5]- cloudbox_limits[4])+1);
00544
00545
00546
00547
00548
00549 p2gridpos(p_gp,
00550 p_grid[Range(cloudbox_limits[0],
00551 2,
00552 (cloudbox_limits[1]- cloudbox_limits[0]))],
00553 p_grid[Range(cloudbox_limits[0],
00554 (cloudbox_limits[1]- cloudbox_limits[0])+1)]);
00555 gridpos(lat_gp,
00556 lat_grid[Range(cloudbox_limits[2],
00557 2,
00558 (cloudbox_limits[3]- cloudbox_limits[2]))],
00559 lat_grid[Range(cloudbox_limits[2],
00560 (cloudbox_limits[3]- cloudbox_limits[2])+1)]);
00561 gridpos(lon_gp,
00562 lon_grid[Range(cloudbox_limits[4],
00563 2,
00564 (cloudbox_limits[5]- cloudbox_limits[4]))],
00565 lon_grid[Range(cloudbox_limits[4],
00566 (cloudbox_limits[5]- cloudbox_limits[4])+1)]);
00567
00568
00569
00570
00571
00572 Matrix itw_p((cloudbox_limits[1]- cloudbox_limits[0])+1, 2);
00573 Matrix itw_lat((cloudbox_limits[3]- cloudbox_limits[2])+1, 2);
00574 Matrix itw_lon((cloudbox_limits[5]- cloudbox_limits[4])+1, 2);
00575
00576 interpweights ( itw_p, p_gp );
00577 interpweights ( itw_lat, lat_gp );
00578 interpweights ( itw_lon, lon_gp );
00579
00580
00581 for (Index lat_index = 0;
00582 lat_index <= (cloudbox_limits[3]-cloudbox_limits[2]); ++ lat_index)
00583 {
00584 for (Index lon_index = 0;
00585 lon_index <= (cloudbox_limits[5]-cloudbox_limits[4]);
00586 ++ lon_index)
00587 {
00588 for (Index za_index = 0; za_index < N_za ; ++ za_index)
00589 {
00590 for (Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
00591 {
00592 for (Index i = 0 ; i < N_i ; ++ i)
00593 {
00594
00595 VectorView target_field = doit_i_field(Range(joker),
00596 lat_index,
00597 lon_index,
00598 za_index,
00599 aa_index,
00600 i);
00601
00602 ConstVectorView source_field = scat_i_p(f_index,
00603 Range(joker),
00604 lat_index,
00605 lon_index,
00606 za_index,
00607 aa_index,
00608 i);
00609
00610 interp(target_field,
00611 itw_p,
00612 source_field,
00613 p_gp);
00614 }
00615 }
00616 }
00617 }
00618 }
00619
00620 for (Index p_index = 0;
00621 p_index <= (cloudbox_limits[1]-cloudbox_limits[0]) ; ++ p_index)
00622 {
00623 for (Index lon_index = 0;
00624 lon_index <= (cloudbox_limits[5]-cloudbox_limits[4]) ;
00625 ++ lon_index)
00626 {
00627 for (Index za_index = 0; za_index < N_za ; ++ za_index)
00628 {
00629 for (Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
00630 {
00631 for (Index i = 0 ; i < N_i ; ++ i)
00632 {
00633
00634 VectorView target_field = doit_i_field
00635 (p_index, Range(joker), lon_index,
00636 za_index, aa_index, i);
00637
00638 ConstVectorView source_field = scat_i_lat
00639 (f_index, p_index, Range(joker),
00640 lon_index, za_index, aa_index, i);
00641
00642 interp(target_field,
00643 itw_lat,
00644 source_field,
00645 lat_gp);
00646 }
00647 }
00648 }
00649 }
00650 }
00651
00652 for (Index p_index = 0;
00653 p_index <= (cloudbox_limits[1]-cloudbox_limits[0]); ++ p_index)
00654 {
00655 for (Index lat_index = 0;
00656 lat_index <= (cloudbox_limits[3]-cloudbox_limits[2]);
00657 ++ lat_index)
00658 {
00659 for (Index za_index = 0; za_index < N_za ; ++ za_index)
00660 {
00661 for (Index aa_index = 0; aa_index < N_aa ; ++ aa_index)
00662 {
00663 for (Index i = 0 ; i < N_i ; ++ i)
00664 {
00665
00666 VectorView target_field = doit_i_field(p_index,
00667 lat_index,
00668 Range(joker),
00669 za_index,
00670 aa_index,
00671 i);
00672
00673 ConstVectorView source_field = scat_i_lon(f_index,
00674 p_index,
00675 lat_index,
00676 Range(joker),
00677 za_index,
00678 aa_index,
00679 i);
00680
00681 interp(target_field,
00682 itw_lon,
00683 source_field,
00684 lon_gp);
00685 }
00686 }
00687 }
00688 }
00689 }
00690
00691 }
00692 }
00693
00694
00695
00696 void doit_i_fieldSetConst(
00697 Tensor6& doit_i_field,
00698
00699 const Tensor7& scat_i_p,
00700 const Tensor7& scat_i_lat,
00701 const Tensor7& scat_i_lon,
00702 const Vector& p_grid,
00703 const Vector& lat_grid,
00704 const Vector& lon_grid,
00705 const ArrayOfIndex& cloudbox_limits,
00706 const Index& atmosphere_dim,
00707 const Index& stokes_dim,
00708
00709 const Vector& doit_i_field_values)
00710 {
00711 out2 << " Set initial field to constant values: " << doit_i_field_values << "\n";
00712
00713
00714
00715 Index N_za = scat_i_p.npages();
00716 Index N_aa = scat_i_p.nrows();
00717 Index N_i = stokes_dim;
00718 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
00719 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
00720 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
00721
00722 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
00723
00724
00725 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
00726
00727
00728 if (stokes_dim < 0 || stokes_dim > 4)
00729 throw runtime_error(
00730 "The dimension of stokes vector must be"
00731 "1,2,3, or 4");
00732
00733 if ( cloudbox_limits.nelem()!= 2*atmosphere_dim)
00734 throw runtime_error(
00735 "*cloudbox_limits* is a vector which contains the"
00736 "upper and lower limit of the cloud for all "
00737 "atmospheric dimensions. So its dimension must"
00738 "be 2 x *atmosphere_dim*");
00739
00740
00741
00742 if(atmosphere_dim == 1)
00743 {
00744 out3 << " atm_dim = 1\n";
00745
00746
00747 doit_i_field.resize((cloudbox_limits[1] - cloudbox_limits[0])+1, 1, 1, N_za,
00748 1, N_i);
00749 doit_i_field = 0.;
00750
00751
00752 for (Index za_index = 0; za_index < N_za; za_index++)
00753 {
00754 for (Index i = 0; i < stokes_dim; i++)
00755 {
00756
00757 doit_i_field(cloudbox_limits[1]-cloudbox_limits[0], 0, 0, za_index,
00758 0, i) =
00759 scat_i_p(0, 1, 0, 0, za_index, 0, i);
00760
00761 doit_i_field(0, 0, 0, za_index, 0, i) =
00762 scat_i_p(0, 0, 0, 0, za_index, 0, i);
00763 for (Index scat_p_index = 1; scat_p_index < cloudbox_limits[1] -
00764 cloudbox_limits[0]; scat_p_index++ )
00765
00766 doit_i_field(scat_p_index, 0, 0, za_index, 0, i) = doit_i_field_values[i];
00767 }
00768 }
00769 }
00770 else
00771 {
00772 if ( !is_size(scat_i_p, 1, 2, Nlat_cloud,
00773 Nlon_cloud, N_za, N_aa, stokes_dim)
00774 || !is_size(scat_i_lat, 1, Np_cloud, 2,
00775 Nlon_cloud, N_za, N_aa, stokes_dim)
00776 || !is_size(scat_i_lon, 1, Np_cloud,
00777 Nlat_cloud, 2, N_za, N_aa, stokes_dim) )
00778 throw runtime_error(
00779 "One of the interface variables (*scat_i_p*, "
00780 "*scat_i_lat* or *scat_i_lon*) does not have "
00781 "the right dimensions. \n Probably you have "
00782 "calculated them before for another value of "
00783 "*stokes_dim*."
00784 );
00785
00786
00787
00788 out3 << "atm_dim = 3\n";
00789 doit_i_field.resize((cloudbox_limits[1]- cloudbox_limits[0])+1,
00790 (cloudbox_limits[3]- cloudbox_limits[2])+1,
00791 (cloudbox_limits[5]- cloudbox_limits[4])+1,
00792 N_za,
00793 N_aa,
00794 N_i);
00795
00796 doit_i_field = 0.;
00797
00798
00799
00800 for (Index za_index = 0; za_index < N_za; za_index++)
00801 {
00802 for (Index aa_index = 0; aa_index < N_aa; aa_index++)
00803 {
00804 for (Index i = 0; i < stokes_dim; i++)
00805 {
00806
00807
00808 for (Index lat_index = cloudbox_limits[2];
00809 lat_index <= cloudbox_limits[3]; lat_index++)
00810 {
00811 for (Index lon_index = cloudbox_limits[4];
00812 lon_index <= cloudbox_limits[5]; lon_index++)
00813 {
00814
00815 doit_i_field(cloudbox_limits[1]-cloudbox_limits[0],
00816 lat_index-cloudbox_limits[2],
00817 lon_index-cloudbox_limits[4],
00818 za_index, aa_index, i) =
00819 scat_i_p(0, 1, lat_index-cloudbox_limits[2],
00820 lon_index-cloudbox_limits[4],
00821 za_index, aa_index, i);
00822
00823 doit_i_field(0, lat_index-cloudbox_limits[2],
00824 lon_index-cloudbox_limits[4],
00825 za_index, aa_index, i) =
00826 scat_i_p(0, 0, lat_index-cloudbox_limits[2],
00827 lon_index-cloudbox_limits[4],
00828 za_index, aa_index, i);
00829 }
00830 }
00831
00832 for (Index p_index = cloudbox_limits[0];
00833 p_index <= cloudbox_limits[1]; p_index++)
00834 {
00835
00836
00837 for (Index lon_index = cloudbox_limits[4];
00838 lon_index <= cloudbox_limits[5]; lon_index++)
00839 {
00840
00841 doit_i_field(p_index-cloudbox_limits[0],
00842 cloudbox_limits[3]-cloudbox_limits[2],
00843 lon_index-cloudbox_limits[4],
00844 za_index, aa_index, i) =
00845 scat_i_lat(0, p_index-cloudbox_limits[0],
00846 1, lon_index-cloudbox_limits[4],
00847 za_index, aa_index, i);
00848
00849 doit_i_field(p_index-cloudbox_limits[0], 0,
00850 lon_index-cloudbox_limits[4],
00851 za_index, aa_index, i) =
00852 scat_i_lat(0, p_index-cloudbox_limits[0], 0,
00853 lon_index-cloudbox_limits[4],
00854 za_index, aa_index, i);
00855
00856 }
00857
00858 for (Index lat_index = cloudbox_limits[2];
00859 lat_index <= cloudbox_limits[3]; lat_index++)
00860 {
00861
00862 doit_i_field(p_index-cloudbox_limits[0],
00863 lat_index-cloudbox_limits[2],
00864 cloudbox_limits[5]-cloudbox_limits[4],
00865 za_index, aa_index, i) =
00866 scat_i_lon(0, p_index-cloudbox_limits[0],
00867 lat_index-cloudbox_limits[2], 1,
00868 za_index, aa_index, i);
00869
00870 doit_i_field(p_index-cloudbox_limits[0],
00871 lat_index-cloudbox_limits[2],
00872 0,
00873 za_index, aa_index, i) =
00874 scat_i_lon(0, p_index-cloudbox_limits[0],
00875 lat_index-cloudbox_limits[2], 0,
00876 za_index, aa_index, i);
00877 }
00878 }
00879
00880
00881
00882
00883 for( Index p_index = (cloudbox_limits[0]+1);
00884 p_index < cloudbox_limits[1] ;
00885 p_index ++)
00886 {
00887 for (Index lat_index = (cloudbox_limits[2]+1);
00888 lat_index < cloudbox_limits[3];
00889 lat_index++)
00890 {
00891 for (Index lon_index = (cloudbox_limits[4]+1);
00892 lon_index < cloudbox_limits[5];
00893 lon_index++)
00894 {
00895 doit_i_field(p_index-cloudbox_limits[0],
00896 lat_index-cloudbox_limits[2],
00897 lon_index-cloudbox_limits[4],
00898 za_index, aa_index, i) =
00899 doit_i_field_values[i];
00900 }
00901 }
00902 }
00903 }
00904 }
00905 }
00906
00907 }
00908 }
00909
00910
00911
00912 void ParticleTypeInit(
00913 ArrayOfSingleScatteringData& scat_data_raw,
00914 ArrayOfGField3& pnd_field_raw
00915 )
00916 {
00917 scat_data_raw.reserve(20);
00918 pnd_field_raw.reserve(20);
00919 }
00920
00921
00922
00923 void ParticleTypeAddAll(
00924 ArrayOfSingleScatteringData& scat_data_raw,
00925 ArrayOfGField3& pnd_field_raw,
00926
00927 const Index& atmosphere_dim,
00928 const Vector& f_grid,
00929 const Vector& p_grid,
00930 const Vector& lat_grid,
00931 const Vector& lon_grid,
00932 const ArrayOfIndex& cloudbox_limits,
00933
00934 const String& filename_scat_data,
00935 const String& pnd_field_file)
00936 {
00937
00938
00939
00940 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
00941 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
00942
00943
00944 if ( cloudbox_limits.nelem() != 2*atmosphere_dim )
00945 throw runtime_error(
00946 "*cloudbox_limits* is a vector which contains"
00947 "the upper and lower\n"
00948 "limit of the cloud for all atmospheric dimensions.\n"
00949 "So its length must be 2 x *atmosphere_dim*" );
00950
00951 if( f_grid.nelem() == 0 )
00952 throw runtime_error( "The frequency grid is empty." );
00953 chk_if_increasing( "f_grid", f_grid );
00954
00955
00956
00957 ArrayOfString data_files;
00958 xml_read_from_file(filename_scat_data, data_files);
00959 scat_data_raw.resize(data_files.nelem());
00960
00961 for (Index i = 0; i<data_files.nelem(); i++)
00962 {
00963
00964 out2 << " Read single scattering data\n";
00965 xml_read_from_file( data_files[i],
00966 scat_data_raw[i]);
00967
00968 chk_single_scattering_data(scat_data_raw[i],
00969 data_files[i], f_grid);
00970
00971 }
00972
00973 out2 << " Read particle number density date \n";
00974 xml_read_from_file(pnd_field_file, pnd_field_raw);
00975
00976 chk_pnd_raw_data(pnd_field_raw,
00977 pnd_field_file, atmosphere_dim, p_grid, lat_grid,
00978 lon_grid, cloudbox_limits);
00979 }
00980
00981
00982
00983 void ParticleTypeAdd(
00984 ArrayOfSingleScatteringData& scat_data_raw,
00985 ArrayOfGField3& pnd_field_raw,
00986
00987 const Index& atmosphere_dim,
00988 const Vector& f_grid,
00989 const Vector& p_grid,
00990 const Vector& lat_grid,
00991 const Vector& lon_grid,
00992 const ArrayOfIndex& cloudbox_limits,
00993
00994 const String& scat_data_file,
00995 const String& pnd_field_file
00996 )
00997 {
00998
00999
01000
01001 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
01002 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
01003
01004
01005 if ( cloudbox_limits.nelem() != 2*atmosphere_dim )
01006 throw runtime_error(
01007 "*cloudbox_limits* is a vector which contains"
01008 "the upper and lower\n"
01009 "limit of the cloud for all atmospheric dimensions.\n"
01010 "So its length must be 2 x *atmosphere_dim*" );
01011
01012 if( f_grid.nelem() == 0 )
01013 throw runtime_error( "The frequency grid is empty." );
01014 chk_if_increasing( "f_grid", f_grid );
01015
01016
01017
01018
01019
01020 SingleScatteringData scat_data;
01021 scat_data_raw.push_back(scat_data);
01022
01023 GField3 pnd_field_data;
01024 pnd_field_raw.push_back(pnd_field_data);
01025
01026 out2 << " Read single scattering data\n";
01027 xml_read_from_file(scat_data_file, scat_data_raw[scat_data_raw.nelem()-1]);
01028
01029 chk_single_scattering_data(scat_data_raw[scat_data_raw.nelem()-1],
01030 scat_data_file, f_grid);
01031
01032 out2 << " Read particle number density field\n";
01033 if (pnd_field_file.nelem() < 1)
01034 out1 << "Warning: No pnd_field_file specified. Ignored. \n";
01035 else
01036 {
01037 xml_read_from_file(pnd_field_file,
01038 pnd_field_raw[pnd_field_raw.nelem()-1]);
01039
01040 chk_pnd_data(pnd_field_raw[pnd_field_raw.nelem()-1],
01041 pnd_field_file, atmosphere_dim, p_grid, lat_grid,
01042 lon_grid, cloudbox_limits);
01043 }
01044 }
01045
01046
01047
01048 void pnd_fieldCalc(
01049 Tensor4& pnd_field,
01050
01051 const Vector& p_grid,
01052 const Vector& lat_grid,
01053 const Vector& lon_grid,
01054 const ArrayOfGField3& pnd_field_raw,
01055 const Index& atmosphere_dim,
01056 const ArrayOfIndex& cloudbox_limits
01057 )
01058 {
01059
01060
01061
01062
01063 if (pnd_field_raw.nelem() == 0)
01064 throw runtime_error(
01065 "No particle number density data given. Please\n"
01066 "use WSMs *ParticleTypeInit* and \n"
01067 "*ParticleTypeAdd(All)* for reading cloud particle\n"
01068 "data.\n"
01069 );
01070
01071
01072 if (!((atmosphere_dim == 1) || (atmosphere_dim == 3)))
01073 throw runtime_error(
01074 "*atmosphere_dim* must be 1 or 3, because \n"
01075 "scattering is only implemented for 1D and 3D.\n"
01076 "DOIT works in 1D and 3D, Monte Carlo only in 3D.\n"
01077 );
01078
01079 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
01080 if ( cloudbox_limits.nelem()!= 2*atmosphere_dim)
01081 throw runtime_error(
01082 "*cloudbox_limits* is a vector which contains the"
01083 "upper and lower limit of the cloud for all "
01084 "atmospheric dimensions. So its dimension must"
01085 "be 2 x *atmosphere_dim*");
01086
01087 const Index Np_cloud = cloudbox_limits[1]-cloudbox_limits[0]+1;
01088
01089 ConstVectorView p_grid_cloud = p_grid[Range(cloudbox_limits[0], Np_cloud)];
01090
01091
01092 if ( atmosphere_dim == 1)
01093 {
01094
01095 pnd_field.resize(pnd_field_raw.nelem(), Np_cloud, 1, 1);
01096
01097
01098 ArrayOfGridPos gp_p(Np_cloud);
01099
01100
01101
01102 for (Index i = 0; i < pnd_field_raw.nelem(); ++ i)
01103 {
01104
01105 p2gridpos(gp_p, pnd_field_raw[i].get_numeric_grid(GFIELD3_P_GRID), p_grid_cloud);
01106
01107
01108 Matrix itw(Np_cloud, 2);
01109
01110 interpweights( itw, gp_p);
01111
01112 interp( pnd_field(i, joker, 0, 0),
01113 itw, pnd_field_raw[i](joker, 0, 0), gp_p);
01114 }
01115
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 else
01156 {
01157 const Index Nlat_cloud = cloudbox_limits[3]-cloudbox_limits[2]+1;
01158 const Index Nlon_cloud = cloudbox_limits[5]-cloudbox_limits[4]+1;
01159
01160 ConstVectorView lat_grid_cloud =
01161 lat_grid[Range(cloudbox_limits[2], Nlat_cloud)];
01162 ConstVectorView lon_grid_cloud =
01163 lon_grid[Range(cloudbox_limits[4], Nlon_cloud)];
01164
01165
01166 pnd_field.resize(pnd_field_raw.nelem(), Np_cloud, Nlat_cloud,
01167 Nlon_cloud);
01168
01169
01170
01171 ArrayOfGridPos gp_p(Np_cloud);
01172 ArrayOfGridPos gp_lat(Nlat_cloud);
01173 ArrayOfGridPos gp_lon(Nlon_cloud);
01174
01175
01176
01177
01178 for (Index i = 0; i < pnd_field_raw.nelem(); ++ i)
01179 {
01180
01181 p2gridpos(gp_p, pnd_field_raw[i].get_numeric_grid(GFIELD3_P_GRID),
01182 p_grid_cloud);
01183 gridpos(gp_lat, pnd_field_raw[i].get_numeric_grid(GFIELD3_LAT_GRID),
01184 lat_grid_cloud);
01185 gridpos(gp_lon, pnd_field_raw[i].get_numeric_grid(GFIELD3_LON_GRID),
01186 lon_grid_cloud);
01187
01188
01189 Tensor4 itw(Np_cloud, Nlat_cloud, Nlon_cloud, 8);
01190
01191 interpweights( itw, gp_p, gp_lat, gp_lon );
01192
01193
01194 interp( pnd_field(i, joker, joker, joker),
01195 itw, pnd_field_raw[i], gp_p, gp_lat, gp_lon);
01196 }
01197 }
01198 }
01199
01200
01201
01202 void DoitCloudboxFieldPut(
01203 Tensor7& scat_i_p,
01204 Tensor7& scat_i_lat,
01205 Tensor7& scat_i_lon,
01206 Tensor4& doit_i_field1D_spectrum,
01207
01208 const Tensor6& doit_i_field,
01209 const Vector& f_grid,
01210 const Index& f_index,
01211 const Vector& p_grid,
01212 const Vector& lat_grid,
01213 const Vector& lon_grid,
01214 const Vector& scat_za_grid,
01215 const Vector& scat_aa_grid,
01216 const Index& stokes_dim,
01217 const Index& atmosphere_dim,
01218 const ArrayOfIndex& cloudbox_limits,
01219 const Matrix& sensor_pos,
01220 const Tensor3& z_field
01221 )
01222 {
01223
01224 Index N_f = f_grid.nelem();
01225 Index N_za = scat_za_grid.nelem();
01226 Index N_aa = scat_aa_grid.nelem();
01227 Index N_p = cloudbox_limits[1] - cloudbox_limits[0] +1;
01228
01229
01230
01231 assert( f_index < f_grid.nelem() );
01232
01233 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 );
01234
01235
01236 chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid );
01237
01238
01239 if (stokes_dim < 0 || stokes_dim > 4)
01240 throw runtime_error(
01241 "The dimension of stokes vector must be"
01242 "1,2,3, or 4");
01243
01244 if ( cloudbox_limits.nelem()!= 2*atmosphere_dim)
01245 throw runtime_error(
01246 "*cloudbox_limits* is a vector which contains the"
01247 "upper and lower limit of the cloud for all "
01248 "atmospheric dimensions. So its dimension must"
01249 "be 2 x *atmosphere_dim*");
01250
01251
01252
01253 doit_i_field1D_spectrum.resize(N_f, N_p, N_za, stokes_dim);
01254 doit_i_field1D_spectrum = 0;
01255
01256
01257
01258 if(atmosphere_dim == 1)
01259 {
01260 bool in_cloudbox = false;
01261
01262
01263 for (Index i = 0; i < sensor_pos.ncols(); i++)
01264 {
01265
01266 if(sensor_pos(i, 0) >= z_field(cloudbox_limits[0], 0, 0) &&
01267 sensor_pos(i, 0) <= z_field(cloudbox_limits[1], 0, 0) )
01268 {
01269 in_cloudbox = true;
01270 out2 << " Sensor position in cloudbox, store radiation field\n"
01271 << " in cloudbox for all frequencies. \n";
01272 }
01273 }
01274
01275
01276 assert ( is_size( doit_i_field,
01277 (cloudbox_limits[1] - cloudbox_limits[0]) + 1,
01278 1,
01279 1,
01280 N_za,
01281 1,
01282 stokes_dim));
01283
01284 assert ( is_size( scat_i_p,
01285 N_f, 2, 1, 1, N_za, 1, stokes_dim ));
01286
01287 for (Index za = 0; za < N_za; za++)
01288 {
01289 for (Index i = 0; i < stokes_dim; i++)
01290 {
01291
01292
01293 scat_i_p(f_index, 0, 0, 0,
01294 za, 0, i) =
01295 doit_i_field(0, 0, 0, za, 0, i);
01296
01297 scat_i_p(f_index, 1, 0, 0,
01298 za, 0, i) =
01299 doit_i_field(cloudbox_limits[1] - cloudbox_limits[0],
01300 0, 0, za, 0, i);
01301
01302
01303
01304 if( in_cloudbox)
01305 {
01306 doit_i_field1D_spectrum(f_index, joker, za, i) =
01307 doit_i_field(joker, 0, 0, za, 0, i);
01308 }
01309
01310 }
01311 }
01312
01313
01314 }
01315
01316 if(atmosphere_dim == 3)
01317 {
01318
01319 Index N_lat = cloudbox_limits[3] - cloudbox_limits[2] + 1;
01320 Index N_lon = cloudbox_limits[5] - cloudbox_limits[4] + 1;
01321
01322
01323 assert ( is_size( doit_i_field,
01324 cloudbox_limits[1] - cloudbox_limits[0] + 1,
01325 N_lat,
01326 N_lon,
01327 N_za,
01328 N_aa,
01329 stokes_dim));
01330
01331
01332 scat_i_p.resize(N_f, 2, N_lat, N_lon, N_za, N_aa, stokes_dim);
01333 scat_i_lat.resize(N_f, N_p, 2, N_lon, N_za, N_aa, stokes_dim);
01334 scat_i_lon.resize(N_f, N_p, N_lat, 2, N_za, N_aa, stokes_dim);
01335
01336 for (Index za = 0; za < N_za; za++)
01337 {
01338 for (Index aa = 0; aa < N_aa; aa++)
01339 {
01340 for (Index i = 0; i < stokes_dim; i++)
01341 {
01342
01343
01344
01345 for (Index lat = 0; lat < N_lat; lat++)
01346 {
01347 for (Index lon = 0; lon < N_lon; lon++)
01348 {
01349
01350 scat_i_p(f_index, 0, lat, lon,
01351 za, aa, i) =
01352 doit_i_field(0, lat, lon, za, aa, i);
01353
01354 scat_i_p(f_index, 1, lat, lon,
01355 za, aa, i) =
01356 doit_i_field(cloudbox_limits[1]-cloudbox_limits[0],
01357 lat, lon, za, aa, i);
01358 }
01359 }
01360
01361
01362
01363 for (Index p = 0; p < N_p; p++)
01364 {
01365 for (Index lon = 0; lon < N_lon; lon++)
01366 {
01367
01368 scat_i_lat(f_index, p, 0, lon,
01369 za, aa, i) =
01370 doit_i_field(p, 0, lon, za, aa, i);
01371
01372 scat_i_lat(f_index, p, 1, lon,
01373 za, aa, i) =
01374 doit_i_field(p, cloudbox_limits[3]-
01375 cloudbox_limits[2],
01376 lon, za, aa, i);
01377 }
01378
01379
01380 for (Index lat = 0; lat < N_lat; lat++)
01381 {
01382
01383 scat_i_lon(f_index, p, lat, 0,
01384 za, aa, i) =
01385 doit_i_field(p, lat, 0, za, aa, i);
01386
01387 scat_i_lon(f_index, p, lat, 1,
01388 za, aa, i) =
01389 doit_i_field(p, lat, cloudbox_limits[5]-
01390 cloudbox_limits[4], za, aa, i);
01391 }
01392 }
01393 }
01394 }
01395 }
01396 }
01397 }
01398
01399
01400
01401 void CloudboxGetIncoming(
01402 Workspace& ws,
01403 Tensor7& scat_i_p,
01404 Tensor7& scat_i_lat,
01405 Tensor7& scat_i_lon,
01406 Index& cloudbox_on,
01407 const Agenda& ppath_step_agenda,
01408 const Agenda& rte_agenda,
01409 const Agenda& iy_space_agenda,
01410 const Agenda& surface_prop_agenda,
01411 const Agenda& iy_cloudbox_agenda,
01412 const Index& atmosphere_dim,
01413 const Vector& p_grid,
01414 const Vector& lat_grid,
01415 const Vector& lon_grid,
01416 const Tensor3& z_field,
01417 const Tensor3& t_field,
01418 const Tensor4& vmr_field,
01419 const Matrix& r_geoid,
01420 const Matrix& z_surface,
01421 const ArrayOfIndex& cloudbox_limits,
01422 const Vector& f_grid,
01423 const Index& stokes_dim,
01424 const Vector& scat_za_grid,
01425 const Vector& scat_aa_grid )
01426 {
01427 Index Nf = f_grid.nelem();
01428 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
01429 Index Nza = scat_za_grid.nelem();
01430 Index Ni = stokes_dim;
01431 Matrix iy;
01432 Ppath ppath;
01433
01434
01435
01436 if( !(atmosphere_dim == 1 || atmosphere_dim == 3) )
01437 throw runtime_error( "The atmospheric dimensionality must be 1 or 3.");
01438
01439
01440 if( scat_za_grid[0] != 0. || scat_za_grid[Nza-1] != 180. )
01441 throw runtime_error(
01442 "*scat_za_grid* must include 0 and 180 degrees as endpoints." );
01443
01444
01445
01446
01447
01448
01449 cloudbox_on = 0;
01450
01451 if( atmosphere_dim == 1 )
01452 {
01453
01454 scat_i_p.resize( Nf, 2, 1, 1, Nza, 1, Ni );
01455 scat_i_lat.resize( 0, 0, 0, 0, 0, 0, 0 );
01456 scat_i_lon.resize( 0, 0, 0, 0, 0, 0, 0 );
01457
01458
01459 Vector los(1), pos(1);
01460
01461
01462
01463 for (Index boundary = 0; boundary <= 1; boundary++)
01464 {
01465 pos[0] = r_geoid(0,0) + z_field( cloudbox_limits[boundary], 0, 0 );
01466
01467 for (Index scat_za_index = 0; scat_za_index < Nza; scat_za_index ++)
01468 {
01469 los[0] = scat_za_grid[scat_za_index];
01470
01471 iy_calc_no_jacobian( ws, iy, ppath,
01472 ppath_step_agenda, rte_agenda,
01473 iy_space_agenda, surface_prop_agenda,
01474 iy_cloudbox_agenda, atmosphere_dim,
01475 p_grid, lat_grid, lon_grid, z_field,
01476 t_field, vmr_field,
01477 r_geoid, z_surface, cloudbox_on,
01478 cloudbox_limits, pos, los, f_grid,
01479 stokes_dim );
01480
01481 scat_i_p( joker, boundary, 0, 0, scat_za_index, 0, joker ) = iy;
01482 }
01483 }
01484 }
01485
01486
01487
01488 else
01489 {
01490 Index Naa = scat_aa_grid.nelem();
01491
01492 if( scat_aa_grid[0] != 0. || scat_aa_grid[Naa-1] != 360. )
01493 throw runtime_error(
01494 "*scat_aa_grid* must include 0 and 360 degrees as endpoints." );
01495
01496 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
01497 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
01498
01499
01500
01501
01502 Vector aa_grid(Naa);
01503 for(Index i = 0; i<Naa; i++)
01504 aa_grid[i] = scat_aa_grid[i] - 180;
01505
01506
01507 scat_i_p.resize( Nf, 2, Nlat_cloud, Nlon_cloud, Nza, Naa, Ni );
01508 scat_i_lat.resize( Nf, Np_cloud, 2, Nlon_cloud, Nza, Naa, Ni );
01509 scat_i_lon.resize( Nf, Np_cloud, Nlat_cloud, 2, Nza, Naa, Ni );
01510
01511
01512 Vector los(2), pos(3);
01513
01514
01515
01516
01517 for (Index boundary = 0; boundary <= 1; boundary++)
01518 {
01519 for (Index lat_index = 0; lat_index < Nlat_cloud; lat_index++ )
01520 {
01521 for (Index lon_index = 0; lon_index < Nlon_cloud; lon_index++ )
01522 {
01523 pos[0] = r_geoid(lat_index + cloudbox_limits[2],
01524 lon_index + cloudbox_limits[4])
01525 + z_field(cloudbox_limits[boundary],
01526 lat_index + cloudbox_limits[2],
01527 lon_index + cloudbox_limits[4]);
01528 pos[1] = lat_grid[lat_index + cloudbox_limits[2]];
01529 pos[2] = lon_grid[lon_index + cloudbox_limits[4]];
01530
01531 for (Index scat_za_index = 0; scat_za_index < Nza;
01532 scat_za_index ++)
01533 {
01534 for (Index scat_aa_index = 0; scat_aa_index < Naa;
01535 scat_aa_index ++)
01536 {
01537 los[0] = scat_za_grid[scat_za_index];
01538 los[1] = aa_grid[scat_aa_index];
01539
01540
01541
01542 if( !( ( scat_za_index == 0 ||
01543 scat_za_index == (Nza-1) ) &&
01544 scat_aa_index == 0 ) )
01545 {
01546 iy_calc_no_jacobian( ws, iy, ppath,
01547 ppath_step_agenda,
01548 rte_agenda, iy_space_agenda,
01549 surface_prop_agenda,
01550 iy_cloudbox_agenda,
01551 atmosphere_dim, p_grid,
01552 lat_grid, lon_grid, z_field,
01553 t_field, vmr_field,
01554 r_geoid, z_surface,
01555 cloudbox_on,
01556 cloudbox_limits,
01557 pos, los, f_grid,
01558 stokes_dim );
01559 }
01560
01561 scat_i_p( joker, boundary, lat_index, lon_index,
01562 scat_za_index, scat_aa_index, joker) = iy;
01563 }
01564 }
01565 }
01566 }
01567 }
01568
01569
01570 for (Index boundary = 0; boundary <= 1; boundary++)
01571 {
01572 for (Index p_index = 0; p_index < Np_cloud; p_index++ )
01573 {
01574 for (Index lon_index = 0; lon_index < Nlon_cloud; lon_index++ )
01575 {
01576 pos[0] = r_geoid(cloudbox_limits[boundary+2],
01577 lon_index + cloudbox_limits[4])
01578 + z_field(p_index + cloudbox_limits[0],
01579 cloudbox_limits[boundary+2],
01580 lon_index + cloudbox_limits[4]);
01581 pos[1] = lat_grid[cloudbox_limits[boundary+2]];
01582 pos[2] = lon_grid[lon_index + cloudbox_limits[4]];
01583
01584 for (Index scat_za_index = 0; scat_za_index < Nza;
01585 scat_za_index ++)
01586 {
01587 for (Index scat_aa_index = 0; scat_aa_index < Naa;
01588 scat_aa_index ++)
01589 {
01590 los[0] = scat_za_grid[scat_za_index];
01591 los[1] = aa_grid[scat_aa_index];
01592
01593
01594
01595 if( !( ( scat_za_index == 0 ||
01596 scat_za_index == (Nza-1) ) &&
01597 scat_aa_index == 0 ) )
01598 {
01599 iy_calc_no_jacobian( ws, iy, ppath,
01600 ppath_step_agenda,
01601 rte_agenda, iy_space_agenda,
01602 surface_prop_agenda,
01603 iy_cloudbox_agenda,
01604 atmosphere_dim, p_grid,
01605 lat_grid, lon_grid, z_field,
01606 t_field, vmr_field,
01607 r_geoid, z_surface,
01608 cloudbox_on,
01609 cloudbox_limits, pos, los,
01610 f_grid, stokes_dim );
01611 }
01612
01613 scat_i_lat( joker, p_index, boundary, lon_index,
01614 scat_za_index, scat_aa_index, joker) = iy;
01615 }
01616 }
01617 }
01618 }
01619 }
01620
01621
01622 for (Index boundary = 0; boundary <= 1; boundary++)
01623 {
01624 for (Index p_index = 0; p_index < Np_cloud; p_index++ )
01625 {
01626 for (Index lat_index = 0; lat_index < Nlat_cloud; lat_index++ )
01627 {
01628 pos[0] = r_geoid(lat_index + cloudbox_limits[2],
01629 cloudbox_limits[boundary+4])
01630 + z_field(p_index + cloudbox_limits[0],
01631 lat_index + cloudbox_limits[2],
01632 cloudbox_limits[boundary+4]);
01633 pos[1] = lat_grid[lat_index + cloudbox_limits[2]];
01634 pos[2] = lon_grid[cloudbox_limits[boundary+4]];
01635
01636 for (Index scat_za_index = 0; scat_za_index < Nza;
01637 scat_za_index ++)
01638 {
01639 for (Index scat_aa_index = 0; scat_aa_index < Naa;
01640 scat_aa_index ++)
01641 {
01642 los[0] = scat_za_grid[scat_za_index];
01643 los[1] = aa_grid[scat_aa_index];
01644
01645
01646
01647 if( !( ( scat_za_index == 0 ||
01648 scat_za_index == (Nza-1) ) &&
01649 scat_aa_index == 0 ) )
01650 {
01651 iy_calc_no_jacobian( ws, iy, ppath,
01652 ppath_step_agenda,
01653 rte_agenda, iy_space_agenda,
01654 surface_prop_agenda,
01655 iy_cloudbox_agenda,
01656 atmosphere_dim, p_grid,
01657 lat_grid, lon_grid, z_field,
01658 t_field, vmr_field, r_geoid,
01659 z_surface, cloudbox_on,
01660 cloudbox_limits,
01661 pos, los, f_grid,
01662 stokes_dim );
01663 }
01664
01665 scat_i_lon( joker, p_index, lat_index, boundary,
01666 scat_za_index, scat_aa_index, joker) = iy;
01667 }
01668 }
01669 }
01670 }
01671 }
01672 }
01673 cloudbox_on = 1;
01674 }
01675
01676
01677
01678 void CloudboxGetIncoming1DAtm(
01679 Workspace& ws,
01680 Tensor7& scat_i_p,
01681 Tensor7& scat_i_lat,
01682 Tensor7& scat_i_lon,
01683 Index& cloudbox_on,
01684 const Agenda& ppath_step_agenda,
01685 const Agenda& rte_agenda,
01686 const Agenda& iy_space_agenda,
01687 const Agenda& surface_prop_agenda,
01688 const Agenda& iy_cloudbox_agenda,
01689 const Index& atmosphere_dim,
01690 const Vector& p_grid,
01691 const Vector& lat_grid,
01692 const Vector& lon_grid,
01693 const Tensor3& z_field,
01694 const Tensor3& t_field,
01695 const Tensor4& vmr_field,
01696 const Matrix& r_geoid,
01697 const Matrix& z_surface,
01698 const ArrayOfIndex& cloudbox_limits,
01699 const Vector& f_grid,
01700 const Index& stokes_dim,
01701 const Vector& scat_za_grid,
01702 const Vector& scat_aa_grid )
01703 {
01704 Index Nf = f_grid.nelem();
01705 Index Np_cloud = cloudbox_limits[1] - cloudbox_limits[0] + 1;
01706 Index Nlat_cloud = cloudbox_limits[3] - cloudbox_limits[2] + 1;
01707 Index Nlon_cloud = cloudbox_limits[5] - cloudbox_limits[4] + 1;
01708 Index Nza = scat_za_grid.nelem();
01709 Index Naa = scat_aa_grid.nelem();
01710 Index Ni = stokes_dim;
01711 Matrix iy;
01712 Ppath ppath;
01713
01714
01715
01716 if( atmosphere_dim != 3 )
01717 throw runtime_error( "The atmospheric dimensionality must be 3.");
01718
01719
01720 if( scat_za_grid[0] != 0. || scat_za_grid[Nza-1] != 180. )
01721 throw runtime_error(
01722 "*scat_za_grid* must include 0 and 180 degrees as endpoints." );
01723 if( scat_aa_grid[0] != 0. || scat_aa_grid[Naa-1] != 360. )
01724 throw runtime_error(
01725 "*scat_aa_grid* must include 0 and 360 degrees as endpoints." );
01726
01727
01728
01729
01730
01731 cloudbox_on = 0;
01732
01733
01734
01735
01736 Vector aa_grid(Naa);
01737 for(Index i = 0; i<Naa; i++)
01738 aa_grid[i] = scat_aa_grid[i] - 180;
01739
01740
01741
01742 Index aa_index = 0;
01743
01744
01745 scat_i_p.resize(Nf, 2, Nlat_cloud, Nlon_cloud, Nza, Naa, Ni);
01746 scat_i_lat.resize(Nf, Np_cloud, 2, Nlon_cloud, Nza, Naa, Ni);
01747 scat_i_lon.resize(Nf, Np_cloud, Nlat_cloud, 2, Nza, Naa, Ni);
01748
01749
01750 Vector los(2), pos(3);
01751
01752
01753 pos[1] = lat_grid[cloudbox_limits[2]];
01754 pos[2] = lon_grid[cloudbox_limits[4]];
01755 los[1] = aa_grid[aa_index];
01756
01757
01758 for (Index p_index = 0; p_index < Np_cloud; p_index++ )
01759 {
01760 pos[0] = r_geoid(cloudbox_limits[2], cloudbox_limits[4])
01761 + z_field(cloudbox_limits[0] + p_index, cloudbox_limits[2],
01762 cloudbox_limits[4]);
01763
01764 for (Index scat_za_index = 0; scat_za_index < Nza; scat_za_index++ )
01765 {
01766 los[0] = scat_za_grid[scat_za_index];
01767
01768 iy_calc_no_jacobian(ws, iy, ppath, ppath_step_agenda,
01769 rte_agenda, iy_space_agenda, surface_prop_agenda,
01770 iy_cloudbox_agenda, atmosphere_dim, p_grid,
01771 lat_grid, lon_grid, z_field, t_field, vmr_field,
01772 r_geoid, z_surface,
01773 cloudbox_on, cloudbox_limits, pos,
01774 los, f_grid, stokes_dim );
01775
01776 for (Index aa = 0; aa < Naa; aa ++)
01777 {
01778
01779 if(p_index == 0)
01780 {
01781 for (Index lat = 0; lat < Nlat_cloud; lat ++)
01782 {
01783 for (Index lon = 0; lon < Nlon_cloud; lon ++)
01784 {
01785 scat_i_p( joker, 0, lat, lon, scat_za_index, aa,
01786 joker )
01787 = iy;
01788 }
01789 }
01790 }
01791
01792 else if (p_index == Np_cloud-1)
01793 for (Index lat = 0; lat < Nlat_cloud; lat ++)
01794 {
01795 for (Index lon = 0; lon < Nlon_cloud; lon ++)
01796 {
01797 scat_i_p( joker, 1, lat, lon, scat_za_index, aa,
01798 joker )
01799 = iy;
01800 }
01801 }
01802
01803
01804 for (Index lat = 0; lat < 2; lat ++)
01805 {
01806 for (Index lon = 0; lon < Nlon_cloud; lon ++)
01807 {
01808 scat_i_lat( joker, p_index, lat, lon,
01809 scat_za_index, aa, joker)
01810 = iy;
01811 }
01812 }
01813
01814
01815 for (Index lat = 0; lat < Nlat_cloud; lat ++)
01816 {
01817 for (Index lon = 0; lon < 2; lon ++)
01818 {
01819 scat_i_lon( joker, p_index, lat, lon,
01820 scat_za_index, aa, joker)
01821 = iy;
01822 }
01823 }
01824 }
01825 }
01826 }
01827 cloudbox_on = 1;
01828 }
01829
01830
01831
01832 void iyInterpCloudboxField(
01833 Matrix& iy,
01834 const Tensor7& scat_i_p,
01835 const Tensor7& scat_i_lat,
01836 const Tensor7& scat_i_lon,
01837 const Tensor4& doit_i_field1D_spectrum,
01838 const GridPos& rte_gp_p,
01839 const GridPos& rte_gp_lat,
01840 const GridPos& rte_gp_lon,
01841 const Vector& rte_los,
01842 const Index& cloudbox_on,
01843 const ArrayOfIndex& cloudbox_limits,
01844 const Index& atmosphere_dim,
01845 const Index& stokes_dim,
01846 const Vector& scat_za_grid,
01847 const Vector& scat_aa_grid,
01848 const Vector& f_grid)
01849 {
01850 iy_interp_cloudbox_field( iy, scat_i_p, scat_i_lat, scat_i_lon,
01851 doit_i_field1D_spectrum, rte_gp_p,
01852 rte_gp_lat, rte_gp_lon, rte_los, cloudbox_on,
01853 cloudbox_limits, atmosphere_dim, stokes_dim,
01854 scat_za_grid, scat_aa_grid, f_grid, "linear" );
01855 }
01856
01857
01858
01859 void iyInterpPolyCloudboxField(
01860 Matrix& iy,
01861 const Tensor7& scat_i_p,
01862 const Tensor7& scat_i_lat,
01863 const Tensor7& scat_i_lon,
01864 const Tensor4& doit_i_field1D_spectrum,
01865 const GridPos& rte_gp_p,
01866 const GridPos& rte_gp_lat,
01867 const GridPos& rte_gp_lon,
01868 const Vector& rte_los,
01869 const Index& cloudbox_on,
01870 const ArrayOfIndex& cloudbox_limits,
01871 const Index& atmosphere_dim,
01872 const Index& stokes_dim,
01873 const Vector& scat_za_grid,
01874 const Vector& scat_aa_grid,
01875 const Vector& f_grid )
01876 {
01877 iy_interp_cloudbox_field( iy, scat_i_p, scat_i_lat, scat_i_lon,
01878 doit_i_field1D_spectrum, rte_gp_p,
01879 rte_gp_lat, rte_gp_lon, rte_los, cloudbox_on,
01880 cloudbox_limits, atmosphere_dim, stokes_dim,
01881 scat_za_grid, scat_aa_grid, f_grid, "polynomial" );
01882 }
01883