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() );