ARTS  2.3.1285(git:92a29ea9-dirty)
m_transmitter.cc
Go to the documentation of this file.
1 /* Copyright (C) 2012
2  Patrick Eriksson <Patrick.Eriksson@chalmers.se>
3  Stefan Buehler <sbuehler(at)ltu.se>
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation; either version 2, or (at your option) any
8  later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18  USA. */
19 
20 /*===========================================================================
21  === File description
22  ===========================================================================*/
23 
33 /*===========================================================================
34  === External declarations
35  ===========================================================================*/
36 
37 #include <cmath>
38 #include <stdexcept>
39 #include "arts.h"
40 #include "auto_md.h"
41 #include "complex.h"
42 #include "geodetic.h"
43 #include "jacobian.h"
44 #include "lin_alg.h"
45 #include "logic.h"
46 #include "math_funcs.h"
47 #include "messages.h"
48 #include "rte.h"
49 #include "sensor.h"
50 
51 extern const Numeric DEG2RAD;
52 extern const Numeric PI;
53 extern const Numeric RAD2DEG;
54 extern const Numeric SPEED_OF_LIGHT;
55 
56 /* Workspace method: Doxygen documentation will be auto-generated */
57 /* Has not been updated since v2.2
58 void iyRadioLink(
59  Workspace& ws,
60  Matrix& iy,
61  ArrayOfTensor4& iy_aux,
62  Ppath& ppath,
63  ArrayOfTensor3& diy_dx,
64  const Index& stokes_dim,
65  const Vector& f_grid,
66  const Index& atmosphere_dim,
67  const Vector& p_grid,
68  const Vector& lat_grid,
69  const Vector& lon_grid,
70  const Tensor3& z_field,
71  const Tensor3& t_field,
72  const Tensor4& vmr_field,
73  const ArrayOfArrayOfSpeciesTag& abs_species,
74  const Tensor3& wind_u_field,
75  const Tensor3& wind_v_field,
76  const Tensor3& wind_w_field,
77  const Tensor3& mag_u_field,
78  const Tensor3& mag_v_field,
79  const Tensor3& mag_w_field,
80  const Vector& refellipsoid,
81  const Matrix& z_surface,
82  const Index& cloudbox_on,
83  const ArrayOfIndex& cloudbox_limits,
84  const Tensor4& pnd_field,
85  const ArrayOfArrayOfSingleScatteringData& scat_data,
86  const Matrix& particle_masses,
87  const ArrayOfString& iy_aux_vars,
88  const Index& jacobian_do,
89  const Agenda& ppath_agenda,
90  const Agenda& ppath_step_agenda,
91  const Agenda& propmat_clearsky_agenda,
92  const Agenda& iy_transmitter_agenda,
93  const Index& iy_agenda_call1,
94  const Tensor3& iy_transmission,
95  const Vector& rte_pos,
96  const Vector& rte_los,
97  const Vector& rte_pos2,
98  const Numeric& rte_alonglos_v,
99  const Numeric& ppath_lmax,
100  const Numeric& ppath_lraytrace,
101  const Index& defocus_method,
102  const Numeric& defocus_shift,
103  const Verbosity& verbosity )
104 {
105  // Throw error if unsupported features are requested
106  if( !iy_agenda_call1 )
107  throw runtime_error(
108  "Recursive usage not possible (iy_agenda_call1 must be 1)" );
109  if( !iy_transmission.empty() )
110  throw runtime_error( "*iy_transmission* must be empty" );
111  if( jacobian_do )
112  throw runtime_error( "This method does not provide any jacobians and "
113  "*jacobian_do* must be 0." );
114  if( defocus_method < 1 || defocus_method > 2 )
115  throw runtime_error( "Allowed choices for *defocus_method* is 1 and 2." );
116  diy_dx.resize(0);
117 
118 
119  //- Determine propagation path
120  ppath_agendaExecute( ws, ppath, ppath_lmax, ppath_lraytrace, rte_pos, rte_los,
121  rte_pos2, cloudbox_on, 0, t_field, z_field, vmr_field,
122  f_grid, ppath_agenda );
123 
124  //- Set np to zero if ground intersection
125  const Index radback = ppath_what_background(ppath);
126  // np should already be 1 fon non-OK cases, but for extra safety ...
127  if( radback == 0 || radback == 2 )
128  { ppath.np = 1; }
129 
130  // Some basic sizes
131  //
132  const Index nf = f_grid.nelem();
133  const Index ns = stokes_dim;
134  const Index np = ppath.np;
135 
136 
137  // The below copied from iyEmission. Activate for-loop when jacobians
138  // introduced.
139 
140  // Set up variable with index of species where we want abs_per_species.
141  // This variable can below be extended in iy_aux part.
142  //
143  ArrayOfIndex iaps(0);
144  //
145  //for( Index i=0; i<jac_species_i.nelem(); i++ )
146  // {
147  // if( jac_species_i[i] >= 0 )
148  // { iaps.push_back( jac_species_i[i] ); }
149  // }
150 
151  //=== iy_aux part ===========================================================
152  Index auxPressure = -1,
153  auxTemperature = -1,
154  auxAbsSum = -1,
155  auxPartExt = -1,
156  auxImpactParam = -1,
157  auxFreeSpaceLoss = -1,
158  auxFreeSpaceAtte = -1,
159  auxAtmosphericLoss = -1,
160  auxDefocusingLoss = -1,
161  auxFarRotTotal = -1,
162  auxFarRotSpeed = -1,
163  auxExtraPathDelay = -1,
164  auxBendingAngle = -1;
165  ArrayOfIndex auxAbsSpecies(0), auxAbsIsp(0);
166  ArrayOfIndex auxVmrSpecies(0), auxVmrIsp(0);
167  ArrayOfIndex auxPartCont(0), auxPartContI(0);
168  ArrayOfIndex auxPartField(0), auxPartFieldI(0);
169  //
170  const Index naux = iy_aux_vars.nelem();
171  iy_aux.resize( naux );
172  //
173  for( Index i=0; i<naux; i++ )
174  {
175  if( iy_aux_vars[i] == "Pressure" )
176  { auxPressure = i; iy_aux[i].resize( 1, 1, 1, np ); }
177  else if( iy_aux_vars[i] == "Temperature" )
178  { auxTemperature = i; iy_aux[i].resize( 1, 1, 1, np ); }
179  else if( iy_aux_vars[i].substr(0,13) == "VMR, species " )
180  {
181  Index ispecies;
182  istringstream is(iy_aux_vars[i].substr(13,2));
183  is >> ispecies;
184  if( ispecies < 0 || ispecies>=abs_species.nelem() )
185  {
186  ostringstream os;
187  os << "You have selected VMR of species with index "
188  << ispecies << ".\nThis species does not exist!";
189  throw runtime_error( os.str() );
190  }
191  auxVmrSpecies.push_back(i);
192  auxVmrIsp.push_back(ispecies);
193  iy_aux[i].resize( 1, 1, 1, np );
194  }
195  else if( iy_aux_vars[i] == "Absorption, summed" )
196  { auxAbsSum = i; iy_aux[i].resize( nf, ns, ns, np ); }
197  else if( iy_aux_vars[i] == "Particle extinction, summed" )
198  {
199  auxPartExt = i;
200  iy_aux[i].resize( nf, ns, ns, np );
201  iy_aux[i] = 0;
202  }
203  else if( iy_aux_vars[i].substr(0,20) == "Absorption, species " )
204  {
205  Index ispecies;
206  istringstream is(iy_aux_vars[i].substr(20,2));
207  is >> ispecies;
208  if( ispecies < 0 || ispecies>=abs_species.nelem() )
209  {
210  ostringstream os;
211  os << "You have selected absorption species with index "
212  << ispecies << ".\nThis species does not exist!";
213  throw runtime_error( os.str() );
214  }
215  auxAbsSpecies.push_back(i);
216  const Index ihit = find_first( iaps, ispecies );
217  if( ihit >= 0 )
218  { auxAbsIsp.push_back( ihit ); }
219  else
220  {
221  iaps.push_back(ispecies);
222  auxAbsIsp.push_back( iaps.nelem()-1 );
223  }
224  iy_aux[i].resize( nf, ns, ns, np );
225  }
226  else if( iy_aux_vars[i].substr(0,14) == "Mass content, " )
227  {
228  Index icont;
229  istringstream is(iy_aux_vars[i].substr(14,2));
230  is >> icont;
231  if( icont < 0 || icont>=particle_masses.ncols() )
232  {
233  ostringstream os;
234  os << "You have selected particle mass content category with "
235  << "index " << icont << ".\nThis category is not defined!";
236  throw runtime_error( os.str() );
237  }
238  auxPartCont.push_back(i);
239  auxPartContI.push_back(icont);
240  iy_aux[i].resize( 1, 1, 1, np );
241  }
242  else if( iy_aux_vars[i].substr(0,10) == "PND, type " )
243  {
244  Index ip;
245  istringstream is(iy_aux_vars[i].substr(10,2));
246  is >> ip;
247  if( ip < 0 || ip>=pnd_field.nbooks() )
248  {
249  ostringstream os;
250  os << "You have selected particle number density field with "
251  << "index " << ip << ".\nThis field is not defined!";
252  throw runtime_error( os.str() );
253  }
254  auxPartField.push_back(i);
255  auxPartFieldI.push_back(ip);
256  iy_aux[i].resize( 1, 1, 1, np );
257  }
258  else if( iy_aux_vars[i] == "Impact parameter" )
259  { auxImpactParam = i; iy_aux[i].resize( 1, 1, 1, 1 ); }
260  else if( iy_aux_vars[i] == "Free space loss" )
261  { auxFreeSpaceLoss = i; iy_aux[i].resize( 1, 1, 1, 1 ); }
262  else if( iy_aux_vars[i] == "Free space attenuation" )
263  { auxFreeSpaceAtte = i; iy_aux[i].resize( 1, 1, 1, np ); }
264  else if( iy_aux_vars[i] == "Atmospheric loss" )
265  { auxAtmosphericLoss = i; iy_aux[i].resize( nf, 1, 1, 1 ); }
266  else if( iy_aux_vars[i] == "Defocusing loss" )
267  { auxDefocusingLoss = i; iy_aux[i].resize( 1, 1, 1, 1 ); }
268  else if( iy_aux_vars[i] == "Faraday rotation" )
269  { auxFarRotTotal = i; iy_aux[i].resize( nf, 1, 1, 1 ); iy_aux[i] = 0; }
270  else if( iy_aux_vars[i] == "Faraday speed" )
271  { auxFarRotSpeed = i; iy_aux[i].resize( nf, 1, 1, np ); iy_aux[i] = 0; }
272  else if( iy_aux_vars[i] == "Extra path delay" )
273  { auxExtraPathDelay = i; iy_aux[i].resize( 1, 1, 1, 1 ); }
274  else if( iy_aux_vars[i] == "Bending angle" )
275  { auxBendingAngle = i; iy_aux[i].resize( 1, 1, 1, 1 ); }
276  else
277  {
278  ostringstream os;
279  os << "In *iy_aux_vars* you have included: \"" << iy_aux_vars[i]
280  << "\"\nThis choice is not recognised.";
281  throw runtime_error( os.str() );
282  }
283  }
284 
285  // Special stuff to handle Faraday rotation
286  Index ife = -1; // When ready, ife refers abs_per_species
287  if( auxFarRotTotal>=0 || auxFarRotSpeed>=0 )
288  {
289  if( stokes_dim < 3 )
290  throw runtime_error(
291  "To include Faraday rotation, stokes_dim >= 3 is required." );
292 
293  // Determine species index of free electrons
294  for( Index sp = 0; sp < abs_species.nelem() && ife < 0; sp++ )
295  {
296  if (abs_species[sp][0].Type() == SpeciesTag::TYPE_FREE_ELECTRONS)
297  { ife = sp; }
298  }
299  // If not found, then aux values already set to zero
300  if( ife < 0 )
301  {
302  auxFarRotTotal = -1;
303  auxFarRotSpeed = -1;
304  }
305  else
306  {
307  const Index ihit = find_first( iaps, ife );
308  if( ihit >= 0 )
309  { ife = ihit; }
310  else
311  {
312  iaps.push_back(ife);
313  ife = iaps.nelem() - 1;
314  }
315  }
316  }
317  //===========================================================================
318 
319 
320  // Handle cases whn no link was establsihed
321  if( radback == 0 || radback == 2 )
322  {
323  Numeric fillvalue = 0;
324  if( radback == 0 )
325  { fillvalue = NAN; }
326  //
327  iy.resize( nf, stokes_dim );
328  iy = fillvalue;
329  //
330  for( Index i=0; i<naux; i++ )
331  { iy_aux[i] = fillvalue; }
332  //
333  return;
334  }
335 
336 
337  // Transmitted signal
338  //
339  iy_transmitter_agendaExecute( ws, iy, f_grid,
340  ppath.pos(np-1,Range(0,atmosphere_dim)),
341  ppath.los(np-1,joker), iy_transmitter_agenda );
342  if( iy.ncols() != stokes_dim || iy.nrows() != nf )
343  { throw runtime_error( "The size of *iy* returned from "
344  "*iy_transmitter_agenda* is not correct." ); }
345 
346 
347  // Get atmospheric and attenuation quantities for each ppath point/step
348  //
349  Vector ppath_p, ppath_t;
350  Matrix ppath_vmr, ppath_pnd, ppath_mag, ppath_wind, ppath_f, ppath_t_nlte;
351  ArrayOfArrayOfPropagationMatrix abs_per_species, dummy_dppath_ext_dx;
352  ArrayOfPropagationMatrix ppath_ext, pnd_ext_mat;
353  Tensor4 trans_partial, trans_cumulat;
354  ArrayOfArrayOfStokesVector dummy_dppath_nlte_dx;
355  ArrayOfStokesVector dummy_ppath_nlte_source;
356  Vector scalar_tau;
357  ArrayOfIndex clear2cloudy, dummy_lte;
358  ArrayOfMatrix dummy_ppath_dpnd_dx;
359  ArrayOfTensor4 dummy_dpnd_field_dx;
360  const Tensor4 t_nlte_field_empty(0,0,0,0);
361  //
362  if( np > 1 )
363  {
364  get_ppath_atmvars( ppath_p, ppath_t, ppath_t_nlte, ppath_vmr,
365  ppath_wind, ppath_mag,
366  ppath, atmosphere_dim, p_grid, t_field, t_nlte_field_empty,
367  vmr_field, wind_u_field, wind_v_field, wind_w_field,
368  mag_u_field, mag_v_field, mag_w_field );
369 
370  get_ppath_f( ppath_f, ppath, f_grid, atmosphere_dim,
371  rte_alonglos_v, ppath_wind );
372 
373  get_ppath_pmat( ws, ppath_ext, dummy_ppath_nlte_source, dummy_lte, abs_per_species,
374  dummy_dppath_ext_dx, dummy_dppath_nlte_dx,
375  propmat_clearsky_agenda, ArrayOfRetrievalQuantity(0), ppath,
376  ppath_p, ppath_t, ppath_t_nlte, ppath_vmr, ppath_f,
377  ppath_mag, f_grid, stokes_dim, iaps );
378 
379  if( !cloudbox_on )
380  {
381  ArrayOfArrayOfIndex extmat_case;
382  get_ppath_trans( trans_partial, extmat_case, trans_cumulat,
383  scalar_tau, ppath, ppath_ext, f_grid, stokes_dim );
384  }
385  else
386  {
387  // Extract basic scattering data
388  Array<ArrayOfArrayOfSingleScatteringData> scat_data_single;
389  ArrayOfArrayOfIndex extmat_case;
390  Tensor3 pnd_abs_vec;
391 
392  get_ppath_cloudvars( clear2cloudy, ppath_pnd, dummy_ppath_dpnd_dx,
393  ppath, atmosphere_dim, cloudbox_limits,
394  pnd_field, dummy_dpnd_field_dx );
395  get_ppath_partopt( pnd_abs_vec, pnd_ext_mat, scat_data_single,
396  clear2cloudy, ppath_pnd, ppath, ppath_t,
397  stokes_dim, ppath_f, atmosphere_dim, scat_data,
398  verbosity );
399 
400  get_ppath_trans2( trans_partial, extmat_case, trans_cumulat,
401  scalar_tau, ppath, ppath_ext, f_grid, stokes_dim,
402  clear2cloudy, pnd_ext_mat );
403  }
404  }
405 
406  // Ppath length variables
407  //
408  Numeric lbg; // Bent geometrical length of ray path
409  Numeric lba; // Bent apparent length of ray path
410  //
411  lbg = ppath.end_lstep;
412  lba = lbg;
413 
414  // Do RT calculations
415  //
416  if( np > 1 )
417  {
418  //=== iy_aux part =======================================================
419  // iy_aux for point np-1:
420  // Pressure
421  if( auxPressure >= 0 )
422  { iy_aux[auxPressure](0,0,0,np-1) = ppath_p[np-1]; }
423  // Temperature
424  if( auxTemperature >= 0 )
425  { iy_aux[auxTemperature](0,0,0,np-1) = ppath_t[np-1]; }
426  // VMR
427  for( Index j=0; j<auxVmrSpecies.nelem(); j++ )
428  { iy_aux[auxVmrSpecies[j]](0,0,0,np-1) = ppath_vmr(auxVmrIsp[j],np-1);}
429  // Absorption
430  if( auxAbsSum >= 0 )
431  { for( Index iv=0; iv<nf; iv++ ) {
432  for( Index is1=0; is1<ns; is1++ ){
433  for( Index is2=0; is2<ns; is2++ ){
434  iy_aux[auxAbsSum](iv,is1,is2,np-1) =
435  ppath_ext[np-1](iv,is1,is2); } } } }
436  for( Index j=0; j<auxAbsSpecies.nelem(); j++ )
437  { for( Index iv=0; iv<nf; iv++ ) {
438  for( Index is1=0; is1<stokes_dim; is1++ ){
439  for( Index is2=0; is2<stokes_dim; is2++ ){
440  iy_aux[auxAbsSpecies[j]](iv,is1,is2,np-1) =
441  abs_per_species[np-1][auxAbsIsp[j]](iv,is1,is2); } } } }
442  // Particle properties
443  if( cloudbox_on )
444  {
445  // Extinction
446  if( auxPartExt >= 0 && clear2cloudy[np-1] >= 0 )
447  {
448  const Index ic = clear2cloudy[np-1];
449  for( Index iv=0; iv<nf; iv++ ) {
450  for( Index is1=0; is1<ns; is1++ ){
451  for( Index is2=0; is2<ns; is2++ ){
452  iy_aux[auxPartExt](iv,is1,is2,np-1) =
453  pnd_ext_mat[ic](iv,is1,is2); } } }
454  }
455  // Particle mass content
456  for( Index j=0; j<auxPartCont.nelem(); j++ )
457  { iy_aux[auxPartCont[j]](0,0,0,np-1) = ppath_pnd(joker,np-1) *
458  particle_masses(joker,auxPartContI[j]); }
459  // Particle number density
460  for( Index j=0; j<auxPartField.nelem(); j++ )
461  { iy_aux[auxPartField[j]](0,0,0,np-1) =
462  ppath_pnd(auxPartFieldI[j],np-1); }
463  }
464  // Free space
465  if( auxFreeSpaceAtte >= 0 )
466  { iy_aux[auxFreeSpaceAtte](joker,0,0,np-1) = 2/lbg; }
467  // Faraday speed
468  if( auxFarRotSpeed >= 0 )
469  { for( Index iv=0; iv<nf; iv++ ) {
470  iy_aux[auxFarRotSpeed](iv,0,0,np-1) = 0.5 *
471  abs_per_species[np-1][ife](iv,1,2); } }
472  //=======================================================================
473 
474  // Loop ppath steps
475  for( Index ip=np-2; ip>=0; ip-- )
476  {
477  // Lengths
478  lbg += ppath.lstep[ip];
479  lba += ppath.lstep[ip] * (ppath.ngroup[ip]+ppath.ngroup[ip+1]) / 2.0;
480 
481  // Atmospheric loss of path step + Faraday rotation
482  if( stokes_dim == 1 )
483  {
484  for( Index iv=0; iv<nf; iv++ )
485  { iy(iv,0) = iy(iv,0) * trans_partial(iv,0,0,ip); }
486  }
487  else
488  {
489  for( Index iv=0; iv<nf; iv++ )
490  {
491  // Unpolarised:
492  if( is_diagonal( trans_partial(iv,joker,joker,ip) ) )
493  {
494  for( Index is=0; is<ns; is++ )
495  { iy(iv,is) = iy(iv,is) * trans_partial(iv,is,is,ip); }
496  }
497  // The general case:
498  else
499  {
500  Vector t1(ns);
501  mult( t1, trans_partial(iv,joker,joker,ip), iy(iv,joker));
502  iy(iv,joker) = t1;
503  }
504  }
505  }
506 
507  //=== iy_aux part ===================================================
508  // Pressure
509  if( auxPressure >= 0 )
510  { iy_aux[auxPressure](0,0,0,ip) = ppath_p[ip]; }
511  // Temperature
512  if( auxTemperature >= 0 )
513  { iy_aux[auxTemperature](0,0,0,ip) = ppath_t[ip]; }
514  // VMR
515  for( Index j=0; j<auxVmrSpecies.nelem(); j++ )
516  { iy_aux[auxVmrSpecies[j]](0,0,0,ip) = ppath_vmr(auxVmrIsp[j],ip);}
517  // Absorption
518  if( auxAbsSum >= 0 )
519  { for( Index iv=0; iv<nf; iv++ ) {
520  for( Index is1=0; is1<ns; is1++ ){
521  for( Index is2=0; is2<ns; is2++ ){
522  iy_aux[auxAbsSum](iv,is1,is2,ip) =
523  ppath_ext[ip](iv,is1,is2); } } } }
524  for( Index j=0; j<auxAbsSpecies.nelem(); j++ )
525  { for( Index iv=0; iv<nf; iv++ ) {
526  for( Index is1=0; is1<stokes_dim; is1++ ){
527  for( Index is2=0; is2<stokes_dim; is2++ ){
528  iy_aux[auxAbsSpecies[j]](iv,is1,is2,ip) =
529  abs_per_species[ip][auxAbsIsp[j]](iv,is1,is2); } } } }
530  // Particle properties
531  if( cloudbox_on )
532  {
533  // Extinction
534  if( auxPartExt >= 0 && clear2cloudy[ip] >= 0 )
535  {
536  const Index ic = clear2cloudy[ip];
537  for( Index iv=0; iv<nf; iv++ ) {
538  for( Index is1=0; is1<ns; is1++ ){
539  for( Index is2=0; is2<ns; is2++ ){
540  iy_aux[auxPartExt](iv,is1,is2,ip) =
541  pnd_ext_mat[ic](iv,is1,is2); } } }
542  }
543  // Particle mass content
544  for( Index j=0; j<auxPartCont.nelem(); j++ )
545  { iy_aux[auxPartCont[j]](0,0,0,ip) = ppath_pnd(joker,ip) *
546  particle_masses(joker,auxPartContI[j]); }
547  // Particle number density
548  for( Index j=0; j<auxPartField.nelem(); j++ )
549  { iy_aux[auxPartField[j]](0,0,0,ip) =
550  ppath_pnd(auxPartFieldI[j],ip); }
551  }
552  // Free space loss
553  if( auxFreeSpaceAtte >= 0 )
554  { iy_aux[auxFreeSpaceAtte](joker,0,0,ip) = 2/lbg; }
555  // Faraday rotation, total
556  if( auxFarRotTotal >= 0 )
557  { for( Index iv=0; iv<nf; iv++ ) {
558  iy_aux[auxFarRotTotal](iv,0,0,0) += RAD2DEG * ppath.lstep[ip] *
559  0.25 * ( abs_per_species[ip][ife](iv,1,2)+
560  abs_per_species[ip+1][ife](iv,1,2)); } }
561  // Faraday speed
562  if( auxFarRotSpeed >= 0 )
563  { for( Index iv=0; iv<nf; iv++ ) {
564  iy_aux[auxFarRotSpeed](iv,0,0,ip) = 0.5 *
565  abs_per_species[ip][ife](iv,1,2); } }
566  //===================================================================
567  }
568 
569 
570  //=== iy_aux part =======================================================
571  if( auxAtmosphericLoss >= 0 )
572  { iy_aux[auxAtmosphericLoss](joker,0,0,0) = iy(joker,0); }
573  if( auxImpactParam >= 0 )
574  {
575  assert( ppath.constant >= 0 );
576  iy_aux[auxImpactParam](joker,0,0,0) = ppath.constant;
577  }
578  //=======================================================================
579 
580 
581  // Remaing length of ppath
582  lbg += ppath.start_lstep;
583  lba += ppath.start_lstep;
584 
585 
586  // Determine total free space loss
587  Numeric fspl = 1 / ( 4 * PI * lbg*lbg );
588  //
589  if( auxFreeSpaceLoss >= 0 )
590  { iy_aux[auxFreeSpaceLoss] = fspl; }
591 
592 
593  // Determine defocusing loss
594  Numeric dfl = 1;
595  if( defocus_method == 1 )
596  {
597  defocusing_general( ws, dfl, ppath_step_agenda, atmosphere_dim,
598  p_grid, lat_grid, lon_grid, t_field, z_field,
599  vmr_field, f_grid, refellipsoid,
600  z_surface, ppath, ppath_lmax, ppath_lraytrace,
601  defocus_shift, verbosity );
602  }
603  else if( defocus_method == 2 )
604  { defocusing_sat2sat( ws, dfl, ppath_step_agenda, atmosphere_dim,
605  p_grid, lat_grid, lon_grid, t_field, z_field,
606  vmr_field, f_grid, refellipsoid,
607  z_surface, ppath, ppath_lmax, ppath_lraytrace,
608  defocus_shift, verbosity );
609  }
610  if( auxDefocusingLoss >= 0 )
611  { iy_aux[auxDefocusingLoss] = dfl; }
612 
613 
614 
615  // Include free space and defocusing losses
616  iy *= fspl*dfl;
617 
618 
619  // Extra path delay
620  if( auxExtraPathDelay >= 0 )
621  {
622  // Radius of rte_pos and rte_pos2
623  const Numeric r1 = ppath.end_pos[0] +
624  pos2refell_r( atmosphere_dim, refellipsoid,
625  lat_grid, lon_grid, ppath.end_pos );
626  const Numeric r2 = ppath.start_pos[0] +
627  pos2refell_r( atmosphere_dim, refellipsoid,
628  lat_grid, lon_grid, ppath.start_pos );
629 
630  // Geometrical distance between start and end point
631  Numeric lgd ;
632  if( atmosphere_dim <= 2 )
633  { distance2D( lgd, r1, ppath.end_pos[1], r2, ppath.start_pos[1] ); }
634  else
635  { distance3D( lgd, r1, ppath.end_pos[1], ppath.end_pos[2],
636  r2, ppath.start_pos[1], ppath.start_pos[2] ); }
637  //
638  iy_aux[auxExtraPathDelay] = ( lba - lgd ) / SPEED_OF_LIGHT;
639  }
640 
641 
642  // Bending angle
643  if( auxBendingAngle >= 0 )
644  {
645  Numeric ba = -999;
646  bending_angle1d( ba, ppath );
647  //
648  iy_aux[auxBendingAngle] = ba;
649  }
650  }
651 }
652 */
653 
654 /* Workspace method: Doxygen documentation will be auto-generated */
656  Matrix& iy,
657  ArrayOfMatrix& iy_aux,
658  ArrayOfTensor3& diy_dx,
659  Vector& ppvar_p,
660  Vector& ppvar_t,
661  EnergyLevelMap& ppvar_nlte,
662  Matrix& ppvar_vmr,
663  Matrix& ppvar_wind,
664  Matrix& ppvar_mag,
665  Matrix& ppvar_pnd,
666  Matrix& ppvar_f,
667  Tensor3& ppvar_iy,
668  Tensor4& ppvar_trans_cumulat,
669  const Index& stokes_dim,
670  const Vector& f_grid,
671  const Index& atmosphere_dim,
672  const Vector& p_grid,
673  const Tensor3& t_field,
674  const EnergyLevelMap& nlte_field,
675  const Tensor4& vmr_field,
676  const ArrayOfArrayOfSpeciesTag& abs_species,
677  const Tensor3& wind_u_field,
678  const Tensor3& wind_v_field,
679  const Tensor3& wind_w_field,
680  const Tensor3& mag_u_field,
681  const Tensor3& mag_v_field,
682  const Tensor3& mag_w_field,
683  const Index& cloudbox_on,
684  const ArrayOfIndex& cloudbox_limits,
685  const Tensor4& pnd_field,
686  const ArrayOfTensor4& dpnd_field_dx,
687  const ArrayOfString& scat_species,
688  const ArrayOfArrayOfSingleScatteringData& scat_data,
689  const ArrayOfString& iy_aux_vars,
690  const Index& jacobian_do,
691  const ArrayOfRetrievalQuantity& jacobian_quantities,
692  const Ppath& ppath,
693  const Agenda& propmat_clearsky_agenda,
694  const Agenda& water_p_eq_agenda,
695  const Agenda& iy_transmitter_agenda,
696  const Index& iy_agenda_call1,
697  const Tensor3& iy_transmission,
698  const Numeric& rte_alonglos_v,
699  const Verbosity&) {
700  // Some basic sizes
701  const Index nf = f_grid.nelem();
702  const Index ns = stokes_dim;
703  const Index np = ppath.np;
704 
705  // Radiative background index
706  const Index rbi = ppath_what_background(ppath);
707 
708  // Checks of input
709  // Throw error if unsupported features are requested
710  if (!iy_agenda_call1)
711  throw runtime_error(
712  "Recursive usage not possible (iy_agenda_call1 must be 1)");
713  if (!iy_transmission.empty())
714  throw runtime_error("*iy_transmission* must be empty");
715  if (rbi < 1 || rbi > 9)
716  throw runtime_error(
717  "ppath.background is invalid. Check your "
718  "calculation of *ppath*?");
719  if (jacobian_do) {
720  if (dpnd_field_dx.nelem() != jacobian_quantities.nelem())
721  throw runtime_error(
722  "*dpnd_field_dx* not properly initialized:\n"
723  "Number of elements in dpnd_field_dx must be equal number of jacobian"
724  " quantities.\n(Note: jacobians have to be defined BEFORE *pnd_field*"
725  " is calculated/set.");
726  }
727  // iy_aux_vars checked below
728 
729  // Transmitted signal
731  iy,
732  f_grid,
733  ppath.pos(np - 1, Range(0, atmosphere_dim)),
734  ppath.los(np - 1, joker),
735  iy_transmitter_agenda);
736  if (iy.ncols() != ns || iy.nrows() != nf) {
737  ostringstream os;
738  os << "The size of *iy* returned from *iy_transmitter_agenda* is\n"
739  << "not correct:\n"
740  << " expected size = [" << nf << "," << stokes_dim << "]\n"
741  << " size of iy = [" << iy.nrows() << "," << iy.ncols() << "]\n";
742  throw runtime_error(os.str());
743  }
744 
745  // Init Jacobian quantities
746  Index j_analytical_do = 0;
747  if (jacobian_do) FOR_ANALYTICAL_JACOBIANS_DO(j_analytical_do = 1;)
748  //
749  const Index nq = j_analytical_do ? jacobian_quantities.nelem() : 0;
750  ArrayOfTensor3 diy_dpath(nq);
751  ArrayOfIndex jac_species_i(nq), jac_scat_i(nq), jac_is_t(nq), jac_wind_i(nq);
752  ArrayOfIndex jac_mag_i(nq), jac_other(nq);
753 
754  if (j_analytical_do) {
755  rtmethods_jacobian_init(jac_species_i,
756  jac_scat_i,
757  jac_is_t,
758  jac_wind_i,
759  jac_mag_i,
760  jac_other,
761  diy_dx,
762  diy_dpath,
763  ns,
764  nf,
765  np,
766  nq,
767  abs_species,
768  cloudbox_on,
769  scat_species,
770  dpnd_field_dx,
771  jacobian_quantities,
772  iy_agenda_call1);
773  }
774 
775  // Init iy_aux and fill where possible
776  const Index naux = iy_aux_vars.nelem();
777  iy_aux.resize(naux);
778  //
779  Index auxOptDepth = -1;
780  //
781  for (Index i = 0; i < naux; i++) {
782  iy_aux[i].resize(nf, ns);
783  iy_aux[i] = 0;
784 
785  if (iy_aux_vars[i] == "Radiative background")
786  iy_aux[i](joker, 0) = (Numeric)min((Index)2, rbi - 1);
787  else if (iy_aux_vars[i] == "Optical depth")
788  auxOptDepth = i;
789  else {
790  ostringstream os;
791  os << "The only allowed strings in *iy_aux_vars* are:\n"
792  << " \"Radiative background\"\n"
793  << " \"Optical depth\"\n"
794  << "but you have selected: \"" << iy_aux_vars[i] << "\"";
795  throw runtime_error(os.str());
796  }
797  }
798 
799  // Get atmospheric and radiative variables along the propagation path
800  //
801  ppvar_trans_cumulat.resize(np, nf, ns, ns);
802 
803  ArrayOfRadiationVector lvl_rad(np, RadiationVector(nf, ns));
805  np, ArrayOfRadiationVector(nq, RadiationVector(nf, ns)));
806 
807  ArrayOfTransmissionMatrix lyr_tra(np, TransmissionMatrix(nf, ns));
808  ArrayOfArrayOfTransmissionMatrix dlyr_tra_above(
810  ArrayOfArrayOfTransmissionMatrix dlyr_tra_below(
812 
813  ArrayOfIndex clear2cloudy;
814  //
815  if (np == 1 && rbi == 1) { // i.e. ppath is totally outside the atmosphere:
816  ppvar_p.resize(0);
817  ppvar_t.resize(0);
818  ppvar_vmr.resize(0, 0);
819  ppvar_wind.resize(0, 0);
820  ppvar_mag.resize(0, 0);
821  ppvar_pnd.resize(0, 0);
822  ppvar_f.resize(0, 0);
823  ppvar_iy.resize(0, 0, 0);
824  } else {
825  // ppvar_iy
826  ppvar_iy.resize(nf, ns, np);
827  ppvar_iy(joker, joker, np - 1) = iy;
828 
829  // Basic atmospheric variables
830  get_ppath_atmvars(ppvar_p,
831  ppvar_t,
832  ppvar_nlte,
833  ppvar_vmr,
834  ppvar_wind,
835  ppvar_mag,
836  ppath,
837  atmosphere_dim,
838  p_grid,
839  t_field,
840  nlte_field,
841  vmr_field,
842  wind_u_field,
843  wind_v_field,
844  wind_w_field,
845  mag_u_field,
846  mag_v_field,
847  mag_w_field);
848 
849  get_ppath_f(
850  ppvar_f, ppath, f_grid, atmosphere_dim, rte_alonglos_v, ppvar_wind);
851 
852  // pnd_field
853  ArrayOfMatrix ppvar_dpnd_dx(0);
854  //
855  if (cloudbox_on)
856  get_ppath_cloudvars(clear2cloudy,
857  ppvar_pnd,
858  ppvar_dpnd_dx,
859  ppath,
860  atmosphere_dim,
861  cloudbox_limits,
862  pnd_field,
863  dpnd_field_dx);
864  else {
865  clear2cloudy.resize(np);
866  for (Index ip = 0; ip < np; ip++) clear2cloudy[ip] = -1;
867  }
868 
869  // Size radiative variables always used
870  PropagationMatrix K_this(nf, ns), K_past(nf, ns), Kp(nf, ns);
871  StokesVector a(nf, ns), S(nf, ns), Sp(nf, ns);
872  ArrayOfIndex lte(np);
873 
874  // Init variables only used if analytical jacobians done
875  Vector dB_dT(0);
876  ArrayOfPropagationMatrix dK_this_dx(nq), dK_past_dx(nq), dKp_dx(nq);
877  ArrayOfStokesVector da_dx(nq), dS_dx(nq), dSp_dx(nq);
878  //
879  Index temperature_derivative_position = -1;
880  bool do_hse = false;
881 
882  if (j_analytical_do) {
883  dB_dT.resize(nf);
884  FOR_ANALYTICAL_JACOBIANS_DO(dK_this_dx[iq] = PropagationMatrix(nf, ns);
885  dK_past_dx[iq] = PropagationMatrix(nf, ns);
886  dKp_dx[iq] = PropagationMatrix(nf, ns);
887  da_dx[iq] = StokesVector(nf, ns);
888  dS_dx[iq] = StokesVector(nf, ns);
889  dSp_dx[iq] = StokesVector(nf, ns);
890  if (jacobian_quantities[iq] == JacPropMatType::Temperature) {
891  temperature_derivative_position = iq;
892  do_hse = jacobian_quantities[iq].Subtag() ==
893  "HSE on";
894  })
895  }
896 
897  // Loop ppath points and determine radiative properties
898  for (Index ip = 0; ip < np; ip++) {
900  K_this,
901  S,
902  lte[ip],
903  dK_this_dx,
904  dS_dx,
905  propmat_clearsky_agenda,
906  jacobian_quantities,
907  ppvar_f(joker, ip),
908  ppvar_mag(joker, ip),
909  ppath.los(ip, joker),
910  ppvar_nlte[ip],
911  ppvar_vmr(joker, ip),
912  ppvar_t[ip],
913  ppvar_p[ip],
914  jac_species_i,
915  j_analytical_do);
916 
917  if (j_analytical_do) {
919  dS_dx,
920  jacobian_quantities,
921  ppvar_f(joker, ip),
922  ppath.los(ip, joker),
923  ppvar_vmr(joker, ip),
924  ppvar_t[ip],
925  ppvar_p[ip],
926  jac_species_i,
927  jac_wind_i,
928  lte[ip],
929  atmosphere_dim,
930  j_analytical_do);
931  }
932 
933  if (clear2cloudy[ip] + 1) {
935  Kp,
936  da_dx,
937  dKp_dx,
938  jacobian_quantities,
939  ppvar_pnd(joker, Range(ip, 1)),
940  ppvar_dpnd_dx,
941  ip,
942  scat_data,
943  ppath.los(ip, joker),
944  ppvar_t[Range(ip, 1)],
945  atmosphere_dim,
946  jacobian_do);
947  K_this += Kp;
948 
949  if (j_analytical_do) {
950  FOR_ANALYTICAL_JACOBIANS_DO(dK_this_dx[iq] += dKp_dx[iq];)
951  }
952  }
953 
954  // Transmission
955  if (ip not_eq 0) {
956  const Numeric dr_dT_past =
957  do_hse ? ppath.lstep[ip - 1] / (2.0 * ppvar_t[ip - 1]) : 0;
958  const Numeric dr_dT_this =
959  do_hse ? ppath.lstep[ip - 1] / (2.0 * ppvar_t[ip]) : 0;
960  stepwise_transmission(lyr_tra[ip],
961  dlyr_tra_above[ip],
962  dlyr_tra_below[ip],
963  K_past,
964  K_this,
965  dK_past_dx,
966  dK_this_dx,
967  ppath.lstep[ip - 1],
968  dr_dT_past,
969  dr_dT_this,
970  temperature_derivative_position);
971  }
972 
973  swap(K_past, K_this);
974  swap(dK_past_dx, dK_this_dx);
975  }
976  }
977 
978  const ArrayOfTransmissionMatrix tot_tra =
980 
981  // iy_aux: Optical depth
982  if (auxOptDepth >= 0) {
983  for (Index iv = 0; iv < nf; iv++)
984  iy_aux[auxOptDepth](iv, 0) = -std::log(tot_tra[np - 1](iv, 0, 0));
985  }
986 
987  lvl_rad[np - 1] = iy;
988 
989  // Radiative transfer calculations
990  for (Index ip = np - 2; ip >= 0; ip--) {
991  lvl_rad[ip] = lvl_rad[ip + 1];
992  update_radiation_vector(lvl_rad[ip],
993  dlvl_rad[ip],
994  dlvl_rad[ip + 1],
995  RadiationVector(),
996  RadiationVector(),
999  lyr_tra[ip + 1],
1000  tot_tra[ip],
1001  dlyr_tra_above[ip + 1],
1002  dlyr_tra_below[ip + 1],
1004  }
1005 
1006  // Copy back to ARTS external style
1007  iy = lvl_rad[0];
1008  for (Index ip = 0; ip < lvl_rad.nelem(); ip++) {
1009  ppvar_trans_cumulat(ip, joker, joker, joker) = tot_tra[ip];
1010  ppvar_iy(joker, joker, ip) = lvl_rad[ip];
1011  if (j_analytical_do)
1012  FOR_ANALYTICAL_JACOBIANS_DO(diy_dpath[iq](ip, joker, joker) =
1013  dlvl_rad[ip][iq];);
1014  }
1015 
1016  // Finalize analytical Jacobians
1017  if (j_analytical_do) {
1019  diy_dx,
1020  diy_dpath,
1021  ns,
1022  nf,
1023  np,
1024  atmosphere_dim,
1025  ppath,
1026  ppvar_p,
1027  ppvar_t,
1028  ppvar_vmr,
1029  iy_agenda_call1,
1030  iy_transmission,
1031  water_p_eq_agenda,
1032  jacobian_quantities,
1033  jac_species_i,
1034  jac_is_t);
1035  }
1036 }
1037 
1038 /* Workspace method: Doxygen documentation will be auto-generated */
1040  const Index& stokes_dim,
1041  const Vector& f_grid,
1042  const ArrayOfIndex& instrument_pol,
1043  const Verbosity&) {
1044  const Index nf = f_grid.nelem();
1045 
1046  if (instrument_pol.nelem() != nf)
1047  throw runtime_error(
1048  "The length of *f_grid* and the number of elements "
1049  "in *instrument_pol* must be equal.");
1050 
1051  iy.resize(nf, stokes_dim);
1052 
1053  for (Index i = 0; i < nf; i++) {
1054  stokes2pol(iy(i, joker), stokes_dim, instrument_pol[i], 1);
1055  }
1056 }
1057 
1058 /* Workspace method: Doxygen documentation will be auto-generated */
1060  const Index& stokes_dim,
1061  const Vector& f_grid,
1062  const ArrayOfIndex& instrument_pol,
1063  const Verbosity&) {
1064  const Index nf = f_grid.nelem();
1065 
1066  if (instrument_pol.nelem() != 1)
1067  throw runtime_error(
1068  "The number of elements in *instrument_pol* must be 1.");
1069 
1070  iy.resize(nf, stokes_dim);
1071 
1072  stokes2pol(iy(0, joker), stokes_dim, instrument_pol[0], 1);
1073 
1074  for (Index i = 1; i < nf; i++) {
1075  iy(i, joker) = iy(0, joker);
1076  }
1077 }
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
const Numeric RAD2DEG
Class to keep track of Transmission Matrices for Stokes Dim 1-4.
#define ns
void get_ppath_f(Matrix &ppath_f, const Ppath &ppath, ConstVectorView f_grid, const Index &atmosphere_dim, const Numeric &rte_alonglos_v, ConstMatrixView ppath_wind)
Determines the Doppler shifted frequencies along the propagation path.
Definition: rte.cc:1257
A class implementing complex numbers for ARTS.
The Agenda class.
Definition: agenda_class.h:44
void get_stepwise_clearsky_propmat(Workspace &ws, PropagationMatrix &K, StokesVector &S, Index &lte, ArrayOfPropagationMatrix &dK_dx, ArrayOfStokesVector &dS_dx, const Agenda &propmat_clearsky_agenda, const ArrayOfRetrievalQuantity &jacobian_quantities, ConstVectorView ppath_f_grid, ConstVectorView ppath_magnetic_field, ConstVectorView ppath_line_of_sight, const EnergyLevelMap &ppath_nlte, ConstVectorView ppath_vmrs, const Numeric &ppath_temperature, const Numeric &ppath_pressure, const ArrayOfIndex &jacobian_species, const bool &jacobian_do)
Gets the clearsky propgation matrix and NLTE contributions.
Definition: rte.cc:1322
Index nelem() const
Number of elements.
Definition: array.h:195
const Numeric DEG2RAD
Declarations having to do with the four output streams.
Matrix los
Line-of-sight at each ppath point.
Definition: ppath.h:66
Routines for setting up the jacobian.
The Vector class.
Definition: matpackI.h:860
void stepwise_transmission(TransmissionMatrix &T, ArrayOfTransmissionMatrix &dT1, ArrayOfTransmissionMatrix &dT2, const PropagationMatrix &K1, const PropagationMatrix &K2, const ArrayOfPropagationMatrix &dK1, const ArrayOfPropagationMatrix &dK2, const Numeric &r, const Numeric &dr_dtemp1, const Numeric &dr_dtemp2, const Index temp_deriv_pos)
Set the stepwise transmission matrix.
The Tensor4 class.
Definition: matpackIV.h:421
The range class.
Definition: matpackI.h:160
Vector lstep
The length between ppath points.
Definition: ppath.h:70
Linear algebra functions.
bool empty() const
Check if variable is empty.
Definition: matpackIII.cc:38
void get_ppath_cloudvars(ArrayOfIndex &clear2cloudy, Matrix &ppath_pnd, ArrayOfMatrix &ppath_dpnd_dx, const Ppath &ppath, const Index &atmosphere_dim, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx)
Determines the particle fields along a propagation path.
Definition: rte.cc:1153
void rtmethods_jacobian_init(ArrayOfIndex &jac_species_i, ArrayOfIndex &jac_scat_i, ArrayOfIndex &jac_is_t, ArrayOfIndex &jac_wind_i, ArrayOfIndex &jac_mag_i, ArrayOfIndex &jac_other, ArrayOfTensor3 &diy_dx, ArrayOfTensor3 &diy_dpath, const Index &ns, const Index &nf, const Index &np, const Index &nq, const ArrayOfArrayOfSpeciesTag &abs_species, const Index &cloudbox_on, const ArrayOfString &scat_species, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, const Index &iy_agenda_call1, const bool is_active)
This function fixes the initial steps around Jacobian calculations, to be done inside radiative trans...
Definition: rte.cc:2348
Matrix pos
The distance between start pos and the last position in pos.
Definition: ppath.h:64
void iyTransmissionStandard(Workspace &ws, Matrix &iy, ArrayOfMatrix &iy_aux, ArrayOfTensor3 &diy_dx, Vector &ppvar_p, Vector &ppvar_t, EnergyLevelMap &ppvar_nlte, Matrix &ppvar_vmr, Matrix &ppvar_wind, Matrix &ppvar_mag, Matrix &ppvar_pnd, Matrix &ppvar_f, Tensor3 &ppvar_iy, Tensor4 &ppvar_trans_cumulat, const Index &stokes_dim, const Vector &f_grid, const Index &atmosphere_dim, const Vector &p_grid, const Tensor3 &t_field, const EnergyLevelMap &nlte_field, const Tensor4 &vmr_field, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfTensor4 &dpnd_field_dx, const ArrayOfString &scat_species, const ArrayOfArrayOfSingleScatteringData &scat_data, const ArrayOfString &iy_aux_vars, const Index &jacobian_do, const ArrayOfRetrievalQuantity &jacobian_quantities, const Ppath &ppath, const Agenda &propmat_clearsky_agenda, const Agenda &water_p_eq_agenda, const Agenda &iy_transmitter_agenda, const Index &iy_agenda_call1, const Tensor3 &iy_transmission, const Numeric &rte_alonglos_v, const Verbosity &)
WORKSPACE METHOD: iyTransmissionStandard.
void get_ppath_atmvars(Vector &ppath_p, Vector &ppath_t, EnergyLevelMap &ppath_nlte, Matrix &ppath_vmr, Matrix &ppath_wind, Matrix &ppath_mag, const Ppath &ppath, const Index &atmosphere_dim, ConstVectorView p_grid, ConstTensor3View t_field, const EnergyLevelMap &nlte_field, ConstTensor4View vmr_field, ConstTensor3View wind_u_field, ConstTensor3View wind_v_field, ConstTensor3View wind_w_field, ConstTensor3View mag_u_field, ConstTensor3View mag_v_field, ConstTensor3View mag_w_field)
Determines pressure, temperature, VMR, winds and magnetic field for each propgataion path point...
Definition: rte.cc:1034
#define min(a, b)
Stokes vector is as Propagation matrix but only has 4 possible values.
#define FOR_ANALYTICAL_JACOBIANS_DO(what_to_do)
Definition: jacobian.h:405
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
Array< RadiationVector > ArrayOfRadiationVector
Index ppath_what_background(const Ppath &ppath)
Returns the case number for the radiative background.
Definition: ppath.cc:1494
Sensor modelling functions.
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:432
The Tensor3 class.
Definition: matpackIII.h:339
void swap(ComplexVector &v1, ComplexVector &v2)
Swaps two objects.
Definition: complex.cc:731
The global header file for ARTS.
_CS_string_type str() const
Definition: sstream.h:491
ArrayOfTransmissionMatrix cumulative_transmission(const ArrayOfTransmissionMatrix &T, const CumulativeTransmission type)
Accumulate the transmission matrix over all layers.
Array< TransmissionMatrix > ArrayOfTransmissionMatrix
void get_stepwise_scattersky_propmat(StokesVector &ap, PropagationMatrix &Kp, ArrayOfStokesVector &dap_dx, ArrayOfPropagationMatrix &dKp_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, ConstMatrixView ppath_1p_pnd, const ArrayOfMatrix &ppath_dpnd_dx, const Index ppath_1p_id, const ArrayOfArrayOfSingleScatteringData &scat_data, ConstVectorView ppath_line_of_sight, ConstVectorView ppath_temperature, const Index &atmosphere_dim, const bool &jacobian_do)
Computes the contribution by scattering at propagation path point.
Definition: rte.cc:1591
const Joker joker
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
The Matrix class.
Definition: matpackI.h:1193
Radiation Vector for Stokes dimension 1-4.
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:664
const Numeric PI
Header file for logic.cc.
This can be used to make arrays out of anything.
Definition: array.h:40
const Numeric SPEED_OF_LIGHT
void update_radiation_vector(RadiationVector &I, ArrayOfRadiationVector &dI1, ArrayOfRadiationVector &dI2, const RadiationVector &J1, const RadiationVector &J2, const ArrayOfRadiationVector &dJ1, const ArrayOfRadiationVector &dJ2, const TransmissionMatrix &T, const TransmissionMatrix &PiT, const ArrayOfTransmissionMatrix &dT1, const ArrayOfTransmissionMatrix &dT2, const RadiativeTransferSolver solver)
Update the Radiation Vector.
void iy_transmitterMultiplePol(Matrix &iy, const Index &stokes_dim, const Vector &f_grid, const ArrayOfIndex &instrument_pol, const Verbosity &)
WORKSPACE METHOD: iy_transmitterMultiplePol.
void resize(Index n)
Resize function.
Definition: matpackI.cc:404
void rtmethods_jacobian_finalisation(Workspace &ws, ArrayOfTensor3 &diy_dx, ArrayOfTensor3 &diy_dpath, const Index &ns, const Index &nf, const Index &np, const Index &atmosphere_dim, const Ppath &ppath, const Vector &ppvar_p, const Vector &ppvar_t, const Matrix &ppvar_vmr, const Index &iy_agenda_call1, const Tensor3 &iy_transmission, const Agenda &water_p_eq_agenda, const ArrayOfRetrievalQuantity &jacobian_quantities, const ArrayOfIndex jac_species_i, const ArrayOfIndex jac_is_t)
This function fixes the last steps to made on the Jacobian in some radiative transfer WSMs...
Definition: rte.cc:2416
void adapt_stepwise_partial_derivatives(ArrayOfPropagationMatrix &dK_dx, ArrayOfStokesVector &dS_dx, const ArrayOfRetrievalQuantity &jacobian_quantities, ConstVectorView ppath_f_grid, ConstVectorView ppath_line_of_sight, ConstVectorView ppath_vmrs, const Numeric &ppath_temperature, const Numeric &ppath_pressure, const ArrayOfIndex &jacobian_species, const ArrayOfIndex &jacobian_wind, const Index &lte, const Index &atmosphere_dim, const bool &jacobian_do)
Adapts clearsky partial derivatives.
Definition: rte.cc:59
Index np
Number of points describing the ppath.
Definition: ppath.h:52
Workspace class.
Definition: workspace_ng.h:40
void stokes2pol(VectorView w, const Index &stokes_dim, const Index &ipol_1based, const Numeric nv)
stokes2pol
Definition: sensor.cc:1041
void iy_transmitterSinglePol(Matrix &iy, const Index &stokes_dim, const Vector &f_grid, const ArrayOfIndex &instrument_pol, const Verbosity &)
WORKSPACE METHOD: iy_transmitterSinglePol.
The structure to describe a propagation path and releated quantities.
Definition: ppath.h:48
void iy_transmitter_agendaExecute(Workspace &ws, Matrix &iy, const Vector &f_grid, const Vector &rtp_pos, const Vector &rtp_los, const Agenda &input_agenda)
Definition: auto_md.cc:24486
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:429
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1064
Declaration of functions in rte.cc.
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1056