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
00039
00040
00041
00042
00043 #include <cmath>
00044 #include <stdexcept>
00045 #include "arts.h"
00046 #include "arts_omp.h"
00047 #include "auto_md.h"
00048 #include "check_input.h"
00049 #include "jacobian.h"
00050 #include "logic.h"
00051 #include "math_funcs.h"
00052 #include "messages.h"
00053 #include "physics_funcs.h"
00054 #include "ppath.h"
00055 #include "rte.h"
00056 #include "special_interp.h"
00057
00058 extern const String ABSSPECIES_MAINTAG;
00059 extern const String TEMPERATURE_MAINTAG;
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 void RteCalc(
00072 Workspace& ws,
00073 Vector& y,
00074 Vector& y_f,
00075 ArrayOfIndex& y_pol,
00076 Matrix& y_pos,
00077 Matrix& y_los,
00078 Matrix& jacobian,
00079 const Agenda& ppath_step_agenda,
00080 const Agenda& rte_agenda,
00081 const Agenda& iy_space_agenda,
00082 const Agenda& surface_prop_agenda,
00083 const Agenda& iy_cloudbox_agenda,
00084 const Index& atmosphere_dim,
00085 const Vector& p_grid,
00086 const Vector& lat_grid,
00087 const Vector& lon_grid,
00088 const Tensor3& z_field,
00089 const Tensor3& t_field,
00090 const Tensor4& vmr_field,
00091 const ArrayOfArrayOfSpeciesTag& abs_species,
00092 const Matrix& r_geoid,
00093 const Matrix& z_surface,
00094 const Index& cloudbox_on,
00095 const ArrayOfIndex& cloudbox_limits,
00096 const Sparse& sensor_response,
00097 const Vector& sensor_response_f,
00098 const ArrayOfIndex& sensor_response_pol,
00099 const Vector& sensor_response_za,
00100 const Vector& sensor_response_aa,
00101 const Matrix& sensor_pos,
00102 const Matrix& sensor_los,
00103 const Vector& f_grid,
00104 const Index& stokes_dim,
00105 const Index& antenna_dim,
00106 const Vector& mblock_za_grid,
00107 const Vector& mblock_aa_grid,
00108 const ArrayOfRetrievalQuantity& jacobian_quantities,
00109 const ArrayOfArrayOfIndex& jacobian_indices,
00110 const String& y_unit,
00111 const String& jacobian_unit )
00112 {
00113
00114
00115
00116 Index nf=0, nmblock=0, nza=0, naa=0, nblock=0;
00117
00118 rtecalc_check_input( nf, nmblock, nza, naa, nblock, atmosphere_dim, p_grid,
00119 lat_grid, lon_grid, z_field, t_field, r_geoid, z_surface,
00120 cloudbox_on, cloudbox_limits, sensor_response,
00121 sensor_pos, sensor_los, f_grid, stokes_dim, antenna_dim,
00122 mblock_za_grid, mblock_aa_grid, y_unit, jacobian_unit );
00123
00124 if( nblock != sensor_response_f.nelem() ||
00125 nblock != sensor_response_pol.nelem() ||
00126 nblock != sensor_response_za.nelem() )
00127 {
00128 throw runtime_error( "Sensor auxiliary variables have not correct size." );
00129 }
00130
00131
00132
00133 chk_not_empty( "ppath_step_agenda", ppath_step_agenda );
00134 chk_not_empty( "rte_agenda", rte_agenda );
00135
00136
00137
00138
00139
00140 y.resize( nmblock*nblock );
00141 y_f.resize( nmblock*nblock );
00142 y_pol.resize( nmblock*nblock );
00143 y_pos.resize( nmblock*nblock, sensor_pos.ncols() );
00144 y_los.resize( nmblock*nblock, sensor_los.ncols() );
00145
00146
00147 Vector ib( nf*nza*naa*stokes_dim );
00148
00149
00150
00151
00152 ArrayOfIndex rte_do_vmr_jacs(0);
00153 Index rte_do_t_jacs = 0;
00154
00155 ArrayOfIndex jqi_vmr(0);
00156 ArrayOfIndex ji0_vmr(0);
00157 ArrayOfIndex jin_vmr(0);
00158 Index jqi_t = 0;
00159 Index ji0_t = 0;
00160 Index jin_t = 0;
00161 ArrayOfMatrix ib_vmr_jacs(0);
00162 Matrix ib_t_jacs(0,0);
00163
00164 Index ppath_array_do = 0;
00165
00166 String j_unit = jacobian_unit;
00167 if ( jacobian_unit == "-" )
00168 { j_unit = y_unit; }
00169
00170 for( Index i=0; i<jacobian_quantities.nelem(); i++ )
00171 {
00172 if ( jacobian_quantities[i].MainTag() == ABSSPECIES_MAINTAG &&
00173 jacobian_quantities[i].Analytical() )
00174 {
00175 ppath_array_do = 1;
00176 jqi_vmr.push_back( i );
00177
00178 ArrayOfSpeciesTag tags;
00179 array_species_tag_from_string( tags,
00180 jacobian_quantities[i].Subtag() );
00181 Index si = chk_contains( "abs_species", abs_species, tags );
00182 rte_do_vmr_jacs.push_back( si );
00183
00184 ArrayOfIndex ji = jacobian_indices[i];
00185 const Index nx = ji[1]-ji[0]+1;
00186 ji0_vmr.push_back( ji[0] );
00187 jin_vmr.push_back( nx );
00188 ib_vmr_jacs.push_back( Matrix(ib.nelem(),nx,0.0) );
00189 }
00190 if ( jacobian_quantities[i].MainTag() == TEMPERATURE_MAINTAG &&
00191 jacobian_quantities[i].Analytical() )
00192 {
00193 ppath_array_do = 1;
00194 jqi_t = i;
00195 rte_do_t_jacs = 1;
00196
00197 ArrayOfIndex ji = jacobian_indices[i];
00198 const Index nx = ji[1]-ji[0]+1;
00199 ji0_t = ji[0];
00200 jin_t = nx;
00201 ib_t_jacs = Matrix(ib.nelem(),nx,0.0);
00202 }
00203 }
00204
00205
00206
00207 Workspace l_ws (ws);
00208 Agenda l_iy_space_agenda (iy_space_agenda);
00209 Agenda l_ppath_step_agenda (ppath_step_agenda);
00210 Agenda l_rte_agenda (rte_agenda);
00211 Agenda l_surface_prop_agenda (surface_prop_agenda);
00212 Agenda l_iy_cloudbox_agenda (iy_cloudbox_agenda);
00213
00214
00215
00216
00217 Index nydone = 0;
00218
00219 for( Index mblock_index=0; mblock_index<nmblock; mblock_index++ )
00220 {
00221
00222 #pragma omp parallel firstprivate(l_ws,l_iy_space_agenda,l_ppath_step_agenda,l_rte_agenda,l_surface_prop_agenda,l_iy_cloudbox_agenda)
00223 #pragma omp for
00224
00225 for( Index iza=0; iza<nza; iza++ )
00226 {
00227
00228
00229 try
00230 {
00231
00232 Matrix iy;
00233 Ppath ppath;
00234 ArrayOfPpath ppath_array;
00235 Index ppath_array_index;
00236 ArrayOfTensor4 diy_dvmr;
00237 ArrayOfTensor4 diy_dt;
00238
00239 for( Index iaa=0; iaa<naa; iaa++ )
00240 {
00241
00242 const Index nbdone = ( iza*naa + iaa ) * nf * stokes_dim;
00243
00244
00245
00246 Vector los( sensor_los.ncols() );
00247
00248 los = sensor_los( mblock_index, joker );
00249 los[0] += mblock_za_grid[iza];
00250
00251 if( antenna_dim == 2 )
00252 { los[1] += mblock_aa_grid[iaa]; }
00253
00254
00255
00256 ppath_array_index = -1;
00257 ppath_array.resize(0);
00258
00259 diy_dvmr.resize(0);
00260 diy_dt.resize(0);
00261
00262
00263 iy_calc( l_ws, iy, ppath, ppath_array_index, ppath_array,
00264 diy_dvmr, diy_dt,
00265 l_ppath_step_agenda, l_rte_agenda,
00266 l_iy_space_agenda, l_surface_prop_agenda,
00267 l_iy_cloudbox_agenda, atmosphere_dim, p_grid,
00268 lat_grid, lon_grid, z_field, t_field, vmr_field,
00269 r_geoid, z_surface, cloudbox_on, cloudbox_limits,
00270 sensor_pos(mblock_index,joker), los, f_grid,
00271 stokes_dim, ppath_array_do, rte_do_vmr_jacs,
00272 rte_do_t_jacs );
00273
00274
00275 apply_y_unit( iy, y_unit, f_grid );
00276
00277
00278 for( Index is=0; is<stokes_dim; is++ )
00279 { ib[Range(nbdone+is,nf,stokes_dim)] = iy(joker,is); }
00280
00281
00282
00283
00284
00285 for( Index ig=0; ig<rte_do_vmr_jacs.nelem(); ig++ )
00286 {
00287
00288 const String mode =
00289 jacobian_quantities[jqi_vmr[ig]].Mode();
00290 if( mode == "vmr" )
00291 {}
00292 else if( mode == "rel" )
00293 {
00294 for( Index ia=0; ia<ppath_array.nelem(); ia++ )
00295 {
00296 if( ppath_array[ia].np > 1 )
00297 {
00298 for( Index ip=0; ip<ppath_array[ia].np; ip++ )
00299 diy_dvmr[ia](ig,ip,joker,joker) *=
00300 ppath_array[ia].vmr(rte_do_vmr_jacs[ig],ip);
00301 }
00302 }
00303 }
00304 else if( mode == "nd" )
00305 {
00306 for( Index ia=0; ia<ppath_array.nelem(); ia++ )
00307 {
00308 if( ppath_array[ia].np > 1 )
00309 {
00310 for( Index ip=0; ip<ppath_array[ia].np; ip++ )
00311 diy_dvmr[ia](ig,ip,joker,joker) /=
00312 number_density( ppath_array[ia].p[ip],
00313 ppath_array[ia].t[ip] );
00314 }
00315 }
00316 }
00317 else
00318 { assert(0); }
00319
00320
00321 jacobian_from_path_to_rgrids( ib_vmr_jacs[ig], nbdone,
00322 diy_dvmr, ig, atmosphere_dim, ppath_array,
00323 jacobian_quantities[jqi_vmr[ig]] );
00324
00325
00326 apply_y_unit(
00327 ib_vmr_jacs[ig](Range(nbdone,nf*stokes_dim),joker),
00328 j_unit, f_grid );
00329 }
00330
00331
00332 if( rte_do_t_jacs )
00333 {
00334
00335 jacobian_from_path_to_rgrids( ib_t_jacs, nbdone, diy_dt,
00336 0, atmosphere_dim, ppath_array,
00337 jacobian_quantities[jqi_t] );
00338
00339
00340 apply_y_unit(ib_t_jacs(Range(nbdone,nf*stokes_dim),joker),
00341 j_unit, f_grid );
00342 }
00343
00344
00345
00346 }
00347
00348 }
00349 catch (runtime_error e)
00350 {
00351 exit_or_rethrow(e.what());
00352 }
00353 }
00354
00355
00356
00357 mult( y[Range(nydone,nblock)], sensor_response, ib );
00358
00359
00360 for( Index ii=0; ii<nblock; ii++ )
00361 {
00362 y_f[nydone+ii] = sensor_response_f[ii];
00363 y_pol[nydone+ii] = sensor_response_pol[ii];
00364 y_pos(nydone+ii,joker) = sensor_pos(mblock_index,joker);
00365 y_los(nydone+ii,0) = sensor_los(mblock_index,0) +
00366 sensor_response_za[ii];
00367 if( sensor_response_aa.nelem() )
00368 {
00369 y_los(nydone+ii,1) = sensor_los(mblock_index,0) +
00370 sensor_response_aa[ii];
00371 }
00372 }
00373
00374
00375 for( Index ig=0; ig<rte_do_vmr_jacs.nelem(); ig++ )
00376 {
00377 mult( jacobian(Range(nydone,nblock),Range(ji0_vmr[ig],jin_vmr[ig])),
00378 sensor_response, ib_vmr_jacs[ig] );
00379 }
00380 if( rte_do_t_jacs )
00381 {
00382 mult( jacobian(Range(nydone,nblock),Range(ji0_t,jin_t)),
00383 sensor_response, ib_t_jacs );
00384 }
00385
00386
00387
00388 nydone += nblock;
00389 }
00390 }
00391
00392
00393
00394
00395
00396 void RteCalcNoJacobian(
00397 Workspace& ws,
00398 Vector& y,
00399 Vector& y_f,
00400 ArrayOfIndex& y_pol,
00401 Matrix& y_pos,
00402 Matrix& y_los,
00403 const Agenda& ppath_step_agenda,
00404 const Agenda& rte_agenda,
00405 const Agenda& iy_space_agenda,
00406 const Agenda& surface_prop_agenda,
00407 const Agenda& iy_cloudbox_agenda,
00408 const Index& atmosphere_dim,
00409 const Vector& p_grid,
00410 const Vector& lat_grid,
00411 const Vector& lon_grid,
00412 const Tensor3& z_field,
00413 const Tensor3& t_field,
00414 const Tensor4& vmr_field,
00415 const Matrix& r_geoid,
00416 const Matrix& z_surface,
00417 const Index& cloudbox_on,
00418 const ArrayOfIndex& cloudbox_limits,
00419 const Sparse& sensor_response,
00420 const Vector& sensor_response_f,
00421 const ArrayOfIndex& sensor_response_pol,
00422 const Vector& sensor_response_za,
00423 const Vector& sensor_response_aa,
00424 const Matrix& sensor_pos,
00425 const Matrix& sensor_los,
00426 const Vector& f_grid,
00427 const Index& stokes_dim,
00428 const Index& antenna_dim,
00429 const Vector& mblock_za_grid,
00430 const Vector& mblock_aa_grid,
00431 const String& y_unit )
00432 {
00433 Matrix jacobian;
00434 ArrayOfRetrievalQuantity jacobian_quantities;
00435 ArrayOfArrayOfIndex jacobian_indices;
00436 String jacobian_unit;
00437 ArrayOfArrayOfSpeciesTag abs_species(0);
00438
00439
00440 jacobianOff( jacobian, jacobian_quantities, jacobian_indices, jacobian_unit );
00441
00442 RteCalc( ws, y, y_f, y_pol, y_pos, y_los, jacobian,
00443 ppath_step_agenda, rte_agenda, iy_space_agenda, surface_prop_agenda,
00444 iy_cloudbox_agenda, atmosphere_dim, p_grid, lat_grid, lon_grid,
00445 z_field, t_field, vmr_field, abs_species, r_geoid, z_surface,
00446 cloudbox_on, cloudbox_limits, sensor_response, sensor_response_f,
00447 sensor_response_pol, sensor_response_za, sensor_response_aa,
00448 sensor_pos, sensor_los, f_grid, stokes_dim, antenna_dim,
00449 mblock_za_grid, mblock_aa_grid,
00450 jacobian_quantities, jacobian_indices,
00451 y_unit, jacobian_unit );
00452 }
00453
00454
00455
00456 void RteCalcMC(
00457 Workspace& ws,
00458 Vector& y,
00459 Vector& y_f,
00460 ArrayOfIndex& y_pol,
00461 Matrix& y_pos,
00462 Matrix& y_los,
00463 Vector& mc_error,
00464 const Agenda& iy_space_agenda,
00465 const Agenda& surface_prop_agenda,
00466 const Agenda& opt_prop_gas_agenda,
00467 const Agenda& abs_scalar_gas_agenda,
00468 const Index& atmosphere_dim,
00469 const Vector& p_grid,
00470 const Vector& lat_grid,
00471 const Vector& lon_grid,
00472 const Tensor3& z_field,
00473 const Tensor3& t_field,
00474 const Tensor4& vmr_field,
00475 const Matrix& r_geoid,
00476 const Matrix& z_surface,
00477 const Index& cloudbox_on,
00478 const ArrayOfIndex& cloudbox_limits,
00479 const Tensor4& pnd_field,
00480 const ArrayOfSingleScatteringData& scat_data_raw,
00481 const Sparse& sensor_response,
00482 const Vector& sensor_response_f,
00483 const ArrayOfIndex& sensor_response_pol,
00484 const Vector& sensor_response_za,
00485 const Vector& sensor_response_aa,
00486 const Matrix& sensor_pos,
00487 const Matrix& sensor_los,
00488 const Vector& f_grid,
00489 const Index& stokes_dim,
00490 const Index& antenna_dim,
00491 const Vector& mblock_za_grid,
00492 const Vector& mblock_aa_grid,
00493 const String& y_unit,
00494 const Numeric& mc_std_err,
00495 const Index& mc_max_time,
00496 const Index& mc_max_iter,
00497 const Index& mc_z_field_is_1D )
00498 {
00499
00500
00501
00502 Index nf=0, nmblock=0, nza=0, naa=0, nblock=0;
00503
00504 if( atmosphere_dim != 3 )
00505 throw runtime_error(
00506 "Monte Carlos calculations require that *atmosphere_dim* is 3." );
00507
00508 rtecalc_check_input( nf, nmblock, nza, naa, nblock, atmosphere_dim, p_grid,
00509 lat_grid, lon_grid, z_field, t_field, r_geoid, z_surface,
00510 cloudbox_on, cloudbox_limits, sensor_response,
00511 sensor_pos, sensor_los, f_grid, stokes_dim, antenna_dim,
00512 mblock_za_grid, mblock_aa_grid, y_unit, "-" );
00513
00514 if( nblock != sensor_response_f.nelem() ||
00515 nblock != sensor_response_pol.nelem() ||
00516 nblock != sensor_response_za.nelem() )
00517 {
00518 throw runtime_error( "Sensor auxiliary variables have not correct size." );
00519
00520 }
00521
00522
00523 Tensor3 mc_points;
00524
00525 MCAntenna mc_antenna;
00526 mc_antenna.set_pencil_beam();
00527
00528
00529
00530
00531
00532 y.resize( nmblock*nblock );
00533 y_f.resize( nmblock*nblock );
00534 y_pol.resize( nmblock*nblock );
00535 y_pos.resize( nmblock*nblock, sensor_pos.ncols() );
00536 y_los.resize( nmblock*nblock, sensor_los.ncols() );
00537 mc_error.resize( nmblock*nblock );
00538 mc_error = 0.0;
00539
00540
00541 Vector ib( nf*nza*naa*stokes_dim );
00542 Vector ib_error( nf*nza*naa*stokes_dim );
00543
00544
00545
00546
00547 Index nydone = 0;
00548
00549
00550
00551
00552 Workspace l_ws (ws);
00553 Agenda l_iy_space_agenda (iy_space_agenda);
00554 Agenda l_surface_prop_agenda (surface_prop_agenda);
00555 Agenda l_opt_prop_gas_agenda (opt_prop_gas_agenda);
00556 Agenda l_abs_scalar_gas_agenda (abs_scalar_gas_agenda);
00557
00558 for( Index mblock_index=0; mblock_index<nmblock; mblock_index++ )
00559 {
00560 #pragma omp parallel firstprivate(l_ws,l_iy_space_agenda,l_surface_prop_agenda,l_opt_prop_gas_agenda,l_abs_scalar_gas_agenda)
00561 #pragma omp for
00562 for( Index iza=0; iza<nza; iza++ )
00563 {
00564
00565
00566 try
00567 {
00568 Matrix los(1,sensor_los.ncols());
00569 Matrix pos(1,sensor_pos.ncols());
00570
00571
00572 Vector iyf;
00573 Vector iyf_error;
00574
00575
00576 Index mc_iteration_count;
00577 Index mc_seed;
00578
00579
00580 for( Index iaa=0; iaa<naa; iaa++ )
00581 {
00582
00583 pos(0,joker) = sensor_pos( mblock_index, joker );
00584
00585
00586 los(0,joker) = sensor_los( mblock_index, joker );
00587 los(0,0) += mblock_za_grid[iza];
00588 if( antenna_dim == 2 )
00589 { los(0,1) += mblock_aa_grid[iaa]; }
00590
00591 for( Index f_index=0; f_index<nf; f_index++ )
00592 {
00593 ArrayOfSingleScatteringData scat_data_mono;
00594
00595 scat_data_monoCalc( scat_data_mono, scat_data_raw,
00596 f_grid, f_index );
00597
00598
00599
00600 MCSetSeedFromTime( mc_seed );
00601
00602 MCGeneral( l_ws,
00603 iyf, mc_iteration_count, iyf_error, mc_points,
00604 mc_antenna, f_grid, f_index, pos, los,
00605 stokes_dim, l_iy_space_agenda,
00606 l_surface_prop_agenda, l_opt_prop_gas_agenda,
00607 l_abs_scalar_gas_agenda,
00608 p_grid, lat_grid, lon_grid,
00609 z_field, r_geoid, z_surface,
00610 t_field, vmr_field,
00611 cloudbox_limits, pnd_field,
00612 scat_data_mono, mc_seed,
00613 y_unit, mc_std_err, mc_max_time, mc_max_iter,
00614 mc_z_field_is_1D );
00615
00616
00617 const Index nbdone = ( ( iza*naa + iaa ) * nf +
00618 f_index ) * stokes_dim;
00619
00620
00621 for( Index is=0; is<stokes_dim; is++ )
00622 {
00623 ib[nbdone+is] = iyf[is];
00624 ib_error[nbdone+is] = iyf_error[is];
00625 }
00626
00627 }
00628 }
00629
00630 }
00631 catch (runtime_error e)
00632 {
00633 exit_or_rethrow(e.what());
00634 }
00635 }
00636
00637
00638
00639
00640 mult( y[Range(nydone,nblock)], sensor_response, ib );
00641
00642 for( Index irow=0; irow<nblock; irow++ )
00643 {
00644 for( Index icol=0; icol<sensor_response.ncols(); icol++ )
00645 { mc_error[nydone+irow] +=
00646 pow( sensor_response(irow,icol)*ib_error[icol], (Numeric)2.0 );
00647 }
00648 }
00649
00650
00651 for( Index ii=0; ii<nblock; ii++ )
00652 {
00653 y_f[nydone+ii] = sensor_response_f[ii];
00654 y_pol[nydone+ii] = sensor_response_pol[ii];
00655 y_pos(nydone+ii,joker) = sensor_pos(mblock_index,joker);
00656 y_los(nydone+ii,0) = sensor_los(mblock_index,0) +
00657 sensor_response_za[ii];
00658 if( sensor_response_aa.nelem() )
00659 {
00660 y_los(nydone+ii,1) = sensor_los(mblock_index,0) +
00661 sensor_response_aa[ii];
00662 }
00663 }
00664
00665
00666 nydone += nblock;
00667 }
00668
00669
00670 transform( mc_error, sqrt, mc_error );
00671 }
00672
00673
00674
00675
00676 void RteStd( Workspace& ws,
00677
00678 Matrix& iy,
00679 ArrayOfTensor4& diy_dvmr,
00680 ArrayOfTensor4& diy_dt,
00681
00682 const Ppath& ppath,
00683 const ArrayOfPpath& ppath_array,
00684 const Index& ppath_array_index,
00685 const Vector& f_grid,
00686 const Index& stokes_dim,
00687 const Agenda& emission_agenda,
00688 const Agenda& abs_scalar_gas_agenda,
00689 const ArrayOfIndex& rte_do_gas_jacs,
00690 const Index& rte_do_t_jacs )
00691 {
00692 Tensor4 dummy(0,0,0,0);
00693
00694 rte_std( ws, iy, dummy, diy_dvmr, diy_dt,
00695 ppath, ppath_array, ppath_array_index, f_grid, stokes_dim,
00696 emission_agenda, abs_scalar_gas_agenda,
00697 rte_do_gas_jacs, rte_do_t_jacs, false );
00698 }
00699
00700
00701
00702 void RteStdWithTransmissions(
00703 Workspace& ws,
00704
00705 Matrix& iy,
00706 Tensor4& ppath_transmissions,
00707 ArrayOfTensor4& diy_dvmr,
00708 ArrayOfTensor4& diy_dt,
00709
00710 const Ppath& ppath,
00711 const ArrayOfPpath& ppath_array,
00712 const Index& ppath_array_index,
00713 const Vector& f_grid,
00714 const Index& stokes_dim,
00715 const Agenda& emission_agenda,
00716 const Agenda& abs_scalar_gas_agenda,
00717 const ArrayOfIndex& rte_do_gas_jacs,
00718 const Index& rte_do_t_jacs )
00719 {
00720 rte_std( ws, iy, ppath_transmissions, diy_dvmr, diy_dt,
00721 ppath, ppath_array, ppath_array_index, f_grid, stokes_dim,
00722 emission_agenda, abs_scalar_gas_agenda,
00723 rte_do_gas_jacs, rte_do_t_jacs, true );
00724 }
00725
00726
00727
00728
00729
00730 void yUnit(
00731 Vector& y,
00732 const String& y_unit,
00733 const Vector& y_f )
00734 {
00735 const Index n = y.nelem();
00736
00737 if( y_f.nelem() != n )
00738 {
00739 ostringstream os;
00740 os << "The length of *y* and *y_f* must be the same";
00741 throw runtime_error( os.str() );
00742 }
00743
00744 if( y_unit == "1" )
00745 {}
00746
00747 else if( y_unit == "RJBT" )
00748 {
00749 for( Index i=0; i<n; i++ )
00750 {
00751 y[i] = invrayjean( y[i], y_f[i] );
00752 }
00753 }
00754
00755 else if( y_unit == "PlanckBT" )
00756 {
00757 for( Index i=0; i<n; i++ )
00758 {
00759 y[i] = invplanck( y[i], y_f[i] );
00760 }
00761 }
00762 else
00763 {
00764 ostringstream os;
00765 os << "Unknown option: y_unit = \"" << y_unit << "\"\n"
00766 << "Recognised choices are: \"1\", \"RJBT\" and \"PlanckBT\"";
00767 throw runtime_error( os.str() );
00768 }
00769 }