76 const Index& stokes_dim,
83 throw runtime_error(
"No need to use this method with *iy_unit* = \"1\"." );
88 os <<
"The spectrum matrix *iy* is required to have original radiance\n"
89 <<
"unit, but this seems not to be the case. This as a value above\n"
90 <<
"1e-3 is found in *iy*.";
91 throw runtime_error( os.str() );
96 for(
Index is=0; is<stokes_dim; is++ )
97 { i_pol[is] = is + 1; }
103 if( iy_aux_vars[i] ==
"iy" || iy_aux_vars[i] ==
"Error" ||
104 iy_aux_vars[i] ==
"Error (uncorrelated)" )
106 if( iy_aux[i].nrows() > 1 )
107 throw runtime_error(
"Data marked as \"iy\" or \"Error\" "
108 "have incorrect size." );
109 for(
Index j=0; j<iy_aux[i].ncols(); j++ )
126 const Index& atmfields_checked,
127 const Index& atmgeom_checked,
133 const Index& cloudbox_on,
134 const Index& cloudbox_checked,
138 const Agenda& iy_main_agenda,
143 if( atmfields_checked != 1 )
144 throw runtime_error(
"The atmospheric fields must be flagged to have "
145 "passed a consistency check (atmfields_checked=1)." );
146 if( atmgeom_checked != 1 )
147 throw runtime_error(
"The atmospheric geometry must be flagged to have "
148 "passed a consistency check (atmgeom_checked=1)." );
149 if( cloudbox_checked != 1 )
150 throw runtime_error(
"The cloudbox must be flagged to have "
151 "passed a consistency check (cloudbox_checked=1)." );
155 Tensor3 iy_transmission(0,0,0);
160 iy_aux_vars, cloudbox_on, 0, t_field,
161 z_field, vmr_field, f_grid, rte_pos, rte_los, rte_pos2,
176 const Index& stokes_dim,
178 const Index& atmosphere_dim,
190 const Index& cloudbox_on,
193 const Index& jacobian_do,
196 const Agenda& ppath_agenda,
197 const Agenda& blackbody_radiation_agenda,
198 const Agenda& propmat_clearsky_agenda,
199 const Agenda& iy_main_agenda,
200 const Agenda& iy_space_agenda,
201 const Agenda& iy_surface_agenda,
202 const Agenda& iy_cloudbox_agenda,
203 const Index& iy_agenda_call1,
204 const Tensor3& iy_transmission,
209 const Numeric& ppath_lraytrace,
215 cloudbox_on, 0, t_field, z_field, vmr_field, f_grid,
229 Index j_analytical_do = 0;
231 ArrayOfIndex jac_species_i(0), jac_is_t(0), jac_wind_i(0);
235 if( !j_analytical_do )
236 { diy_dx.resize( 0 ); }
239 diy_dpath.resize( nq );
240 jac_species_i.resize( nq );
241 jac_is_t.resize( nq );
242 jac_wind_i.resize( nq );
245 diy_dpath[iq].resize( np, nf,
ns );
249 jac_wind_i, jacobian_quantities, abs_species );
250 if( iy_agenda_call1 )
255 jacobian_indices[iq][1]-jacobian_indices[iq][0]+1, nf,
ns );
268 for(
Index i=0; i<jac_species_i.nelem(); i++ )
270 if( jac_species_i[i] >= 0 )
271 { iaps.push_back( jac_species_i[i] ); }
276 Index auxPressure = -1,
286 if( !iy_agenda_call1 )
287 { iy_aux.resize( 0 ); }
291 iy_aux.resize( naux );
293 for(
Index i=0; i<naux; i++ )
295 if( iy_aux_vars[i] ==
"Pressure" )
296 { auxPressure = i; iy_aux[i].resize( 1, 1, 1, np ); }
297 else if( iy_aux_vars[i] ==
"Temperature" )
298 { auxTemperature = i; iy_aux[i].resize( 1, 1, 1, np ); }
299 else if( iy_aux_vars[i].substr(0,13) ==
"VMR, species " )
302 istringstream is(iy_aux_vars[i].substr(13,2));
304 if( ispecies < 0 || ispecies>=abs_species.
nelem() )
307 os <<
"You have selected VMR of species with index "
308 << ispecies <<
".\nThis species does not exist!";
309 throw runtime_error( os.str() );
311 auxVmrSpecies.push_back(i);
312 auxVmrIsp.push_back(ispecies);
313 iy_aux[i].resize( 1, 1, 1, np );
315 else if( iy_aux_vars[i] ==
"Absorption, summed" )
316 { auxAbsSum = i; iy_aux[i].resize( nf,
ns,
ns, np ); }
317 else if( iy_aux_vars[i].substr(0,20) ==
"Absorption, species " )
320 istringstream is(iy_aux_vars[i].substr(20,2));
322 if( ispecies < 0 || ispecies>=abs_species.
nelem() )
325 os <<
"You have selected absorption species with index "
326 << ispecies <<
".\nThis species does not exist!";
327 throw runtime_error( os.str() );
329 auxAbsSpecies.push_back(i);
332 { auxAbsIsp.push_back( ihit ); }
335 iaps.push_back(ispecies);
336 auxAbsIsp.push_back( iaps.
nelem()-1 );
338 iy_aux[i].resize( nf,
ns,
ns, np );
340 else if( iy_aux_vars[i] ==
"Radiative background" )
341 { auxBackground = i; iy_aux[i].resize( nf, 1, 1, 1 ); }
342 else if( iy_aux_vars[i] ==
"iy" && auxIy < 0 )
343 { auxIy = i; iy_aux[i].resize( nf,
ns, 1, np ); }
344 else if( iy_aux_vars[i] ==
"Transmission" && auxTrans < 0 )
345 { auxTrans = i; iy_aux[i].resize( nf,
ns,
ns, np ); }
346 else if( iy_aux_vars[i] ==
"Optical depth" )
347 { auxOptDepth = i; iy_aux[i].resize( nf, 1, 1, 1 ); }
348 else if( iy_aux_vars[i].substr(0,14) ==
"Mass content, " )
349 { iy_aux[i].resize( 0, 0, 0, 0 ); }
350 else if( iy_aux_vars[i].substr(0,10) ==
"PND, type " )
351 { iy_aux[i].resize( 0, 0, 0, 0 ); }
355 os <<
"In *iy_aux_vars* you have included: \"" << iy_aux_vars[i]
356 <<
"\"\nThis choice is not recognised.";
357 throw runtime_error( os.str() );
368 Matrix ppath_vmr, ppath_wind, ppath_mag, ppath_f;
372 Tensor4 trans_partial, trans_cumulat;
380 ppath_wind, ppath_mag,
381 ppath, atmosphere_dim, p_grid, t_field, vmr_field,
382 wind_u_field, wind_v_field, wind_w_field,
383 mag_u_field, mag_v_field, mag_w_field );
384 get_ppath_f( ppath_f, ppath, f_grid, atmosphere_dim,
385 rte_alonglos_v, ppath_wind );
387 propmat_clearsky_agenda, ppath,
388 ppath_p, ppath_t, ppath_vmr, ppath_f,
389 ppath_mag, f_grid, stokes_dim, iaps );
391 scalar_tau, ppath, ppath_abs, f_grid, stokes_dim );
393 ppath, ppath_t, ppath_f );
400 for(
Index iv=0; iv<nf; iv++ )
408 if( iy_agenda_call1 )
417 iy_trans_new, jacobian_do, ppath, rte_pos2,
418 atmosphere_dim, t_field, z_field, vmr_field,
419 cloudbox_on, stokes_dim, f_grid, iy_main_agenda,
420 iy_space_agenda, iy_surface_agenda, iy_cloudbox_agenda,
427 if( auxBackground >= 0 )
437 {
for(
Index iv=0; iv<nf; iv++ ) {
440 { iy_aux[auxTrans] = trans_cumulat; }
442 if( auxOptDepth >= 0 )
443 { iy_aux[auxOptDepth](
joker,0,0,0) = scalar_tau; }
459 Tensor4 ppath_at2, ppath_awu, ppath_awv, ppath_aww;
462 if( j_analytical_do )
467 for(
Index iq=0; iq<jac_is_t.nelem(); iq++ )
472 Vector t2 = ppath_t; t2 += dt;
474 propmat_clearsky_agenda, ppath, ppath_p,
475 t2, ppath_vmr, ppath_f, ppath_mag, f_grid,
478 ppath, t2, ppath_f );
480 else if( jac_wind_i[iq] )
482 if( jac_wind_i[iq] == 1 )
487 rte_alonglos_v, w2 );
489 propmat_clearsky_agenda, ppath, ppath_p,
490 ppath_t, ppath_vmr, f2, ppath_mag, f_grid,
493 else if( jac_wind_i[iq] == 2 )
498 rte_alonglos_v, w2 );
500 propmat_clearsky_agenda, ppath, ppath_p,
501 ppath_t, ppath_vmr, f2, ppath_mag, f_grid,
504 else if( jac_wind_i[iq] == 3 )
509 rte_alonglos_v, w2 );
511 propmat_clearsky_agenda, ppath, ppath_p,
512 ppath_t, ppath_vmr, f2, ppath_mag, f_grid,
523 if( auxPressure >= 0 )
524 { iy_aux[auxPressure](0,0,0,np-1) = ppath_p[np-1]; }
526 if( auxTemperature >= 0 )
527 { iy_aux[auxTemperature](0,0,0,np-1) = ppath_t[np-1]; }
529 for(
Index j=0; j<auxVmrSpecies.nelem(); j++ )
530 { iy_aux[auxVmrSpecies[j]](0,0,0,np-1) = ppath_vmr(auxVmrIsp[j],np-1); }
533 {
for(
Index iv=0; iv<nf; iv++ ) {
534 for(
Index is1=0; is1<
ns; is1++ ){
535 for(
Index is2=0; is2<
ns; is2++ ){
536 iy_aux[auxAbsSum](iv,is1,is2,np-1) =
537 ppath_abs(iv,is1,is2,np-1); } } } }
538 for(
Index j=0; j<auxAbsSpecies.nelem(); j++ )
539 {
for(
Index iv=0; iv<nf; iv++ ) {
540 for(
Index is1=0; is1<
ns; is1++ ){
541 for(
Index is2=0; is2<
ns; is2++ ){
542 iy_aux[auxAbsSpecies[j]](iv,is1,is2,np-1) =
543 abs_per_species(auxAbsIsp[j],iv,is1,is2,np-1); } } } }
549 for(
Index ip=np-2; ip>=0; ip-- )
555 for(
Index iv=0; iv<nf; iv++ )
556 { bbar[iv] = 0.5 * ( ppath_blackrad(iv,ip) +
557 ppath_blackrad(iv,ip+1) ); }
560 if( j_analytical_do )
564 for(
Index iv=0; iv<nf; iv++ )
566 sibi(iv,0) = iy(iv,0) - bbar[iv];
568 { sibi(iv,is) = iy(iv,is); }
575 for(
Index iq=0; iq<nq; iq++ )
577 if( jacobian_quantities[iq].Analytical() )
580 if( jac_species_i[iq] >= 0 )
584 const Index isp = jac_species_i[iq];
589 jacobian_quantities[iq].Mode(),
590 ppath_vmr(isp,ip), ppath_p[ip],
593 jacobian_quantities[iq].Mode(),
594 ppath_vmr(isp,ip+1), ppath_p[ip+1],
597 for(
Index iv=0; iv<nf; iv++ )
600 if( extmat_case[ip][iv] == 1 )
603 trans_cumulat(iv,0,0,ip+1);
604 const Numeric y = x * sibi(iv,0);
606 diy_dpath[iq](ip ,iv,0) += y * unitscf1 *
607 abs_per_species(iiaps,iv,0,0,ip );
608 diy_dpath[iq](ip+1,iv,0) += y * unitscf2 *
609 abs_per_species(iiaps,iv,0,0,ip+1);
613 const Numeric z = x * iy(iv,is);
614 diy_dpath[iq](ip ,iv,is) += z * unitscf1*
615 abs_per_species(iiaps,iv,0,0,ip );
616 diy_dpath[iq](ip+1,iv,is) += z * unitscf2*
617 abs_per_species(iiaps,iv,0,0,ip+1);
629 for(
Index is1=0; is1<
ns; is1++ ) {
630 for(
Index is2=0; is2<
ns; is2++ ) {
631 ext_mat(is1,is2) = 0.5 * ( dd *
632 abs_per_species(iiaps,iv,is1,is2,ip ) +
633 ppath_abs(iv,is1,is2,ip) +
634 ppath_abs(iv,is1,is2,ip+1) );
637 ext_mat, ppath.
lstep[ip] );
638 for(
Index is1=0; is1<
ns; is1++ ) {
639 for(
Index is2=0; is2<
ns; is2++ ) {
640 dtdx(is1,is2) = (unitscf1/dd) *
642 trans_partial(iv,is1,is2,ip) );
648 diy_dpath[iq](ip,iv,
joker) += y;
651 for(
Index is1=0; is1<
ns; is1++ ) {
652 for(
Index is2=0; is2<
ns; is2++ ) {
653 ext_mat(is1,is2) = 0.5 * ( dd *
654 abs_per_species(iiaps,iv,is1,is2,ip+1) +
655 ppath_abs(iv,is1,is2,ip) +
656 ppath_abs(iv,is1,is2,ip+1) );
659 ext_mat, ppath.
lstep[ip] );
660 for(
Index is1=0; is1<
ns; is1++ ) {
661 for(
Index is2=0; is2<
ns; is2++ ) {
662 dtdx(is1,is2) = (unitscf2/dd) *
664 trans_partial(iv,is1,is2,ip) );
669 diy_dpath[iq](ip+1,iv,
joker) += y;
675 else if( jac_wind_i[iq] )
677 for(
Index iv=0; iv<nf; iv++ )
681 Tensor4* ppath_awx = &ppath_awv;
682 if( jac_wind_i[iq] == 1 )
683 { ppath_awx = &ppath_awu; }
684 else if( jac_wind_i[iq] == 3 )
685 { ppath_awx = &ppath_aww; }
688 if( extmat_case[ip][iv] == 1 )
690 const Numeric dkdx1 = (1/dw) * (
691 (*ppath_awx)(iv,0,0,ip ) -
692 ppath_abs(iv,0,0,ip ) );
693 const Numeric dkdx2 = (1/dw) * (
694 (*ppath_awx)(iv,0,0,ip+1) -
695 ppath_abs(iv,0,0,ip+1) );
697 trans_cumulat(iv,0,0,ip+1);
698 const Numeric y = x * sibi(iv,0);
700 diy_dpath[iq](ip ,iv,0) += y * dkdx1;
701 diy_dpath[iq](ip+1,iv,0) += y * dkdx2;
705 const Numeric z = x * iy(iv,is);
706 diy_dpath[iq](ip ,iv,is) += z * dkdx1;
707 diy_dpath[iq](ip+1,iv,is) += z * dkdx2;
717 for(
Index is1=0; is1<
ns; is1++ ) {
718 for(
Index is2=0; is2<
ns; is2++ ) {
719 ext_mat(is1,is2) = 0.5 * (
720 (*ppath_awx)(iv,is1,is2,ip ) +
721 ppath_abs(iv,is1,is2,ip+1) );
724 ext_mat, ppath.
lstep[ip] );
725 for(
Index is1=0; is1<
ns; is1++ ) {
726 for(
Index is2=0; is2<
ns; is2++ ) {
727 dtdx(is1,is2) = (1/dw) *
729 trans_partial(iv,is1,is2,ip) );
735 diy_dpath[iq](ip,iv,
joker) += y;
738 for(
Index is1=0; is1<
ns; is1++ ) {
739 for(
Index is2=0; is2<
ns; is2++ ) {
740 ext_mat(is1,is2) = 0.5 * (
741 ppath_abs(iv,is1,is2,ip ) +
742 (*ppath_awx)(iv,is1,is2,ip+1) );
745 ext_mat, ppath.
lstep[ip] );
746 for(
Index is1=0; is1<
ns; is1++ ) {
747 for(
Index is2=0; is2<
ns; is2++ ) {
748 dtdx(is1,is2) = (1/dw) *
750 trans_partial(iv,is1,is2,ip) );
755 diy_dpath[iq](ip+1,iv,
joker) += y;
761 else if( jac_is_t[iq] )
763 for(
Index iv=0; iv<nf; iv++ )
766 if( extmat_case[ip][iv] == 1 )
769 ppath_at2(iv,0,0,ip ) -
770 ppath_abs(iv,0,0,ip ) );
772 ppath_at2(iv,0,0,ip+1) -
773 ppath_abs(iv,0,0,ip+1) );
775 trans_cumulat(iv,0,0,ip+1);
776 const Numeric y = x * sibi(iv,0);
778 diy_dpath[iq](ip ,iv,0) += y * dkdt1;
779 diy_dpath[iq](ip+1,iv,0) += y * dkdt2;
783 const Numeric z = x * iy(iv,is);
784 diy_dpath[iq](ip ,iv,is) += z * dkdt1;
785 diy_dpath[iq](ip+1,iv,is) += z * dkdt2;
790 trans_cumulat(iv,0,0,ip) *
791 ( 1.0 - trans_partial(iv,0,0,ip));
792 diy_dpath[iq](ip ,iv,0) += v/dt * (
794 ppath_blackrad(iv,ip) );
795 diy_dpath[iq](ip+1,iv,0) += v/dt * (
797 ppath_blackrad(iv,ip+1) );
801 if( jacobian_quantities[iq].Subtag() ==
806 ppath_abs(iv,0,0,ip ) +
807 ppath_abs(iv,0,0,ip+1) );
808 diy_dpath[iq](ip ,iv,0) += y * kbar /
810 diy_dpath[iq](ip+1,iv,0) += y * kbar /
815 const Numeric z = x * iy(iv,is);
816 diy_dpath[iq](ip ,iv,is) +=
817 z * kbar / ppath_t[ip];
818 diy_dpath[iq](ip+1,iv,is) +=
819 z * kbar / ppath_t[ip+1];
829 for(
Index is1=0; is1<
ns; is1++ ) {
830 for(
Index is2=0; is2<
ns; is2++ ) {
831 ext_mat(is1,is2) = 0.5 * (
832 ppath_at2(iv,is1,is2,ip ) +
833 ppath_abs(iv,is1,is2,ip+1) );
836 ext_mat, ppath.
lstep[ip] );
837 for(
Index is1=0; is1<
ns; is1++ ) {
838 for(
Index is2=0; is2<
ns; is2++ ) {
839 dtdx(is1,is2) = (1/dt) *
841 trans_partial(iv,is1,is2,ip) );
847 diy_dpath[iq](ip,iv,
joker) += y;
850 for(
Index is1=0; is1<
ns; is1++ ) {
851 for(
Index is2=0; is2<
ns; is2++ ) {
852 ext_mat(is1,is2) = 0.5 * (
853 ppath_abs(iv,is1,is2,ip ) +
854 ppath_at2(iv,is1,is2,ip+1) );
857 ext_mat, ppath.
lstep[ip] );
858 for(
Index is1=0; is1<
ns; is1++ ) {
859 for(
Index is2=0; is2<
ns; is2++ ) {
860 dtdx(is1,is2) = (1/dt) *
862 trans_partial(iv,is1,is2,ip) );
867 diy_dpath[iq](ip+1,iv,
joker) += y;
871 ( 1.0 - trans_partial(iv,0,0,ip));
872 Numeric dbdt = 0.5/dt * ( ppath_bt2(iv,ip) -
873 ppath_blackrad(iv,ip) );
876 { x[is] = -trans_partial(iv,is,0,ip)*dbdt; }
879 diy_dpath[iq](ip,iv,
joker) += y;
881 dbdt = 0.5/dt * ( ppath_bt2(iv,ip+1) -
882 ppath_blackrad(iv,ip+1) );
885 { x[is] = -trans_partial(iv,is,0,ip)*dbdt; }
888 diy_dpath[iq](ip+1,iv,
joker) += y;
891 if( jacobian_quantities[iq].Subtag() ==
894 for(
Index is1=0; is1<
ns; is1++ ) {
895 for(
Index is2=0; is2<
ns; is2++ ) {
896 ext_mat(is1,is2) = 0.5 * (
897 ppath_abs(iv,is1,is2,ip ) +
898 ppath_abs(iv,is1,is2,ip+1) );
902 ppath_t[ip] + ppath_t[ip+1] );
907 for(
Index is1=0; is1<
ns; is1++ ) {
908 for(
Index is2=0; is2<
ns; is2++ ) {
909 dtdx(is1,is2) = (1/dt) *
911 trans_partial(iv,is1,is2,ip) );
921 diy_dpath[iq](ip ,iv,is) += y[is] *
922 0.5 * tbar / ppath_t[ip];
923 diy_dpath[iq](ip+1,iv,is) += y[is] *
924 0.5 * tbar / ppath_t[ip+1];
943 if( auxPressure >= 0 )
944 { iy_aux[auxPressure](0,0,0,ip) = ppath_p[ip]; }
946 if( auxTemperature >= 0 )
947 { iy_aux[auxTemperature](0,0,0,ip) = ppath_t[ip]; }
949 for(
Index j=0; j<auxVmrSpecies.nelem(); j++ )
950 { iy_aux[auxVmrSpecies[j]](0,0,0,ip) = ppath_vmr(auxVmrIsp[j],ip);}
953 {
for(
Index iv=0; iv<nf; iv++ ) {
954 for(
Index is1=0; is1<
ns; is1++ ){
955 for(
Index is2=0; is2<
ns; is2++ ){
956 iy_aux[auxAbsSum](iv,is1,is2,ip) =
957 ppath_abs(iv,is1,is2,ip); } } } }
958 for(
Index j=0; j<auxAbsSpecies.nelem(); j++ )
959 {
for(
Index iv=0; iv<nf; iv++ ) {
960 for(
Index is1=0; is1<
ns; is1++ ){
961 for(
Index is2=0; is2<
ns; is2++ ){
962 iy_aux[auxAbsSpecies[j]](iv,is1,is2,ip) =
963 abs_per_species(auxAbsIsp[j],iv,is1,is2,ip); } } } }
973 if( j_analytical_do )
976 if( !iy_agenda_call1 )
978 Matrix X, Y(
ns,diy_dpath[0].npages());
981 for(
Index iv=0; iv<nf; iv++ )
993 diy_dpath[iq], atmosphere_dim, ppath, ppath_p );
1001 if( iy_agenda_call1 )
1007 os <<
"When any unit conversion is applied, "
1008 <<
"*blackbody_radiation_agenda\nmust use "
1009 <<
"*blackbody_radiationPlanck* or a corresponding WSM.\nA test "
1010 <<
"call of the agenda indicates that this is not the case.";
1011 throw runtime_error( os.str() );
1018 { n = ppath.
nreal[np-1]; }
1022 for(
Index is=0; is<
ns; is++ )
1023 { i_pol[is] = is + 1; }
1027 if( j_analytical_do )
1030 f_grid, n, i_pol ); )
1039 if( iy_aux_vars[
q] ==
"iy")
1041 for(
Index ip=0; ip<ppath.
np; ip++ )
1043 ppath.
nreal[ip], i_pol ); }
1061 const Index& stokes_dim,
1066 const Index& cloudbox_on,
1067 const Index& iy_agenda_call1,
1068 const Tensor3& iy_transmission,
1072 const Index& jacobian_do,
1073 const Agenda& iy_sub_agenda,
1077 if( !iy_agenda_call1 )
1078 throw runtime_error(
1079 "Recursive usage not possible (iy_agenda_call1 must be 1)" );
1080 if( iy_transmission.
ncols() )
1081 throw runtime_error(
"*iy_transmission* must be empty" );
1085 for(
Index i=0; i<nf; i++ )
1093 1, iy_transmission, iy_aux_vars, cloudbox_on,
1094 jacobian_do, t_field, z_field, vmr_field,
1096 rte_pos, rte_los, rte_pos2, iy_sub_agenda );
1101 iy.
resize( nf, stokes_dim );
1103 iy_aux.resize( iy_aux1.
nelem() );
1106 if( iy_aux1[
q].ncols() > 1 )
1107 throw runtime_error(
"When using this method, *iy_aux_vars* "
1108 "is not allowed to include along-the-path variables." );
1109 iy_aux[
q].resize(nf,iy_aux1[
q].npages(),iy_aux1[
q].nrows(),1);
1112 diy_dx.resize( diy_dx1.
nelem() );
1114 { diy_dx[
q].resize( diy_dx1[
q].npages(), nf, stokes_dim ); }
1136 const Index& iy_agenda_call1,
1137 const Tensor3& iy_transmission,
1141 const Index& jacobian_do,
1142 const Index& atmosphere_dim,
1149 const Vector& refellipsoid,
1151 const Index& cloudbox_on,
1153 const Index& stokes_dim,
1156 const Agenda& iy_space_agenda,
1157 const Agenda& surface_rtprop_agenda,
1158 const Agenda& propmat_clearsky_agenda,
1159 const Agenda& ppath_step_agenda,
1160 const Numeric& ppath_lraytrace,
1164 const Index& mc_max_time,
1165 const Index& mc_max_iter,
1166 const Index& mc_min_iter,
1170 if( atmosphere_dim != 3 )
1171 throw runtime_error(
1172 "Only 3D atmospheres are allowed (atmosphere_dim must be 3)" );
1174 throw runtime_error(
1175 "The cloudbox must be activated (cloudbox_on must be 1)" );
1177 throw runtime_error(
1178 "This method does not provide any jacobians (jacobian_do must be 0)" );
1179 if( !iy_agenda_call1 )
1180 throw runtime_error(
1181 "Recursive usage not possible (iy_agenda_call1 must be 1)" );
1182 if( iy_transmission.
ncols() )
1183 throw runtime_error(
"*iy_transmission* must be empty" );
1190 iy.
resize( nf, stokes_dim );
1194 Index auxError = -1;
1197 iy_aux.resize( naux );
1199 for(
Index i=0; i<naux; i++ )
1201 if( iy_aux_vars[i] ==
"Error (uncorrelated)" )
1202 { auxError = i; iy_aux[i].resize( nf, stokes_dim, 1, 1 ); }
1206 os <<
"In *iy_aux_vars* you have included: \"" << iy_aux_vars[i]
1207 <<
"\"\nThis choice is not recognised.";
1208 throw runtime_error( os.str() );
1220 Matrix pos(1,3), los(1,2);
1222 pos(0,
joker) = rte_pos;
1223 los(0,
joker) = rte_los;
1226 Agenda l_ppath_step_agenda (ppath_step_agenda);
1227 Agenda l_iy_space_agenda (iy_space_agenda);
1228 Agenda l_propmat_clearsky_agenda (propmat_clearsky_agenda);
1229 Agenda l_surface_rtprop_agenda (surface_rtprop_agenda);
1232 bool failed =
false;
1235 #pragma omp parallel for \
1236 if (!arts_omp_in_parallel() && nf > 1) \
1237 firstprivate(l_ws, l_ppath_step_agenda, l_iy_space_agenda, \
1238 l_propmat_clearsky_agenda, l_surface_rtprop_agenda)
1239 for(
Index f_index=0; f_index<nf; f_index++ )
1241 if (failed)
continue;
1247 f_grid, f_index, verbosity );
1255 Index mc_iteration_count;
1258 MCGeneral( l_ws, y, mc_iteration_count, mc_error, mc_points, mc_antenna,
1259 f_grid, f_index, pos, los, stokes_dim, atmosphere_dim,
1260 l_ppath_step_agenda, ppath_lraytrace, l_iy_space_agenda,
1261 l_surface_rtprop_agenda, l_propmat_clearsky_agenda,
1262 p_grid, lat_grid, lon_grid, z_field,
1263 refellipsoid, z_surface, t_field, vmr_field,
1264 cloudbox_on, cloudbox_limits,
1265 pnd_field, scat_data_array_mono, 1, 1, 1,
1266 mc_seed, iy_unit, mc_std_err, mc_max_time, mc_max_iter,
1267 mc_min_iter, verbosity);
1270 assert( y.
nelem() == stokes_dim );
1272 iy(f_index,
joker) = y;
1275 { iy_aux[auxError](f_index,
joker,0,0) = mc_error; }
1276 }
catch (runtime_error e) {
1278 os <<
"Error for f_index = " << f_index <<
" (" << f_grid[f_index]
1279 <<
")" << endl << e.what();
1280 #pragma omp critical (iyMC_fail)
1281 { failed =
true; fail_msg = os.str(); }
1287 throw runtime_error(fail_msg);
1299 const Index& jacobian_do,
1304 throw runtime_error(
"*iy_aux* and *iy_aux_vars* must have the same "
1305 "number of elements." );
1308 throw runtime_error(
"This method can not provide any jacobians and "
1309 "*jacobian_do* must be 0." );
1313 for(
Index i=0; i<iy_aux.
nelem() && !ready; i++ )
1315 if( iy_aux_vars[i] == aux_var )
1317 if( iy_aux[i].nrows() > 1 || iy_aux[i].ncols() > 1 )
1319 throw runtime_error(
"If an auxiliary variable shall be inserted "
1320 "in *iy*, its row and page dimensions must have size 1." );
1322 if( iy_aux[i].nbooks() != iy.
nrows() )
1324 throw runtime_error(
"If an auxiliary variable shall be inserted "
1325 "in *iy*, its frequency dimension must match"
1326 "the length of existing *iy*." );
1333 for(
Index is=0; is<iy_aux[i].npages(); is++ )
1335 iy(iv,is) = iy_aux[i](iv,is,0,0);
1344 throw runtime_error(
"The selected auxiliary variable to insert in *iy* "
1345 "is either not defined at all or is not set." );
1356 const Index& atmfields_checked,
1357 const Index& cloudbox_checked,
1358 const Index& atmosphere_dim,
1359 const Index& cloudbox_on,
1362 const Matrix& particle_masses,
1372 if( atmfields_checked != 1 )
1373 throw runtime_error(
"The atmospheric fields must be flagged to have "
1374 "passed a consistency check (atmfields_checked=1)." );
1375 if( cloudbox_checked != 1 )
1376 throw runtime_error(
"The cloudbox must be flagged to have "
1377 "passed a consistency check (cloudbox_checked=1)." );
1379 throw runtime_error(
1380 "The cloudbox must be activated (cloudbox_on must be 1)" );
1381 if( iy_aux.
nelem() != naux )
1382 throw runtime_error(
"*iy_aux_vars* and *iy_aux* must have the same array "
1383 "length. (You can not call this WSM before the main "
1390 for(
Index i=0; i<naux; i++ )
1392 if( iy_aux_vars[i].substr(0,14) ==
"Mass content, " )
1395 istringstream is(iy_aux_vars[i].substr(14,2));
1397 if( icont < 0 || icont>=particle_masses.
ncols() )
1400 os <<
"You have selected particle mass content category with "
1401 <<
"index " << icont <<
".\nThis category is not defined!";
1402 throw runtime_error( os.str() );
1404 auxPartCont.push_back(i);
1405 auxPartContI.push_back(icont);
1406 iy_aux[i].resize( 1, 1, 1, np );
1408 else if( iy_aux_vars[i].substr(0,10) ==
"PND, type " )
1411 istringstream is(iy_aux_vars[i].substr(10,2));
1413 if( ip < 0 || ip>=pnd_field.
nbooks() )
1416 os <<
"You have selected particle number density field with "
1417 <<
"index " << ip <<
".\nThis field is not defined!";
1418 throw runtime_error( os.str() );
1420 auxPartField.push_back(i);
1421 auxPartFieldI.push_back(ip);
1422 iy_aux[i].resize( 1, 1, 1, np );
1426 if( auxPartCont.nelem() + auxPartField.nelem() > 0 )
1431 for(
Index ip=0; ip<np; ip++ )
1440 cloudbox_limits,
true, atmosphere_dim ) )
1443 gpc_p[0], gpc_lat[0], gpc_lon[0],
1444 ppath.
gp_p[ip], gp_lat, gp_lon,
1445 atmosphere_dim, cloudbox_limits );
1450 gpc_p, gpc_lat, gpc_lon, itw );
1456 for(
Index ip=0; ip<np; ip++ )
1459 for(
Index j=0; j<auxPartCont.nelem(); j++ )
1460 { iy_aux[auxPartCont[j]](0,0,0,ip) = ppath_pnd(
joker,ip) *
1461 particle_masses(
joker,auxPartContI[j]); }
1463 for(
Index j=0; j<auxPartField.nelem(); j++ )
1464 { iy_aux[auxPartField[j]](0,0,0,ip) =
1465 ppath_pnd(auxPartFieldI[j],ip); }
1482 const Index& atmosphere_dim,
1486 const Index& cloudbox_on,
1487 const Index& stokes_dim,
1489 const Matrix& sensor_pos,
1490 const Matrix& sensor_los,
1491 const Matrix& transmitter_pos,
1492 const Vector& mblock_za_grid,
1493 const Vector& mblock_aa_grid,
1494 const Index& antenna_dim,
1495 const Sparse& sensor_response,
1496 const Vector& sensor_response_f,
1498 const Vector& sensor_response_za,
1499 const Vector& sensor_response_aa,
1500 const Agenda& iy_main_agenda,
1501 const Agenda& jacobian_agenda,
1502 const Index& jacobian_do,
1507 const Index& mblock_index,
1509 const Index& j_analytical_do)
1515 Vector iyb, iyb_error, yb(n1y);
1518 iyb_calc(ws, iyb, iyb_aux_array[mblock_index], diyb_dx,
1519 mblock_index, atmosphere_dim, t_field, z_field, vmr_field,
1520 cloudbox_on, stokes_dim, f_grid, sensor_pos, sensor_los,
1521 transmitter_pos, mblock_za_grid, mblock_aa_grid, antenna_dim,
1522 iy_main_agenda, j_analytical_do, jacobian_quantities,
1523 jacobian_indices, iy_aux_vars, verbosity);
1532 mult( yb, sensor_response, iyb );
1538 for(
Index i=0; i<n1y; i++ )
1540 y_f[row0+i] = sensor_response_f[i];
1541 y_pol[row0+i] = sensor_response_pol[i];
1542 y_pos(row0+i,
joker) = sensor_pos(mblock_index,
joker);
1543 y_los(row0+i,0) = sensor_los(mblock_index,0) +
1544 sensor_response_za[i];
1545 if( sensor_response_aa.
nelem() )
1547 y_los(row0+i,1) = sensor_los(mblock_index,0) +
1548 sensor_response_aa[i];
1555 if( j_analytical_do )
1558 mult(jacobian(rowind,
1559 Range(jacobian_indices[iq][0],
1560 jacobian_indices[iq][1]-jacobian_indices[iq][0]+1)),
1561 sensor_response, diyb_dx[iq] );
1573 catch (runtime_error e)
1575 #pragma omp critical (yCalc_fail)
1576 { fail_msg = e.what(); failed =
true; }
1592 const Index& atmfields_checked,
1593 const Index& atmgeom_checked,
1594 const Index& atmosphere_dim,
1598 const Index& cloudbox_on,
1599 const Index& cloudbox_checked,
1600 const Index& sensor_checked,
1601 const Index& stokes_dim,
1603 const Matrix& sensor_pos,
1604 const Matrix& sensor_los,
1605 const Matrix& transmitter_pos,
1606 const Vector& mblock_za_grid,
1607 const Vector& mblock_aa_grid,
1608 const Index& antenna_dim,
1609 const Sparse& sensor_response,
1610 const Vector& sensor_response_f,
1612 const Vector& sensor_response_za,
1613 const Vector& sensor_response_aa,
1614 const Agenda& iy_main_agenda,
1615 const Agenda& jacobian_agenda,
1616 const Index& jacobian_do,
1628 if ( f_grid.
nelem() == 0 )
1629 {
throw runtime_error (
"The frequency grid is empty." ); }
1632 {
throw runtime_error(
"All frequencies in *f_grid* must be > 0." ); }
1634 if( atmfields_checked != 1 )
1635 throw runtime_error(
"The atmospheric fields must be flagged to have "
1636 "passed a consistency check (atmfields_checked=1)." );
1637 if( atmgeom_checked != 1 )
1638 throw runtime_error(
"The atmospheric geometry must be flagged to have "
1639 "passed a consistency check (atmgeom_checked=1)." );
1640 if( cloudbox_checked != 1 )
1641 throw runtime_error(
"The cloudbox must be flagged to have "
1642 "passed a consistency check (cloudbox_checked=1)." );
1643 if( sensor_checked != 1 )
1644 throw runtime_error(
"The sensor variables must be flagged to have "
1645 "passed a consistency check (sensor_checked=1)." );
1652 if( antenna_dim == 1 )
1656 const Index niyb = nf * nza * naa * stokes_dim;
1666 y_f.
resize( nmblock*n1y );
1667 y_pol.resize( nmblock*n1y );
1677 Index j_analytical_do = 0;
1681 jacobian.
resize( nmblock*n1y,
1682 jacobian_indices[jacobian_indices.
nelem()-1][1]+1 );
1686 j_analytical_do = 1;
1690 { jacobian.
resize( 0, 0 ); }
1698 bool failed =
false;
1701 || (nf <= nmblock && nmblock >= nza))
1703 out3 <<
" Parallelizing mblock loop (" << nmblock <<
" iterations)\n";
1708 Agenda l_jacobian_agenda (jacobian_agenda);
1709 Agenda l_iy_main_agenda (iy_main_agenda);
1711 #pragma omp parallel for \
1712 firstprivate(l_ws, l_jacobian_agenda, l_iy_main_agenda)
1713 for(
Index mblock_index=0; mblock_index<nmblock; mblock_index++ )
1716 if (failed)
continue;
1743 sensor_response_pol,
1749 jacobian_quantities,
1761 out3 <<
" Not parallelizing mblock loop (" << nmblock <<
" iterations)\n";
1763 for(
Index mblock_index=0; mblock_index<nmblock; mblock_index++ )
1766 if (failed)
continue;
1793 sensor_response_pol,
1799 jacobian_quantities,
1811 if (failed)
throw runtime_error(fail_msg);
1820 y_aux[
q].resize( nmblock*n1y );
1822 for(
Index mblock_index=0; mblock_index<nmblock; mblock_index++ )
1830 if( iy_aux_vars[
q] ==
"Error (uncorrelated)" )
1832 for(
Index i=0; i<n1y; i++ )
1834 const Index row = row0+i;
1836 for(
Index j=0; j<niyb; j++ )
1837 { y_aux[
q][row] += pow( sensor_response(i,j) *
1838 iyb_aux_array[mblock_index][
q][j], (
Numeric)2.0 ); }
1839 y_aux[
q][row] = sqrt( y_aux[
q][row] );
1843 {
mult( y_aux[
q][rowind], sensor_response,
1844 iyb_aux_array[mblock_index][
q] ); }
1863 const Index& atmfields_checked,
1864 const Index& atmgeom_checked,
1865 const Index& atmosphere_dim,
1869 const Index& cloudbox_on,
1870 const Index& cloudbox_checked,
1871 const Index& sensor_checked,
1872 const Index& stokes_dim,
1874 const Matrix& sensor_pos,
1875 const Matrix& sensor_los,
1876 const Matrix& transmitter_pos,
1877 const Vector& mblock_za_grid,
1878 const Vector& mblock_aa_grid,
1879 const Index& antenna_dim,
1880 const Sparse& sensor_response,
1881 const Vector& sensor_response_f,
1883 const Vector& sensor_response_za,
1884 const Vector& sensor_response_aa,
1885 const Agenda& iy_main_agenda,
1886 const Agenda& jacobian_agenda,
1887 const Index& jacobian_do,
1891 const Index& append_instrument_wfs,
1898 throw runtime_error(
"Input *y* is empty. Use *yCalc*" );
1899 if( y_f.
nelem() != n1 )
1900 throw runtime_error(
"Lengths of input *y* and *y_f* are inconsistent." );
1901 if( y_pol.
nelem() != n1 )
1902 throw runtime_error(
"Lengths of input *y* and *y_pol* are inconsistent." );
1903 if( y_pos.
nrows() != n1 )
1904 throw runtime_error(
"Sizes of input *y* and *y_pos* are inconsistent." );
1905 if( y_los.
nrows() != n1 )
1906 throw runtime_error(
"Sizes of input *y* and *y_los* are inconsistent." );
1909 nrq1 = jacobian_quantities1.
nelem();
1910 if( jacobian.
nrows() != n1 )
1911 throw runtime_error(
"Sizes of *y* and *jacobian* are inconsistent." );
1912 if( jacobian_indices1.
nelem() != nrq1 )
1913 throw runtime_error(
"Lengths of *jacobian_quantities_copy* and "
1914 "*jacobian_indices_copy* are inconsistent." );
1915 if( jacobian.
ncols() != jacobian_indices1[nrq1-1][1]+1 )
1916 throw runtime_error(
"Size of input *jacobian* and max value in "
1917 "*jacobian_indices_copy* are inconsistent." );
1923 Matrix y_pos2, y_los2, jacobian2;
1927 yCalc( ws, y2, y_f2, y_pol2, y_pos2, y_los2, y_aux2, jacobian2,
1928 atmfields_checked, atmgeom_checked, atmosphere_dim, t_field,
1929 z_field, vmr_field, cloudbox_on, cloudbox_checked, sensor_checked,
1930 stokes_dim, f_grid, sensor_pos, sensor_los, transmitter_pos,
1931 mblock_za_grid, mblock_aa_grid, antenna_dim, sensor_response,
1932 sensor_response_f, sensor_response_pol, sensor_response_za,
1933 sensor_response_aa, iy_main_agenda, jacobian_agenda, jacobian_do,
1934 jacobian_quantities, jacobian_indices, iy_aux_vars, verbosity );
1938 throw runtime_error(
1939 "Different number of columns in *y_pos* between the measurements." );
1941 throw runtime_error(
1942 "Different number of columns in *y_pos* between the measurements." );
1951 const Vector y1=y, y_f1=y_f;
1952 const Matrix y_pos1=y_pos, y_los1=y_los;
1960 y_f[
Range(0,n1)] = y_f1; y_f[
Range(n1,n2)] = y_f2;
1965 y_los.
resize( n1+n2, y_los1.ncols() );
1968 y_pol.resize( n1+n2 );
1969 for(
Index i=0; i<n1; i++ )
1970 { y_pol[i] = y_pol1[i]; }
1971 for(
Index i=0; i<n2; i++ )
1972 { y_pol[n1+i] = y_pol2[i]; }
1981 for(
Index a=0; a<na; a++ )
1983 y_aux[a].resize( n1+n2 );
1985 { y_aux[a][
Range(0,n1)] = y_aux1[a]; }
1987 { y_aux[a][
Range(0,n1)] = 0; }
1989 { y_aux[a][
Range(n1,n2)] = y_aux2[a]; }
1991 { y_aux[a][
Range(n1,n2)] = 0; }
2003 jacobian_quantities = jacobian_quantities1;
2004 jacobian_indices = jacobian_indices1;
2009 const Index nrq2 = jacobian_quantities2.
nelem();
2012 for(
Index q2=0; q2<nrq2; q2++ )
2022 append_instrument_wfs )
2026 if( jacobian_quantities2[q2].MainTag() ==
2027 jacobian_quantities1[
q1].MainTag() )
2030 if( jacobian_quantities2[q2].MainTag() ==
2033 if( jacobian_quantities2[q2].Subtag() ==
2034 jacobian_quantities1[
q1].Subtag() )
2036 if( jacobian_quantities2[q2].Mode() ==
2037 jacobian_quantities1[
q1].Mode() )
2042 os <<
"Jacobians for "
2043 << jacobian_quantities2[q2].MainTag()<<
"/"
2044 << jacobian_quantities2[q2].Subtag()
2045 <<
" shall be appended.\nThis requires "
2046 <<
"that the same retrieval unit is used "
2047 <<
"but it seems that this requirement is "
2049 throw runtime_error(os.str());
2054 else if( jacobian_quantities2[q2].MainTag() ==
2057 if( jacobian_quantities2[q2].Subtag() ==
2058 jacobian_quantities1[
q1].Subtag() )
2063 os <<
"Jacobians for "
2064 << jacobian_quantities2[q2].MainTag()<<
"/"
2065 << jacobian_quantities2[q2].Subtag()
2066 <<
" shall be appended.\nThis requires "
2067 <<
"that HSE is either ON or OFF for both "
2068 <<
"parts but it seems that this requirement "
2070 throw runtime_error(os.str());
2074 else if( jacobian_quantities2[q2].Subtag() ==
2075 jacobian_quantities1[
q1].Subtag() )
2085 map_table[q2] = jacobian_quantities.
nelem();
2086 jacobian_quantities.push_back( jacobian_quantities2[q2] );
2088 indices[0] = jacobian_indices[jacobian_indices.
nelem()-1][1]+1;
2089 indices[1] = indices[0] + jacobian_indices2[q2][1] -
2090 jacobian_indices2[q2][0];
2091 jacobian_indices.push_back( indices );
2096 map_table[q2] = pos;
2100 bool any_wrong =
false;
2102 { any_wrong =
true; }
2107 if( grids1[g].nelem() != grids2[g].nelem() )
2108 { any_wrong =
true; }
2113 const Numeric v1 = grids1[g][e];
2114 const Numeric v2 = grids2[g][e];
2115 if( ( v1 == 0 &&
abs(v2) > 1e-9 ) ||
2116 abs(v1-v2)/v1 > 1e-6 )
2117 { any_wrong =
true; }
2125 os <<
"Jacobians for "
2126 << jacobian_quantities2[q2].MainTag()
2127 <<
"/" << jacobian_quantities2[q2].Subtag()
2128 <<
" shall be appended.\nThis requires that the "
2129 <<
"same grids are used for both measurements,\nbut "
2130 <<
"it seems that this requirement is not met.";
2131 throw runtime_error(os.str());
2138 const Index nrq = jacobian_quantities.
nelem();
2139 const Matrix jacobian1 = jacobian;
2141 jacobian.
resize( n1+n2, jacobian_indices[nrq-1][1]+1 );
2145 jacobian(
Range(0,n1),
Range(0,jacobian_indices1[nrq1-1][1]+1)) = jacobian1;
2147 for(
Index q2=0; q2<nrq2; q2++ )
2149 jacobian(
Range(n1,n2),
Range(jacobian_indices[map_table[q2]][0],
2150 jacobian_indices[map_table[q2]][1]-
2151 jacobian_indices[map_table[q2]][0]+1) ) =
2152 jacobian2(
joker,
Range(jacobian_indices2[q2][0],
2153 jacobian_indices2[q2][1]-
2154 jacobian_indices2[q2][0]+1) );
2170 if( iy_unit ==
"1" )
2171 {
throw runtime_error(
2172 "No need to use this method with *iy_unit* = \"1\"." ); }
2177 os <<
"The spectrum vector *y* is required to have original radiance\n"
2178 <<
"unit, but this seems not to be the case. This as a value above\n"
2179 <<
"1e-3 is found in *y*.";
2180 throw runtime_error( os.str() );
2187 const bool do_j = jacobian.
nrows() == ny;
2190 if( do_j &&
max(jacobian) > 1e-3 )
2193 os <<
"The method can not be used with jacobian quantities that are not\n"
2194 <<
"obtained through radiative transfer calculations. One example on\n"
2195 <<
"quantity that can not be handled is *jacobianAddPolyfit*.\n"
2196 <<
"The maximum value of *jacobian* indicates that one or several\n"
2197 <<
"such jacobian quantities are included.";
2198 throw runtime_error( os.str() );
2203 if( iy_unit ==
"PlanckBT" )
2218 while( i0+n < ny && y_f[i0] == y_f[i0+n] )
2223 bool any_quv =
false;
2225 for(
Index i=0; i<n; i++ )
2227 const Index ix=i0+i;
2229 i_pol[i] = y_pol[ix];
2230 if( i_pol[i] > 1 && i_pol[i] < 5 )
2239 if( any_quv && i_pol[0] != 1 )
2242 os <<
"The conversion to PlanckBT, of the Jacobian and "
2243 <<
"errors for Q, U and V, requires that I (first Stokes "
2244 <<
"element) is at hand and that the data are sorted in "
2245 <<
"such way that I comes first for each frequency.";
2246 throw runtime_error( os.str() );
2261 y[ii] = yv(0,
joker);
2277 for(
Index i=0; i<ny; i++ )
2280 i_pol[0] = y_pol[i];
2285 iy_unit, y_f[i], 1, i_pol ); }