<resource schema="__system">
	<meta name="creationDate">2017-02-08T11:00:00</meta>
	<meta name="description">Definitions dealing with the EPN-TAP2 table
	schema used to describe solar system observations.</meta>
	<meta name="subject">solar-system-astronomy</meta>

	<STREAM id="_minmax">
		<doc>
			Generates a pair of minimum/maximum column pairs.  You must
			fill out basename, baseucd, basedescr, unit.
		</doc>
		<column name="\basename\+_min" type="double precision"
			ucd="\baseucd;stat.min" unit="\unit"
			description="\basedescr, lower limit.">
			<property key="std">1</property>
		</column>
		<column name="\basename\+_max" type="double precision"
			ucd="\baseucd;stat.max" unit="\unit"
			description="\basedescr, upper limit">
			<property key="std">1</property>
		</column>
	</STREAM>
	<STREAM id="_c_minmax">
		<doc>
			Generates a pair of minimum/maximum column pairs.  You must
			fill out basename, baseucd, basedescr, unit.
		</doc>
		<column name="\basename\+min" type="double precision"
			ucd="\baseucd;stat.min" unit="\unit"
			description="\basedescr, lower limit.">
			<property key="std">1</property>
		</column>
		<column name="\basename\+max" type="double precision"
			ucd="\baseucd;stat.max" unit="\unit"
			description="\basedescr, upper limit">
			<property key="std">1</property>
		</column>
	</STREAM>

	<table id="optional_columns">
		<!-- to get this list (for, e.g., allepn), run in vi:
			!/<.table grep "<column" | sed -e 's/.*name="\([^"]*\)".*/\1/'
		-->
		<column name="access_url"	type="text" 
			ucd="meta.ref.url;meta.file"
			description="URL of the data file, case sensitive.  If present,
			then access_format and access_estsize are mandatory."
			displayHint="type=url">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="access_format"	type="text"
			ucd="meta.code.mime"
			description="File format type (RFC 6838 Media Type a.k.a. MIME type)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="access_estsize"	type="integer"
			ucd="phys.size;meta.file" unit="kbyte"
			description="Estimated file size in kbyte.">
			<property key="std">1</property>
			<values nullLiteral="-1"/>
			<property key="extsect">common</property>
		</column>

		<column name="access_md5" type="text"
			ucd="meta.checksum;meta.file" 
			description="MD5 Hash for the file">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="thumbnail_url" type="text" 
			ucd="meta.ref.url;meta.preview"
			description="URL of a thumbnail image with predefined size (png ~200 
			pix, for use in a client only)"
			displayHint="type=url">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="file_name" type="text" 
			ucd="meta.id;meta.file"
			description="Name of the data file only, case sensitive"
			displayHint="type=url">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="datalink_url" type="text" 
			ucd="meta.ref.url"
			tablehead="Datalink"
			description="Link to a datalink document for this dataset"
			displayHint="type=url">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="species" type="text" 
			ucd="meta.id;phys.atmol"
			description="Identifies a chemical species, case sensitive">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="messenger" type="text"
			ucd="instr.bandpass"
			tablehead="Messenger"
			description="Vector of measured signal, including electromagnetic 
			band, from http://www.ivoa.net/rdf/messenger">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="alt_target_name" type="text" 
			ucd="meta.id;src"
			description="Provides alternative target name if more 
			common (e.g. comets); multiple identifiers can be separated
			by hashes">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="target_region"	type="text" 
			ucd="meta.id;src;obs.field"
			description="Type of region or feature of interest">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="feature_name" type="text"
			ucd="meta.id;src;obs.field"
			description="Secondary name (can be standard name of region of
				interest)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="publisher"	type="text" 
			ucd="meta.curation" 
			description="A short string identifying the entity running
				the data service used">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="bib_reference"	type="text" 
			ucd="meta.bib" 
			description="Bibcode or DOI preferred if available,
				or other bibliographic identifier or URL">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="internal_reference" type="text"
			ucd="meta.id.cross"
			tablehead="Related"
			description="Related granule_uid(s) in the current service;
				hash-separated">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="external_link" type="text"
			ucd="meta.ref.url"
			tablehead="See also"
			description="Web page providing more details on this granule"
			displayHint="type=url">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		
		<column name="shape" type="smoc"
			ucd="pos.outline;obs.field" unit="" 
			description="(ST)MOC footprint, valid for celestial, 
				spherical, or body-fixed frames + time coverage">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="spatial_coordinate_description" type="text"
			ucd="meta.code.class;pos.frame"
			description="ID of specific coordinate system and version or 
				properties.">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="spatial_origin" type="text"
			ucd="meta.ref;pos.frame"
			description="Defines the frame origin">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="time_refposition" type="text"
			ucd="meta.ref;time.scale"
			description="Defines where the time is measured (e.g., ground vs.
				spacecraft). Defaults to the observer's frame">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="time_scale"	type="text" 
			ucd="time.scale" 
			description="Defaults to UTC in data services; takes values
			from http://www.ivoa.net/rdf/time_scale otherwise">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="subsolar_longitude_min" type="double precision"
			unit="deg" ucd="pos.bodyrc.lon;stat.min"
			description="Minimum sub-solar point longitude">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="subsolar_longitude_max" type="double precision"
			unit="deg" ucd="pos.bodyrc.lon;stat.max"
			description="Maximum sub-solar point longitude">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="subsolar_latitude_min" type="double precision"
			unit="deg" ucd="pos.bodyrc.lat;stat.min"
			description="Minimum sub-solar point latitude">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="subsolar_latitude_max" type="double precision"
			unit="deg" ucd="pos.bodyrc.lat;stat.max"
			description="Maximum sub-solar point latitude">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="subobserver_longitude_min" type="double precision"
			unit="deg" ucd="pos.bodyrc.lon;stat.min"
			description="Minimum sub-observer point longitude (sub-Earth for ground based observations)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="subobserver_longitude_max" type="double precision"
			unit="deg" ucd="pos.bodyrc.lon;stat.max"
			description="Maximum sub-observer point longitude (sub-Earth for ground based observations)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="subobserver_latitude_min" type="double precision"
			unit="deg" ucd="pos.bodyrc.lat;stat.min"
			description="Minimum sub-observer point latitude (sub-Earth for ground based observations)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="subobserver_latitude_max" type="double precision"
			unit="deg" ucd="pos.bodyrc.lat;stat.max"
			description="Maximum sub-observer point latitude (sub-Earth for ground based observations)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="ra" type="double precision"
			unit="deg" ucd="pos.eq.ra;meta.main"
			description="Right ascension">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="dec" type="double precision"
			unit="deg" ucd="pos.eq.dec;meta.main"
			description="Declination">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="radial_distance_min" type="double precision"
			unit="km" ucd="pos.distance;pos.bodyrc;stat.min"
			description="Min distance from observed area to body center">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="radial_distance_max" type="double precision"
			unit="km" ucd="pos.distance;pos.bodyrc;stat.max"
			description="Max distance from observed area to body center">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="altitude_fromshape_min" type="double precision"
			unit="km" ucd="pos.bodyrc.alt;stat.min"
			description="Min altitude of observed area above shape model / DTM">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="altitude_fromshape_max" type="double precision"
			unit="km" ucd="pos.bodyrc.alt;stat.max"
			description="Max altitude of observed area above shape model / DTM">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="solar_longitude_min" type="double precision"
			unit="deg" ucd="pos.ecliptic.lon;pos.heliocentric;stat.min"
			description="Min Solar longitude Ls (location on orbit / season)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="solar_longitude_max" type="double precision"
			unit="deg" ucd="pos.ecliptic.lon;pos.heliocentric;stat.max"
			description="Max Solar longitude Ls (location on orbit / season)">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="local_time_min" type="double precision"
			unit="h" ucd="time.phase;time.period.rotation;stat.min"
			description="Min local time at observed region">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="local_time_max" type="double precision"
			unit="h" ucd="time.phase;time.period.rotation;stat.max"
			description="Max local time at observed region">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="target_distance_min" type="double precision"
			unit="km" ucd="pos.distance;stat.min"
			description="Min observer-target distance">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="target_distance_max" type="double precision"
			unit="km" ucd="pos.distance;stat.max"
			description="Max observer-target distance">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="target_time_min" type="timestamp"
			ucd="time.start;src"
			description="Min observing time in target frame">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="target_time_max" type="timestamp"
			ucd="time.end;src"
			description="Max observing time in target frame">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="earth_distance_min" type="double precision"
			unit="AU" ucd="pos.distance;stat.min"
			description="Min Earth-target distance">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="earth_distance_max" type="double precision"
			unit="AU" ucd="pos.distance;stat.max"
			description="Max Earth-target distance">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="sun_distance_min" type="double precision"
			unit="AU" ucd="pos.distance;stat.min"
			description="Min Sun-target distance">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="sun_distance_max" type="double precision"
			unit="AU" ucd="pos.distance;stat.max"
			description="Max Sun-target distance">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>


		<column name="filter" type="text"
			ucd="meta.id;instr.filter"
			description="Identifies filter in use, typically for images">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="instrument_type" type="text"
			ucd="meta.id;instr"
			description="type of instrument">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<column name="acquisition_id" type="text"
			ucd="meta.id"
			description="ID of the data file/acquisition in the original archive">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="proposal_id" type="text"
			ucd="meta.id;obs.proposal"
			description="Proposal identifier">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="proposal_pi" type="text"
			ucd="meta.id.PI;obs.proposal"
			description="Proposal principal investigator">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="proposal_title" type="text"
			ucd="meta.title;obs.proposal"
			description="Proposal title">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="campaign" type="text"
			ucd="meta.id;obs.proposal"
			description="Name of the observational campaign">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="target_description" type="text"
			ucd="meta.note;src"
			description="Original target keywords">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="proposal_target_name" type="text"
			ucd="meta.note;obs.proposal"
			description="target name as in proposal title">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="target_apparent_radius" type="double precision"
			unit="arcsec" ucd="phys.angSize;src"
			description="Apparent radius of the target">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>

		<!-- Solar System Objects extension -->

		<column name="mean_radius" type="double precision"
			unit="km" ucd="phys.size.radius"
			description="Mean radius of a solar system object.">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="equatorial_radius" type="double precision"
			unit="km" ucd="phys.size.radius"
			description="Equatorial radius of a solar system object.">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="polar_radius" type="double precision"
			unit="km" ucd="phys.size.radius"
			description="Polar radius of a solar system object.">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="mass" type="double precision"
			unit="kg" ucd="phys.mass"
			description="Mass of object">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="diameter" type="double precision"
			unit="km" ucd="phys.size.diameter"
			description="Target diameter, or equivalent diameter for binary objects">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="sidereal_rotation_period" type="double precision"
			unit="h" ucd="time.period.rotation"
			description="Object rotation rate">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="dynamical_class" type="text"
			ucd="meta.code.class;src"
			description="Class of small body, from a controlled vocabulary (see
				the EPN-TAP specification)">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="dynamical_type" type="text"
			ucd="meta.code.class;src"
			description="Subdivision of the dynamical class, from a controlled
				vocabulary">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>
		<column name="taxonomy_code" type="text"
			ucd="src.class.color"
			description="Code for target taxonomy">
			<property key="std">1</property>
			<property key="extsect">solar system objects</property>
		</column>

		<!-- Maps extension -->

		<column name="map_projection" type="text"
			ucd="pos.projection"
			description="The map projection, preferably as a FITS name or code,
				or parameters as a free string">
			<property key="std">1</property>
			<property key="extsect">maps</property>
		</column>
		<column name="map_height" type="double precision"
			unit="pix" ucd="phys.size"
			description="Map size in px">
			<property key="std">1</property>
			<property key="extsect">maps</property>
		</column>
		<column name="map_width" type="double precision"
			unit="pix" ucd="phys.size"
			description="Map size in px">
			<property key="std">1</property>
			<property key="extsect">maps</property>
		</column>
		<column name="map_scale" type="text"
			ucd="pos.wcs.scale"
			description="Format TBD">
			<property key="std">1</property>
			<property key="extsect">maps</property>
		</column>
		<column name="pixelscale_min" type="double precision"
			unit="km/pix" ucd="instr.scale;stat.min"
			description="Min pixel size at a surface">
			<property key="std">1</property>
			<property key="extsect">maps</property>
		</column>
		<column name="pixelscale_max" type="double precision"
			unit="km/pix" ucd="instr.scale;stat.max"
			description="Max pixel size at a surface">
			<property key="std">1</property>
			<property key="extsect">maps</property>
		</column>

		<!-- contributive works -->
		<column name="original_publisher" type="text"
			ucd="meta.note"
			description="Refers to the source of the data, e. g.,  in 
				compilations of experimental data">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="observer_name" type="text"
			ucd="obs.observer;meta.main"
			description="Observer name">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="observer_institute" type="text"
			ucd="meta.note"
			description="Observer institute">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="observer_id" type="integer"
			ucd="meta.id.PI"
			description="Image observer numeric identifier in service">
			<property key="std">1</property>
			<values nullLiteral="-1"/>
			<property key="extsect">contributive works</property>
		</column>
		<column name="observer_code" type="text"
			ucd="meta.id.PI"
			description="Image observer's username in service">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="observer_country" type="text"
			ucd="meta.note;obs.observer"
			description="Image observer's country of residence">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="observer_lon" type="double precision"
			ucd="obs.observer;pos.earth.lon"
			description="Observer's approximate longitude">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="observer_lat" type="double precision"
			ucd="obs.observer;pos.earth.lat"
			description="Observer's approximate latitude">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="producer_name" type="text"
			ucd="meta.note"
			description="Data producer name, especially in compilations 
				of experimental data">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>
		<column name="producer_institute" type="text"
			ucd="meta.note"
			description="Data producer institute, e. g., in compilations 
				of experimental data">
			<property key="std">1</property>
			<property key="extsect">contributive works</property>
		</column>

		<column name="magnitude" type="double precision"
			unit="mag" ucd="phys.magAbs"
			description="Absolute magnitude. For small bodies, from HG 
				magnitude system">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="flux" type="double precision"
			unit="mJy" ucd="phot.flux.density"
			description="Target flux">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>
		<column name="albedo" type="double precision"
			ucd="phys.albedo"
			description="Target albedo">
			<property key="std">1</property>
			<property key="extsect">common</property>
		</column>


		<!-- Particle spectroscopy -->

		<column name="particle_spectral_type" type="text"
			ucd="meta.id;phys.particle"
			description="The type of axis in use; this is one of ``energy`` (which
				is then in eV), ``mass`` (amu) or ``mass/charge`` (in amu/e).  If you
				use any of this, please contact the DaCHS authors; this 
				needs more work">
			<property key="std">1</property>
			<property key="extsect">particle spectroscopy</property>
		</column>
		<column name="particle_spectral_range_min" type="double precision"
			ucd="phys.mass;phys.particle;stat.min"
			description="Lower bound of the mass/energy of the particles">
			<property key="std">1</property>
			<property key="extsect">particle spectroscopy</property>
		</column>
		<column name="particle_spectral_range_max" type="double precision"
			ucd="phys.mass;phys.particle;stat.max"
			description="Upper bound of the mass/energy of the particles">
			<property key="std">1</property>
			<property key="extsect">particle spectroscopy</property>
		</column>
		<column name="particle_spectral_sampling_step_min" type="double precision"
			ucd="spect.resolution;phys.particle;stat.min"
			description="Minimal separation of different values in the spectral
			range">
			<property key="std">1</property>
			<property key="extsect">particle spectroscopy</property>
		</column>
		<column name="particle_spectral_sampling_step_max" type="double precision"
			ucd="spect.resolution;phys.particle;stat.max"
			description="Maximal separation of different values in the spectral
			range">
			<property key="std">1</property>
			<property key="extsect">particle spectroscopy</property>
		</column>
		<column name="particle_spectral_resolution_min" type="double precision"
			ucd="spect.resolution;phys.particle;stat.min"
			description="Best resolution of the spectral range">
			<property key="std">1</property>
			<property key="extsect">particle spectroscopy</property>
		</column>
		<column name="particle_spectral_resolution_max" type="double precision"
			ucd="spect.resolution;phys.particle;stat.max"
			description="Worst resolution of the spectral range">
			<property key="std">1</property>
			<property key="extsect">particle spectroscopy</property>
		</column>

		<!-- Experimental spectroscopy -->

		<column name="sample_id" type="text"
			ucd="meta.id;src"
			description="Additional ID of the sample, e.g., a specific fraction of a
				meteorite (in addition to target_name). Intended to refer to a
				pre-existing catalogue of a collection, will therefore contain
				a name/id mainly for local use">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="sample_classification" type="text"
			ucd="meta.note;phys.composition"
			description="Information related to class, sub-class, species… as hash
				list">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="sample_inchikey" type="text"
			ucd="phys.composition"
			description="Machine-readable description of the species involved.
			Can be a hash list">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="grain_size_min" type="double precision"
			unit="um" ucd="phys.size;stat.min"
			description="Min sample particle size">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="grain_size_max" type="double precision"
			unit="um" ucd="phys.size;stat.max"
			description="Max sample particle size">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="azimuth_min" type="double precision"
			unit="deg" ucd="pos.azimuth;stat.min"
			description="Min azimuth angle for illumination">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="azimuth_max" type="double precision"
			unit="deg" ucd="pos.azimuth;stat.max"
			description="Max azimuth angle for illumination">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="pressure" type="double precision"
			unit="1e5 Pa" ucd="phys.pressure"
			description="Ambient pressure">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="temperature" type="double precision"
			unit="K" ucd="phys.temperature"
			description="Ambient temperature">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="sample_desc" type="text"
			ucd="meta.note"
			description="Describes the sample, its origin, and possible preparation.
				Can be a hash list">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="setup_desc" type="text"
			ucd="meta.note"
			description="Describes the experimental setup. Can be a hash list">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="data_calibration_desc" type="text"
			ucd="meta.note"
			description="Provides information on post-processing. Can be a hash list">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="geometry_type" type="text"
			ucd="meta.note;instr.setup"
			description="Type of observation, from a controlled vocabulary (cf.
				EPN-TAP specification). Can be a hash list">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="spectrum_type" type="text"
			ucd="meta.note;instr.setup"
			description="Type of spectral observation, from a controlled vocabulary
			(under construction). Can be a hash list">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>
		<column name="measurement_atmosphere" type="text"
			ucd="meta.note;phys.pressure"
			description="Describes experimental conditions. ``vacuum'' for 
				measurements under vacuum">
			<property key="std">1</property>
			<property key="extsect">experimental spectroscopy</property>
		</column>

		<!-- APIS extension -->

		<column name="obs_mode" type="text"
			ucd="meta.code;instr.setup"
			description="Observing mode">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>
		<column name="detector_name" type="text"
			ucd="meta.id;instr.det"
			description="Detector name">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>
		<column name="opt_elem" type="text"
			ucd="meta.id;instr.param"
			description="Optical element name">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>
		<column name="north_pole_position" type="double precision"
			unit="deg" ucd="pos.posAng"
			description="North pole position angle with respect to celestial north
				pole">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>
		<column name="target_primary_hemisphere" type="text"
			ucd="meta.id;obs.field"
			description="Primary observed hemisphere">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>
		<column name="target_secondary_hemisphere" type="text"
			ucd="meta.id;obs.field"
			description="Secondary observed hemisphere">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>
		<column name="orientation" type="double precision"
			ucd="pos.posAng"
			description="Position angle of image y axis (on sky only)">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>
		<column name="platesc" type="double precision"
			unit="arcsec/pix" ucd="instr.scale"
			description="pixel angular size or platescale (on sky only)">
			<property key="std">1</property>
			<property key="extsect">APIS</property>
		</column>

		<!-- Events extension -->

		<column name="event_type" type="text"
			ucd="meta.code.class"
			description="Type of event from a controlled vocabulary (meteor_shower,
			fireball, lunar_flash, comet_tail_crossing...)">
			<property key="std">1</property>
			<property key="extsect">events</property>
		</column>
		<column name="event_status" type="text"
			ucd="meta.code.status"
			description="One of prediction, observation, or utility">
			<property key="std">1</property>
			<property key="extsect">events</property>
		</column>
		<column name="event_cite" type="text"
			ucd="meta.code.status"
			description="Following VOEvent, this is one of followup,
				supersedes, retraction">
			<property key="std">1</property>
			<property key="extsect">events</property>
		</column>

		<!-- Orbital Elements extension -->
		<column name="semi_major_axis" type="double precision"
			unit="AU" ucd="phys.size.smajAxis"
			description="">
			<property key="std">1</property>
			<property key="extsect">orbital elements</property>
		</column>
		<column name="inclination" type="double precision"
			ucd="src.orbital.inclination"
			description="Orbit inclination">
			<property key="std">1</property>
			<property key="extsect">orbital elements</property>
		</column>
		<column name="eccentricity" type="double precision"
			ucd="src.orbital.eccentricity"
			description="Orbit eccentricity">
			<property key="std">1</property>
			<property key="extsect">orbital elements</property>
		</column>
		<column name="long_asc" type="double precision"
			unit="deg" ucd="src.orbital.node"
			description="Longitude of ascending node, J2000.0">
			<property key="std">1</property>
			<property key="extsect">orbital elements</property>
		</column>
		<column name="arg_perihel" type="double precision"
			unit="deg" ucd="src.orbital.periastron"
			description="Argument of Perihelion, J2000.0">
			<property key="std">1</property>
			<property key="extsect">orbital elements</property>
		</column>
		<column name="mean_anomaly" type="double precision"
			unit="deg" ucd="src.orbital.meanAnomaly"
			description="Mean anomaly at the epoch">
			<property key="std">1</property>
			<property key="extsect">orbital elements</property>
		</column>
		<column name="epoch" type="double precision"
			unit="d" ucd="time.epoch"
			description="Epoch of interest">
			<property key="std">1</property>
			<property key="extsect">orbital elements</property>
		</column>
	</table>

	<mixinDef id="table-2_0">

