<resource schema="zcosmos">
	<meta name="creationDate">2015-11-09T16:00:00</meta>
	<meta name="schema-rank">1000</meta>
	<meta name="title">zCOSMOS Bright Spectroscopic Observations DR2</meta>
	<meta name="creator">Bongiorno, A.</meta>
	<meta name="description" format="rst">
	The zCOSMOS redshift survey used 600h on the VIMOS spectrograph spread over
	five observing seasons (2005-2009) to obtain spectra of about 20,000 galaxies
	selected to have Iab &lt; 22.5 across the full 1.7 deg2 of the COSMOS field.
	This part, "zCOSMOS-bright", was designed to yield a high and fairly uniform
	sampling rate (about 70%), with a high success rate in measuring redshifts
	(approaching 100% at 0.5 &lt; z &lt; 0.8), and with sufficient
	velocity accuracy
	(about 100 km/s) to efficiently map the environments of galaxies down to the
	scale of galaxy groups out to redshifts z ~ 1.
	</meta>

	<meta name="subject">galaxies</meta>
	<meta name="subject">redshift-surveys</meta>
	<meta name="subject">observational-cosmology</meta>
	<meta name="subject">spectroscopy</meta>

	<meta name="source">2008Msngr.134...35L</meta>
	<meta name="type">Survey</meta>
	<meta name="instrument">VIMOS</meta>
	<meta name="facility">VLT</meta>

	<meta name="coverage.waveband">Optical</meta>

 	<meta name="ssap.dataSource">pointed</meta>
	<meta name="ssap.creationType">archival</meta>
	<meta name="ssap.testQuery">MAXREC=1</meta>

	<table id="raw_data" onDisk="True" adql="hidden"
			namePath="//ssap#instance">

		<index columns="ssa_specstart"/>
		<index columns="ssa_specend"/>

		<FEED source="//scs#splitPosIndex"
			long="degrees(long(ssa_location))" lat="degrees(lat(ssa_location))"
			columns="ssa_location"/>
		<FEED source="//ssap#obscore-time-index"/>

		<LOOP listItems="
			ssa_dateObs ssa_dstitle ssa_targname ssa_specstart
			ssa_specend ssa_length ssa_cdate
			ssa_timeExt ssa_aperture">
			<events>
				<column original="\item"/>
			</events>
		</LOOP>

		<mixin>//products#table</mixin>
		<mixin>//ssap#plainlocation</mixin>
		<mixin>//ssap#simpleCoverage</mixin>

		<column name="datalink" type="text"
			ucd="meta.ref.url"
			tablehead="Datalink"
			description="A link to a datalink document for this spectrum."
			verbLevel="15" displayHint="type=url"/>
	</table>

	<data id="import">
		<recreateAfter>make_view</recreateAfter>
		<property key="previewDir">previews</property>
		<sources recurse="True" pattern="data/zCOSMOS_BRIGHT_DR2_*.fits"/>

		<fitsProdGrammar qnd="True">
			<rowfilter procDef="//products#define">
				<bind name="table">"\schema.data"</bind>
				<bind name="mime">"application/fits"</bind>
				<bind name="preview">\standardPreviewPath</bind>
				<bind name="preview_mime">"image/png"</bind>
			</rowfilter>
		</fitsProdGrammar>


		<make table="raw_data">
			<rowmaker idmaps="*">
				<var name="specAx">getWCSAxis(@header_, 1)</var>
				<var name="ssa_aperture">vars["ESO INS ADF SKYREG"]/3600.</var>

				<apply procDef="//ssap#fill-plainlocation">
					<bind name="ra">@RA</bind>
					<bind name="dec">@DEC</bind>
					<bind name="aperture">@ssa_aperture</bind>
				</apply>

				<map key="ssa_dateObs">dateTimeToMJD(parseTimestamp(@DATE_OBS,
					"%Y-%m-%d %H:%M:%S"))</map>
				<map key="ssa_dstitle">"{} {}".format(
					@TELESCOP, vars["ESO OBS ID"])</map>
				<map key="ssa_targname">"ICRS %s %s"%(@RA, @DEC)</map>
				<map key="ssa_specstart">@specAx.pixToPhys(1)*1e-10</map>
				<map name="ssa_specend"
						>@specAx.pixToPhys(@specAx.axisLength)*1e-10</map>
				<map name="ssa_length">@specAx.axisLength</map>
				<map name="ssa_timeExt">@EXPTIME</map>
				<map name="ssa_cdate">@DATE</map>

				<map name="datalink">\dlMetaURI{sdl}</map>
			</rowmaker>
		</make>
	</data>


	<table id="data" adql="True">
		<meta name="_associatedDatalinkService">
			<meta name="serviceId">sdl</meta>
			<meta name="idColumn">ssa_pubDID</meta>
		</meta>

		<mixin
			sourcetable="raw_data"
			copiedcolumns="*"
			ssa_aperture="1/3600."
			ssa_bandpass="'IR, Optical, UV'"
			ssa_collection="'zcosmos'"
			ssa_fluxcalib="'RELATIVE'"
			ssa_fluxucd="'phot.flux.density;em.wl'"
			ssa_instrument="'VIMOS'"
			ssa_speccalib="'ABSOLUTE'"
			ssa_specres="2.5e-10"
			ssa_spectralucd="'em.wl;obs.atmos'"
			ssa_fluxunit="''"
			ssa_spectralunit="'Angstrom'"
			ssa_targclass="'X'"
		>//ssap#view</mixin>

		<mixin
			calibLevel="1"
			coverage="ssa_region"
			sResolution="ssa_spaceRes"
			oUCD="ssa_fluxucd"
			emUCD="ssa_spectralucd"
			createDIDIndex="true"
			>//obscore#publishSSAPMIXC</mixin>
	</table>

	<coverage>
		<updater sourceTable="data"/>
	</coverage>

	<data id="make_view" auto="False">
		<make table="data"/>
	</data>

	<table id="spectrum">
		<mixin ssaTable="data"
			fluxDescription="Relative Flux"
			spectralDescription="Wavelength"
			>//ssap#sdm-instance</mixin>
	</table>

	<data id="build_sdm_data" auto="False">
		<embeddedGrammar>
			<iterator>
				<setup>
					<code>
						from gavo.protocols import products
						from gavo.utils import pyfits
					</code>
				</setup>
				<code>

				fitsPath = products.RAccref.fromString(
						self.sourceToken["accref"]).localpath
				hdus = pyfits.open(fitsPath)
				ax = utils.getWCSAxis(hdus[0].header, 1)

				for spec, flux in enumerate(hdus[0].data[0]):
					yield {"spectral": ax.pix0ToPhys(spec), "flux": flux}
				hdus.close()
				</code>
			</iterator>
		</embeddedGrammar>
		<make table="spectrum">
			<parmaker>
				<apply procDef="//ssap#feedSSAToSDM"/>
			</parmaker>
		</make>
	</data>

	<service id="sdl" allowed="dlget,dlmeta,static">
		<meta name="title">zCosmos Datalink Service</meta>
		<meta name="description">Slicing, dicing, and format conversion for
			the zCOSMOS spectra</meta>

		<!-- the static renderer above is so we can hand out the original
			FITS-es in the datalink #progenitor line.  Remove this if
			you don't want this backdoor to your product files, in particular
			if you have access control in place. -->
		<property name="staticData">data</property>

		<datalinkCore>
			<descriptorGenerator procDef="//soda#sdm_genDesc">
				<bind name="ssaTD">"\rdId#data"</bind>
			</descriptorGenerator>
			<dataFunction procDef="//soda#sdm_genData">
				<bind name="builder">"\rdId#build_sdm_data"</bind>
			</dataFunction>
			<FEED source="//soda#sdm_plainfluxcalib"/>
			<FEED source="//soda#sdm_cutout"/>
			<FEED source="//soda#sdm_format"/>

			<metaMaker semantics="#progenitor">
				<code>
					if descriptor.pubDID is None:
						return
					yield descriptor.makeLinkFromFile(
						base.getConfig("inputsDir") / descriptor.accref,
						description="Spectrum as the original 1D array")
				</code>
			</metaMaker>
		</datalinkCore>
	</service>

	<service id="web" defaultRenderer="form">
		<meta name="shortName">zCosmos Web</meta>
		<meta name="title">zCosmos Bright
			Spectroscopic Observations DR2</meta>

		<dbCore queriedTable="data">
			<condDesc buildFrom="ssa_location"/>
			<condDesc buildFrom="ssa_dateObs"/>
			<condDesc>
				<inputKey original="mime">
					<property name="defaultForForm">application/x-votable+xml</property>
					<values>
						<option title="SDM VOTable">application/x-votable+xml</option>
						<option title="1D FITS image">application/fits</option>
					</values>
				</inputKey>
			</condDesc>
		</dbCore>

		<outputTable>
			<autoCols>accref, mime, ssa_targname,
				ssa_aperture, ssa_dateObs, datalink</autoCols>
			<FEED source="//ssap#atomicCoords"/>
			<outputField original="ssa_specstart" displayHint="displayUnit=Angstrom"/>
			<outputField original="ssa_specend" displayHint="displayUnit=Angstrom"/>
		</outputTable>
	</service>

	<service id="ssa" allowed="form,ssap.xml">
		<meta name="shortName">zCosmos SSAP</meta>
		<meta name="title">zCosmos Bright
			Spectroscopic Observations DR2</meta>
		<meta name="ssap.dataSource">pointed</meta>
		<meta name="ssap.testQuery">MAXREC=1</meta>
		<meta name="ssap.creationType">archival</meta>
		<meta name="ssap.complianceLevel">query</meta>
		<publish render="ssap.xml" sets="ivo_managed"/>
		<publish render="form" sets="ivo_managed,local" service="web"/>

		<ssapCore queriedTable="data">
			<property name="previews">auto</property>
			<FEED source="//ssap#hcd_condDescs"/>
		</ssapCore>
	</service>

	<regSuite title="zCOSMOS spectra">
			<regTest title="zCOSMOS SSA interface works">
				<url REQUEST="queryData"
					PUBDID="ivo://org.gavo.dc/~?zcosmos/data/zCOSMOS_BRIGHT_DR2_000826802_ZCMRa26_M1_Q4_13_1.fits"
					>ssa/ssap.xml</url>
				<code>
					rows = self.getVOTableRows()
					self.assertEqual(len(rows), 1)
					self.assertAlmostEqual(rows[0]['ssa_specend'], 9.69458e-07, 10)
					self.assertEqual(rows[0]['accsize'], 37440)
					self.assertEqual(rows[0]['ssa_dstitle'],
						'ESO-VLT-U3 238326')
					self.assertAlmostEqual(rows[0]['ssa_specres'],
						2.5e-10)
				</code>
			</regTest>

		<regTest title="zCOSMOS preview">
			<url preview="True">/getproduct/zcosmos/data/zCOSMOS_BRIGHT_DR2_000826802_ZCMRa26_M1_Q4_13_1.fits</url>
			<code>
				self.assertHasStrings("PNG", b"\\xefs\\xee'")
			</code>
		</regTest>

		<regTest title="zcosmos datalink generation">
			<url FORMAT="application/x-votable+xml;serialization=tabledata"
				ID="ivo://org.gavo.dc/~?zcosmos/data/zCOSMOS_BRIGHT_DR2_000826802_ZCMRa26_M1_Q4_13_1.fits"
				BAND="807e-9 812e-9"
				>sdl/dlget</url>
			<code><![CDATA[
				self.assertHasStrings(
					"<TD>8104.059972763062</TD><TD>1.957910040133415e-18</TD>",
					'value="37440"')
			]]></code>
		</regTest>

		<regTest title="zCOSMOS datalink meta">
			<url ID="ivo://org.gavo.dc/~?zcosmos/data/zCOSMOS_BRIGHT_DR2_000826802_ZCMRa26_M1_Q4_13_1.fits"
				>sdl/dlmeta</url>
			<code>
				rows = self.getVOTableRows()
				# rows[0] is the original FITS
				self.assertEqual(rows[0]["description"],
					"Spectrum as the original 1D array")
				self.assertEqual(rows[0]["semantics"], "#progenitor")
				fitsContent = utils.urlopenRemote(rows[0]["access_url"]).read()
				self.assertEqual(fitsContent[:6], b"SIMPLE",
					"#progenitor link in datalink meta broken")

				# rows[1] is the processing service exercised above
				self.assertEqual(
					rows[1]["description"],
					"Slicing, dicing, and format conversion for the zCOSMOS spectra")

				# the rest is #this and #preview, which I'm too bored to exercise.
			</code>
		</regTest>

		<regTest title="zcosmos obscore">
			<url parSet="TAP" QUERY="SELECT * FROM ivoa.obscore
				WHERE obs_collection='zcosmos' AND 1=CONTAINS(
					POINT('ICRS', 149.73375, 2.28216),
					s_region)"
					RESPONSEFORMAT="votable/td">/tap/sync</url>
			<code>
				row = self.getFirstVOTableRow(rejectExtras=False)
				self.assertEqual(row["em_xel"], 1642)
				self.assertEqual(row["o_ucd"], "phot.flux.density;em.wl")
				self.assertEqual(row["em_ucd"], "em.wl;obs.atmos")
				res = urllib.request.urlopen(row["access_url"])
				self.assertEqual(res.info()["content-type"], row["access_format"])
				res.read() # be nice and exhaust the remote side.
				self.assertEqual(row["facility_name"], "VLT")
				self.assertEqual(row["instrument_name"], "VIMOS")
				self.assertAlmostEqual(row["em_max"], 9.69457914834493e-07)
				self.assertAlmostEqual(row["em_res_power"], 2202.0425)
				self.assertAlmostEqual(row["s_fov"], 0.000833333353511989)
				self.assertTrue(b"TD>Polygon ICRS 149.73" in self.data,
					"New-style polygon serialisation in obscore?")
			</code>
		</regTest>
	</regSuite>

</resource>
