ARTS  2.0.49
doit.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2008 Claudia Emde <claudia.emde@dlr.de>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA.
17 */
18 
31 /*===========================================================================
32  === External declarations
33  ===========================================================================*/
34 
35 #include <stdexcept>
36 #include <iostream>
37 #include <cstdlib>
38 #include <cmath>
39 #include "array.h"
40 #include "auto_md.h"
41 #include "matpackVII.h"
42 #include "ppath.h"
43 #include "agenda_class.h"
44 #include "physics_funcs.h"
45 #include "lin_alg.h"
46 #include "math_funcs.h"
47 #include "messages.h"
48 #include "xml_io.h"
49 #include "rte.h"
50 #include "special_interp.h"
51 #include "doit.h"
52 #include "logic.h"
53 #include "check_input.h"
54 #include "sorting.h"
55 #include "cloudbox.h"
56 
57 extern const Numeric PI;
58 extern const Numeric RAD2DEG;
59 
61 
87  // Output and Input:
88  Tensor5View ext_mat_field,
89  Tensor4View abs_vec_field,
90  // Input:
91  const Agenda& spt_calc_agenda,
92  const Agenda& opt_prop_part_agenda,
93  const Index& scat_za_index,
94  const Index& scat_aa_index,
95  const ArrayOfIndex& cloudbox_limits,
96  ConstTensor3View t_field,
97  ConstTensor4View pnd_field,
98  const Verbosity& verbosity)
99 {
101 
102  // Input variables are checked in the WSMs i_fieldUpdateSeqXXX, from
103  // where this function is called.
104 
105  out3 << "Calculate scattering properties in cloudbox \n";
106 
107  const Index atmosphere_dim = cloudbox_limits.nelem()/2;
108  const Index N_pt = pnd_field.nbooks();
109  const Index stokes_dim = ext_mat_field.ncols();
110 
111  assert( atmosphere_dim == 1 || atmosphere_dim ==3 );
112  assert( ext_mat_field.ncols() == ext_mat_field.nrows() &&
113  ext_mat_field.ncols() == abs_vec_field.ncols());
114 
115  const Index Np_cloud = cloudbox_limits[1]-cloudbox_limits[0]+1;
116 
117  // If atmosohere_dim == 1
118  Index Nlat_cloud = 1;
119  Index Nlon_cloud = 1;
120 
121  if (atmosphere_dim == 3)
122  {
123  Nlat_cloud = cloudbox_limits[3]-cloudbox_limits[2]+1;
124  Nlon_cloud = cloudbox_limits[5]-cloudbox_limits[4]+1;
125  }
126 
127  // Initialize ext_mat(_spt), abs_vec(_spt)
128  // Resize and initialize variables for storing optical properties
129  // of cloud particles
130  Matrix abs_vec_spt_local(N_pt, stokes_dim, 0.);
131  Tensor3 ext_mat_spt_local(N_pt, stokes_dim, stokes_dim, 0.);
132  Matrix abs_vec_local;
133  Tensor3 ext_mat_local;
134  Numeric rte_temperature_local;
135 
136  // Calculate ext_mat, abs_vec for all points inside the cloudbox.
137  // sca_vec can be obtained from the workspace variable doit_scat_field.
138  // As we need the average for each layer, it makes sense to calculte
139  // the coefficients once and store them in an array instead of
140  // calculating at each point the coefficient of the point above and
141  // the point below.
142  // To use special interpolation functions for atmospheric fields we
143  // use ext_mat_field and abs_vec_field:
144 
145  // Loop over all positions inside the cloudbox defined by the
146  // cloudbox_limits.
147  for(Index scat_p_index_local = 0; scat_p_index_local < Np_cloud;
148  scat_p_index_local ++)
149  {
150  for(Index scat_lat_index_local = 0; scat_lat_index_local < Nlat_cloud;
151  scat_lat_index_local ++)
152  {
153  for(Index scat_lon_index_local = 0;
154  scat_lon_index_local < Nlon_cloud;
155  scat_lon_index_local ++)
156  {
157  if (atmosphere_dim == 1)
158  rte_temperature_local =
159  t_field(scat_p_index_local + cloudbox_limits[0], 0, 0);
160  else
161  rte_temperature_local =
162  t_field(scat_p_index_local + cloudbox_limits[0],
163  scat_lat_index_local + cloudbox_limits[2],
164  scat_lon_index_local + cloudbox_limits[4]);
165 
166  //Calculate optical properties for single particle types:
167  //( Execute agendas silently. )
168  spt_calc_agendaExecute(ws, ext_mat_spt_local,
169  abs_vec_spt_local,
170  scat_p_index_local,
171  scat_lat_index_local,
172  scat_lon_index_local,
173  rte_temperature_local,
174  scat_za_index,
175  scat_aa_index,
176  spt_calc_agenda);
177 
178  opt_prop_part_agendaExecute(ws, ext_mat_local, abs_vec_local,
179  ext_mat_spt_local,
180  abs_vec_spt_local,
181  scat_p_index_local,
182  scat_lat_index_local,
183  scat_lon_index_local,
184  opt_prop_part_agenda);
185 
186  // Store coefficients in arrays for the whole cloudbox.
187  abs_vec_field(scat_p_index_local, scat_lat_index_local,
188  scat_lon_index_local,
189  joker) = abs_vec_local(0, joker);
190 
191  ext_mat_field(scat_p_index_local, scat_lat_index_local,
192  scat_lon_index_local,
193  joker, joker) = ext_mat_local(0, joker, joker);
194  }
195  }
196  }
197 }
198 
199 
200 
201 
202 
204 
248  // Input and output
249  Tensor6View doit_i_field,
250  // ppath_step_agenda:
251  const Index& p_index,
252  const Index& scat_za_index,
253  ConstVectorView scat_za_grid,
254  const ArrayOfIndex& cloudbox_limits,
255  ConstTensor6View doit_scat_field,
256  // Calculate scalar gas absorption:
257  const Agenda& abs_scalar_gas_agenda,
258  ConstTensor4View vmr_field,
259  // Gas absorption:
260  const Agenda& opt_prop_gas_agenda,
261  // Propagation path calculation:
262  const Agenda& ppath_step_agenda,
263  ConstVectorView p_grid,
264  ConstTensor3View z_field,
265  ConstMatrixView r_geoid,
266  ConstMatrixView z_surface,
267  // Calculate thermal emission:
268  ConstTensor3View t_field,
269  ConstVectorView f_grid,
270  const Index& f_index,
271  //particle optical properties
272  ConstTensor5View ext_mat_field,
273  ConstTensor4View abs_vec_field,
274  const Agenda& surface_prop_agenda,
275  //const Agenda& surface_prop_agenda,
276  const Index& scat_za_interp,
277  const Verbosity& verbosity)
278 {
279  Matrix iy;
280  Matrix surface_emission;
281  Matrix surface_los;
282  Tensor4 surface_rmatrix;
283  Ppath ppath_step;
284  // Input variables are checked in the WSMs i_fieldUpdateSeqXXX, from
285  // where this function is called.
286 
287  //Initialize ppath for 1D.
288  ppath_init_structure(ppath_step, 1, 1);
289  // See documentation of ppath_init_structure for understanding
290  // the parameters.
291 
292  // Assign value to ppath.pos:
293  ppath_step.z[0] = z_field(p_index,0,0);
294  ppath_step.pos(0,0) = r_geoid(0,0) + ppath_step.z[0];
295 
296  // Define the direction:
297  ppath_step.los(0,0) = scat_za_grid[scat_za_index];
298 
299 
300  // Define the grid positions:
301  ppath_step.gp_p[0].idx = p_index;
302  ppath_step.gp_p[0].fd[0] = 0;
303  ppath_step.gp_p[0].fd[1] = 1;
304 
305  // Call ppath_step_agenda:
306  Vector unused_lat_grid(0);
307  Vector unused_lon_grid(0);
308  ppath_step_agendaExecute(ws, ppath_step, 1, p_grid,
309  unused_lat_grid, unused_lon_grid,
310  z_field, r_geoid, z_surface,
311  ppath_step_agenda);
312 
313  // Check whether the next point is inside or outside the
314  // cloudbox. Only if the next point lies inside the
315  // cloudbox a radiative transfer step caclulation has to
316  // be performed.
317 
318  if((cloudbox_limits[0] <= ppath_step.gp_p[1].idx &&
319  cloudbox_limits[1] > ppath_step.gp_p[1].idx) ||
320  (cloudbox_limits[1] == ppath_step.gp_p[1].idx &&
321  abs(ppath_step.gp_p[1].fd[0]) < 1e-6))
322  {
323  // Stokes dimension
324  const Index stokes_dim = doit_i_field.ncols();
325  // Number of species
326  const Index N_species = vmr_field.nbooks();
327 
328  // Ppath_step normally has 2 points, the starting
329  // point and the intersection point.
330  // But there can be points in between, when a maximum
331  // l_step is given. We have to interpolate on all the
332  // points in the ppath_step.
333 
334  // Initialize variables for interpolated values
335  Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np, 0.);
336  Matrix abs_vec_int(stokes_dim, ppath_step.np, 0.);
337  Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
338  Matrix doit_i_field_int(stokes_dim, ppath_step.np, 0.);
339  Vector t_int(ppath_step.np, 0.);
340  Matrix vmr_list_int(N_species, ppath_step.np, 0.);
341  Vector p_int(ppath_step.np, 0.);
342 
343  interp_cloud_coeff1D(ext_mat_int, abs_vec_int, sca_vec_int,
344  doit_i_field_int, t_int, vmr_list_int, p_int,
345  ext_mat_field, abs_vec_field, doit_scat_field,
346  doit_i_field, t_field, vmr_field, p_grid,
347  ppath_step, cloudbox_limits, scat_za_grid,
348  scat_za_interp, verbosity);
349 
350 
351  // ppath_what_background(ppath_step) tells the
352  // radiative background. More information in the
353  // function get_iy_of_background.
354  // if there is no background we proceed the RT
355  Index bkgr = ppath_what_background(ppath_step);
356 
357  // Radiative transfer from one layer to the next, starting
358  // at the intersection with the next layer and propagating
359  // to the considered point.
360  cloud_RT_no_background(ws, doit_i_field,
361  abs_scalar_gas_agenda,
362  opt_prop_gas_agenda, ppath_step,
363  t_int, vmr_list_int,
364  ext_mat_int, abs_vec_int, sca_vec_int,
365  doit_i_field_int,
366  p_int, cloudbox_limits,
367  f_grid, f_index, p_index, 0, 0,
368  scat_za_index, 0, verbosity);
369 
370  // bkgr=2 indicates that the background is the surface
371  if (bkgr == 2)
372  {
373  // cout << "hit surface "<< ppath_step.gp_p << endl;
374  cloud_RT_surface(ws,
375  doit_i_field, surface_prop_agenda,
376  f_index, stokes_dim, ppath_step, cloudbox_limits,
377  scat_za_grid, scat_za_index);
378 
379  }
380 
381  }//end if inside cloudbox
382 }
383 
385 /*
386  Basically the same as cloud_ppath_update1D, the only difference is that
387  i_field_old is always used as incoming Stokes vector.
388 
389  \author Claudia Emde
390  \date 2005-05-04
391 */
393  // Output
394  Tensor6View doit_i_field,
395  // ppath_step_agenda:
396  const Index& p_index,
397  const Index& scat_za_index,
398  ConstVectorView scat_za_grid,
399  const ArrayOfIndex& cloudbox_limits,
400  ConstTensor6View doit_i_field_old,
401  ConstTensor6View doit_scat_field,
402  // Calculate scalar gas absorption:
403  const Agenda& abs_scalar_gas_agenda,
404  ConstTensor4View vmr_field,
405  // Gas absorption:
406  const Agenda& opt_prop_gas_agenda,
407  // Propagation path calculation:
408  const Agenda& ppath_step_agenda,
409  ConstVectorView p_grid,
410  ConstTensor3View z_field,
411  ConstMatrixView r_geoid,
412  ConstMatrixView z_surface,
413  // Calculate thermal emission:
414  ConstTensor3View t_field,
415  ConstVectorView f_grid,
416  // used for surface ?
417  const Index& f_index,
418  //particle optical properties
419  ConstTensor5View ext_mat_field,
420  ConstTensor4View abs_vec_field,
421  const Agenda& surface_prop_agenda,
422  const Index& scat_za_interp,
423  const Verbosity& verbosity)
424 {
425  Matrix iy;
426  Matrix surface_emission;
427  Matrix surface_los;
428  Tensor4 surface_rmatrix;
429  Ppath ppath_step;
430  // Input variables are checked in the WSMs i_fieldUpdateSeqXXX, from
431  // where this function is called.
432 
433  //Initialize ppath for 1D.
434  ppath_init_structure(ppath_step, 1, 1);
435  // See documentation of ppath_init_structure for understanding
436  // the parameters.
437 
438  // Assign value to ppath.pos:
439  ppath_step.z[0] = z_field(p_index,0,0);
440  ppath_step.pos(0,0) = r_geoid(0,0) + ppath_step.z[0];
441 
442  // Define the direction:
443  ppath_step.los(0,0) = scat_za_grid[scat_za_index];
444 
445 
446  // Define the grid positions:
447  ppath_step.gp_p[0].idx = p_index;
448  ppath_step.gp_p[0].fd[0] = 0;
449  ppath_step.gp_p[0].fd[1] = 1;
450 
451  // Call ppath_step_agenda:
452  Vector unused_lat_grid(0);
453  Vector unused_lon_grid(0);
454  ppath_step_agendaExecute(ws, ppath_step, 1, p_grid,
455  unused_lat_grid, unused_lon_grid,
456  z_field, r_geoid, z_surface,
457  ppath_step_agenda);
458 
459  // Check whether the next point is inside or outside the
460  // cloudbox. Only if the next point lies inside the
461  // cloudbox a radiative transfer step caclulation has to
462  // be performed.
463 
464  if((cloudbox_limits[0] <= ppath_step.gp_p[1].idx &&
465  cloudbox_limits[1] > ppath_step.gp_p[1].idx) ||
466  (cloudbox_limits[1] == ppath_step.gp_p[1].idx &&
467  abs(ppath_step.gp_p[1].fd[0]) < 1e-6))
468  {
469  // Stokes dimension
470  const Index stokes_dim = doit_i_field.ncols();
471  // Number of species
472  const Index N_species = vmr_field.nbooks();
473 
474  // Ppath_step normally has 2 points, the starting
475  // point and the intersection point.
476  // But there can be points in between, when a maximum
477  // l_step is given. We have to interpolate on all the
478  // points in the ppath_step.
479 
480  // Initialize variables for interpolated values
481  Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np, 0.);
482  Matrix abs_vec_int(stokes_dim, ppath_step.np, 0.);
483  Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
484  Matrix doit_i_field_int(stokes_dim, ppath_step.np, 0.);
485  Vector t_int(ppath_step.np, 0.);
486  Matrix vmr_list_int(N_species, ppath_step.np, 0.);
487  Vector p_int(ppath_step.np, 0.);
488 
489  interp_cloud_coeff1D(ext_mat_int, abs_vec_int, sca_vec_int,
490  doit_i_field_int, t_int, vmr_list_int, p_int,
491  ext_mat_field, abs_vec_field, doit_scat_field,
492  doit_i_field_old, t_field, vmr_field, p_grid,
493  ppath_step, cloudbox_limits, scat_za_grid,
494  scat_za_interp, verbosity);
495 
496  // ppath_what_background(ppath_step) tells the
497  // radiative background. More information in the
498  // function get_iy_of_background.
499  // if there is no background we proceed the RT
500  Index bkgr = ppath_what_background(ppath_step);
501 
502  // if 0, there is no background
503  // do this in any case. cause we need downwelling doit_i_field
504  // at the surface for calculating surface scattering
505 
506  // Radiative transfer from one layer to the next, starting
507  // at the intersection with the next layer and propagating
508  // to the considered point.
509  cloud_RT_no_background(ws, doit_i_field,
510  abs_scalar_gas_agenda,
511  opt_prop_gas_agenda, ppath_step,
512  t_int, vmr_list_int,
513  ext_mat_int, abs_vec_int, sca_vec_int,
514  doit_i_field_int,
515  p_int, cloudbox_limits,
516  f_grid, f_index, p_index, 0, 0,
517  scat_za_index, 0, verbosity);
518 
519  if (bkgr == 2)
520  {
521  cloud_RT_surface(ws,
522  doit_i_field, surface_prop_agenda,
523  f_index, stokes_dim, ppath_step, cloudbox_limits,
524  scat_za_grid, scat_za_index);
525 
526  }
527  }//end if inside cloudbox
528 }
529 
530 
531 
532 
534 
582  Tensor6View doit_i_field,
583  // ppath_step_agenda:
584  const Index& p_index,
585  const Index& lat_index,
586  const Index& lon_index,
587  const Index& scat_za_index,
588  const Index& scat_aa_index,
589  ConstVectorView scat_za_grid,
590  ConstVectorView scat_aa_grid,
591  const ArrayOfIndex& cloudbox_limits,
592  ConstTensor6View doit_scat_field,
593  // Calculate scalar gas absorption:
594  const Agenda& abs_scalar_gas_agenda,
595  ConstTensor4View vmr_field,
596  // Gas absorption:
597  const Agenda& opt_prop_gas_agenda,
598  // Propagation path calculation:
599  const Agenda& ppath_step_agenda,
600  ConstVectorView p_grid,
601  ConstVectorView lat_grid,
602  ConstVectorView lon_grid,
603  ConstTensor3View z_field,
604  ConstMatrixView r_geoid,
605  ConstMatrixView z_surface,
606  // Calculate thermal emission:
607  ConstTensor3View t_field,
608  ConstVectorView f_grid,
609  const Index& f_index,
610  //particle optical properties
611  ConstTensor5View ext_mat_field,
612  ConstTensor4View abs_vec_field,
613  const Index&, //scat_za_interp
614  const Verbosity& verbosity
615  )
616 {
618 
619  Ppath ppath_step;
620  const Index stokes_dim = doit_i_field.ncols();
621 
622  Vector sca_vec_av(stokes_dim,0);
623  Vector aa_grid(scat_aa_grid.nelem());
624 
625  for(Index i = 0; i<scat_aa_grid.nelem(); i++)
626  aa_grid[i] = scat_aa_grid[i]-180.;
627 
628  //Initialize ppath for 3D.
629  ppath_init_structure(ppath_step, 3, 1);
630  // See documentation of ppath_init_structure for
631  // understanding the parameters.
632 
633  // Assign value to ppath.pos:
634  ppath_step.z[0] = z_field(p_index,lat_index,
635  lon_index);
636 
637  // The first dimension of pos are the points in
638  // the propagation path.
639  // Here we initialize the first point.
640  // The second is: radius, latitude, longitude
641 
642  ppath_step.pos(0,0) =
643  r_geoid(lat_index, lon_index) + ppath_step.z[0];
644  ppath_step.pos(0,1) = lat_grid[lat_index];
645  ppath_step.pos(0,2) = lon_grid[lon_index];
646 
647  // Define the direction:
648  ppath_step.los(0,0) = scat_za_grid[scat_za_index];
649  ppath_step.los(0,1) = aa_grid[scat_aa_index];
650 
651  // Define the grid positions:
652  ppath_step.gp_p[0].idx = p_index;
653  ppath_step.gp_p[0].fd[0] = 0.;
654  ppath_step.gp_p[0].fd[1] = 1.;
655 
656  ppath_step.gp_lat[0].idx = lat_index;
657  ppath_step.gp_lat[0].fd[0] = 0.;
658  ppath_step.gp_lat[0].fd[1] = 1.;
659 
660  ppath_step.gp_lon[0].idx = lon_index;
661  ppath_step.gp_lon[0].fd[0] = 0.;
662  ppath_step.gp_lon[0].fd[1] = 1.;
663 
664  // Call ppath_step_agenda:
665  ppath_step_agendaExecute(ws, ppath_step, 3, p_grid,
666  lat_grid, lon_grid, z_field, r_geoid, z_surface,
667  ppath_step_agenda);
668 
669  // Check whether the next point is inside or outside the
670  // cloudbox. Only if the next point lies inside the
671  // cloudbox a radiative transfer step caclulation has to
672  // be performed.
673  if (is_inside_cloudbox(ppath_step, cloudbox_limits, true))
674  {
675  // Gridpositions inside the cloudbox.
676  // The optical properties are stored only inside the
677  // cloudbox. For interpolation we use grids
678  // inside the cloudbox.
679 
680  ArrayOfGridPos cloud_gp_p = ppath_step.gp_p;
681  ArrayOfGridPos cloud_gp_lat = ppath_step.gp_lat;
682  ArrayOfGridPos cloud_gp_lon = ppath_step.gp_lon;
683 
684  for(Index i = 0; i<ppath_step.np; i++ )
685  {
686  cloud_gp_p[i].idx -= cloudbox_limits[0];
687  cloud_gp_lat[i].idx -= cloudbox_limits[2];
688  cloud_gp_lon[i].idx -= cloudbox_limits[4];
689  }
690  const Index n1 = cloudbox_limits[1] - cloudbox_limits[0];
691  const Index n2 = cloudbox_limits[3] - cloudbox_limits[2];
692  const Index n3 = cloudbox_limits[5] - cloudbox_limits[4];
693  gridpos_upperend_check( cloud_gp_p[0], n1 );
694  gridpos_upperend_check( cloud_gp_p[ppath_step.np-1], n1 );
695  gridpos_upperend_check( cloud_gp_lat[0], n2 );
696  gridpos_upperend_check( cloud_gp_lat[ppath_step.np-1], n2);
697  gridpos_upperend_check( cloud_gp_lon[0], n3 );
698  gridpos_upperend_check( cloud_gp_lon[ppath_step.np-1], n3 );
699 
700  Matrix itw(ppath_step.np, 8);
701  interpweights(itw, cloud_gp_p, cloud_gp_lat, cloud_gp_lon);
702 
703  Matrix itw_p(ppath_step.np, 2);
704  interpweights(itw_p, cloud_gp_p);
705 
706  // The zenith angles and azimuth of the propagation path are
707  // needed as we have to
708  // interpolate the intensity field and the scattered field on the
709  // right angles.
710  VectorView los_grid_za = ppath_step.los(joker,0);
711  VectorView los_grid_aa = ppath_step.los(joker,1);
712 
713  for(Index i = 0; i<los_grid_aa.nelem(); i++)
714  los_grid_aa[i] = los_grid_aa[i] + 180.;
715 
716  ArrayOfGridPos gp_za(los_grid_za.nelem());
717  gridpos(gp_za, scat_za_grid, los_grid_za);
718 
719  ArrayOfGridPos gp_aa(los_grid_aa.nelem());
720  gridpos(gp_aa, scat_aa_grid, los_grid_aa);
721 
722  Matrix itw_p_za(ppath_step.np, 32);
723  interpweights(itw_p_za, cloud_gp_p, cloud_gp_lat, cloud_gp_lon,
724  gp_za, gp_aa);
725 
726  // Ppath_step normally has 2 points, the starting
727  // point and the intersection point.
728  // But there can be points in between, when a maximum
729  // l_step is given. We have to interpolate on all the
730  // points in the ppath_step.
731 
732  Tensor3 ext_mat_int(stokes_dim, stokes_dim, ppath_step.np);
733  Matrix abs_vec_int(stokes_dim, ppath_step.np);
734  Matrix sca_vec_int(stokes_dim, ppath_step.np, 0.);
735  Matrix doit_i_field_int(stokes_dim, ppath_step.np, 0.);
736  Vector t_int(ppath_step.np);
737  Vector vmr_int(ppath_step.np);
738  Vector p_int(ppath_step.np);
739  Vector stokes_vec(stokes_dim);
740  //Tensor3 ext_mat_gas(stokes_dim, stokes_dim, ppath_step.np);
741  //Matrix abs_vec_gas(stokes_dim, ppath_step.np);
742 
743  // Calculate the average of the coefficients for the layers
744  // to be considered in the
745  // radiative transfer calculation.
746 
747  for (Index i = 0; i < stokes_dim; i++)
748  {
749  // Extinction matrix requires a second loop
750  // over stokes_dim
751  out3 << "Interpolate ext_mat:\n";
752  for (Index j = 0; j < stokes_dim; j++)
753  {
754  //
755  // Interpolation of ext_mat
756  //
757  interp( ext_mat_int(i, j, joker), itw,
758  ext_mat_field(joker, joker, joker, i, j), cloud_gp_p,
759  cloud_gp_lat, cloud_gp_lon);
760  }
761  // Absorption vector:
762  //
763  // Interpolation of abs_vec
764  //
765  interp( abs_vec_int(i,joker), itw,
766  abs_vec_field(joker, joker, joker, i),
767  cloud_gp_p, cloud_gp_lat, cloud_gp_lon);
768  //
769  // Scattered field:
770  //
771  // Interpolation of sca_vec:
772  //
773  out3 << "Interpolate doit_scat_field:\n";
774  interp( sca_vec_int(i, joker), itw_p_za,
775  doit_scat_field(joker, joker, joker, joker, joker, i),
776  cloud_gp_p,
777  cloud_gp_lat, cloud_gp_lon, gp_za, gp_aa);
778  out3 << "Interpolate doit_i_field:\n";
779  interp( doit_i_field_int(i, joker), itw_p_za,
780  doit_i_field(joker, joker, joker, joker, joker, i),
781  cloud_gp_p,
782  cloud_gp_lat, cloud_gp_lon, gp_za, gp_aa);
783  }
784  //
785  // Planck function
786  //
787  // Interpolate temperature field
788  //
789  out3 << "Interpolate temperature field\n";
790  interp( t_int, itw,
791  t_field(joker, joker, joker), ppath_step.gp_p,
792  ppath_step.gp_lat, ppath_step.gp_lon);
793 
794  //
795  // The vmr_field is needed for the gaseous absorption
796  // calculation.
797  //
798  const Index N_species = vmr_field.nbooks();
799  //
800  // Interpolated vmr_list, holds a vmr_list for each point in
801  // ppath_step.
802  //
803  Matrix vmr_list_int(N_species, ppath_step.np);
804 
805  for (Index i = 0; i < N_species; i++)
806  {
807  out3 << "Interpolate vmr field\n";
808  interp( vmr_int, itw,
809  vmr_field(i, joker, joker, joker), ppath_step.gp_p,
810  ppath_step.gp_lat, ppath_step.gp_lon );
811 
812  vmr_list_int(i, joker) = vmr_int;
813  }
814 
815  // Presssure (needed for the calculation of gas absorption)
816  itw2p( p_int, p_grid, ppath_step.gp_p, itw_p);
817 
818  out3 << "Calculate radiative transfer inside cloudbox.\n";
819  cloud_RT_no_background(ws, doit_i_field,
820  abs_scalar_gas_agenda,
821  opt_prop_gas_agenda, ppath_step,
822  t_int, vmr_list_int,
823  ext_mat_int, abs_vec_int, sca_vec_int,
824  doit_i_field_int,
825  p_int, cloudbox_limits,
826  f_grid, f_index, p_index, lat_index, lon_index,
827  scat_za_index, scat_aa_index, verbosity);
828  }//end if inside cloudbox
829 }
830 
832 /*
833  This function calculates RT in the cloudbox (1D) if the next intersected
834  level is an atmospheric level (in contrast to the surface).
835  It is used inside the functions cloud_ppath_update1DXXX.
836 
837  Output:
838  \param doit_i_field Radiation field in cloudbox. This variable is filled
839  with the updated values for a given zenith angle (scat_za_index) and
840  pressure (p_index).
841  Input:
842  \param abs_scalar_gas_agenda Calculate scalar gas absorption.
843  \param opt_prop_gas_agenda Calculate absorption vector and extiction matrix
844  due to gas.
845  \param ppath_step Propagation path step from one pressure level to the next
846  (this can include several points)
847  \param t_int Temperature values interpolated on propagation path points.
848  \param vmr_list_int Interpolated volume mixing ratios.
849  \param ext_mat_int Interpolated particle extinction matrix.
850  \param abs_vec_int Interpolated particle absorption vector.
851  \param sca_vec_int Interpolated particle scattering vector.
852  \param doit_i_field_int Interpolated radiances.
853  \param p_int Interpolated pressure values.
854  \param cloudbox_limits Cloudbox_limits.
855  \param f_grid Frequency grid.
856  \param f_index Frequency index of (monochromatic) scattering calculation.
857  \param p_index Pressure index in *doit_i_field*.
858  \param scat_za_index Zenith angle index in *doit_i_field*.
859 
860  \author Claudia Emde
861  \date 2005-05-13
862 */
864  //Output
865  Tensor6View doit_i_field,
866  // Input
867  const Agenda& abs_scalar_gas_agenda,
868  const Agenda& opt_prop_gas_agenda,
869  const Ppath& ppath_step,
870  ConstVectorView t_int,
871  ConstMatrixView vmr_list_int,
872  ConstTensor3View ext_mat_int,
873  ConstMatrixView abs_vec_int,
874  ConstMatrixView sca_vec_int,
875  ConstMatrixView doit_i_field_int,
876  ConstVectorView p_int,
877  const ArrayOfIndex& cloudbox_limits,
878  ConstVectorView f_grid,
879  const Index& f_index,
880  const Index& p_index,
881  const Index& lat_index,
882  const Index& lon_index,
883  const Index& scat_za_index,
884  const Index& scat_aa_index,
885  const Verbosity& verbosity)
886 {
888 
889  const Index N_species = vmr_list_int.nrows();
890  const Index stokes_dim = doit_i_field.ncols();
891  const Index atmosphere_dim = cloudbox_limits.nelem()/2;
892 
893  Vector sca_vec_av(stokes_dim,0);
894  Vector stokes_vec(stokes_dim, 0.);
895  Vector rte_vmr_list_local(N_species,0.);
896 
897  Matrix abs_scalar_gas_local(1, N_species, 0.);
898  Tensor3 ext_mat_local;
899  Matrix abs_vec_local;
900 
901  // Incoming stokes vector
902  stokes_vec = doit_i_field_int(joker, ppath_step.np-1);
903 
904  for( Index k= ppath_step.np-1; k > 0; k--)
905  {
906  // Length of the path between the two layers.
907  Numeric l_step = ppath_step.l_step[k-1];
908  // Average temperature
909  Numeric rte_temperature_local = 0.5 * (t_int[k] + t_int[k-1]);
910  //
911  // Average pressure
912  Numeric rte_pressure_local = 0.5 * (p_int[k] + p_int[k-1]);
913  //
914  // Average vmrs
915  for (Index i = 0; i < N_species; i++)
916  rte_vmr_list_local[i] = 0.5 * (vmr_list_int(i,k) +
917  vmr_list_int(i,k-1));
918  //
919  // Calculate scalar gas absorption and add it to abs_vec
920  // and ext_mat.
921  //
922 
923  abs_scalar_gas_agendaExecute( ws, abs_scalar_gas_local,
924  f_index,
925  0,
926  rte_pressure_local,
927  rte_temperature_local,
928  rte_vmr_list_local,
929  abs_scalar_gas_agenda );
930 
931  opt_prop_gas_agendaExecute( ws, ext_mat_local,
932  abs_vec_local,
933  f_index,
934  abs_scalar_gas_local,
935  opt_prop_gas_agenda );
936 
937  //
938  // Add average particle extinction to ext_mat.
939  //
940  for (Index i = 0; i < stokes_dim; i++)
941  {
942  for (Index j = 0; j < stokes_dim; j++)
943  {
944  ext_mat_local(0,i,j) += 0.5 *
945  (ext_mat_int(i,j,k) + ext_mat_int(i,j,k-1));
946  }
947  //
948  // Add average particle absorption to abs_vec.
949  //
950  abs_vec_local(0,i) += 0.5 *
951  (abs_vec_int(i,k) + abs_vec_int(i,k-1));
952 
953  //
954  // Averaging of sca_vec:
955  //
956  sca_vec_av[i] = 0.5 *
957  (sca_vec_int(i, k) + sca_vec_int(i, k-1));
958 
959  }
960  // Frequency
961  Numeric f = f_grid[f_index];
962  //
963  // Calculate Planck function
964  //
965  Numeric rte_planck_value = planck(f, rte_temperature_local);
966 
967  // Some messages:
968  out3 << "-----------------------------------------\n";
969  out3 << "Input for radiative transfer step \n"
970  << "calculation inside"
971  << " the cloudbox:" << "\n";
972  out3 << "Stokes vector at intersection point: \n"
973  << stokes_vec
974  << "\n";
975  out3 << "l_step: ..." << l_step << "\n";
976  out3 << "------------------------------------------\n";
977  out3 << "Averaged coefficients: \n";
978  out3 << "Planck function: " << rte_planck_value << "\n";
979  out3 << "Scattering vector: " << sca_vec_av << "\n";
980  out3 << "Absorption vector: " << abs_vec_local(0,joker) << "\n";
981  out3 << "Extinction matrix: " << ext_mat_local(0,joker,joker) << "\n";
982 
983 
984  assert (!is_singular( ext_mat_local(0,joker,joker)));
985 
986  // Radiative transfer step calculation. The Stokes vector
987  // is updated until the considered point is reached.
988  rte_step_std(stokes_vec, Matrix(stokes_dim,stokes_dim),
989  ext_mat_local(0,joker,joker), abs_vec_local(0,joker),
990  sca_vec_av, l_step, rte_planck_value);
991 
992  }// End of loop over ppath_step.
993  // Assign calculated Stokes Vector to doit_i_field.
994  if (atmosphere_dim == 1)
995  doit_i_field(p_index - cloudbox_limits[0], 0, 0, scat_za_index, 0, joker)
996  = stokes_vec;
997  else if (atmosphere_dim == 3)
998  doit_i_field(p_index - cloudbox_limits[0],
999  lat_index - cloudbox_limits[2],
1000  lon_index - cloudbox_limits[4],
1001  scat_za_index, scat_aa_index,
1002  joker) = stokes_vec;
1003 
1004 }
1005 
1007 /*
1008  This function calculates RT in the cloudbox if the next intersected
1009  level is the surface.
1010 
1011  CE (2006-05-29) Included surface_prop_agenda here.
1012 
1013  \author Claudia Emde
1014  \date 2005-05-13
1015 */
1017  //Output
1018  Tensor6View doit_i_field,
1019  //Input
1020  const Agenda& surface_prop_agenda,
1021  const Index& f_index,
1022  const Index& stokes_dim,
1023  const Ppath& ppath_step,
1024  const ArrayOfIndex& cloudbox_limits,
1025  ConstVectorView scat_za_grid,
1026  const Index& scat_za_index
1027  )
1028 {
1029  chk_not_empty( "surface_prop_agenda", surface_prop_agenda );
1030 
1031  Matrix iy;
1032 
1033  // Local output of surface_prop_agenda.
1034  Matrix surface_emission;
1035  Matrix surface_los;
1036  Tensor4 surface_rmatrix;
1037 
1038 
1039  //Set rte_pos, rte_gp_p and rte_los to match the last point
1040  //in ppath.
1041 
1042  Index np = ppath_step.np;
1043 
1044  Vector rte_pos;
1045  rte_pos.resize( ppath_step.pos.ncols() );
1046  rte_pos = ppath_step.pos(np-1,joker);
1047 
1048  Vector rte_los;
1049  rte_los.resize( ppath_step.los.ncols() );
1050  rte_los = ppath_step.los(np-1,joker);
1051 
1052  GridPos dummy_ppath_step_gp_lat;
1053  GridPos dummy_ppath_step_gp_lon;
1054 
1055  //Execute the surface_prop_agenda which gives the surface
1056  //parameters.
1057 
1058  surface_prop_agendaExecute(ws, surface_emission, surface_los,
1059  surface_rmatrix, rte_pos, rte_los,
1060  ppath_step.gp_p[np-1], dummy_ppath_step_gp_lat,
1061  dummy_ppath_step_gp_lon, surface_prop_agenda);
1062 
1063  iy = surface_emission;
1064 
1065  Vector rtmp(stokes_dim); // Reflected Stokes vector for 1 frequency
1066  Index nlos = surface_los.nrows();
1067 
1068  if( nlos > 0 )
1069  {
1070  for( Index ilos=0; ilos<nlos; ilos++ )
1071  {
1072 
1073  mult( rtmp,
1074  surface_rmatrix(ilos,f_index,joker,joker),
1075  doit_i_field(cloudbox_limits[0], 0, 0,
1076  (scat_za_grid.nelem() -1 - scat_za_index), 0,
1077  joker) );
1078  iy(f_index,joker) += rtmp;
1079 
1080  doit_i_field(cloudbox_limits[0], 0, 0,
1081  scat_za_index, 0,
1082  joker) = iy(f_index, joker);
1083  }
1084  }
1085 }
1086 
1087 
1120  //Output:
1121  Ppath& ppath_step,
1122  //Input:
1123  const Agenda& ppath_step_agenda,
1124  const Index& p,
1125  const Index& lat,
1126  const Index& lon,
1127  ConstTensor3View z_field,
1128  ConstMatrixView r_geoid,
1129  ConstMatrixView z_surface,
1130  ConstVectorView scat_za_grid,
1131  ConstVectorView aa_grid,
1132  const Index& scat_za_index,
1133  const Index& scat_aa_index,
1134  ConstVectorView p_grid,
1135  ConstVectorView lat_grid,
1136  ConstVectorView lon_grid)
1137 {
1138  //Initialize ppath for 3D.
1139  ppath_init_structure(ppath_step, 3, 1);
1140  // See documentation of ppath_init_structure for
1141  // understanding the parameters.
1142 
1143  // Assign value to ppath.pos:
1144  //
1145  ppath_step.z[0] = z_field(p, lat, lon);
1146 
1147  // The first dimension of pos are the points in
1148  // the propagation path.
1149  // Here we initialize the first point.
1150  // The second is: radius, latitude, longitude
1151 
1152  ppath_step.pos(0,0) = r_geoid(lat, lon) + ppath_step.z[0];
1153  ppath_step.pos(0,1) = lat_grid[lat];
1154  ppath_step.pos(0,2) = lon_grid[lon];
1155 
1156  // Define the direction:
1157  ppath_step.los(0,0) = scat_za_grid[scat_za_index];
1158  ppath_step.los(0,1) = aa_grid[scat_aa_index];
1159 
1160  // Define the grid positions:
1161  ppath_step.gp_p[0].idx = p;
1162  ppath_step.gp_p[0].fd[0] = 0.;
1163  ppath_step.gp_p[0].fd[1] = 1.;
1164 
1165  ppath_step.gp_lat[0].idx = lat;
1166  ppath_step.gp_lat[0].fd[0] = 0.;
1167  ppath_step.gp_lat[0].fd[1] = 1.;
1168 
1169  ppath_step.gp_lon[0].idx = lon;
1170  ppath_step.gp_lon[0].fd[0] = 0.;
1171  ppath_step.gp_lon[0].fd[1] = 1.;
1172 
1173  // Call ppath_step_agenda:
1174  ppath_step_agendaExecute(ws, ppath_step, 3, p_grid,
1175  lat_grid, lon_grid, z_field, r_geoid, z_surface,
1176  ppath_step_agenda);
1177 }
1178 
1180 
1188  Tensor3View ext_mat_int,
1189  MatrixView abs_vec_int,
1190  MatrixView sca_vec_int,
1191  MatrixView doit_i_field_int,
1192  VectorView t_int,
1193  MatrixView vmr_list_int,
1194  VectorView p_int,
1195  //Input
1196  ConstTensor5View ext_mat_field,
1197  ConstTensor4View abs_vec_field,
1198  ConstTensor6View doit_scat_field,
1199  ConstTensor6View doit_i_field,
1200  ConstTensor3View t_field,
1201  ConstTensor4View vmr_field,
1202  ConstVectorView p_grid,
1203  const Ppath& ppath_step,
1204  const ArrayOfIndex& cloudbox_limits,
1205  ConstVectorView scat_za_grid,
1206  const Index& scat_za_interp,
1207  const Verbosity& verbosity)
1208 {
1209  CREATE_OUT3
1210 
1211  // Stokes dimension
1212  const Index stokes_dim = doit_i_field.ncols();
1213 
1214  // Gridpositions inside the cloudbox.
1215  // The optical properties are stored only inside the
1216  // cloudbox. For interpolation we use grids
1217  // inside the cloudbox.
1218  ArrayOfGridPos cloud_gp_p = ppath_step.gp_p;
1219 
1220  for(Index i = 0; i < ppath_step.np; i++ )
1221  cloud_gp_p[i].idx -= cloudbox_limits[0];
1222 
1223  // Grid index for points at upper limit of cloudbox must be shifted
1224  const Index n1 = cloudbox_limits[1] - cloudbox_limits[0];
1225  gridpos_upperend_check( cloud_gp_p[0], n1 );
1226  gridpos_upperend_check( cloud_gp_p[ppath_step.np-1], n1 );
1227 
1228 
1229  Matrix itw(cloud_gp_p.nelem(),2);
1230  interpweights( itw, cloud_gp_p );
1231 
1232  // The zenith angles of the propagation path are needed as we have to
1233  // interpolate the intensity field and the scattered field on the
1234  // right angles.
1235  Vector los_grid = ppath_step.los(joker,0);
1236 
1237  ArrayOfGridPos gp_za(los_grid.nelem());
1238  gridpos(gp_za, scat_za_grid, los_grid);
1239 
1240  Matrix itw_p_za(cloud_gp_p.nelem(), 4);
1241  interpweights(itw_p_za, cloud_gp_p, gp_za );
1242 
1243  // Calculate the average of the coefficients for the layers
1244  // to be considered in the
1245  // radiative transfer calculation.
1246 
1247  for (Index i = 0; i < stokes_dim; i++)
1248  {
1249  // Extinction matrix requires a second loop
1250  // over stokes_dim
1251  out3 << "Interpolate ext_mat:\n";
1252  for (Index j = 0; j < stokes_dim; j++)
1253  {
1254  //
1255  // Interpolation of ext_mat
1256  //
1257  interp( ext_mat_int(i, j, joker), itw,
1258  ext_mat_field(joker, 0, 0, i, j), cloud_gp_p );
1259  }
1260  // Particle absorption vector:
1261  //
1262  // Interpolation of abs_vec
1263  // //
1264  out3 << "Interpolate abs_vec:\n";
1265  interp( abs_vec_int(i,joker), itw,
1266  abs_vec_field(joker, 0, 0, i), cloud_gp_p );
1267  //
1268  // Scattered field:
1269  //
1270  //
1271 
1272  out3 << "Interpolate doit_scat_field and doit_i_field:\n";
1273  if(scat_za_interp == 0) // linear interpolation
1274  {
1275  interp( sca_vec_int(i, joker), itw_p_za,
1276  doit_scat_field(joker, 0, 0, joker, 0, i),
1277  cloud_gp_p, gp_za);
1278  interp( doit_i_field_int(i, joker), itw_p_za,
1279  doit_i_field(joker, 0, 0, joker, 0, i), cloud_gp_p, gp_za);
1280  }
1281  else if (scat_za_interp == 1) //polynomial interpolation
1282  {
1283  // These intermediate variables are needed because polynomial
1284  // interpolation is not implemented as multidimensional
1285  // interpolation.
1286  Tensor3 sca_vec_int_za(stokes_dim, ppath_step.np,
1287  scat_za_grid.nelem(), 0.);
1288  Tensor3 doit_i_field_int_za(stokes_dim, ppath_step.np,
1289  scat_za_grid.nelem(), 0.);
1290  for (Index za = 0; za < scat_za_grid.nelem(); za++)
1291  {
1292  interp( sca_vec_int_za(i, joker, za), itw,
1293  doit_scat_field(joker, 0, 0, za, 0, i), cloud_gp_p);
1294  out3 << "Interpolate doit_i_field:\n";
1295  interp( doit_i_field_int_za(i, joker, za), itw,
1296  doit_i_field(joker, 0, 0, za, 0, i), cloud_gp_p);
1297  }
1298  for (Index ip = 0; ip < ppath_step.np; ip ++)
1299  {
1300  sca_vec_int(i, ip) =
1301  interp_poly(scat_za_grid, sca_vec_int_za(i, ip, joker),
1302  los_grid[ip], gp_za[ip]);
1303  doit_i_field_int(i, ip) =
1304  interp_poly(scat_za_grid, doit_i_field_int_za(i, ip, joker),
1305  los_grid[ip], gp_za[ip]);
1306  }
1307  }
1308  }
1309  //
1310  // Planck function
1311  //
1312  // Interpolate temperature field
1313  //
1314  out3 << "Interpolate temperature field\n";
1315  interp( t_int, itw, t_field(joker, 0, 0), ppath_step.gp_p );
1316  //
1317  // The vmr_field is needed for the gaseous absorption
1318  // calculation.
1319  //
1320  const Index N_species = vmr_field.nbooks();
1321  //
1322  // Interpolated vmr_list, holds a vmr_list for each point in
1323  // ppath_step.
1324  //
1325  Vector vmr_int(ppath_step.np);
1326 
1327  for (Index i_sp = 0; i_sp < N_species; i_sp ++)
1328  {
1329  out3 << "Interpolate vmr field\n";
1330  interp( vmr_int, itw, vmr_field(i_sp, joker, 0, 0), ppath_step.gp_p );
1331  vmr_list_int(i_sp, joker) = vmr_int;
1332  }
1333  //
1334  // Interpolate pressure
1335  //
1336  itw2p( p_int, p_grid, ppath_step.gp_p, itw);
1337 }
1338 
1339 
1340 
1342 
1383  Tensor6View doit_i_field,
1384  const Index& p_index,
1385  const Index& scat_za_index,
1386  ConstVectorView scat_za_grid,
1387  const ArrayOfIndex& cloudbox_limits,
1388  ConstTensor6View doit_scat_field,
1389  // Calculate scalar gas absorption:
1390  const Agenda& abs_scalar_gas_agenda,
1391  ConstTensor4View vmr_field,
1392  // Gas absorption:
1393  const Agenda& opt_prop_gas_agenda,
1394  // Propagation path calculation:
1395  const Agenda& ppath_step_agenda _U_,
1396  ConstVectorView p_grid,
1397  ConstTensor3View z_field,
1398  ConstMatrixView r_geoid,
1399  // Calculate thermal emission:
1400  ConstTensor3View t_field,
1401  ConstVectorView f_grid,
1402  const Index& f_index,
1403  //particle opticla properties
1404  ConstTensor5View ext_mat_field,
1405  ConstTensor4View abs_vec_field,
1406  const Verbosity& verbosity)
1407 {
1408  CREATE_OUT3
1409 
1410  const Index N_species = vmr_field.nbooks();
1411  const Index stokes_dim = doit_i_field.ncols();
1412  const Index atmosphere_dim = 1;
1413  Matrix abs_scalar_gas(1, N_species, 0.);
1414  Tensor3 ext_mat;
1415  Matrix abs_vec;
1416  Vector rte_vmr_list(N_species,0.);
1417  Vector sca_vec_av(stokes_dim,0);
1418 
1419  // Radiative transfer from one layer to the next, starting
1420  // at the intersection with the next layer and propagating
1421  // to the considered point.
1422  Vector stokes_vec(stokes_dim);
1423  Index bkgr;
1424  if((p_index == 0) && (scat_za_grid[scat_za_index] > 90))
1425  {
1426  bkgr = 2;
1427  }
1428  else
1429  {
1430  bkgr = 0;
1431  }
1432 
1433  // if 0, there is no background
1434  if (bkgr == 0)
1435  {
1436  if(scat_za_grid[scat_za_index] <= 90.0)
1437  {
1438  stokes_vec = doit_i_field(p_index-cloudbox_limits[0] +1, 0, 0, scat_za_index, 0, joker);
1439  Numeric z_field_above = z_field(p_index +1, 0, 0);
1440  Numeric z_field_0 = z_field(p_index, 0, 0);
1441 
1442  Numeric cos_theta, l_step;
1443  if (scat_za_grid[scat_za_index] == 90.0)
1444  {
1445  //cos_theta = cos((scat_za_grid[scat_za_index] -1)*PI/180.);
1446  // cos_theta = cos(89.999999999999*PI/180.);
1447  cos_theta = 1e-20;
1448 
1449  }
1450  else
1451  {
1452  cos_theta = cos(scat_za_grid[scat_za_index]* PI/180.0);
1453  }
1454  Numeric dz = (z_field_above - z_field_0);
1455 
1456  l_step = abs(dz/cos_theta) ;
1457 
1458  // Average temperature
1459  Numeric rte_temperature = 0.5 * (t_field(p_index,0,0)
1460  + t_field(p_index + 1,0,0));
1461  //
1462  // Average pressure
1463  Numeric rte_pressure = 0.5 * (p_grid[p_index]
1464  + p_grid[p_index + 1]);
1465 
1466  // Average vmrs
1467  for (Index j = 0; j < N_species; j++)
1468  rte_vmr_list[j] = 0.5 * (vmr_field(j,p_index,0,0) +
1469  vmr_field(j,p_index + 1,0,0));
1470  //
1471  // Calculate scalar gas absorption and add it to abs_vec
1472  // and ext_mat.
1473  //
1474 
1475  abs_scalar_gas_agendaExecute( ws, abs_scalar_gas,
1476  f_index,
1477  0,
1478  rte_pressure,
1479  rte_temperature,
1480  rte_vmr_list,
1481  abs_scalar_gas_agenda );
1482 
1483  opt_prop_gas_agendaExecute( ws, ext_mat,
1484  abs_vec,
1485  f_index,
1486  abs_scalar_gas,
1487  opt_prop_gas_agenda );
1488 
1489  //
1490  // Add average particle extinction to ext_mat.
1491 
1492  for (Index k = 0; k < stokes_dim; k++)
1493  {
1494  for (Index j = 0; j < stokes_dim; j++)
1495  {
1496 
1497  ext_mat(0,k,j) += 0.5 *
1498  (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) +
1499  ext_mat_field(p_index - cloudbox_limits[0]+ 1,0,0,k,j));
1500  }
1501  //
1502  // Add average particle absorption to abs_vec.
1503  //
1504  abs_vec(0,k) += 0.5 *
1505  (abs_vec_field(p_index- cloudbox_limits[0],0,0,k) +
1506  abs_vec_field(p_index - cloudbox_limits[0]+ 1,0,0,k));
1507 
1508  //
1509  // Averaging of sca_vec:
1510  //
1511  sca_vec_av[k] += 0.5 *
1512  (doit_scat_field(p_index- cloudbox_limits[0],0,0,scat_za_index,0, k) +
1513  doit_scat_field(p_index - cloudbox_limits[0]+ 1,0,0,scat_za_index,0,k));
1514 
1515  }
1516  // Frequency
1517  Numeric f = f_grid[f_index];
1518  //
1519  // Calculate Planck function
1520  //
1521  Numeric rte_planck_value = planck(f, rte_temperature);
1522 
1523  // Some messages:
1524  out3 << "-----------------------------------------\n";
1525  out3 << "Input for radiative transfer step \n"
1526  << "calculation inside"
1527  << " the cloudbox:" << "\n";
1528  out3 << "Stokes vector at intersection point: \n"
1529  << stokes_vec
1530  << "\n";
1531  out3 << "l_step: ..." << l_step << "\n";
1532  out3 << "------------------------------------------\n";
1533  out3 << "Averaged coefficients: \n";
1534  out3 << "Planck function: " << rte_planck_value << "\n";
1535  out3 << "Scattering vector: " << sca_vec_av << "\n";
1536  out3 << "Absorption vector: " << abs_vec(0,joker) << "\n";
1537  out3 << "Extinction matrix: " << ext_mat(0,joker,joker) << "\n";
1538 
1539 
1540  assert (!is_singular( ext_mat(0,joker,joker)));
1541 
1542  // Radiative transfer step calculation. The Stokes vector
1543  // is updated until the considered point is reached.
1544  rte_step_std(stokes_vec, Matrix(stokes_dim,stokes_dim),
1545  ext_mat(0,joker,joker), abs_vec(0,joker),
1546  sca_vec_av, l_step, rte_planck_value);
1547 
1548  // Assign calculated Stokes Vector to doit_i_field.
1549  doit_i_field(p_index - cloudbox_limits[0],
1550  0, 0,
1551  scat_za_index, 0,
1552  joker) = stokes_vec;
1553  }
1554  if(scat_za_grid[scat_za_index] > 90)
1555  {
1556  stokes_vec = doit_i_field(p_index-cloudbox_limits[0] -1, 0, 0, scat_za_index, 0, joker);
1557  Numeric z_field_below = z_field(p_index -1, 0, 0);
1558  Numeric z_field_0 = z_field(p_index, 0, 0);
1559 
1560  Numeric cos_theta, l_step;
1561  if (scat_za_grid[scat_za_index] == 90.0)
1562  {
1563  cos_theta = cos((scat_za_grid[scat_za_index] -1)*PI/180.);
1564  //cos_theta = cos(90.00000001*PI/180.);
1565  //cout<<"cos_theta"<<cos_theta<<endl;
1566  }
1567  else
1568  {
1569  cos_theta = cos(scat_za_grid[scat_za_index]* PI/180.0);
1570  }
1571  Numeric dz = ( z_field_0 - z_field_below);
1572  l_step = abs(dz/cos_theta) ;
1573 
1574  // Average temperature
1575  Numeric rte_temperature = 0.5 * (t_field(p_index,0,0)
1576  + t_field(p_index - 1,0,0));
1577  //
1578  // Average pressure
1579  Numeric rte_pressure = 0.5 * (p_grid[p_index]
1580  + p_grid[p_index - 1]);
1581 
1582  //
1583  // Average vmrs
1584  for (Index k = 0; k < N_species; k++)
1585  rte_vmr_list[k] = 0.5 * (vmr_field(k,p_index,0,0) +
1586  vmr_field(k,p_index - 1,0,0));
1587  //
1588  // Calculate scalar gas absorption and add it to abs_vec
1589  // and ext_mat.
1590  //
1591 
1592  abs_scalar_gas_agendaExecute( ws, abs_scalar_gas,
1593  f_index,
1594  0,
1595  rte_pressure,
1596  rte_temperature,
1597  rte_vmr_list,
1598  abs_scalar_gas_agenda );
1599 
1600  opt_prop_gas_agendaExecute( ws, ext_mat,
1601  abs_vec,
1602  f_index,
1603  abs_scalar_gas,
1604  opt_prop_gas_agenda );
1605 
1606  //
1607  // Add average particle extinction to ext_mat.
1608  //
1609 
1610  // cout<<"cloudbox_limits[1]"<<cloudbox_limits[1]<<endl;
1611 // cout<<"p_index - cloudbox_limits[0]"<<p_index - cloudbox_limits[0]<<endl;
1612  for (Index k = 0; k < stokes_dim; k++)
1613  {
1614  for (Index j = 0; j < stokes_dim; j++)
1615  {
1616 
1617  ext_mat(0,k,j) += 0.5 *
1618  (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) +
1619  ext_mat_field(p_index - cloudbox_limits[0]- 1,0,0,k,j));
1620  }
1621  //
1622  // Add average particle absorption to abs_vec.
1623  //
1624  abs_vec(0,k) += 0.5 *
1625  (abs_vec_field(p_index - cloudbox_limits[0],0,0,k) +
1626  abs_vec_field(p_index - cloudbox_limits[0]- 1,0,0,k));
1627 
1628  //
1629  // Averaging of sca_vec:
1630  //
1631  sca_vec_av[k] += 0.5 *
1632  (doit_scat_field(p_index- cloudbox_limits[0],0,0,scat_za_index,0, k) +
1633  doit_scat_field(p_index - cloudbox_limits[0]- 1,0,0,scat_za_index,0,k));
1634 
1635  }
1636  // Frequency
1637  Numeric f = f_grid[f_index];
1638  //
1639  // Calculate Planck function
1640  //
1641  Numeric rte_planck_value = planck(f, rte_temperature);
1642 
1643  // Some messages:
1644  out3 << "-----------------------------------------\n";
1645  out3 << "Input for radiative transfer step \n"
1646  << "calculation inside"
1647  << " the cloudbox:" << "\n";
1648  out3 << "Stokes vector at intersection point: \n"
1649  << stokes_vec
1650  << "\n";
1651  out3 << "l_step: ..." << l_step << "\n";
1652  out3 << "------------------------------------------\n";
1653  out3 << "Averaged coefficients: \n";
1654  out3 << "Planck function: " << rte_planck_value << "\n";
1655  out3 << "Scattering vector: " << sca_vec_av << "\n";
1656  out3 << "Absorption vector: " << abs_vec(0,joker) << "\n";
1657  out3 << "Extinction matrix: " << ext_mat(0,joker,joker) << "\n";
1658 
1659 
1660  assert (!is_singular( ext_mat(0,joker,joker)));
1661 
1662  // Radiative transfer step calculation. The Stokes vector
1663  // is updated until the considered point is reached.
1664  rte_step_std(stokes_vec, Matrix(stokes_dim,stokes_dim),
1665  ext_mat(0,joker,joker), abs_vec(0,joker),
1666  sca_vec_av, l_step, rte_planck_value);
1667 
1668  // Assign calculated Stokes Vector to doit_i_field.
1669  doit_i_field(p_index - cloudbox_limits[0],
1670  0, 0,
1671  scat_za_index, 0,
1672  joker) = stokes_vec;
1673  }
1674 
1675 
1676  }// if loop end - for non_ground background
1677 
1678  // bkgr=2 indicates that the background is the surface
1679  else if (bkgr == 2)
1680  {
1681  //Set rte_pos, rte_gp_p and rte_los to match the last point
1682  //in ppath.
1683  //pos
1684  Vector rte_pos( atmosphere_dim );
1685  Numeric z_field_0 = z_field(0, 0, 0);
1686  rte_pos = z_field_0 + r_geoid(0,0);//ppath_step.pos(np-1,Range(0,atmosphere_dim));
1687  //los
1688  Vector rte_los(1);
1689  rte_los = scat_za_grid[scat_za_index];//ppath_step.los(np-1,joker);
1690  //gp_p
1691  //GridPos rte_gp_p;
1692  //rte_gp_p.idx = p_index;
1693  //rte_gp_p.fd[0] = 0;
1694  //rte_gp_p.fd[1] = 1;
1695  //gridpos_copy( rte_gp_p, ppath_step.gp_p[np-1] );
1696  // Executes the surface agenda
1697  // FIXME: Convert to new agenda scheme before using
1698  // surface_prop_agenda.execute();
1699 
1700  throw runtime_error(
1701  "Surface reflections inside cloud box not yet handled." );
1702  /*
1703  See comment in function above
1704  // Check returned variables
1705  if( surface_emission.nrows() != f_grid.nelem() ||
1706  surface_emission.ncols() != stokes_dim )
1707  throw runtime_error(
1708  "The size of the created *surface_emission* is not correct.");
1709 
1710  Index nlos = surface_los.nrows();
1711 
1712  // Define a local vector doit_i_field_sum which adds the
1713  // products of groudnd_refl_coeffs with the downwelling
1714  // radiation for each elements of surface_los
1715  Vector doit_i_field_sum(stokes_dim,0);
1716  // Loop over the surface_los elements
1717  for( Index ilos=0; ilos < nlos; ilos++ )
1718  {
1719  if( stokes_dim == 1 )
1720  {
1721  doit_i_field_sum[0] += surface_refl_coeffs(ilos,f_index,0,0) *
1722  doit_i_field(cloudbox_limits[0],
1723  0, 0,
1724  (scat_za_grid.nelem() -1 - scat_za_index), 0,
1725  0);
1726  }
1727  else
1728  {
1729  Vector stokes_vec2(stokes_dim);
1730  mult( stokes_vec2,
1731  surface_refl_coeffs(ilos,0,joker,joker),
1732  doit_i_field(cloudbox_limits[0],
1733  0, 0,
1734  (scat_za_grid.nelem() -1 - scat_za_index), 0,
1735  joker));
1736  for( Index is=0; is < stokes_dim; is++ )
1737  {
1738  doit_i_field_sum[is] += stokes_vec2[is];
1739  }
1740 
1741  }
1742  }
1743  // Copy from *doit_i_field_sum* to *doit_i_field*, and add the surface emission
1744  for( Index is=0; is < stokes_dim; is++ )
1745  {
1746  doit_i_field (cloudbox_limits[0],
1747  0, 0,
1748  scat_za_index, 0,
1749  is) = doit_i_field_sum[is] + surface_emission(f_index,is);
1750  }
1751 
1752  //cout<<"scat_za_grid"<<scat_za_grid[scat_za_index]<<endl;
1753  //cout<<"p_index"<<p_index<<endl;
1754  //cout<<"cloudboxlimit[0]"<<cloudbox_limits[0]<<endl;
1755  // now the RT is done to the next point in the path.
1756  //
1757  Vector stokes_vec_local;
1758  stokes_vec_local = doit_i_field (0,
1759  0, 0,
1760  scat_za_index, 0,
1761  joker);
1762 
1763  Numeric z_field_above = z_field(p_index +1, 0, 0);
1764  //Numeric z_field_0 = z_field(p_index, 0, 0);
1765  Numeric cos_theta;
1766  if (scat_za_grid[scat_za_index] == 90.0)
1767  {
1768  //cos_theta = cos((scat_za_grid[scat_za_index] -1)*PI/180.);
1769  cos_theta = cos(90.00000001*PI/180.);
1770  }
1771  else
1772  {
1773  cos_theta = cos(scat_za_grid[scat_za_index]* PI/180.0);
1774  }
1775  Numeric dz = (z_field_above - z_field_0);
1776 
1777  Numeric l_step = abs(dz/cos_theta) ;
1778 
1779  // Average temperature
1780  Numeric rte_temperature = 0.5 * (t_field(p_index,0,0)
1781  + t_field(p_index + 1,0,0));
1782 
1783  //
1784  // Average pressure
1785  Numeric rte_pressure = 0.5 * (p_grid[p_index]
1786  + p_grid[p_index + 1]);
1787 
1788  //
1789  const Index N_species = vmr_field.nbooks();
1790  // Average vmrs
1791  for (Index k = 0; k < N_species; k++)
1792  {
1793  rte_vmr_list[k] = 0.5 * (vmr_field(k,p_index,0,0) +
1794  vmr_field(k,p_index + 1,0,0));
1795  }
1796  //
1797  // Calculate scalar gas absorption and add it to abs_vec
1798  // and ext_mat.
1799  //
1800 
1801  // FIXME: Convert to new agenda scheme before using
1802  //abs_scalar_gas_agenda.execute(p_index);
1803 
1804  opt_prop_gas_agendaExecute(ext_mat, abs_vec, abs_scalar_gas,
1805  opt_prop_gas_agenda);
1806 
1807  //
1808  // Add average particle extinction to ext_mat.
1809  //
1810  //cout<<"Reached Here ????????????????????????????????????????????????";
1811  for (Index k = 0; k < stokes_dim; k++)
1812  {
1813  for (Index j = 0; j < stokes_dim; j++)
1814  {
1815  ext_mat(0,k,j) += 0.5 *
1816  (ext_mat_field(p_index - cloudbox_limits[0],0,0,k,j) +
1817  ext_mat_field(p_index - cloudbox_limits[0]+ 1,0,0,k,j));
1818  }
1819 
1820 
1821  //
1822  //
1823  // Add average particle absorption to abs_vec.
1824  //
1825  abs_vec(0,k) += 0.5 *
1826  (abs_vec_field(p_index - cloudbox_limits[0],0,0,k) +
1827  abs_vec_field(p_index - cloudbox_limits[0]+1,0,0,k));
1828  //
1829  // Averaging of sca_vec:
1830  //
1831  sca_vec_av[k] = 0.5*( doit_scat_field(p_index- cloudbox_limits[0],
1832  0, 0, scat_za_index, 0, k)
1833  + doit_scat_field(p_index- cloudbox_limits[0]+1,
1834  0, 0, scat_za_index, 0, k)) ;
1835 
1836  }
1837  // Frequency
1838  Numeric f = f_grid[f_index];
1839  //
1840  // Calculate Planck function
1841  //
1842  Numeric rte_planck_value = planck(f, rte_temperature);
1843 
1844  assert (!is_singular( ext_mat(0,joker,joker)));
1845 
1846  // Radiative transfer step calculation. The Stokes vector
1847  // is updated until the considered point is reached.
1848  rte_step_std(stokes_vec_local, ext_mat(0,joker,joker),
1849  abs_vec(0,joker),
1850  sca_vec_av, l_step, rte_planck_value);
1851  // Assign calculated Stokes Vector to doit_i_field.
1852  doit_i_field(p_index - cloudbox_limits[0],
1853  0, 0,
1854  scat_za_index, 0,
1855  joker) = stokes_vec_local;
1856  */
1857  }//end else loop over surface
1858 }
1859 
1860 
1861 
1862 
1886 void za_gridOpt(//Output:
1887  Vector& za_grid_opt,
1888  Matrix& doit_i_field_opt,
1889  // Input
1890  ConstVectorView za_grid_fine,
1891  ConstTensor6View doit_i_field,
1892  const Numeric& acc,
1893  const Index& scat_za_interp)
1894 {
1895  Index N_za = za_grid_fine.nelem();
1896 
1897  assert(doit_i_field.npages() == N_za);
1898 
1899  Index N_p = doit_i_field.nvitrines();
1900 
1901  Vector i_approx_interp(N_za);
1902  Vector za_reduced(2);
1903 
1904  ArrayOfIndex idx;
1905  idx.push_back(0);
1906  idx.push_back(N_za-1);
1907  ArrayOfIndex idx_unsorted;
1908 
1909  Numeric max_diff = 100;
1910 
1911  ArrayOfGridPos gp_za(N_za);
1912  Matrix itw(za_grid_fine.nelem(), 2);
1913 
1914  ArrayOfIndex i_sort;
1915  Vector diff_vec(N_za);
1916  Vector max_diff_za(N_p);
1917  ArrayOfIndex ind_za(N_p);
1918  Numeric max_diff_p;
1919  Index ind_p=0;
1920 
1921  while( max_diff > acc )
1922  {
1923  za_reduced.resize(idx.nelem());
1924  doit_i_field_opt.resize(N_p, idx.nelem());
1925  max_diff_za = 0.;
1926  max_diff_p = 0.;
1927 
1928  // Interpolate reduced internsity field on fine za_grid for
1929  // all pressure levels
1930  for( Index i_p = 0; i_p < N_p; i_p++ )
1931  {
1932  for( Index i_za_red = 0; i_za_red < idx.nelem(); i_za_red ++)
1933  {
1934  za_reduced[i_za_red] = za_grid_fine[idx[i_za_red]];
1935  doit_i_field_opt(i_p, i_za_red) = doit_i_field(i_p, 0, 0, idx[i_za_red],
1936  0, 0);
1937  }
1938  // Calculate grid positions
1939  gridpos(gp_za, za_reduced, za_grid_fine);
1940  //linear interpolation
1941  if(scat_za_interp == 0 || idx.nelem() < 3)
1942  {
1943  interpweights(itw, gp_za);
1944  interp(i_approx_interp, itw, doit_i_field_opt(i_p, joker), gp_za);
1945  }
1946  else if(scat_za_interp == 1)
1947  {
1948  for(Index i_za = 0; i_za < N_za; i_za ++)
1949  {
1950  i_approx_interp[i_za] =
1951  interp_poly(za_reduced, doit_i_field_opt(i_p, joker),
1952  za_grid_fine[i_za],
1953  gp_za[i_za]);
1954  }
1955  }
1956  else
1957  // Interpolation method not defined
1958  assert(false);
1959 
1960  // Calculate differences between approximated i-vector and
1961  // exact i_vector for the i_p pressure level
1962  for (Index i_za = 0; i_za < N_za; i_za ++)
1963  {
1964  diff_vec[i_za] = abs( doit_i_field(i_p, 0, 0, i_za, 0 ,0)
1965  - i_approx_interp[i_za]);
1966  if( diff_vec[i_za] > max_diff_za[i_p] )
1967  {
1968  max_diff_za[i_p] = diff_vec[i_za];
1969  ind_za[i_p] = i_za;
1970  }
1971  }
1972  // Take maximum value of max_diff_za
1973  if( max_diff_za[i_p] > max_diff_p )
1974  {
1975  max_diff_p = max_diff_za[i_p];
1976  ind_p = i_p;
1977  }
1978  }
1979 
1980 
1981  //Transform in %
1982  max_diff = max_diff_p/doit_i_field(ind_p, 0, 0, ind_za[ind_p], 0, 0)*100.;
1983 
1984  idx.push_back(ind_za[ind_p]);
1985  idx_unsorted = idx;
1986 
1987  i_sort.resize(idx_unsorted.nelem());
1988  get_sorted_indexes(i_sort, idx_unsorted);
1989 
1990  for (Index i = 0; i<idx_unsorted.nelem(); i++)
1991  idx[i] = idx_unsorted[i_sort[i]];
1992 
1993  za_reduced.resize(idx.nelem());
1994  }
1995 
1996  za_grid_opt.resize(idx.nelem());
1997  doit_i_field_opt.resize(N_p, idx.nelem());
1998  for(Index i = 0; i<idx.nelem(); i++)
1999  {
2000  za_grid_opt[i] = za_grid_fine[idx[i]];
2001  doit_i_field_opt(joker, i) = doit_i_field(joker, 0, 0, idx[i], 0, 0);
2002  }
2003 }
2004 
2005 
2007 /*
2008  See WSM *iyInterpCloudboxField*.
2009 
2010  \param iy Out: As the WSV with same name.
2011  \param scat_i_p In: As the WSV with same name.
2012  \param scat_i_lat In: As the WSV with same name.
2013  \param scat_i_lon In: As the WSV with same name.
2014  \param doit_i_field1D_spectrum In: As the WSV with same name.
2015  \param rte_gp_p In: As the WSV with same name.
2016  \param rte_gp_lat In: As the WSV with same name.
2017  \param rte_gp_lon In: As the WSV with same name.
2018  \param rte_los In: As the WSV with same name.
2019  \param cloudbox_on In: As the WSV with same name.
2020  \param cloudbox_limits In: As the WSV with same name.
2021  \param atmosphere_dim In: As the WSV with same name.
2022  \param stokes_dim In: As the WSV with same name.
2023  \param scat_za_grid In: As the WSV with same name.
2024  \param scat_aa_grid In: As the WSV with same name.
2025  \param f_grid In: As the WSV with same name.
2026  \param p_grid In: As the WSV with same name.
2027  \param interpmeth Interpolation method. Can be "linear" or
2028  "polynomial".
2029 
2030  \author Claudia Emde and Patrick Eriksson
2031  \date 2004-09-29
2032 */
2034  const Tensor7& scat_i_p,
2035  const Tensor7& scat_i_lat,
2036  const Tensor7& scat_i_lon,
2037  const Tensor4& doit_i_field1D_spectrum,
2038  const GridPos& rte_gp_p,
2039  const GridPos& rte_gp_lat,
2040  const GridPos& rte_gp_lon,
2041  const Vector& rte_los,
2042  const Index& cloudbox_on,
2043  const ArrayOfIndex& cloudbox_limits,
2044  const Index& atmosphere_dim,
2045  const Index& stokes_dim,
2046  const Vector& scat_za_grid,
2047  const Vector& scat_aa_grid,
2048  const Vector& f_grid,
2049  const String& interpmeth,
2050  const Verbosity& verbosity)
2051 {
2052  CREATE_OUT3
2053 
2054  //--- Check input -----------------------------------------------------------
2055  if( !(atmosphere_dim == 1 || atmosphere_dim == 3) )
2056  throw runtime_error( "The atmospheric dimensionality must be 1 or 3.");
2057  if( !cloudbox_on )
2058  throw runtime_error( "The cloud box is not activated and no outgoing "
2059  "field can be returned." );
2060  if ( cloudbox_limits.nelem() != 2*atmosphere_dim )
2061  throw runtime_error(
2062  "*cloudbox_limits* is a vector which contains the upper and lower\n"
2063  "limit of the cloud for all atmospheric dimensions.\n"
2064  "So its length must be 2 x *atmosphere_dim*" );
2065  if( scat_za_grid.nelem() == 0 )
2066  throw runtime_error( "The variable *scat_za_grid* is empty. Are dummy "
2067  "values from *cloudboxOff used?" );
2068  if( !( interpmeth == "linear" || interpmeth == "polynomial" ) )
2069  throw runtime_error( "Unknown interpolation method. Possible choices are "
2070  "\"linear\" and \"polynomial\"." );
2071  if( interpmeth == "polynomial" && atmosphere_dim != 1 )
2072  throw runtime_error( "Polynomial interpolation method is only available"
2073  "for *atmosphere_dim* = 1." );
2074  // Size of scat_i_p etc is checked below
2075  //---------------------------------------------------------------------------
2076 
2077 
2078  //--- Determine if at border or inside of cloudbox (or outside!)
2079  //
2080  // Let us introduce a number coding for cloud box borders.
2081  // Borders have the same number as position in *cloudbox_limits*.
2082  // Innside cloud box is coded as 99, and outside as > 100.
2083  Index border = 999;
2084  //
2085  //- Check if at any border
2086  if( is_gridpos_at_index_i( rte_gp_p, cloudbox_limits[0] ) )
2087  { border = 0; }
2088  else if( is_gridpos_at_index_i( rte_gp_p, cloudbox_limits[1] ) )
2089  { border = 1; }
2090  if( atmosphere_dim == 3 && border > 100 )
2091  {
2092  if( is_gridpos_at_index_i( rte_gp_lat, cloudbox_limits[2] ) )
2093  { border = 2; }
2094  else if( is_gridpos_at_index_i( rte_gp_lat, cloudbox_limits[3] ) )
2095  { border = 3; }
2096  else if( is_gridpos_at_index_i( rte_gp_lon, cloudbox_limits[4] ) )
2097  { border = 4; }
2098  else if( is_gridpos_at_index_i( rte_gp_lon, cloudbox_limits[5] ) )
2099  { border = 5; }
2100  }
2101 
2102  //
2103  //- Check if inside
2104  if( border > 100 )
2105  {
2106  // Assume inside as it is easiest to detect if outside (can be detected
2107  // check in one dimension at the time)
2108  bool inside = true;
2109  Numeric fgp;
2110 
2111  // Check in pressure dimension
2112  fgp = fractional_gp( rte_gp_p );
2113  if( fgp < Numeric(cloudbox_limits[0]) ||
2114  fgp > Numeric(cloudbox_limits[1]) )
2115  { inside = false; }
2116 
2117  // Check in lat and lon dimensions
2118  if( atmosphere_dim == 3 && inside )
2119  {
2120  fgp = fractional_gp( rte_gp_lat );
2121  if( fgp < Numeric(cloudbox_limits[2]) ||
2122  fgp > Numeric(cloudbox_limits[3]) )
2123  { inside = false; }
2124  fgp = fractional_gp( rte_gp_lon );
2125  if( fgp < Numeric(cloudbox_limits[4]) ||
2126  fgp > Numeric(cloudbox_limits[5]) )
2127  { inside = false; }
2128  }
2129 
2130  if( inside )
2131  { border = 99; }
2132  }
2133 
2134  // If outside, something is wrong
2135  if( border > 100 )
2136  {
2137 
2138  throw runtime_error(
2139  "Given position has been found to be outside the cloudbox." );
2140  }
2141 
2142  //- Sizes
2143  const Index nf = f_grid.nelem();
2144  DEBUG_ONLY (const Index np = cloudbox_limits[1] - cloudbox_limits[0] + 1);
2145  const Index nza = scat_za_grid.nelem();
2146 
2147  //- Resize *iy*
2148  iy.resize( nf, stokes_dim );
2149 
2150 
2151  // Sensor points inside the cloudbox
2152  if( border == 99 )
2153  {
2154  if (atmosphere_dim == 3)
2155  {
2156  throw runtime_error(
2157  "3D DOIT calculations are not implemented\n"
2158  "for observations from inside the cloudbox.\n"
2159  );
2160  }
2161  else
2162  {
2163  assert(atmosphere_dim == 1);
2164 
2165  // *doit_i_field1D_spectra* is normally calculated internally:
2166  assert( is_size(doit_i_field1D_spectrum, nf, np, nza, stokes_dim) );
2167 
2168  out3 << " Interpolating outgoing field:\n";
2169  out3 << " zenith_angle: " << rte_los[0] << "\n";
2170  out3 << " Sensor inside cloudbox at position: " <<
2171  rte_gp_p << "\n";
2172 
2173  // Grid position in *scat_za_grid*
2174  GridPos gp_za;
2175  gridpos( gp_za, scat_za_grid, rte_los[0] );
2176 
2177  // Corresponding interpolation weights
2178  Vector itw_za(2);
2179  interpweights( itw_za, gp_za );
2180 
2181  // Grid position in *p_grid* (only cloudbox part because
2182  // doit_i_field1D_spectra is only defined inside the cloudbox
2183  GridPos gp_p;
2184  gp_p = rte_gp_p;
2185  gp_p.idx = rte_gp_p.idx - cloudbox_limits[0];
2186  gridpos_upperend_check( gp_p, cloudbox_limits[1] -
2187  cloudbox_limits[0] );
2188 
2189  cout << gp_p << endl;
2190 
2191  Vector itw_p(2);
2192  interpweights( itw_p, gp_p );
2193 
2194  Vector iy_p(nza);
2195 
2196  if( interpmeth == "linear" )
2197  {
2198  for(Index is = 0; is < stokes_dim; is++ )
2199  {
2200  for(Index iv = 0; iv < nf; iv++ )
2201  {
2202  for (Index i_za = 0; i_za < nza; i_za++)
2203  {
2204  iy_p[i_za] = interp
2205  (itw_p, doit_i_field1D_spectrum(iv, joker, i_za, is),
2206  gp_p);
2207  }
2208  iy(iv,is) = interp( itw_za, iy_p, gp_za);
2209  }
2210  }
2211  }
2212  else
2213  {
2214  for(Index is = 0; is < stokes_dim; is++ )
2215  {
2216  for(Index iv = 0; iv < nf; iv++ )
2217  {
2218  for (Index i_za = 0; i_za < nza; i_za++)
2219  {
2220  iy_p[i_za] = interp
2221  (itw_p, doit_i_field1D_spectrum(iv, joker, i_za, is),
2222  gp_p);
2223  }
2224  iy(iv,is) = interp_poly( scat_za_grid, iy_p, rte_los[0],
2225  gp_za );
2226  }
2227  }
2228  }
2229 
2230  }
2231 
2232  }
2233 
2234  // Sensor outside the cloudbox
2235 
2236  // --- 1D ------------------------------------------------------------------
2237  else if( atmosphere_dim == 1 )
2238  {
2239  // Use assert to check *scat_i_p* as this variable should to 99% be
2240  // calculated internally, and thus make it possible to avoid this check.
2241  assert( is_size( scat_i_p, nf,2,1,1,scat_za_grid.nelem(),1,stokes_dim ));
2242 
2243  out3 << " Interpolating outgoing field:\n";
2244  out3 << " zenith_angle: " << rte_los[0] << "\n";
2245  if( border )
2246  out3 << " top side\n";
2247  else
2248  out3 << " bottom side\n";
2249 
2250  // Grid position in *scat_za_grid*
2251  GridPos gp;
2252  gridpos( gp, scat_za_grid, rte_los[0] );
2253 
2254  // Corresponding interpolation weights
2255  Vector itw(2);
2256  interpweights( itw, gp );
2257 
2258  if( interpmeth == "linear" )
2259  {
2260  for(Index is = 0; is < stokes_dim; is++ )
2261  {
2262  for(Index iv = 0; iv < nf; iv++ )
2263  {
2264 
2265  iy(iv,is) = interp( itw,
2266  scat_i_p( iv, border, 0, 0, joker, 0, is ),
2267  gp );
2268  }
2269  }
2270  }
2271  else
2272  {
2273  for(Index is = 0; is < stokes_dim; is++ )
2274  {
2275  for(Index iv = 0; iv < nf; iv++ )
2276  {
2277  iy(iv,is) = interp_poly( scat_za_grid,
2278  scat_i_p( iv, border, 0, 0, joker, 0, is ) , rte_los[0],
2279  gp );
2280  }
2281  }
2282  }
2283  }
2284 
2285  // --- 3D ------------------------------------------------------------------
2286  else
2287  {
2288  // Use asserts to check *scat_i_XXX* as these variables should to 99% be
2289  // calculated internally, and thus make it possible to avoid this check.
2290  assert ( is_size( scat_i_p, nf, 2, scat_i_p.nshelves(),
2291  scat_i_p.nbooks(), scat_za_grid.nelem(),
2292  scat_aa_grid.nelem(), stokes_dim ));
2293 
2294  assert ( is_size( scat_i_lat, nf, scat_i_lat.nvitrines(), 2,
2295  scat_i_p.nbooks(), scat_za_grid.nelem(),
2296  scat_aa_grid.nelem(), stokes_dim ));
2297  assert ( is_size( scat_i_lon, nf, scat_i_lat.nvitrines(),
2298  scat_i_p.nshelves(), 2, scat_za_grid.nelem(),
2299  scat_aa_grid.nelem(), stokes_dim ));
2300 
2301  out3 << " Interpolating outgoing field:\n";
2302  out3 << " zenith angle : " << rte_los[0] << "\n";
2303  out3 << " azimuth angle: " << rte_los[1]+180. << "\n";
2304 
2305 
2306  // Scattering angle grid positions
2307  GridPos gp_za, gp_aa;
2308  gridpos( gp_za, scat_za_grid, rte_los[0] );
2309  gridpos( gp_aa, scat_aa_grid, rte_los[1]+180. );
2310 
2311  // Interpolation weights (for 4D "red" interpolation)
2312  Vector itw(16);
2313 
2314  // Outgoing from pressure level
2315  if( border <= 1 )
2316  {
2317  // Lat and lon grid positions with respect to cloud box
2318  GridPos cb_gp_lat, cb_gp_lon;
2319  cb_gp_lat = rte_gp_lat;
2320  cb_gp_lon = rte_gp_lon;
2321  cb_gp_lat.idx -= cloudbox_limits[2];
2322  cb_gp_lon.idx -= cloudbox_limits[4];
2323  //
2324  gridpos_upperend_check( cb_gp_lat, cloudbox_limits[3] -
2325  cloudbox_limits[2] );
2326  gridpos_upperend_check( cb_gp_lon, cloudbox_limits[5] -
2327  cloudbox_limits[4] );
2328 
2329  interpweights( itw, cb_gp_lat, cb_gp_lon, gp_za, gp_aa );
2330 
2331  for(Index is = 0; is < stokes_dim; is++ )
2332  {
2333  for(Index iv = 0; iv < nf; iv++ )
2334  {
2335  iy(iv,is) = interp( itw,
2336  scat_i_p( iv, border, joker, joker, joker, joker, is ),
2337  cb_gp_lat, cb_gp_lon, gp_za, gp_aa );
2338  }
2339  }
2340  }
2341 
2342  // Outgoing from latitude level
2343  else if( border <= 3 )
2344  {
2345  // Pressure and lon grid positions with respect to cloud box
2346  GridPos cb_gp_p, cb_gp_lon;
2347  cb_gp_p = rte_gp_p;
2348  cb_gp_lon = rte_gp_lon;
2349  cb_gp_p.idx -= cloudbox_limits[0];
2350  cb_gp_lon.idx -= cloudbox_limits[4];
2351  //
2352  gridpos_upperend_check( cb_gp_p, cloudbox_limits[1] -
2353  cloudbox_limits[0] );
2354  gridpos_upperend_check( cb_gp_lon, cloudbox_limits[5] -
2355  cloudbox_limits[4] );
2356 
2357  interpweights( itw, cb_gp_p, cb_gp_lon, gp_za, gp_aa );
2358 
2359  for(Index is = 0; is < stokes_dim; is++ )
2360  {
2361  for(Index iv = 0; iv < nf; iv++ )
2362  {
2363  iy(iv,is) = interp( itw,
2364  scat_i_lat( iv, joker, border-2, joker, joker, joker, is ),
2365  cb_gp_p, cb_gp_lon, gp_za, gp_aa );
2366  }
2367  }
2368  }
2369 
2370  // Outgoing from longitude level
2371  else
2372  {
2373  // Pressure and lat grid positions with respect to cloud box
2374  GridPos cb_gp_p, cb_gp_lat;
2375  cb_gp_p = rte_gp_p;
2376  cb_gp_lat = rte_gp_lat;
2377  cb_gp_p.idx -= cloudbox_limits[0];
2378  cb_gp_lat.idx -= cloudbox_limits[2];
2379  //
2380  gridpos_upperend_check( cb_gp_p, cloudbox_limits[1] -
2381  cloudbox_limits[0] );
2382  gridpos_upperend_check( cb_gp_lat, cloudbox_limits[3] -
2383  cloudbox_limits[2] );
2384 
2385  interpweights( itw, cb_gp_p, cb_gp_lat, gp_za, gp_aa );
2386 
2387  for(Index is = 0; is < stokes_dim; is++ )
2388  {
2389  for(Index iv = 0; iv < nf; iv++ )
2390  {
2391  iy(iv,is) = interp( itw,
2392  scat_i_lon( iv, joker, joker, border-4, joker, joker, is ),
2393  cb_gp_p, cb_gp_lat, gp_za, gp_aa );
2394  }
2395  }
2396  }
2397  }
2398 }
2399 
2400 
2401 
2402 
2403 
2404 
Matrix
The Matrix class.
Definition: matpackI.h:767
iy_interp_cloudbox_field
void iy_interp_cloudbox_field(Matrix &iy, const Tensor7 &scat_i_p, const Tensor7 &scat_i_lat, const Tensor7 &scat_i_lon, const Tensor4 &doit_i_field1D_spectrum, const GridPos &rte_gp_p, const GridPos &rte_gp_lat, const GridPos &rte_gp_lon, const Vector &rte_los, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &scat_za_grid, const Vector &scat_aa_grid, const Vector &f_grid, const String &interpmeth, const Verbosity &verbosity)
Interpolation of cloud box intensity field.
Definition: doit.cc:2033
ConstTensor7View::nshelves
Index nshelves() const
Returns the number of shelves.
Definition: matpackVII.cc:43
ppath_init_structure
void ppath_init_structure(Ppath &ppath, const Index &atmosphere_dim, const Index &np)
ppath_init_structure
Definition: ppath.cc:2461
MatrixView
The MatrixView class.
Definition: matpackI.h:668
ppath_step_agendaExecute
void ppath_step_agendaExecute(Workspace &ws, Ppath &ppath_step, const Index atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &r_geoid, const Matrix &z_surface, const Agenda &input_agenda)
Definition: auto_md.cc:10292
auto_md.h
RAD2DEG
const Numeric RAD2DEG
interp_poly
Numeric interp_poly(ConstVectorView x, ConstVectorView y, const Numeric &x_i, const GridPos &gp)
Polynomial interpolation.
Definition: interpolation.cc:2909
rte_step_std
void rte_step_std(VectorView stokes_vec, MatrixView trans_mat, ConstMatrixView ext_mat_av, ConstVectorView abs_vec_av, ConstVectorView sca_vec_av, const Numeric &l_step, const Numeric &rte_planck_value)
rte_step_std
Definition: rte.cc:1092
gridpos
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
Definition: interpolation.cc:167
is_gridpos_at_index_i
bool is_gridpos_at_index_i(const GridPos &gp, const Index &i)
is_gridpos_at_index_i
Definition: interpolation.cc:665
cloud_ppath_update1D
void cloud_ppath_update1D(Workspace &ws, Tensor6View doit_i_field, const Index &p_index, const Index &scat_za_index, ConstVectorView scat_za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &abs_scalar_gas_agenda, ConstTensor4View vmr_field, const Agenda &opt_prop_gas_agenda, const Agenda &ppath_step_agenda, ConstVectorView p_grid, ConstTensor3View z_field, ConstMatrixView r_geoid, ConstMatrixView z_surface, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Agenda &surface_prop_agenda, const Index &scat_za_interp, const Verbosity &verbosity)
cloud_ppath_update1D
Definition: doit.cc:247
abs_scalar_gas_agendaExecute
void abs_scalar_gas_agendaExecute(Workspace &ws, Matrix &abs_scalar_gas, const Index f_index, const Numeric rte_doppler, const Numeric rte_pressure, const Numeric rte_temperature, const Vector &rte_vmr_list, const Agenda &input_agenda)
Definition: auto_md.cc:9032
ppath_step_in_cloudbox
void ppath_step_in_cloudbox(Workspace &ws, Ppath &ppath_step, const Agenda &ppath_step_agenda, const Index &p, const Index &lat, const Index &lon, ConstTensor3View z_field, ConstMatrixView r_geoid, ConstMatrixView z_surface, ConstVectorView scat_za_grid, ConstVectorView aa_grid, const Index &scat_za_index, const Index &scat_aa_index, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid)
Definition: doit.cc:1119
Tensor3
The Tensor3 class.
Definition: matpackIII.h:340
itw2p
void itw2p(VectorView p_values, ConstVectorView p_grid, const ArrayOfGridPos &gp, ConstMatrixView itw)
itw2p
Definition: special_interp.cc:763
ConstTensor5View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackV.cc:56
ConstTensor6View::npages
Index npages() const
Returns the number of pages.
Definition: matpackVI.cc:49
za_gridOpt
void za_gridOpt(Vector &za_grid_opt, Matrix &doit_i_field_opt, ConstVectorView za_grid_fine, ConstTensor6View doit_i_field, const Numeric &acc, const Index &scat_za_interp)
Definition: doit.cc:1886
joker
const Joker joker
interp
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
Definition: interpolation.cc:1000
cloud_RT_no_background
void cloud_RT_no_background(Workspace &ws, Tensor6View doit_i_field, const Agenda &abs_scalar_gas_agenda, const Agenda &opt_prop_gas_agenda, const Ppath &ppath_step, ConstVectorView t_int, ConstMatrixView vmr_list_int, ConstTensor3View ext_mat_int, ConstMatrixView abs_vec_int, ConstMatrixView sca_vec_int, ConstMatrixView doit_i_field_int, ConstVectorView p_int, const ArrayOfIndex &cloudbox_limits, ConstVectorView f_grid, const Index &f_index, const Index &p_index, const Index &lat_index, const Index &lon_index, const Index &scat_za_index, const Index &scat_aa_index, const Verbosity &verbosity)
cloud_RT_no_background
Definition: doit.cc:863
opt_prop_gas_agendaExecute
void opt_prop_gas_agendaExecute(Workspace &ws, Tensor3 &ext_mat, Matrix &abs_vec, const Index f_index, const Matrix &abs_scalar_gas, const Agenda &input_agenda)
Definition: auto_md.cc:10073
chk_not_empty
void chk_not_empty(const String &x_name, const Agenda &x)
chk_not_empty
Definition: check_input.cc:880
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:771
is_singular
bool is_singular(ConstMatrixView A)
Checks if a square matrix is singular.
Definition: logic.cc:353
doit.h
Radiative transfer in cloudbox.
fractional_gp
Numeric fractional_gp(const GridPos &gp)
fractional_gp
Definition: interpolation.cc:504
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
surface_prop_agendaExecute
void surface_prop_agendaExecute(Workspace &ws, Matrix &surface_emission, Matrix &surface_los, Tensor4 &surface_rmatrix, const Vector &rte_pos, const Vector &rte_los, const GridPos &rte_gp_p, const GridPos &rte_gp_lat, const GridPos &rte_gp_lon, const Agenda &input_agenda)
Definition: auto_md.cc:10590
cloud_fieldsCalc
void cloud_fieldsCalc(Workspace &ws, Tensor5View ext_mat_field, Tensor4View abs_vec_field, const Agenda &spt_calc_agenda, const Agenda &opt_prop_part_agenda, const Index &scat_za_index, const Index &scat_aa_index, const ArrayOfIndex &cloudbox_limits, ConstTensor3View t_field, ConstTensor4View pnd_field, const Verbosity &verbosity)
cloud_fieldsCalc
Definition: doit.cc:86
cloud_RT_surface
void cloud_RT_surface(Workspace &ws, Tensor6View doit_i_field, const Agenda &surface_prop_agenda, const Index &f_index, const Index &stokes_dim, const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, ConstVectorView scat_za_grid, const Index &scat_za_index)
cloud_RT_surface
Definition: doit.cc:1016
Tensor4
The Tensor4 class.
Definition: matpackIV.h:375
array.h
This file contains the definition of Array.
is_size
bool is_size(ConstVectorView x, const Index &n)
Verifies that the size of x is l.
Definition: logic.cc:90
Ppath
The structure to describe a propagation path and releated quantities.
Definition: ppath.h:59
Ppath::gp_p
ArrayOfGridPos gp_p
Definition: ppath.h:66
Agenda
The Agenda class.
Definition: agenda_class.h:44
DEBUG_ONLY
#define DEBUG_ONLY(...)
Definition: arts.h:146
ConstTensor4View
A constant view of a Tensor4.
Definition: matpackIV.h:149
Tensor3View
The Tensor3View class.
Definition: matpackIII.h:234
Array< Index >
get_sorted_indexes
void get_sorted_indexes(ArrayOfIndex &sorted, const T &data)
get_sorted_indexes
Definition: sorting.h:79
ConstTensor6View::nvitrines
Index nvitrines() const
Returns the number of vitrines.
Definition: matpackVI.cc:31
agenda_class.h
Declarations for agendas.
mult
void mult(VectorView y, const ConstMatrixView &M, const ConstVectorView &x)
Matrix Vector multiplication.
Definition: matpackI.cc:1607
CREATE_OUT3
#define CREATE_OUT3
Definition: messages.h:208
Ppath::gp_lat
ArrayOfGridPos gp_lat
Definition: ppath.h:67
messages.h
Declarations having to do with the four output streams.
gridpos_upperend_check
void gridpos_upperend_check(GridPos &gp, const Index &ie)
gridpos_upperend_check
Definition: interpolation.cc:608
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
_U_
#define _U_
Definition: config.h:158
my_basic_string
The implementation for String, the ARTS string class.
Definition: mystring.h:62
abs
#define abs(x)
Definition: continua.cc:13094
Ppath::los
Matrix los
Definition: ppath.h:69
Ppath::gp_lon
ArrayOfGridPos gp_lon
Definition: ppath.h:68
Ppath::np
Index np
Definition: ppath.h:61
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:175
VectorView
The VectorView class.
Definition: matpackI.h:373
is_inside_cloudbox
bool is_inside_cloudbox(const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, const bool include_boundaries)
Definition: cloudbox.cc:764
ConstTensor7View::nvitrines
Index nvitrines() const
Returns the number of vitrines.
Definition: matpackVII.cc:37
physics_funcs.h
Ppath::z
Vector z
Definition: ppath.h:64
ConstTensor4View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:78
ConstTensor6View
A constant view of a Tensor6.
Definition: matpackVI.h:167
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
lin_alg.h
Linear algebra functions.
Verbosity
Definition: messages.h:50
Tensor5View
The Tensor5View class.
Definition: matpackV.h:278
Ppath::l_step
Vector l_step
Definition: ppath.h:65
ConstTensor4View::nbooks
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:60
math_funcs.h
Matrix::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1549
cloud_ppath_update1D_planeparallel
void cloud_ppath_update1D_planeparallel(Workspace &ws, Tensor6View doit_i_field, const Index &p_index, const Index &scat_za_index, ConstVectorView scat_za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &abs_scalar_gas_agenda, ConstTensor4View vmr_field, const Agenda &opt_prop_gas_agenda, const Agenda &ppath_step_agenda, ConstVectorView p_grid, ConstTensor3View z_field, ConstMatrixView r_geoid, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Verbosity &verbosity)
Radiative transfer calculation inside cloudbox for planeparallel case.
Definition: doit.cc:1382
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:591
cloudbox.h
Internal cloudbox functions.
opt_prop_part_agendaExecute
void opt_prop_part_agendaExecute(Workspace &ws, Tensor3 &ext_mat, Matrix &abs_vec, const Tensor3 &ext_mat_spt, const Matrix &abs_vec_spt, const Index scat_p_index, const Index scat_lat_index, const Index scat_lon_index, const Agenda &input_agenda)
Definition: auto_md.cc:10140
planck
Numeric planck(const Numeric &f, const Numeric &t)
planck
Definition: physics_funcs.cc:219
interp_cloud_coeff1D
void interp_cloud_coeff1D(Tensor3View ext_mat_int, MatrixView abs_vec_int, MatrixView sca_vec_int, MatrixView doit_i_field_int, VectorView t_int, MatrixView vmr_list_int, VectorView p_int, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, ConstTensor6View doit_scat_field, ConstTensor6View doit_i_field, ConstTensor3View t_field, ConstTensor4View vmr_field, ConstVectorView p_grid, const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, ConstVectorView scat_za_grid, const Index &scat_za_interp, const Verbosity &verbosity)
interp_cloud_coeff1D
Definition: doit.cc:1187
GridPos
Structure to store a grid position.
Definition: interpolation.h:74
ConstTensor7View::nbooks
Index nbooks() const
Returns the number of books.
Definition: matpackVII.cc:49
ConstTensor5View::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackV.cc:50
ppath.h
Propagation path structure and functions.
logic.h
Header file for logic.cc.
cloud_ppath_update1D_noseq
void cloud_ppath_update1D_noseq(Workspace &ws, Tensor6View doit_i_field, const Index &p_index, const Index &scat_za_index, ConstVectorView scat_za_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_i_field_old, ConstTensor6View doit_scat_field, const Agenda &abs_scalar_gas_agenda, ConstTensor4View vmr_field, const Agenda &opt_prop_gas_agenda, const Agenda &ppath_step_agenda, ConstVectorView p_grid, ConstTensor3View z_field, ConstMatrixView r_geoid, ConstMatrixView z_surface, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Agenda &surface_prop_agenda, const Index &scat_za_interp, const Verbosity &verbosity)
cloud_ppath_update1D_noseq
Definition: doit.cc:392
rte.h
Declaration of functions in rte.cc.
Workspace
Workspace class.
Definition: workspace_ng.h:47
ConstTensor3View
A constant view of a Tensor3.
Definition: matpackIII.h:147
Tensor4View
The Tensor4View class.
Definition: matpackIV.h:245
special_interp.h
Header file for special_interp.cc.
spt_calc_agendaExecute
void spt_calc_agendaExecute(Workspace &ws, Tensor3 &ext_mat_spt, Matrix &abs_vec_spt, const Index scat_p_index, const Index scat_lat_index, const Index scat_lon_index, const Numeric rte_temperature, const Index scat_za_index, const Index scat_aa_index, const Agenda &input_agenda)
Definition: auto_md.cc:10511
GridPos::idx
Index idx
Definition: interpolation.h:75
PI
const Numeric PI
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
check_input.h
ppath_what_background
Index ppath_what_background(const Ppath &ppath)
ppath_what_background
Definition: ppath.cc:2561
Vector
The Vector class.
Definition: matpackI.h:555
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:300
Ppath::pos
Matrix pos
Definition: ppath.h:63
sorting.h
Contains sorting routines.
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
ConstTensor6View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackVI.cc:61
interpweights
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
Definition: interpolation.cc:756
ConstTensor5View
A constant view of a Tensor5.
Definition: matpackV.h:160
Tensor7
The Tensor7 class.
Definition: matpackVII.h:1912
matpackVII.h
Tensor6View
The Tensor6View class.
Definition: matpackVI.h:450
cloud_ppath_update3D
void cloud_ppath_update3D(Workspace &ws, Tensor6View doit_i_field, const Index &p_index, const Index &lat_index, const Index &lon_index, const Index &scat_za_index, const Index &scat_aa_index, ConstVectorView scat_za_grid, ConstVectorView scat_aa_grid, const ArrayOfIndex &cloudbox_limits, ConstTensor6View doit_scat_field, const Agenda &abs_scalar_gas_agenda, ConstTensor4View vmr_field, const Agenda &opt_prop_gas_agenda, const Agenda &ppath_step_agenda, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, ConstTensor3View z_field, ConstMatrixView r_geoid, ConstMatrixView z_surface, ConstTensor3View t_field, ConstVectorView f_grid, const Index &f_index, ConstTensor5View ext_mat_field, ConstTensor4View abs_vec_field, const Index &, const Verbosity &verbosity)
Radiative transfer calculation along a path inside the cloudbox (3D).
Definition: doit.cc:581
xml_io.h
This file contains basic functions to handle XML data files.