<!-- the lower part of the documentation is produced by the following
piece of python:

import textwrap
from gavo import api

accum, sects = [], {}

for col in api.resolveCrossId("//epntap2#optional_columns"):
	sects.setdefault(col.getProperty("extsect"), []).append(col)

for sectName, cols in sorted(sects.items()):
	sectName = f"The {sectName} extension"
	accum.append("\n"+sectName+"\n"+("."*len(sectName)))
	for col in sorted(cols, key=lambda c: c.name):
		accum.append(f":{col.name}:")
		accum.append(textwrap.indent(textwrap.fill(col.description), "  "))

print(textwrap.indent("\n".join(accum), "\t\t\t"))
-->


		<doc><![CDATA[
			This mixin defines a table suitable for publication via the
			`EPN-TAP protocol`_.

			According to the standard definition, tables mixing this in
			should be called ``epn_core``.  The mixin already arranges
			for the table to be accessible by ADQL and be on disk.

			This also causes the product table to be populated.
			This means that grammars feeding such tables need a 
			`//products#define`_ row filter.  At the very least, you need to say::

				<rowfilter procDef="//products#define">
					<bind name="table">"\schema.epn_core"</bind>
				</rowfilter>

			If you absolutely cannot use //products#define, you will hve 
			to manually provide the prodtblFsize (file size in *bytes*),
			prodtblAccref (product URL), and prodtblPreview (thumbnail image
			or None) keys in what's coming from your grammar.

			Use the `//epntap2#populate-2_0`_ apply in rowmakers
			feeding tables mixing this in.

			.. _EPN-TAP protocol: https://ivoa.net/documents/EPNTAP/

			The mixin has a parameter ``optional_columns``, which accepts
			space-separated columns from the following extensions:

			The APIS extension
			..................
			:detector_name:
			  Detector name
			:north_pole_position:
			  North pole position angle with respect to celestial north pole
			:obs_mode:
			  Observing mode
			:opt_elem:
			  Optical element name
			:orientation:
			  Position angle of image y axis (on sky only)
			:platesc:
			  pixel angular size or platescale (on sky only)
			:target_primary_hemisphere:
			  Primary observed hemisphere
			:target_secondary_hemisphere:
			  Secondary observed hemisphere

			The common extension
			....................
			:access_estsize:
			  Estimated file size in kbyte.
			:access_format:
			  File format type (RFC 6838 Media Type a.k.a. MIME type)
			:access_md5:
			  MD5 Hash for the file
			:access_url:
			  URL of the data file, case sensitive. If present, then access_format
			  and access_estsize are mandatory.
			:acquisition_id:
			  ID of the data file/acquisition in the original archive
			:albedo:
			  Target albedo
			:alt_target_name:
			  Provides alternative target name if more common (e.g. comets);
			  multiple identifiers can be separated by hashes
			:altitude_fromshape_max:
			  Max altitude of observed area above shape model / DTM
			:altitude_fromshape_min:
			  Min altitude of observed area above shape model / DTM
			:bib_reference:
			  Bibcode or DOI preferred if available, or other bibliographic
			  identifier or URL
			:campaign:
			  Name of the observational campaign
			:datalink_url:
			  Link to a datalink document for this dataset
			:dec:
			  Declination
			:earth_distance_max:
			  Max Earth-target distance
			:earth_distance_min:
			  Min Earth-target distance
			:external_link:
			  Web page providing more details on this granule
			:feature_name:
			  Secondary name (can be standard name of region of interest)
			:file_name:
			  Name of the data file only, case sensitive
			:filter:
			  Identifies filter in use, typically for images
			:flux:
			  Target flux
			:instrument_type:
			  type of instrument
			:internal_reference:
			  Related granule_uid(s) in the current service; hash-separated
			:local_time_max:
			  Max local time at observed region
			:local_time_min:
			  Min local time at observed region
			:magnitude:
			  Absolute magnitude. For small bodies, from HG magnitude system
			:messenger:
			  Vector of measured signal, including electromagnetic band, from
			  http://www.ivoa.net/rdf/messenger
			:original_publisher:
			  Refers to the source of the data, e. g., in compilations of
			  experimental data
			:proposal_id:
			  Proposal identifier
			:proposal_pi:
			  Proposal principal investigator
			:proposal_target_name:
			  target name as in proposal title
			:proposal_title:
			  Proposal title
			:publisher:
			  A short string identifying the entity running the data service used
			:ra:
			  Right ascension
			:radial_distance_max:
			  Max distance from observed area to body center
			:radial_distance_min:
			  Min distance from observed area to body center
			:shape:
			  (ST)MOC footprint, valid for celestial, spherical, or body-fixed
			  frames + time coverage
			:solar_longitude_max:
			  Max Solar longitude Ls (location on orbit / season)
			:solar_longitude_min:
			  Min Solar longitude Ls (location on orbit / season)
			:spatial_coordinate_description:
			  ID of specific coordinate system and version or properties.
			:spatial_origin:
			  Defines the frame origin
			:species:
			  Identifies a chemical species, case sensitive
			:subobserver_latitude_max:
			  Maximum sub-observer point latitude (sub-Earth for ground based
			  observations)
			:subobserver_latitude_min:
			  Minimum sub-observer point latitude (sub-Earth for ground based
			  observations)
			:subobserver_longitude_max:
			  Maximum sub-observer point longitude (sub-Earth for ground based
			  observations)
			:subobserver_longitude_min:
			  Minimum sub-observer point longitude (sub-Earth for ground based
			  observations)
			:subsolar_latitude_max:
			  Maximum sub-solar point latitude
			:subsolar_latitude_min:
			  Minimum sub-solar point latitude
			:subsolar_longitude_max:
			  Maximum sub-solar point longitude
			:subsolar_longitude_min:
			  Minimum sub-solar point longitude
			:sun_distance_max:
			  Max Sun-target distance
			:sun_distance_min:
			  Min Sun-target distance
			:target_apparent_radius:
			  Apparent radius of the target
			:target_description:
			  Original target keywords
			:target_distance_max:
			  Max observer-target distance
			:target_distance_min:
			  Min observer-target distance
			:target_region:
			  Type of region or feature of interest
			:target_time_max:
			  Max observing time in target frame
			:target_time_min:
			  Min observing time in target frame
			:thumbnail_url:
			  URL of a thumbnail image with predefined size (png ~200 pix, for use
			  in a client only)
			:time_refposition:
			  Defines where the time is measured (e.g., ground vs. spacecraft).
			  Defaults to the observer's frame
			:time_scale:
			  Defaults to UTC in data services; takes values from
			  http://www.ivoa.net/rdf/time_scale otherwise

			The contributive works extension
			................................
			:observer_code:
			  Image observer's username in service
			:observer_country:
			  Image observer's country of residence
			:observer_id:
			  Image observer numeric identifier in service
			:observer_institute:
			  Observer institute
			:observer_lat:
			  Observer's approximate latitude
			:observer_lon:
			  Observer's approximate longitude
			:observer_name:
			  Observer name
			:producer_institute:
			  Data producer institute, e. g., in compilations of experimental data
			:producer_name:
			  Data producer name, especially in compilations of experimental data

			The events extension
			....................
			:event_cite:
			  Following VOEvent, this is one of followup, supersedes, retraction
			:event_status:
			  One of prediction, observation, or utility
			:event_type:
			  Type of event from a controlled vocabulary (meteor_shower, fireball,
			  lunar_flash, comet_tail_crossing...)

			The experimental spectroscopy extension
			.......................................
			:azimuth_max:
			  Max azimuth angle for illumination
			:azimuth_min:
			  Min azimuth angle for illumination
			:data_calibration_desc:
			  Provides information on post-processing. Can be a hash list
			:geometry_type:
			  Type of observation, from a controlled vocabulary (cf. EPN-TAP
			  specification). Can be a hash list
			:grain_size_max:
			  Max sample particle size
			:grain_size_min:
			  Min sample particle size
			:measurement_atmosphere:
			  Describes experimental conditions. ``vacuum`` for measurements under
			  vacuum
			:pressure:
			  Ambient pressure
			:sample_classification:
			  Information related to class, sub-class, species… as hash list
			:sample_desc:
			  Describes the sample, its origin, and possible preparation. Can be a
			  hash list
			:sample_id:
			  Additional ID of the sample, e.g., a specific fraction of a meteorite
			  (in addition to target_name). Intended to refer to a pre-existing
			  catalogue of a collection, will therefore contain a name/id mainly for
			  local use
			:sample_inchikey:
			  Machine-readable description of the species involved. Can be a hash
			  list
			:setup_desc:
			  Describes the experimental setup. Can be a hash list
			:spectrum_type:
			  Type of spectral observation, from a controlled vocabulary (under
			  construction). Can be a hash list
			:temperature:
			  Ambient temperature

			The maps extension
			..................
			:map_height:
			  Map size in px
			:map_projection:
			  The map projection, preferably as a FITS name or code, or parameters
			  as a free string
			:map_scale:
			  Format TBD
			:map_width:
			  Map size in px
			:pixelscale_max:
			  Max pixel size at a surface
			:pixelscale_min:
			  Min pixel size at a surface

			The orbital elements extension
			..............................
			:arg_perihel:
			  Argument of Perihelion, J2000.0
			:eccentricity:
			  Orbit eccentricity
			:inclination:
			  Orbit inclination
			:long_asc:
			  Longitude of ascending node, J2000.0
			:mean_anomaly:
			  Mean anomaly at the epoch
			:semi_major_axis:


			The particle spectroscopy extension
			...................................
			:particle_spectral_range_max:
			  Upper bound of the mass/energy of the particles
			:particle_spectral_range_min:
			  Lower bound of the mass/energy of the particles
			:particle_spectral_resolution_max:
			  Worst resolution of the spectral range
			:particle_spectral_resolution_min:
			  Best resolution of the spectral range
			:particle_spectral_sampling_step_max:
			  Maximal separation of different values in the spectral range
			:particle_spectral_sampling_step_min:
			  Minimal separation of different values in the spectral range
			:particle_spectral_type:
			  The type of axis in use; this is one of ``energy`` (which is then in
			  eV), ``mass`` (amu) or ``mass/charge`` (in amu/e). If you use any of
			  this, please contact the DaCHS authors; this needs more work

			The solar system objects extension
			..................................
			:diameter:
			  Target diameter, or equivalent diameter for binary objects
			:dynamical_class:
			  Class of small body, from a controlled vocabulary (see the EPN-TAP
			  specification)
			:dynamical_type:
			  Subdivision of the dynamical class, from a controlled vocabulary
			:equatorial_radius:
			  Equatorial radius of a solar system object.
			:mass:
			  Mass of object
			:mean_radius:
			  Mean radius of a solar system object.
			:polar_radius:
			  Polar radius of a solar system object.
			:sidereal_rotation_period:
			  Object rotation rate
			:taxonomy_code:
			  Code for target taxonomy
		]]></doc>

		<mixinPar key="spatial_frame_type" description="Flavour of the 
			coordinate system.  Since this determines the units of the
			coordinates columns, this must be set globally for the
			entire dataset. Values defined by EPN-TAP and understood
			by this mixin include celestial, body, cartesian, cylindrical, 
			spherical, none." />
		<mixinPar key="optional_columns" description="Space-separated list
			of names of optional columns to include.  For the column names 
			available include see sect. 3 of the EPN-TAP specification or
			the list of the various sections above."
			>__EMPTY__</mixinPar>

		<processEarly>
			<setup>
				<code>
					from gavo import base
					from gavo import rscdef
					from gavo.protocols import sdm
					
					META_BY_FRAME_TYPE = {
						# (units, ucds, descriptions)
						"celestial": (
							("deg", "deg", "AU"),
							("pos.eq.ra", "pos.eq.dec", "pos.distance"),
							(	"Right Ascension (ICRS)",
								"Declination (ICRS)",
								"Distance from coordiate origin")),

						"body": (
							("deg", "deg", "km"),
							("pos.bodyrc.lon", "pos.bodyrc.lat", "pos.bodyrc.alt"),
							(	"Longitude on body",
								"Latitude on body",
								"Altitude from reference surface")),

						"cartesian": (
							("km", "km", "km"),
							("pos.cartesian.x", "pos.cartesian.y", "pos.cartesian.z"),
							(	"Cartesian coordinate in x direction",
								"Cartesian coordinate in y direction",
								"Cartesian coordinate in z direction")),

						"spherical": (
							("m", "deg", "deg"),
							("pos.distance", "pos.az.zd", "pos.az.azi"),
							(	"Radial distance in spherical coordinates",
								"Polar angle or colatitude in spherical coordinates",
								"Azimuth in spherical coordinates")),

						"cylindrical": (
							("km", "deg", "km"),
							("pos.distance", "pos.az.azi", "pos.distance"),
							(	"Radial distance in cylindrical coordinates",
								"Azimuth in cylindrical coordinates",
								"Height in cylindrical coordinates")),

						"none": (
							("", "", ""),
							("", "", ""),
							("", "", "")),
						}

					# maps coordinate UCDs to resolution UCDs as per table note 2
					RESOLUTION_UCD = {
						"pos": "pos.resolution",
						"pos.az.ai": "pos.angResolution",
						"pos.distance": "pos.resolution",
						"pos.az.zd": "pos.angResolution",
						"pos.az.azi": "pos.angResolution",
						"pos.eq.ra": "pos.angResolution",
						"pos.eq.dec": "pos.angResolution",
						"pos.bodyrc.lon": "pos.angResolution",
						"pos.bodyrc.lat": "pos.angResolution",
						"pos.bodyrc.alt": "pos.resolution",
						"pos.cartesian.x": "pos.resolution",
						"pos.cartesian.y": "pos.resolution",
						"pos.cartesian.z": "pos.resolution",
					}

					def setFrameMeta(tableDef, spatialFrameType):
						if spatialFrameType not in META_BY_FRAME_TYPE:
							raise base.StructureError("Unknown EPN-TAP frame type: %s."%
									spatialFrameType,
								hint="Known frame types are: %s"%(
									", ".join(META_BY_FRAME_TYPE)))

						units, ucds, descriptions = META_BY_FRAME_TYPE[spatialFrameType]
						for cooIndex in range(3):
							prefix = "c%d"%(cooIndex+1)
							for postfix in ["min", "max", 
									"_resol_min", "_resol_max"]:
								col = tableDef.getColumnByName(prefix+postfix)

								if units[cooIndex]:
									col.unit = col.unit.replace(
										"__replace_framed__", units[cooIndex])
								else:
									col.unit = ""

								if ucds[cooIndex]:
									col.ucd = col.ucd.replace(
										"__replace_framed__", ucds[cooIndex])
									col.ucd = col.ucd.replace(
										"__replace_resolution_ucd__", 
										RESOLUTION_UCD[ucds[cooIndex]])
								else:
									col.ucd = ""
								
								if descriptions[cooIndex]:
									col.description = col.description.replace(
										"__replace_framed__", descriptions[cooIndex])
								else:
									col.description = ("(This data collection does not give"
										" coordinates)")

					def addOptionalColumns(tableDef, columnNames):
						sourceTable = base.resolveCrossId("//epntap2#optional_columns")
						for columnName in columnNames.split():
							tableDef.columns.append(
								sourceTable.getColumnByName(columnName))
				</code>
			</setup>
			<code>
				setFrameMeta(substrate, mixinPars["spatial_frame_type"])
				substrate.setProperty("spatial_frame_type", 
					mixinPars["spatial_frame_type"])
				if mixinPars["optional_columns"]:
					addOptionalColumns(substrate, mixinPars["optional_columns"])
			</code>
		</processEarly>

		<events>
			<adql>True</adql>
			<onDisk>True</onDisk>
			<meta name="utype">ivo://ivoa.net/std/epntap#table-2.0</meta>
			<meta name="info" infoName="SERVICE_PROTOCOL" 
				infoValue="2.0">EPN-TAP</meta>

			<dm>
				(stc2:Coords) {
					time: {
						frame: {
							timescale: @time_scale | UTC
							refPosition: @time_refposition | TOPOCENTER
							time0: 0
						}
						location: @time_min
					}
				}
			</dm>
			<dm>
				(stc2:Coords) {
					time: {
						frame: {
							timescale: @time_scale | UTC
							refPosition: @time_refposition | TOPOCENTER
							time0: 0
						}
						location: @time_max
					}
				}
			</dm>

			<column name="granule_uid" type="text" required="True"
				ucd="meta.id"
				description="Internal table row index,
					which must be unique within the table. Can be alphanumeric.">
				<property key="std">1</property>
			</column>
			<column name="granule_gid" type="text" required="True"
				ucd="meta.id"
				description="Common to granules of same type (e.g. same map projection, 
					or geometry data products). Can be alphanumeric.">
				<property key="std">1</property>
			</column>
			<column name="obs_id" type="text" required="True"
				ucd="meta.id;obs"
				description="Associates granules derived from the same data (e.g. 
					various representations/processing levels). 
					Can be alphanumeric, may be the ID of original observation.">
				<property key="std">1</property>
			</column>
			<column name="dataproduct_type"	type="text" 
				ucd="meta.code.class"
				description="The high-level organization of the data product,
					from a controlled vocabulary (e.g., 'im' for image, sp for spectrum).
					Multiple terms may be used, separated by # characters."
				note="et_prod">
				<property key="std">1</property>
				<values>
					<option>im</option>
					<option>ma</option>
					<option>sp</option>
					<option>ds</option>
					<option>sc</option>
					<option>pr</option>
					<option>pf</option>
					<option>vo</option>
					<option>mo</option>
					<option>cu</option>
					<option>ts</option>
					<option>ca</option>
					<option>ci</option>
					<option>sv</option>
					<option>ev</option>
				</values>
			</column>
			<column name="target_name"	type="text" 
				ucd="meta.id;src"
				description="Standard IAU name of target (from a list related 
					to target class), case sensitive">
				<property key="std">1</property>
			</column>
			<column name="target_class"	type="text" 
				ucd="src.class"
				description="Type of target, from a controlled vocabulary.">
				<property key="std">1</property>
				<values>
					<option>asteroid</option>
					<option>dwarf_planet</option>
					<option>planet</option>
					<option>satellite</option>
					<option>comet</option>
					<option>exoplanet</option>
					<option>interplanetary_medium</option>
					<option>sample</option>
					<option>sky</option>
					<option>spacecraft</option>
					<option>spacejunk</option>
					<option>star</option>
					<option>calibration</option>
				</values>
			</column>

			<column name="time_min"	
				ucd="time.start;obs" unit="d"
				type="double precision"
				description="Acquisition start time (in JD), as UTC at
				time_refposition"/>
			<column name="time_max"	
				ucd="time.end;obs" unit="d"
				type="double precision"
				description="Acquisition stop time (in JD), as UTC at
				time_refposition"/>

			<FEED source="_minmax"
				basename="time_sampling_step"
				baseucd="time.resolution" unit="s"
				basedescr="Sampling time for measurements of dynamical
					phenomena"/>
			<FEED source="_minmax"
				basename="time_exp"
				baseucd="time.duration;obs.exposure" unit="s"
				basedescr="Integration time of the measurement"/>
			<FEED source="_minmax"
				basename="spectral_range"
				baseucd="em.freq" unit="Hz"
				basedescr="Spectral range (frequency)"/>

			<FEED source="_minmax"
				basename="spectral_sampling_step"
				baseucd="em.freq;spect.binSize" unit="Hz"
				basedescr="Spectral sampling step"/>
			<FEED source="_minmax"
				basename="spectral_resolution"
				baseucd="spect.resolution" unit=""
				basedescr="Spectral resolution"/>

			<FEED source="_c_minmax"
				basename="c1"
				baseucd="__replace_framed__" unit="__replace_framed__"
				basedescr="__replace_framed__"/>
			<FEED source="_c_minmax"
				basename="c2"
				baseucd="__replace_framed__" unit="__replace_framed__"
				basedescr="__replace_framed__"/>
			<FEED source="_c_minmax"
				basename="c3"
				baseucd="__replace_framed__" unit="__replace_framed__"
				basedescr="__replace_framed__"/>

			<column name="s_region"	type="spoly"  xtype="adql:REGION"
				ucd="pos.outline;obs.field" unit="" 
				description="ObsCore-like footprint, valid for celestial, 
					spherical, or body-fixed frames">
				<property key="std">1</property>
			</column>
			<FEED source="_minmax"
				basename="c1_resol"
				baseucd="__replace_resolution_ucd__" unit="__replace_framed__"
				basedescr="Resolution in the first coordinate"/>
			<FEED source="_minmax"
				basename="c2_resol"
				baseucd="__replace_resolution_ucd__" unit="__replace_framed__"
				basedescr="Resolution in the second coordinate"/>
			<FEED source="_minmax"
				basename="c3_resol"
				baseucd="__replace_resolution_ucd__" unit="__replace_framed__"
				basedescr="Resolution in the third coordinate"/>

			<column name="spatial_frame_type"	type="text" 
				ucd="meta.code.class;pos.frame"
				description="Flavor of coordinate system, 
					defines the nature of coordinates. From a controlled vocabulary,
					where 'none' means undefined.">
				<property key="std">1</property>
				<values default="\spatial_frame_type">
					<option>celestial</option>
					<option>body</option>
					<option>cartesian</option>
					<option>cylindrical</option>
					<option>spherical</option>
					<option>none</option>
				</values>
			</column>
			<FEED source="_minmax"
				basename="incidence"
				baseucd="pos.incidenceAng" unit="deg"
				basedescr="Incidence angle (solar zenithal angle) during
					data acquisition"/>
			<FEED source="_minmax"
				basename="emergence"
				baseucd="pos.emergenceAng" unit="deg"
				basedescr="Emergence angle during data acquisition"/>
			<FEED source="_minmax"
				basename="phase"
				baseucd="pos.phaseAng" unit="deg"
				basedescr="Phase angle during data acquisition"/>
			<column name="instrument_host_name"	type="text" 
				ucd="meta.id;instr.obsty"
				description="Standard name of the observatory or spacecraft">
				<property key="std">1</property>
			</column>
			<column name="instrument_name"	type="text" 
				ucd="meta.id;instr" 
				description="Standard name of instrument">
				<property key="std">1</property>
			</column>
			<column name="measurement_type"	type="text" 
				ucd="meta.ucd" 
				description="UCD(s) defining the data, with multiple entries
					separated by hash (#) characters.">
				<property key="std">1</property>
			</column>

			<column name="processing_level" type="integer" required="True"
				ucd="meta.calibLevel"
				description="Dataset-related encoding, or simplified CODMAC
					calibration level"
				note="et_cal">
				<property key="std">1</property>
			</column>

			<column name="creation_date" type="timestamp" 
				ucd="time.creation" 	unit=""
				description="Date of first entry of this granule">
				<property key="std">1</property>
			</column>
			<column name="modification_date" type="timestamp" 
				ucd="time.processing" unit=""
				description="Date of last modification (used to handle mirroring)">
				<property key="std">1</property>
			</column>
			<column name="release_date" type="timestamp" 
				ucd="time.release" 	unit=""
				description="Start of public access period">
				<property key="std">1</property>
			</column>

			<column name="service_title"	type="text" 
				ucd="meta.title" 
				description="Title of resource (an acronym really, 
								will be used to handle multiservice results)">
				<property key="std">1</property>
			</column>


			<meta name="note" tag="et_prod">
				The following values are defined for this field:

				im -- image
					associated scalar fields with two spatial axes, e.g., images with
					multiple color planes like from multichannel or filter cameras. 
					Preview images (e.g. map with axis and caption) also belong here. 
					Conversely, all vectorial 2D fields are described as catalogue 
					(see below).
				ma -- map
					scalar field/rasters with two spatial axes covering a large 
					area and projected either on the sky or on a planetary body, 
					associated to a Projection parameter (with a short enumerated 
					list of possible values).  This is mostly intended to identify 
					complete coverages that can be used as reference basemaps.
				sp-- spectrum
					measurements organized primarily along a spectral axis, e.g., 
					radiance spectra. This includes spectral aggregates (series 
					of related spectra with non-connected spectral ranges, e.g., 
					from several channels of the same instrument 
				ds -- dynamic spectrum
					consecutive spectral measurements through time, organized 
					as a time series. This typically implies successive spectra of 
					the same target or field of view.
				sc -- spectral cube
					sets of spectral measurements with 1 or 2 D spatial coverage, e.g.,
					imaging spectroscopy. The choice between Image and spectral_cube is
					related to the characteristics of the instrument (which dimension 
					is most resolved and which dimensions are acquired simultaneously). 
					The choice between dynamic_spectrum and spectral_cube is related 
					to the uniformity of the field of view.
				pr -- profile
					scalar or vectorial measurements along 1 spatial dimension, e.g.,
					atmospheric profiles, atmospheric paths, sub-surface profiles, 
					traverses…
				pf -- photometric profile
					scalar or vectorial measurements along 1 angular dimension, e.g., 
					phase or polarization curves, phase functions, emission-phase 
					function sequences… typically associated to variations in 
					illumination angle parameters.
				vo -- volume
					other measurements with 3 spatial dimensions, e.g., internal or
					atmospheric structures, including shells/shape models (3D surfaces).
				mo -- movie
					sets of chronological 2 D spatial measurements.
				cu -- cube
					multidimensional data with 3 or more axes, e.g., all that is not
					described by other 3 D data types such as spectral cubes or volume.
					This is mostly intended to accommodate unusual data with multiple 
					dimensions.
				ts -- time series
					measurements organized primarily as a function of time (with 
					exception of dynamical spectra and movies, i.e. usually a scalar 
					quantity). Typical examples of time series include space-borne 
					dust detector measurements, daily or seasonal curves measured at 
					a given location (e.g., a lander), and light curves.
				ca -- catalog 
					applies to a single granule providing a list of events, a catalog 
					of object parameters, a list of features… It is good practice to 
					describe the type of data included in the catalogue using a 
					hash-separated-list (e.g., a table of spectra should be described 
					by ca#sp, so that it will respond to a query for spectra).
				ci -- catalogue item
					applies when the service itself provides a catalogue, with entries 
					described as individual granules. The service can be, e.g., a list
					of asteroid properties or spectral lines. Catalogue_item can be 
					limited to scalar quantities (including strings), and possibly to 
					a single element. This organization allows the user to search inside 
					the catalogue from the TAP query interface.
				sv -- spatial vector
					vector information associated to localization, such as spatial
					footprints or a GIS-related element.  This could contain a kml 
					or geojson file (STC-S strings are provided though the s_region 
					parameter, though). This includes maps of vectors, e.g., wind maps.
				ev -- event
					individual events, typically formatted in VOEvent. Characteristics 
					are provided via the event_* parameters.
			</meta>

			<meta name="note" tag="et_cal">
				CODMAC levels are:

				1 -- raw

				2 -- edited

				3 -- calibrated

				4 -- resampled

				5 -- derived

				6 -- ancillary
			</meta>
		</events>

	</mixinDef>


	<mixinDef id="localfile-2_0">
		<doc>
			Use this mixin if your epntap table is filled with local products
			(i.e., sources matches files on your hard disk that DaCHS should
			hand out itself).  This will arrange for your products to be
			entered into the products table, and it will automatically
			compute file size, etc.

			This wants a `//products#define`_ rowfilter in your grammar
			and a `//epntap2#populate-localfile-2_0`_ apply in your rowmaker.
		</doc>
		<events>
			<index columns="accref"/>
			<column original="//products#products.accref" hidden="True"/>
		</events>
		<FEED source="//products#hackProductsData"/>
	</mixinDef>


	<procDef type="apply" id="populate-2_0">
		<doc><![CDATA[
			Sets metadata for an epntap data set, including its products definition.

			The values are left in vars, so you need to do manual copying,
			e.g., using idmaps="*".

			In some descriptions below, you will see __replace_framed__.  This
			means that the actual descriptions, units, and UCDs will depend
			on the value of spatial_frame_type in `the //epntap2#table-2_0 mixin`_.
			After you have made a first (possibly severely incomplete) import
			of your table, you can see the actual metadata by opening
			http://localhost:8080/tableinfo/yourschema.epn_core.
		]]></doc>

		<setup>
			<par key="index_" description="A numeric reference for the
				item.  By default, this is just the row number.  As this will
				(usually) change when new data is added, you should override it
				with some unique integer number specific to the data product 
				when there is such a thing." late="True">\rowsMade</par>
			<par key="target_name" description="Name of the target object,
				preferably according to the official IAU nomenclature.
				As appropriate, take these from the exoplanet encyclopedia
				http://exoplanet.eu, the meteor catalog at 
				http://www.lpi.usra.edu/meteor/, the catalog of stardust
				samples at http://curator.jsc.nasa.gov/stardust/catalog/" 
				late="True"/>
			<par key="time_scale" description="Time scale used for the
				various times, as given by IVOA's STC data model.  Choose
				from TT, TDB, TOG, TOB, TAI, UTC, GPS, UNKNOWN" 
				late="True">"UTC"</par>
			<par key="time_refposition" description="Indicates where the time is 
				measured, can be a planet or a spacecraft."
				late="True">"TOPOCENTER"</par>
			<par key="instrument_host_name" description="Name of the observatory
				or spacecraft that the observation originated from; for
				ground-based data, use IAU observatory codes, 
				http://www.minorplanetcenter.net/iau/lists/ObsCodesF.html,
				for space-borne instruments use
				http://nssdc.gsfc.nasa.gov/nmc/" late="True"/>
			<par key="instrument_name" description="Service providers are
				invited to include multiple values for instrument_name, e.g.,
				complete name + usual acronym. This will allow queries on either
				'VISIBLE AND INFRARED THERMAL IMAGING SPECTROMETER' or VIRTIS to
				produce the same reply." late="True">None</par>
			<par key="target_region" description="This is a complement to the
				target name to identify a substructure of the target that was
				being observed (e.g., Atmosphere, Surface).  Take terms from
				them Spase dictionary at http://www.spase-group.org or the
				IVOA thesaurus." late="True">None</par>
			<par key="target_class" description="The type of the target;
				choose from asteroid, dwarf_planet, planet, satellite, comet, 
				exoplanet, interplanetary_medium, ring, sample, sky, spacecraft, 
				spacejunk, star" late="True">"UNKNOWN"</par>
			<par key="s_region" description="A spatial footprint
				of a dataset located on a spherical coordinate system.  
				Currently, this is fixed to be a spherical polygon (fill it
				with something like
				pgsphere.SPoly.fromDALI([@long1, @lat1, @long2, @lat2,...], all
				coordinates in degrees)."
				late="True">None</par>
			<par key="processing_level" description="CODMAC calibration level; 
				see the et_cal note 
				http://dc.g-vo.org/tableinfo/titan.epn_core#note-et_cal for
				what values are defined here"
				late="True">None</par>

			<!-- Note: only late parameters allowed in here.  Also, don't
			define anything here unless you have to; we pick up the
			columns from the mixin's stream automatically. -->

			<!-- if you add more manual parameters, make sure you list them
			in overridden below -->

			<LOOP>
				<codeItems>
					# overridden is a set of column names for which the parameters
					# are manually defined above or which are set in some other way.
					overridden = set(["index_",
						"target_name", "time_scale", "time_refposition",
						"instrument_host_name", "instrument_name",
						"target_region", "target_class",
						"spatial_frame_type", "s_region", "processing_level"])

					mixin = context.getById("table-2_0")
					colDict = {}
					for type, name, content, pos in mixin.events.events_:
						if type=="value":
							colDict[name] = content
						elif type=="end":
							if name=="column":
								if colDict.get("name") not in overridden:
									if colDict.get("required", False):
										colDict["default"] = ''
									else:
										colDict["default"] = 'None'
									yield colDict
								colDict = {}
				</codeItems>
				<events>
					<par key="\name" description="\description"
						late="True">\default</par>
				</events>
			</LOOP>
			<code>
				# find myself to get the list of my parameters
				for app in parent.apps:
					if app.procDef and app.procDef.id=='populate-2_0':
						break
				else:
					raise base.Error("Internal: epntap#populate-2_0 cannot find itself")

				EPNTAP_KEYS = [p.key for p in app.procDef.setups[0].pars]
				del app
			</code>
		</setup>
		
		<code>
			l = locals()
			for key in EPNTAP_KEYS:
				vars[key] = l[key]
			vars["spatial_frame_type"] = targetTable.tableDef.getProperty(
				"spatial_frame_type", None)
		</code>
	</procDef>

	<procDef id="populate-localfile-2_0" type="apply">
		<doc>
			Use this apply when you use `the //epntap2#localfile-2_0 mixin`_.
			This will only (properly) work when you use a `//products#define`_
			rowfilter; if you have that, this will work without further 
			configuration.
		</doc>
		<setup>
			<par name="creation_date" late="True" description="A timestamp
				giving the dataset's creation time as a datetime object"
				>\sourceCDate</par>
		</setup>
		<code>			
			# map things from products#define
			vars["access_estsize"] = vars["prodtblFsize"]/1024
			vars["access_url"] = makeProductLink(vars["prodtblAccref"])
			if @prodtblPreview:
				vars["thumbnail"] = @prodtblPreview
			vars["accref"] = vars["prodtblAccref"]
			vars["creation_date"] = creation_date
		</code>
	</procDef>
</resource>
