47 Index& abs_xsec_agenda_checked,
50 const Agenda& abs_xsec_agenda,
54 bool needs_lines =
false;
55 bool needs_continua =
false;
56 bool needs_cia =
false;
58 for (
Index sp = 0; sp < abs_species.
nelem(); sp++)
60 for (
Index tgs = 0; tgs < abs_species[sp].
nelem(); tgs++)
62 switch (abs_species[sp][tgs].Type())
72 os <<
"Unknown species type: " <<
73 abs_species[sp][tgs].Type();
74 throw runtime_error(os.str());
83 && !abs_xsec_agenda.
has_method(
"abs_xsec_per_speciesAddLines"))
86 "*abs_species* contains line species but *abs_xsec_agenda*\n" 87 "does not contain *abs_xsec_per_speciesAddLines*.");
91 && !abs_xsec_agenda.
has_method(
"abs_xsec_per_speciesAddConts"))
94 "*abs_species* contains continuum species but *abs_xsec_agenda*\n" 95 "does not contain *abs_xsec_per_speciesAddConts*.");
99 && !abs_xsec_agenda.
has_method(
"abs_xsec_per_speciesAddCIA"))
102 "*abs_species* contains CIA species but *abs_xsec_agenda*\n" 103 "does not contain *abs_xsec_per_speciesAddCIA*.");
107 abs_xsec_agenda_checked = 1;
116 Index& atmfields_checked,
117 const Index& atmosphere_dim,
130 const Index& abs_f_interp_order,
131 const Index& negative_vmr_ok,
138 p_grid, lat_grid, lon_grid );
140 p_grid, lat_grid, lon_grid );
143 if( !negative_vmr_ok && abs_species.
nelem() &&
min(vmr_field) < 0 )
144 throw runtime_error(
"All values in *vmr_field* must be >= 0." );
147 if(
min(t_field) <= 0 )
148 throw runtime_error(
"All temperatures in *t_field* must be > 0." );
151 if( wind_w_field.
npages() > 0 )
154 p_grid, lat_grid, lon_grid );
156 if( atmosphere_dim < 3 && wind_v_field.
npages() > 0 )
159 p_grid, lat_grid, lon_grid );
161 if( atmosphere_dim > 2 )
163 if( wind_u_field.
npages() > 0 )
165 if( wind_v_field.
npages() > 0 )
167 bool chk_poles =
false;
169 p_grid, lat_grid, lon_grid, chk_poles);
171 p_grid, lat_grid, lon_grid, chk_poles);
173 "wind_u_field", wind_u_field,
174 atmosphere_dim, lat_grid);
179 p_grid, lat_grid, lon_grid );
184 if( wind_v_field.
npages() > 0 )
187 p_grid, lat_grid, lon_grid);
193 if (wind_u_field.
npages() > 0 ||
194 wind_v_field.
npages() > 0 ||
195 wind_w_field.
npages() > 0)
197 if (abs_f_interp_order==0)
200 os <<
"You have a wind field set, but abs_f_interp_order zero.\n" 201 <<
"This is not allowed. Though abs_f_interp_order only is\n" 202 <<
"required and has an effect if absorption lookup tables\n" 203 <<
"are used, for safety reasons you also have to set it >0\n" 204 <<
"in case of on-the-fly absorption.";
205 throw runtime_error(os.str());
210 if( mag_w_field.
npages() > 0 )
213 mag_w_field, atmosphere_dim, p_grid, lat_grid, lon_grid );
215 if( mag_u_field.
npages() > 0 )
217 if( mag_v_field.
npages() > 0 )
219 bool chk_poles =
false;
221 p_grid, lat_grid, lon_grid, chk_poles );
223 p_grid, lat_grid, lon_grid, chk_poles );
225 "mag_u_field", mag_u_field,
226 atmosphere_dim, lat_grid);
231 p_grid, lat_grid, lon_grid );
236 if( mag_v_field.
npages() > 0 )
239 p_grid, lat_grid, lon_grid);
244 atmfields_checked = 1;
253 Index& atmgeom_checked,
254 const Index& atmosphere_dim,
259 const Vector& refellipsoid,
269 if( refellipsoid.
nelem() != 2 )
270 throw runtime_error(
"The WSV *refellispoid* must be a vector of " 272 if( refellipsoid[0] <= 0 )
273 throw runtime_error(
"The first element of *refellipsoid* must " 275 if( refellipsoid[1] < 0 || refellipsoid[1] > 1 )
276 throw runtime_error(
"The second element of *refellipsoid* must be " 278 if( atmosphere_dim == 1 && refellipsoid[1] != 0 )
279 throw runtime_error(
"For 1D, the second element of *refellipsoid* " 280 "(the eccentricity) must be 0." );
283 p_grid, lat_grid, lon_grid );
285 lat_grid, lon_grid );
288 for(
Index row=0; row<z_field.
nrows(); row++ )
290 for(
Index col=0; col<z_field.
ncols(); col++ )
293 os <<
"z_field (for latitude nr " << row <<
" and longitude nr " 303 for(
Index row=0; row<z_surface.
nrows(); row++ )
305 for(
Index col=0; col<z_surface.
ncols(); col++ )
307 if( z_surface(row,col)<z_field(0,row,col) ||
308 z_surface(row,col)>=z_field(z_field.
npages()-1,row,col) )
311 os <<
"The surface altitude (*z_surface*) cannot be outside\n" 312 <<
"of the altitudes in *z_field*.\n" 313 <<
"z_surface: " << z_surface(row,col) <<
"\n" 314 <<
"min of z_field: " << z_field(0,row,col) <<
"\n" 315 <<
"max of z_field: " 316 << z_field(z_field.
npages()-1,row,col) <<
"\n";
317 if( atmosphere_dim > 1 )
318 os <<
"\nThis was found to be the case for:\n" 319 <<
"latitude " << lat_grid[row];
320 if( atmosphere_dim > 2 )
321 os <<
"\nlongitude " << lon_grid[col];
322 throw runtime_error( os.str() );
336 Index& cloudbox_checked,
337 const Index& atmfields_checked,
338 const Index& atmosphere_dim,
347 const Index& cloudbox_on,
351 const Matrix& particle_masses,
358 if( atmfields_checked != 1 )
359 throw runtime_error(
"The atmospheric fields must be flagged to have " 360 "passed a consistency check (atmfields_checked=1)." );
369 ow <<
"The scattering methods are not (yet?) handling winds. For this\n" 370 <<
"reason, the WSVs for wind fields must all be empty with an\n." 371 <<
"active cloudbox.";
372 if( wind_w_field.
npages() > 0 )
373 {
throw runtime_error( ow.str() ); }
374 if( wind_v_field.
npages() > 0 )
375 {
throw runtime_error( ow.str() ); }
376 if( atmosphere_dim > 2 && wind_u_field.
npages() > 0 )
377 {
throw runtime_error( ow.str() ); }
383 Index has_absparticles=0;
384 for(
Index sp = 0; sp < abs_species.
nelem() && has_absparticles < 1; sp++ )
391 if ( has_absparticles )
393 throw runtime_error(
"For scattering calculations (cloudbox is on)," 394 "abs_species is not allowed to contain\n" 395 "'particles' (absorbing-only particles)!" );
399 if( cloudbox_limits.
nelem() != atmosphere_dim*2 )
402 os <<
"The array *cloudbox_limits* has incorrect length.\n" 403 <<
"For atmospheric dim. = " << atmosphere_dim
404 <<
" the length shall be " << atmosphere_dim*2
405 <<
" but it is " << cloudbox_limits.
nelem() <<
".";
406 throw runtime_error( os.str() );
408 if( cloudbox_limits[1]<=cloudbox_limits[0] || cloudbox_limits[0]<0 ||
409 cloudbox_limits[1]>=p_grid.
nelem() )
412 os <<
"Incorrect value(s) for cloud box pressure limit(s) found." 413 <<
"\nValues are either out of range or upper limit is not " 414 <<
"greater than lower limit.\nWith present length of " 415 <<
"*p_grid*, OK values are 0 - " << p_grid.
nelem()-1
416 <<
".\nThe pressure index limits are set to " 417 << cloudbox_limits[0] <<
" - " << cloudbox_limits[1] <<
".";
418 throw runtime_error( os.str() );
421 Index nlat=1, nlon=1;
423 if( atmosphere_dim >= 2 )
425 nlat = lat_grid.
nelem();
426 if( cloudbox_limits[3]<=cloudbox_limits[2] ||
427 cloudbox_limits[2]<1 || cloudbox_limits[3]>=nlat-1 )
430 os <<
"Incorrect value(s) for cloud box latitude limit(s) found." 431 <<
"\nValues are either out of range or upper limit is not " 432 <<
"greater than lower limit.\nWith present length of " 433 <<
"*lat_grid*, OK values are 1 - " << nlat-2
434 <<
".\nThe latitude index limits are set to " 435 << cloudbox_limits[2] <<
" - " << cloudbox_limits[3] <<
".";
436 throw runtime_error( os.str() );
438 if( ( lat_grid[cloudbox_limits[2]] - lat_grid[0] < llmin ) &&
439 ( atmosphere_dim==2 || (atmosphere_dim==3 && lat_grid[0]>-90)) )
442 os <<
"Too small distance between cloudbox and lower end of " 443 <<
"latitude grid.\n" 444 <<
"This distance must be " << llmin <<
" degrees.\n" 445 <<
"Cloudbox ends at " << lat_grid[cloudbox_limits[2]]
446 <<
" and latitude grid starts at " << lat_grid[0] <<
".";
447 throw runtime_error( os.str() );
449 if( ( lat_grid[nlat-1] - lat_grid[cloudbox_limits[3]] < llmin ) &&
450 ( atmosphere_dim==2 ||
451 (atmosphere_dim==3 && lat_grid[nlat-1]<90) ) )
454 os <<
"Too small distance between cloudbox and upper end of " 455 <<
"latitude grid.\n" 456 <<
"This distance must be " << llmin <<
" degrees.\n" 457 <<
"Cloudbox ends at " << lat_grid[cloudbox_limits[3]]
458 <<
" and latitude grid ends at " << lat_grid[nlat-1] <<
".";
459 throw runtime_error( os.str() );
463 if( atmosphere_dim >= 3 )
465 nlon = lon_grid.
nelem();
466 if( cloudbox_limits[5]<=cloudbox_limits[4] || cloudbox_limits[4]<1 ||
467 cloudbox_limits[5]>=nlon-1 )
470 os <<
"Incorrect value(s) for cloud box longitude limit(s) found" 471 <<
".\nValues are either out of range or upper limit is not " 472 <<
"greater than lower limit.\nWith present length of " 473 <<
"*lon_grid*, OK values are 1 - " << nlon-2
474 <<
".\nThe longitude limits are set to " 475 << cloudbox_limits[4] <<
" - " << cloudbox_limits[5] <<
".";
476 throw runtime_error( os.str() );
478 if( lon_grid[nlon-1] - lon_grid[0] < 360 )
480 const Numeric latmax =
max(
abs(lat_grid[cloudbox_limits[2]]),
481 abs(lat_grid[cloudbox_limits[3]]) );
483 if( lon_grid[cloudbox_limits[4]]-lon_grid[0] < llmin/lfac )
486 os <<
"Too small distance between cloudbox and lower end of" 487 <<
"the longitude\ngrid. This distance must here be " 488 << llmin/lfac <<
" degrees.";
489 throw runtime_error( os.str() );
491 if( lon_grid[nlon-1]-lon_grid[cloudbox_limits[5]] < llmin/lfac )
494 os <<
"Too small distance between cloudbox and upper end of" 495 <<
"the longitude\ngrid. This distance must here be " 496 << llmin/lfac <<
" degrees.";
497 throw runtime_error( os.str() );
503 for(
Index o=0; o<nlon; o++ )
505 for(
Index a=0; a<nlat; a++ )
507 if( z_field(cloudbox_limits[1],a,o) <= z_surface(a,o) )
509 "The upper vertical limit of the cloudbox must be above " 510 "the surface altitude (for all latitudes and longitudes)." );
518 Vector g1( cloudbox_limits[1]-cloudbox_limits[0]+1 ), g2(0), g3(0);
519 if( atmosphere_dim >= 2 )
520 { g2.resize( cloudbox_limits[3]-cloudbox_limits[2]+1 ); }
521 if( atmosphere_dim == 3 )
522 { g3.
resize( cloudbox_limits[5]-cloudbox_limits[4]+1 ); }
524 chk_atm_field(
"pnd_field", pnd_field, atmosphere_dim, np, g1, g2, g3 );
526 if(
min(pnd_field) < 0 )
527 throw runtime_error(
"Negative values in *pnd_field* not allowed." );
529 for(
Index a=0; a<g2.nelem(); a++ ) {
531 if(
max(pnd_field(
joker,0,a,o)) > 0 &&
532 z_field(cloudbox_limits[0],a,o) > z_surface(a,o) )
533 throw runtime_error(
"A non-zero value found in *pnd_field* at the" 534 " lower altitude limit of the cloudbox (but the " 535 "position is not at or below the surface altitude)." );
538 throw runtime_error(
"A non-zero value found in *pnd_field* at " 539 "upper altitude limit of the cloudbox." );
540 if( atmosphere_dim >= 2 )
543 throw runtime_error(
"A non-zero value found in *pnd_field* at " 544 "lower latitude limit of the cloudbox." );
546 throw runtime_error(
"A non-zero value found in *pnd_field* at " 547 "upper latitude limit of the cloudbox." );
549 if( atmosphere_dim == 3 )
552 throw runtime_error(
"A non-zero value found in *pnd_field* at " 553 "lower longitude limit of the cloudbox." );
555 throw runtime_error(
"A non-zero value found in *pnd_field* at " 556 "upper longitude limit of the cloudbox." );
561 if( particle_masses.
nrows() > 0 )
563 if( particle_masses.
nrows() != np )
564 throw runtime_error(
"The WSV *particle_masses* must either be " 565 "empty or have a row size matching the " 566 "length of *scat_data_array*." );
567 if(
min(particle_masses) < 0 )
569 "All values in *particles_masses* must be >= 0." );
574 cloudbox_checked = 1;
584 Index& propmat_clearsky_agenda_checked,
587 const Agenda& propmat_clearsky_agenda,
590 bool needs_lines =
false;
591 bool needs_zeeman =
false;
592 bool needs_continua =
false;
593 bool needs_cia =
false;
595 bool needs_particles =
false;
597 for (
Index sp = 0; sp < abs_species.
nelem(); sp++)
599 for (
Index tgs = 0; tgs < abs_species[sp].
nelem(); tgs++)
601 switch (abs_species[sp][tgs].Type())
611 os <<
"Unknown species type: " <<
612 abs_species[sp][tgs].Type();
613 throw runtime_error(os.str());
619 if ((needs_lines || needs_continua || needs_cia)
620 && !(propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddOnTheFly")
621 || propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddFromLookup")))
623 throw runtime_error(
"*abs_species* contains line species, CIA species, or continua but " 624 "*propmat_clearsky_agenda*\n" 625 "does not contain *propmat_clearskyAddOnTheFly* nor " 626 "*propmat_clearskyAddFromLookup*.");
630 && !propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddZeeman"))
632 throw runtime_error(
"*abs_species* contains Zeeman species but *propmat_clearsky_agenda*\n" 633 "does not contain *propmat_clearskyAddZeeman*.");
644 && !propmat_clearsky_agenda.
has_method(
"propmat_clearskyAddParticles"))
646 throw runtime_error(
"*abs_species* contains particles but *propmat_clearsky_agenda*\n" 647 "does not contain *propmat_clearskyAddParticles*.");
650 propmat_clearsky_agenda_checked = 1;
659 Index& sensor_checked,
660 const Index& atmosphere_dim,
661 const Index& stokes_dim,
665 const Matrix& transmitter_pos,
666 const Vector& mblock_za_grid,
667 const Vector& mblock_aa_grid,
668 const Index& antenna_dim,
669 const Sparse& sensor_response,
670 const Vector& sensor_response_f,
672 const Vector& sensor_response_za,
673 const Vector& sensor_response_aa,
681 if( antenna_dim == 1 )
685 const Index niyb = nf * nza * naa * stokes_dim;
690 if( sensor_pos.
ncols() != atmosphere_dim )
691 throw runtime_error(
"The number of columns of sensor_pos must be " 692 "equal to the atmospheric dimensionality." );
693 if( atmosphere_dim <= 2 && sensor_los.
ncols() != 1 )
694 throw runtime_error(
"For 1D and 2D, sensor_los shall have one column." );
695 if( atmosphere_dim == 3 && sensor_los.
ncols() != 2 )
696 throw runtime_error(
"For 3D, sensor_los shall have two columns." );
697 if( sensor_los.
nrows() != nmblock )
700 os <<
"The number of rows of sensor_pos and sensor_los must be " 701 <<
"identical, but sensor_pos has " << nmblock <<
" rows,\n" 702 <<
"while sensor_los has " << sensor_los.
nrows() <<
" rows.";
703 throw runtime_error( os.str() );
705 if(
max( sensor_los(
joker,0) ) > 180 )
707 "First column of *sensor_los* is not allowed to have values above 180." );
708 if( atmosphere_dim == 2 )
710 if(
min( sensor_los(
joker,0) ) < -180 )
711 throw runtime_error(
"For atmosphere_dim = 2, first column of " 712 "*sensor_los* is not allowed to have values below -180." );
716 if(
min( sensor_los(
joker,0) ) < 0 )
717 throw runtime_error(
"For atmosphere_dim != 2, first column of " 718 "*sensor_los* is not allowed to have values below 0." );
720 if( atmosphere_dim == 3 &&
max( sensor_los(
joker,1) ) > 180 )
722 "Second column of *sensor_los* is not allowed to have values above 180." );
725 if( transmitter_pos.
ncols() > 0 && transmitter_pos.
nrows() > 0 )
727 if( transmitter_pos.
nrows() != sensor_pos.
nrows() )
728 throw runtime_error(
"*transmitter_pos* must either be empty or have " 729 "the same number of rows as *sensor_pos*." );
730 if( transmitter_pos.
ncols() !=
max(
Index(2),atmosphere_dim) )
731 throw runtime_error(
"*transmitter_pos* must either be empty, have " 732 "2 for 1D/2D or 3 columns for 3D." );
740 throw runtime_error(
"The measurement block zenith angle grid is empty." );
743 if( antenna_dim == 1 )
745 if( mblock_aa_grid.
nelem() != 0 )
747 "For antenna_dim = 1, the azimuthal angle grid must be empty." );
751 if( atmosphere_dim < 3 )
752 throw runtime_error(
"2D antennas (antenna_dim=2) can only be " 753 "used with 3D atmospheres." );
754 if( mblock_aa_grid.
nelem() == 0 )
756 "The measurement block azimuthal angle grid is empty." );
762 if( sensor_response.
ncols() != niyb )
765 os <<
"The *sensor_response* matrix does not have the right size,\n" 766 <<
"either the method *sensor_responseInit* has not been run or some\n" 767 <<
"of the other sensor response methods has not been correctly\n" 769 throw runtime_error( os.str() );
774 if( antenna_dim==1 && sensor_response_aa.
nelem() )
775 throw runtime_error(
"If *antenna_dim* is 1, *sensor_response_aa* must " 778 if( n1y != sensor_response_f.
nelem() || n1y != sensor_response_pol.
nelem() ||
779 n1y != sensor_response_za.
nelem() ||
780 ( antenna_dim==2 && n1y != sensor_response_aa.
nelem() ) )
783 os <<
"Sensor auxiliary variables do not have the correct size.\n" 784 <<
"The following variables should all have same size:\n" 785 <<
"length of y for one block : " << n1y <<
"\n" 786 <<
"sensor_response_f.nelem() : " << sensor_response_f.
nelem()
787 <<
"\nsensor_response_pol.nelem(): " << sensor_response_pol.
nelem()
788 <<
"\nsensor_response_za.nelem() : " << sensor_response_za.
nelem()
790 if( antenna_dim == 2 )
791 { os <<
"sensor_response_aa.nelem() : " << sensor_response_aa.
nelem()
793 throw runtime_error( os.str() );
INDEX Index
The type to use for all integer numbers and indices.
void atmfields_checkedCalc(Index &atmfields_checked, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const ArrayOfArrayOfSpeciesTag &abs_species, const Tensor3 &t_field, const Tensor4 &vmr_field, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Tensor3 &mag_u_field, const Tensor3 &mag_v_field, const Tensor3 &mag_w_field, const Index &abs_f_interp_order, const Index &negative_vmr_ok, const Verbosity &)
WORKSPACE METHOD: atmfields_checkedCalc.
Index nelem() const
Number of elements.
Index ncols() const
Returns the number of columns.
Index nrows() const
Returns the number of rows.
Index nelem() const
Returns the number of elements.
Index ncols() const
Returns the number of columns.
The global header file for ARTS.
void sensor_checkedCalc(Index &sensor_checked, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &f_grid, const Matrix &sensor_pos, const Matrix &sensor_los, const Matrix &transmitter_pos, const Vector &mblock_za_grid, const Vector &mblock_aa_grid, const Index &antenna_dim, const Sparse &sensor_response, const Vector &sensor_response_f, const ArrayOfIndex &sensor_response_pol, const Vector &sensor_response_za, const Vector &sensor_response_aa, const Verbosity &)
WORKSPACE METHOD: sensor_checkedCalc.
bool has_method(const String &methodname) const
Check if method is in Agenda.
Index ncols() const
Returns the number of columns.
void cloudbox_checkedCalc(Index &cloudbox_checked, const Index &atmfields_checked, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Matrix &z_surface, const Tensor3 &wind_u_field, const Tensor3 &wind_v_field, const Tensor3 &wind_w_field, const Index &cloudbox_on, const ArrayOfIndex &cloudbox_limits, const Tensor4 &pnd_field, const ArrayOfSingleScatteringData &scat_data_array, const Matrix &particle_masses, const ArrayOfArrayOfSpeciesTag &abs_species, const Verbosity &)
WORKSPACE METHOD: cloudbox_checkedCalc.
void atmgeom_checkedCalc(Index &atmgeom_checked, const Index &atmosphere_dim, const Vector &p_grid, const Vector &lat_grid, const Vector &lon_grid, const Tensor3 &z_field, const Vector &refellipsoid, const Matrix &z_surface, const Verbosity &)
WORKSPACE METHOD: atmgeom_checkedCalc.
Index nrows() const
Returns the number of rows.
NUMERIC Numeric
The type to use for all floating point numbers.
Index npages() const
Returns the number of pages.
void resize(Index n)
Assignment operator from VectorView.
void propmat_clearsky_agenda_checkedCalc(Workspace &ws, Index &propmat_clearsky_agenda_checked, const ArrayOfArrayOfSpeciesTag &abs_species, const Agenda &propmat_clearsky_agenda, const Verbosity &)
WORKSPACE METHOD: propmat_clearsky_agenda_checkedCalc.
void abs_xsec_agenda_checkedCalc(Workspace &ws, Index &abs_xsec_agenda_checked, const ArrayOfArrayOfSpeciesTag &abs_species, const Agenda &abs_xsec_agenda, const Verbosity &)
WORKSPACE METHOD: abs_xsec_agenda_checkedCalc.
Index nrows() const
Returns the number of rows.