ARTS  2.3.1285(git:92a29ea9-dirty)
cloudbox.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2012 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 
27 #include "cloudbox.h"
28 
29 extern const Index GFIELD3_P_GRID;
30 extern const Index GFIELD3_LAT_GRID;
31 extern const Index GFIELD3_LON_GRID;
32 
33 /*===========================================================================
34  === External declarations
35  ===========================================================================*/
36 #include <algorithm>
37 #include <cmath>
38 #include <ctime>
39 #include <limits>
40 #include <stdexcept>
41 
42 #include "arts.h"
43 #include "check_input.h"
44 #include "lin_alg.h"
45 #include "logic.h"
46 #include "math_funcs.h"
47 #include "mc_antenna.h"
48 #include "messages.h"
49 #include "physics_funcs.h"
50 #include "ppath.h"
51 #include "rng.h"
52 #include "sorting.h"
53 
55 
67 void chk_pnd_data(const GriddedField3& pnd_field_raw,
68  const String& pnd_field_file,
69  const Index& atmosphere_dim,
70  const Verbosity& verbosity) {
72 
73  const Vector& pfr_lat_grid =
74  pnd_field_raw.get_numeric_grid(GFIELD3_LAT_GRID);
75  const Vector& pfr_lon_grid =
76  pnd_field_raw.get_numeric_grid(GFIELD3_LON_GRID);
77 
78  // The consistency of the dimensions is checked in the reading routine.
79  // Here we have to check whether the atmospheric dimension is correct and whether
80  // the particle number density is 0 on the cloudbox boundary and outside the cloudbox.
81 
82  out3 << "Check particle number density file " << pnd_field_file << "\n";
83 
84  if (atmosphere_dim == 1 &&
85  (pfr_lat_grid.nelem() != 1 || pfr_lon_grid.nelem() != 1)) {
86  ostringstream os;
87  os << "The atmospheric dimension is 1D but the particle "
88  << "number density file * " << pnd_field_file
89  << " is for a 3D atmosphere. \n";
90  throw runtime_error(os.str());
91  }
92 
93  else if (atmosphere_dim == 3) {
94  if (pfr_lat_grid.nelem() == 1 || pfr_lon_grid.nelem() == 1) {
95  ostringstream os;
96  os << "The atmospheric dimension is 3D but the particle "
97  << "number density file * " << pnd_field_file
98  << " is for a 1D or a 2D atmosphere. \n";
99  throw runtime_error(os.str());
100  }
101  }
102 
103  out3 << "Particle number density data is o.k. \n";
104 }
105 
107 
116 void chk_pnd_raw_data(const ArrayOfGriddedField3& pnd_field_raw,
117  const String& pnd_field_file,
118  const Index& atmosphere_dim,
119  const Verbosity& verbosity) {
120  CREATE_OUT3;
121 
122  for (Index i = 0; i < pnd_field_raw.nelem(); i++) {
123  out3 << "Element in pnd_field_raw_file:" << i << "\n";
124  chk_pnd_data(pnd_field_raw[i], pnd_field_file, atmosphere_dim, verbosity);
125  }
126 }
127 
129 
147  const Index& dim,
148  const ArrayOfGriddedField3& pnd_field_raw,
149  ConstVectorView p_grid,
150  ConstVectorView lat_grid,
151  ConstVectorView lon_grid,
152  const ArrayOfIndex& cloudbox_limits) {
153  Numeric p, lat, lon, v;
154  Index n, p_i, lat_i, lon_i;
155  // For any non-zero point, verify we're outside the cloudbox
156  for (n = 0; n < pnd_field_raw.nelem(); n++) {
157  for (p_i = 0; p_i < pnd_field_raw[n].data.npages(); p_i++) {
158  for (lat_i = 0; lat_i < pnd_field_raw[n].data.nrows(); lat_i++) {
159  for (lon_i = 0; lon_i < pnd_field_raw[n].data.ncols(); lon_i++) {
160  v = pnd_field_raw[n].data(p_i, lat_i, lon_i);
161  if (v != 0) {
162  // Verify pressure is between cloudbox limits
163  p = pnd_field_raw[n].get_numeric_grid(GFIELD3_P_GRID)[p_i];
164  // if (!((p <= p_grid[cloudbox_limits[0]]) &
165  // (p >= p_grid[cloudbox_limits[1]]))) {
166  if ((p <= p_grid[cloudbox_limits[1]]) ||
167  ((p >= p_grid[cloudbox_limits[0]]) &&
168  (cloudbox_limits[0] != 0))) {
169  ostringstream os;
170  os << "Found non-zero pnd outside cloudbox. "
171  << "Cloudbox extends from p=" << p_grid[cloudbox_limits[0]]
172  << " Pa to p=" << p_grid[cloudbox_limits[1]]
173  << " Pa, but found pnd=" << v << "/m³ at p=" << p
174  << " Pa for scattering "
175  << "element #" << n << ".";
176  throw runtime_error(os.str());
177  }
178  // Verify latitude is too
179  if (dim > 1) {
180  lat = pnd_field_raw[n].get_numeric_grid(GFIELD3_LAT_GRID)[lat_i];
181  if (!((lat > lat_grid[cloudbox_limits[2]]) bitand
182  (lat < lat_grid[cloudbox_limits[3]]))) {
183  ostringstream os;
184  os << "Found non-zero pnd outside cloudbox. "
185  << "Cloudbox extends from lat="
186  << lat_grid[cloudbox_limits[2]]
187  << "° to lat=" << lat_grid[cloudbox_limits[3]]
188  << "°, but found pnd=" << v << "/m³ at lat=" << lat
189  << "° for scattering "
190  << "element #" << n << ".";
191  throw runtime_error(os.str());
192  }
193  }
194  // Etc. for longitude
195  if (dim > 2) {
196  lon = pnd_field_raw[n].get_numeric_grid(GFIELD3_LON_GRID)[lon_i];
197  if (!((lon > lon_grid[cloudbox_limits[4]]) bitand
198  (lon < lon_grid[cloudbox_limits[5]]))) {
199  ostringstream os;
200  os << "Found non-zero pnd outside cloudbox. "
201  << "Cloudbox extends from lon="
202  << lon_grid[cloudbox_limits[4]]
203  << "° to lat=" << lon_grid[cloudbox_limits[5]]
204  << "°, but found pnd=" << v << "/m³ at lon=" << lon
205  << "° for scattering "
206  << "element #" << n << ".";
207  throw runtime_error(os.str());
208  }
209  }
210  }
211  }
212  }
213  }
214  }
215 }
216 
218 
230 void chk_scat_species(const ArrayOfString& scat_species, const String& delim) {
231  ArrayOfString strarr;
232  Index nelem = 2;
233 
234  for (Index k = 0; k < scat_species.nelem(); k++) {
235  scat_species[k].split(strarr, delim);
236  if (strarr.nelem() < nelem) {
237  ostringstream os;
238  os << "Individual strings in scat_species must contain at least " << nelem
239  << " elements,\n"
240  << "but entry #" << k << " contains only the following "
241  << strarr.nelem() << ":\n"
242  << strarr << "\n";
243  throw runtime_error(os.str());
244  }
245  }
246 }
247 
249 
260  const ArrayOfScatteringMetaData& scat_meta,
261  const Verbosity&) {
262  if (scat_data.nelem() != scat_meta.nelem()) {
263  ostringstream os;
264  os << "The number of elements in in current scat_species' *scat_data* and "
265  << "*scat_meta* do not match.\n"
266  << "Each *scat_data* entry must correspond to one entry in *scat_meta*.";
267  throw runtime_error(os.str());
268  }
269 }
270 
272 
281 void chk_scattering_meta_data(const ScatteringMetaData& scat_meta_single _U_,
282  const String& scat_meta_file,
283  const Verbosity& verbosity) {
284  CREATE_OUT3;
285  out3 << " Check scattering meta data file " << scat_meta_file << "\n";
286 
287  /* this check is outdated. type now is free from!
288  however, we might want to have other things checked here!?
289  - which parameters at least are needed? -> radius, ...?
290  - ...
291  if (scat_meta_single.type != "Ice" && scat_meta_single.type != "Water" && scat_meta_single.type != "Aerosol")
292  {
293  ostringstream os;
294  os << "Type in " << scat_meta_file << " must be 'Ice', 'Water' or 'Aerosol'\n";
295  throw runtime_error( os.str() );
296  }
297 */
298  //(more) checks need to be included
299 }
300 
302 
313 void chk_scat_data(const SingleScatteringData& scat_data_single,
314  const Verbosity& verbosity) {
315  CREATE_OUT3;
316 
317  assert(scat_data_single.ptype == PTYPE_GENERAL ||
318  scat_data_single.ptype == PTYPE_TOTAL_RND ||
319  scat_data_single.ptype == PTYPE_AZIMUTH_RND);
320 
321  if (scat_data_single.za_grid[0] != 0.) {
322  ostringstream os;
323  os << "The first value of the zenith angle grid in the single"
324  << " scattering properties data must be 0.";
325  throw runtime_error(os.str());
326  }
327 
328  if (last(scat_data_single.za_grid) != 180.) {
329  ostringstream os;
330  os << "The last value of the zenith angle grid in the single"
331  << " scattering properties data must be 180.";
332  throw runtime_error(os.str());
333  }
334 
335  if (scat_data_single.ptype == PTYPE_GENERAL &&
336  scat_data_single.aa_grid[0] != -180.) {
337  ostringstream os;
338  os << "For ptype = \"general\" the first value"
339  << " of the azimuth angle grid in the single scattering"
340  << " properties data must be -180.";
341  throw runtime_error(os.str());
342  }
343 
344  if (scat_data_single.ptype == PTYPE_AZIMUTH_RND &&
345  scat_data_single.aa_grid[0] != 0.) {
346  ostringstream os;
347  os << "For ptype = \"azimuthally_random\""
348  << " the first value"
349  << " of the azimuth angle grid in the single scattering"
350  << " properties data must be 0.";
351  throw runtime_error(os.str());
352  }
353 
354  if (scat_data_single.ptype != PTYPE_TOTAL_RND &&
355  last(scat_data_single.aa_grid) != 180.) {
356  ostringstream os;
357  os << "For ptypes = \"azimuthally_random\" and \"general\""
358  << " the last value of the azimuth angle grid in the single"
359  << " scattering properties data must be 180.";
360  throw runtime_error(os.str());
361  }
362 
363  ostringstream os_pha_mat;
364  os_pha_mat << "pha_mat ";
365  ostringstream os_ext_mat;
366  os_ext_mat << "ext_mat ";
367  ostringstream os_abs_vec;
368  os_abs_vec << "abs_vec ";
369 
370  switch (scat_data_single.ptype) {
371  case PTYPE_GENERAL:
372 
373  out3 << " Data is for arbitrarily orientated particles. \n";
374 
375  chk_size(os_pha_mat.str(),
376  scat_data_single.pha_mat_data,
377  scat_data_single.f_grid.nelem(),
378  scat_data_single.T_grid.nelem(),
379  scat_data_single.za_grid.nelem(),
380  scat_data_single.aa_grid.nelem(),
381  scat_data_single.za_grid.nelem(),
382  scat_data_single.aa_grid.nelem(),
383  16);
384 
385  chk_size(os_ext_mat.str(),
386  scat_data_single.ext_mat_data,
387  scat_data_single.f_grid.nelem(),
388  scat_data_single.T_grid.nelem(),
389  scat_data_single.za_grid.nelem(),
390  scat_data_single.aa_grid.nelem(),
391  7);
392 
393  chk_size(os_abs_vec.str(),
394  scat_data_single.abs_vec_data,
395  scat_data_single.f_grid.nelem(),
396  scat_data_single.T_grid.nelem(),
397  scat_data_single.za_grid.nelem(),
398  scat_data_single.aa_grid.nelem(),
399  4);
400  break;
401 
402  case PTYPE_TOTAL_RND:
403 
404  out3 << " Data is for macroscopically isotropic and mirror-symmetric "
405  << "scattering media, i.e. for totally randomly oriented particles "
406  << "with at least one plane of symmetry. \n";
407 
408  chk_size(os_pha_mat.str(),
409  scat_data_single.pha_mat_data,
410  scat_data_single.f_grid.nelem(),
411  scat_data_single.T_grid.nelem(),
412  scat_data_single.za_grid.nelem(),
413  1,
414  1,
415  1,
416  6);
417 
418  chk_size(os_ext_mat.str(),
419  scat_data_single.ext_mat_data,
420  scat_data_single.f_grid.nelem(),
421  scat_data_single.T_grid.nelem(),
422  1,
423  1,
424  1);
425 
426  chk_size(os_abs_vec.str(),
427  scat_data_single.abs_vec_data,
428  scat_data_single.f_grid.nelem(),
429  scat_data_single.T_grid.nelem(),
430  1,
431  1,
432  1);
433  break;
434 
435  case PTYPE_AZIMUTH_RND:
436 
437  out3 << " Data is for azimuthally randomly oriented particles. \n";
438 
439  chk_size(os_pha_mat.str(),
440  scat_data_single.pha_mat_data,
441  scat_data_single.f_grid.nelem(),
442  scat_data_single.T_grid.nelem(),
443  scat_data_single.za_grid.nelem(),
444  scat_data_single.aa_grid.nelem(),
445  scat_data_single.za_grid.nelem(),
446  1,
447  16);
448 
449  chk_size(os_ext_mat.str(),
450  scat_data_single.ext_mat_data,
451  scat_data_single.f_grid.nelem(),
452  scat_data_single.T_grid.nelem(),
453  scat_data_single.za_grid.nelem(),
454  1,
455  3);
456 
457  chk_size(os_abs_vec.str(),
458  scat_data_single.abs_vec_data,
459  scat_data_single.f_grid.nelem(),
460  scat_data_single.T_grid.nelem(),
461  scat_data_single.za_grid.nelem(),
462  1,
463  2);
464  break;
465  }
466 
467  // Here we only check whether the temperature grid is of the unit K, not
468  // whether it corresponds to the required values in t_field. The second
469  // option is not trivial since here one has to look whether the pnd_field
470  // is non-zero for the corresponding temperature. This check is done in the
471  // functions where the multiplication with the particle number density is
472  // done.
473  if (scat_data_single.T_grid[0] < 0. ||
474  last(scat_data_single.T_grid) > 1001.) {
475  ostringstream os;
476  os << "The temperature values in the single scattering data"
477  << " are negative or very large. Check whether you use the "
478  << "right unit [Kelvin].";
479  throw runtime_error(os.str());
480  }
481 }
482 
500  const GridPos& gp_lat,
501  const GridPos& gp_lon,
502  const ArrayOfIndex& cloudbox_limits,
503  const bool& include_boundaries,
504  const Index& atmosphere_dim)
505 
506 {
507  if (include_boundaries) {
508  // Pressure dimension
509  double ipos = fractional_gp(gp_p);
510  if (ipos < double(cloudbox_limits[0]) ||
511  ipos > double(cloudbox_limits[1])) {
512  return false;
513  }
514 
515  else if (atmosphere_dim >= 2) {
516  // Latitude dimension
517  ipos = fractional_gp(gp_lat);
518  if (ipos < double(cloudbox_limits[2]) ||
519  ipos > double(cloudbox_limits[3])) {
520  return false;
521  }
522 
523  else if (atmosphere_dim == 3) {
524  // Longitude dimension
525  ipos = fractional_gp(gp_lon);
526  if (ipos < double(cloudbox_limits[4]) ||
527  ipos > double(cloudbox_limits[5])) {
528  return false;
529  }
530  }
531  }
532  return true;
533  } else {
534  // Pressure dimension
535  double ipos = fractional_gp(gp_p);
536  if (ipos <= double(cloudbox_limits[0]) ||
537  ipos >= double(cloudbox_limits[1])) {
538  return false;
539  }
540 
541  else if (atmosphere_dim >= 2) {
542  // Latitude dimension
543  ipos = fractional_gp(gp_lat);
544  if (ipos <= double(cloudbox_limits[2]) ||
545  ipos >= double(cloudbox_limits[3])) {
546  return false;
547  }
548 
549  else if (atmosphere_dim == 3) {
550  // Longitude dimension
551  ipos = fractional_gp(gp_lon);
552  if (ipos <= double(cloudbox_limits[4]) ||
553  ipos >= double(cloudbox_limits[5])) {
554  return false;
555  }
556  }
557  }
558  return true;
559  }
560 }
561 
579 bool is_inside_cloudbox(const Ppath& ppath_step,
580  const ArrayOfIndex& cloudbox_limits,
581  const bool include_boundaries)
582 
583 {
584  assert(cloudbox_limits.nelem() == 6);
585  const Index np = ppath_step.np;
586 
587  return is_gp_inside_cloudbox(ppath_step.gp_p[np - 1],
588  ppath_step.gp_lat[np - 1],
589  ppath_step.gp_lon[np - 1],
590  cloudbox_limits,
591  include_boundaries);
592 }
593 
611 void bin_quadweights(Vector& w, const Vector& x, const Index& order) {
612  Index nx = x.nelem();
613 
614  assert(nx > 1);
615  assert(is_increasing(x));
616 
617  if (order == 0) {
618  w[0] = min(x[1] - x[0],
619  0.5 * (x[1] + x[0])); // the latter is the half distance
620  // from x0 to x1 plus the distance
621  // to 0, ie 0.5(x1-x0)+x0.
622  w[nx - 1] = x[nx - 1] - x[nx - 2];
623  } else {
624  w[0] = 0.5 * (x[1] - x[0]);
625  w[nx - 1] = 0.5 * (x[nx - 1] - x[nx - 2]);
626  }
627  for (Index i = 1; i < nx - 1; i++) {
628  w[i] = 0.5 * (x[i + 1] - x[i - 1]);
629  }
630 }
631 
633 
646 void chk_scat_species_field(bool& empty_flag,
647  const Tensor3& scat_species_field,
648  const String& fieldname,
649  const Index& dim,
650  const Vector& p_grid,
651  const Vector& lat_grid,
652  const Vector& lon_grid) {
653  // check p
654  if (scat_species_field.npages() != p_grid.nelem()) {
655  ostringstream os;
656  os << "The size of *p_grid* (" << p_grid.nelem()
657  << ") is unequal the number of pages of *" << fieldname << "* ("
658  << scat_species_field.npages() << ").";
659  throw runtime_error(os.str());
660  }
661 
662  // check lat
663  if (dim >= 2) {
664  if (scat_species_field.nrows() != lat_grid.nelem()) {
665  ostringstream os;
666  os << "The size of *lat_grid* (" << lat_grid.nelem()
667  << ") is unequal the number of rows of *" << fieldname << "* ("
668  << scat_species_field.nrows() << ").";
669  throw runtime_error(os.str());
670  }
671  }
672 
673  // check lon
674  if (dim == 3) {
675  if (scat_species_field.ncols() != lon_grid.nelem()) {
676  ostringstream os;
677  os << "The size of *lon_grid* (" << lon_grid.nelem()
678  << ") is unequal the number of columns of *" << fieldname << "* ("
679  << scat_species_field.ncols() << ").";
680  throw runtime_error(os.str());
681  }
682  }
683 
684  empty_flag = false;
685  // set empty_flag to true if a single value of hydromet_field is unequal zero
686  for (Index j = 0; j < scat_species_field.npages(); j++) {
687  for (Index k = 0; k < scat_species_field.nrows(); k++) {
688  for (Index l = 0; l < scat_species_field.ncols(); l++) {
689  if (scat_species_field(j, k, l) != 0.0 &&
690  !std::isnan(scat_species_field(j, k, l)))
691  empty_flag = true;
692  // if ( scat_species_field(j,k,l) != 0.0 ) empty_flag = true;
693  }
694  }
695  }
696 }
697 
699 
715  Index& upper,
716  const Tensor3& scat_species_field,
717  const Index& atmosphere_dim,
718  const Numeric& cloudbox_margin) {
719  if (atmosphere_dim == 1) {
720  // scattering species profiles
721  ConstVectorView ss_prof = scat_species_field(joker, 0, 0);
722 
723  Index i = 0;
724 
725  // find lower cloudbox_limit to surface if margin != -1 (cloudbox not
726  // forced to reach down to surface)
727  if (cloudbox_margin != -1) {
728  // find index of first pressure level where hydromet_field is
729  // unequal 0, starting from the surface
730  for (i = 0; i < lower; i++) {
731  //cout << "for lower limit checking level #" << i << "\n";
732 
733  // if any of the scat species fields contains a non-zero, non-NaN
734  // value at this atm level we found a potential lower limit value
735  if (ss_prof[i] != 0.0 && !std::isnan(ss_prof[i])) {
736  //cout << "found particles\n";
737 
738  // check if lower is the lowest index in all selected
739  // scattering species fields
740  if (lower > i) {
741  lower = i;
742  //cout << "new lower limit at level #" << lower << "\n";
743  }
744  break;
745  }
746  }
747  }
748 
749  // find index of highest pressure level, where scat_species_mass_density_field is
750  // unequal 0, starting from top of the atmosphere
751  for (Index j = scat_species_field.npages() - 1; j >= max(i, upper); j--) {
752  //cout << "for upper limit checking level #" << j << "\n";
753 
754  // if any of the scat species fields contains a non-zero, non-NaN
755  // value at this atm level we found a potential lower limit value
756  if (ss_prof[j] != 0.0 && !std::isnan(ss_prof[j])) {
757  //cout << "found particles\n";
758 
759  // check if upper is the highest index in all selected
760  // scattering species fields
761  if (upper < j) {
762  upper = j;
763  //cout << "new upper limit at level #" << upper << "\n";
764  }
765  break;
766  }
767  }
768  }
769 
770  else {
771  ostringstream os;
772  os << "Not yet available for 2D and 3D cases.";
773  throw runtime_error(os.str());
774  }
775 
776  /* //NOT WORKING YET
777  // Latitude limits
778  else if ( atmosphere_dim == 2 )
779  {
780  MatrixView hydro_lat = hydromet_field ( nhyd, joker, joker, 0 );
781 
782  for ( i=0; i<hydro_lat.nrows(); i++ )
783  {
784  for ( j=0; j<hydro_lat.ncols(); j++ )
785  {
786  if ( hydro_lat[i,j] != 0.0 )
787  {
788 
789  if ( lat1 <= j ) lat1 =j;
790  //cloudbox_limits[2] = lat1;
791  //break;
792  }
793 
794  }
795  if ( lower <= i ) lower = i;
796  }
797 
798  for ( k=hydro_lat.nelem()-1; k>=i; k-- )
799  {
800  if ( hydro_lat[k] != 0.0 )
801  {
802  lat2 = k;
803  cloudbox_limits[3] = lat2;
804  break;
805 
806  }
807 
808  }
809  }
810 
811  // Longitude limits
812  if ( atmosphere_dim == 3 )
813  {
814  Tensor3View hydro_lon = hydromet_field ( nhyd, joker, joker, joker );
815 
816  for ( i=0; i<hydro_lon.nelem(); i++ )
817  {
818  if ( hydro_lon[i] != 0.0 )
819  {
820  lon1 = i;
821  cloudbox_limits[4] = lon1;
822  break;
823  }
824 
825  }
826  for ( j=hydro_lon.nelem()-1; j>=i; j-- )
827  {
828  if ( hydro_lon[j] != 0.0 )
829  {
830  lon2 = j;
831  cloudbox_limits[5] = lon2;
832  break;
833 
834  }
835 }*/
836 }
837 
849  String& species_type,
850  // WS Input:
851  const String& field_name,
852  const String& delim) {
853  ArrayOfString strarr;
854 
855  // split field_name string at '-' and write to ArrayOfString
856  field_name.split(strarr, delim);
857 
858  // first entry is species type
859  // (i.e. "abs_species" or "scat_species". or "T" or "z", which are ignored.)
860  if (strarr.size() > 0 && field_name[0] != '-') {
861  species_type = strarr[0];
862  } else {
863  ostringstream os;
864  os << "No information on field species type found in '" << field_name
865  << "'\n";
866  throw runtime_error(os.str());
867  }
868 }
869 
881  String& species_name,
882  // WS Input:
883  const String& field_name,
884  const String& delim) {
885  ArrayOfString strarr;
886 
887  // split field_name string at '-' and write to ArrayOfString
888  field_name.split(strarr, delim);
889 
890  // second entry is species name
891  // (e.g. "H2O, "O3" etc. for abs_species or "IWC", "LWC" etc. for scat_species)
892  if (strarr.size() > 1) {
893  species_name = strarr[1];
894  } else {
895  ostringstream os;
896  os << "No information on field species name found in '" << field_name
897  << "'\n";
898  throw runtime_error(os.str());
899  }
900 }
901 
912 void parse_atmcompact_scattype( //WS Output:
913  String& scat_type,
914  // WS Input:
915  const String& field_name,
916  const String& delim) {
917  ArrayOfString strarr;
918 
919  // split field_name string at '-' and write to ArrayOfString
920  field_name.split(strarr, delim);
921 
922  // third entry is type of scat_species field
923  // (e.g. "mass_density", "mass_flux", "number_density")
924  if (strarr.size() > 2) {
925  scat_type = strarr[2];
926  } else {
927  ostringstream os;
928  os << "No information on type of scat_species field found in '"
929  << field_name << "'\n";
930  throw runtime_error(os.str());
931  }
932 }
933 
944 void parse_partfield_name( //WS Output:
945  String& partfield_name,
946  // WS Input:
947  const String& part_string,
948  const String& delim) {
949  ArrayOfString strarr;
950 
951  // split scat_species string at delim and write to ArrayOfString
952  part_string.split(strarr, delim);
953 
954  //first entry is scattering species field name (e.g. "IWC", "LWC" etc.)
955  if (strarr.size() > 0 && part_string[0] != delim[0]) {
956  partfield_name = strarr[0];
957  } else {
958  ostringstream os;
959  os << "No information on scattering species field name in '" << part_string
960  << "'\n";
961  throw runtime_error(os.str());
962  }
963 }
964 
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
ArrayOfGridPos gp_lat
Index position with respect to the latitude grid.
Definition: ppath.h:84
void chk_scat_species(const ArrayOfString &scat_species, const String &delim)
Check validity of scat_species setting.
Definition: cloudbox.cc:230
void chk_scattering_data(const ArrayOfSingleScatteringData &scat_data, const ArrayOfScatteringMetaData &scat_meta, const Verbosity &)
Check scattering data general.
Definition: cloudbox.cc:259
Index nelem() const
Number of elements.
Definition: array.h:195
Declarations having to do with the four output streams.
void parse_atmcompact_speciestype(String &species_type, const String &field_name, const String &delim)
Definition: cloudbox.cc:848
The Vector class.
Definition: matpackI.h:860
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
Definition: logic.cc:215
Numeric last(ConstVectorView x)
last
Definition: math_funcs.cc:165
void chk_pnd_field_raw_only_in_cloudbox(const Index &dim, const ArrayOfGriddedField3 &pnd_field_raw, ConstVectorView p_grid, ConstVectorView lat_grid, ConstVectorView lon_grid, const ArrayOfIndex &cloudbox_limits)
chk_pnd_field_raw_only_in_cloudbox
Definition: cloudbox.cc:146
Linear algebra functions.
Numeric fractional_gp(const GridPos &gp)
fractional_gp
cmplx FADDEEVA() w(cmplx z, double relerr)
Definition: Faddeeva.cc:680
#define min(a, b)
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:147
Workspace functions for the solution of cloud-box radiative transfer by Monte Carlo methods...
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
Contains sorting routines.
Structure to store a grid position.
Definition: interpolation.h:73
The Tensor3 class.
Definition: matpackIII.h:339
The global header file for ARTS.
void chk_pnd_raw_data(const ArrayOfGriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files (pnd_field_raw)
Definition: cloudbox.cc:116
void chk_scat_data(const SingleScatteringData &scat_data_single, const Verbosity &verbosity)
Check single scattering data.
Definition: cloudbox.cc:313
_CS_string_type str() const
Definition: sstream.h:491
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:150
bool is_inside_cloudbox(const Ppath &ppath_step, const ArrayOfIndex &cloudbox_limits, const bool include_boundaries)
Definition: cloudbox.cc:579
const Vector & get_numeric_grid(Index i) const
Get a numeric grid.
const Joker joker
member functions of the Rng class and gsl_rng code
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
const Index GFIELD3_LAT_GRID
void chk_scattering_meta_data(const ScatteringMetaData &scat_meta_single, const String &scat_meta_file, const Verbosity &verbosity)
Check scattering data meta.
Definition: cloudbox.cc:281
Propagation path structure and functions.
Header file for logic.cc.
void chk_scat_species_field(bool &empty_flag, const Tensor3 &scat_species_field, const String &fieldname, const Index &dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid)
Check whether field of a specific scattering species zero everywhere.
Definition: cloudbox.cc:646
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:144
This can be used to make arrays out of anything.
Definition: array.h:40
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
Split string into substrings.
Definition: mystring.h:206
void chk_size(const String &x_name, ConstVectorView x, const Index &c)
Runtime check for size of Vector.
Definition: check_input.cc:466
const Index GFIELD3_P_GRID
void parse_partfield_name(String &partfield_name, const String &part_string, const String &delim)
Definition: cloudbox.cc:944
#define max(a, b)
A constant view of a Vector.
Definition: matpackI.h:476
Index np
Number of points describing the ppath.
Definition: ppath.h:52
ArrayOfGridPos gp_lon
Index position with respect to the longitude grid.
Definition: ppath.h:86
Index nelem(const Lines &l)
Number of lines.
void chk_pnd_data(const GriddedField3 &pnd_field_raw, const String &pnd_field_file, const Index &atmosphere_dim, const Verbosity &verbosity)
Check particle number density files.
Definition: cloudbox.cc:67
#define _U_
Definition: config.h:183
const Index GFIELD3_LON_GRID
void parse_atmcompact_scattype(String &scat_type, const String &field_name, const String &delim)
Definition: cloudbox.cc:912
#define CREATE_OUT3
Definition: messages.h:207
void bin_quadweights(Vector &w, const Vector &x, const Index &order)
Definition: cloudbox.cc:611
The structure to describe a propagation path and releated quantities.
Definition: ppath.h:48
Internal cloudbox functions.
bool is_gp_inside_cloudbox(const GridPos &gp_p, const GridPos &gp_lat, const GridPos &gp_lon, const ArrayOfIndex &cloudbox_limits, const bool &include_boundaries, const Index &atmosphere_dim)
Definition: cloudbox.cc:499
void parse_atmcompact_speciesname(String &species_name, const String &field_name, const String &delim)
Definition: cloudbox.cc:880
void find_cloudlimits(Index &lower, Index &upper, const Tensor3 &scat_species_field, const Index &atmosphere_dim, const Numeric &cloudbox_margin)
Adjust uppermost and lowermost cloudy level for one scat_species_*_*_field.
Definition: cloudbox.cc:714
This file contains declerations of functions of physical character.
ArrayOfGridPos gp_p
Index position with respect to the pressure grid.
Definition: ppath.h:82