<resource schema="sp_ace">
	<meta name="creationDate">2014-07-23T12:00:00Z</meta>
	<meta name="schema-rank">100</meta>
	<meta name="title">SP_ACE spectral analysis tool</meta>
	<meta name="description" format="rst">
		SP_ACE computes stellar parameters (gravity, temperature) and element
		abundances from optical stellar spectra (`sample spectrum`_).  It employs
		1D stellar atmosphere models in Local Thermodynamic Equilibrium (LTE).

		The present service does not offer all the options available for SP_Ace
		as documented in `the tutorial`_.  All options are available if running
		SP_Ace locally (cf. `download page`_).

		This service exposes an updated version containing some bug fixes with
		respect to the one described in the paper.

		.. _the tutorial: \getConfig{web}{serverURL}/sp_ace/q/dist/static/tutorial.pdf
		.. _download page: \getConfig{web}{serverURL}/sp_ace/q/dist/static
		.. _sample spectrum: \getConfig{web}{serverURL}/\rdId/c/static/fast_spectrum.txt
	</meta>
	<meta name="creator">Boeche, C.; Demleitner, M.; Heinl, H.</meta>
	<meta name="source">2016A&amp;A...587A...2B</meta>

	<meta name="subject">stellar-abundances</meta>
	<meta name="subject">spectroscopy</meta>
	<meta name="subject">stellar-atmospheres</meta>
	<meta name="subject">astronomy-data-analysis</meta>

	<meta name="_news" author="MD" date="2015-11-30">
		Updated fitting code to new upstream version.
	</meta>
	<meta name="_news" author="MD" date="2016-02-04">
		Updated fitting code to new upstream version fixing a bug in the
		S/N estimation.
	</meta>
	<meta name="_news" author="MD" date="2016-07-28">
		Updated fitting code to upstream version 1.1; normalisation should
		now be more stable.
	</meta>
	<meta name="_news" author="MD" date="2017-06-21">
		Updated fitting code to upstream version 1.2.  See the tutorial
		for a list of changes.
	</meta>
	<meta name="_news" author="MD" date="2017-12-04">
		Updated fitting code to upstream version 1.3, which includes
		a new parameter rv_ini.  See the tutorial for a list of additional
		changes.
	</meta>
	<meta name="_news" author="MD" date="2019-08-12">
		Updated fitting code to upstream version 1.3.1; this just fixes a few
		bugs.
	</meta>
	<meta name="_news" author="MD" date="2020-07-17">
		Updated fitting code to upstream version 1.4.  That's a fairly major
		step; for instance, the spectral range used for fitting is now
		only 4800 and 6860 Å.
	</meta>


	<meta name="copyright">
		If you use results obtained by this service, please cite the original
		publication (see source meta) and acknowlege: This work has made
		use of the sp_ace spectral analysis tool version 1.4.
	</meta>

	<meta name="_longdoc" format="rst"><![CDATA[
		This service's API is relatively easy to operate from user programs or
		scripts.  The parameters available are identical to
		`those of the interactive service </sp_ace/q/c/info#inputs>`_ except
		for the upload modalities.  A parameter definition in a machine-readable
		VOTable is produced by the service itself at
		\getConfig{web}{serverURL}/sp_ace/q/c/api?MAXREC=0

		To run the program offline, please refer to our
		`download page <\getConfig{web}{serverURL}/sp_ace/q/dist>`_

		To run it, upload your radial-velocity-corrected
		continuum-normalised (!) spectrum (example_) giving
		wavelengths in Angstrom vs. flux. Spectra of resolutions outside of
		the 2000 .. 20000 range will probably not yield reliable results.

		Using curl, this would look like this::

			curl -FUPLOAD=spectrum,param:up -Fup=@zw.asc\\
				\getConfig{web}{serverURL}/sp_ace/q/c/api

		Alternative functions or programs may, of course, be used as well.
		Further parameters would just add more -F options (but take care to
		use proper shell quoting).

		This will give you VOTables, which are nice if the result is going to be
		processed with TOPCAT or astropy or similar.  To get CSV, add a
		RESPONSEFORMAT parameter::

			curl -FUPLOAD=spectrum,param:up -Fup=@zw.asc\\
				-FRESPONSEFORMAT=csv\\
				\getConfig{web}{serverURL}/sp_ace/q/c/api

		For convenient processing of multiple spectra, we recommend using
		Python with astropy and the `requests package`_.  The following code
		will print the abundances and global parameters for a spectrum
		in ``tmp/space/fast_spectrum.txt``::

			from cStringIO import StringIO
			from astropy.io.votable import parse_single_table
			import requests

			r = requests.post("http://dc.g-vo.org/sp_ace/q/c/api",
					data = {
						"UPLOAD": "spectrum,param:file",
						"compute_errors": "False"},
					files = {
						"file": open("tmp/space/fast_spectrum.txt")})
			t = parse_single_table(StringIO(r.content))
			print t.array

			for p in t.params:
				print p.name, p.value
		
		If you get messages about bad units, don't worry.  By VOUnit_, Astropy's
		wrong and we are right.

		An additional hint: If you don't absolutely need the errors, don't make
		sp_ace compute them -- it's much faster without them, so that's the
		default.  If you need errors, pass -Fcompute_errors=True.


		.. _requests package: https://pypi.python.org/pypi/requests/2.4.1
		.. _VOUnit: http://ivoa.net/documents/VOUnits
		.. _example: \getConfig{web}{serverURL}/\rdId/c/static/fast_spectrum.txt
	]]></meta>

	<STREAM id="valWithConfidence">
		<doc>
			A param with a confidence interval (give name, ucd, unit, tablehead
			and description and get three params including asymmetric error
			bars.
		</doc>
		<param name="\name"
			ucd="\ucd" unit="\unit"
			tablehead="\tablehead"
			description="\description of the best-fit modelled spectrum."/>
		<param name="\name\+_low"
			ucd="stat.error;\ucd;stat.min" unit="\unit"
			tablehead="Lower \tablehead"
			description="Lower limit of 68% confidence interval of \description"/>
		<param name="\name\+_up"
			ucd="stat.error;\ucd;stat.max" unit="\unit"
			tablehead="Upper \tablehead"
			description="Upper limit of 68% confidence interval of \description"/>
	</STREAM>

	<table id="abundances">
		<meta name="description">Element abundances derived from the spectrum.
		</meta>

		<FEED source="valWithConfidence"
			ucd="phys.temperature.effective" unit="K"
			name="teff" tablehead="T_eff"
			description="Effective Temperature"/>
		<FEED source="valWithConfidence"
			ucd="phys.gravity" unit="cm/s**2"
			name="logg" tablehead="Log g"
			description="Log of gravity"/>
		<FEED source="valWithConfidence"
			ucd="phys.abund.Z" unit="dex"
			name="metals" tablehead="[M/H]"
			description="Metallicity"/>

		<param name="conv" type="smallint"
			ucd="meta.code;stat.fit"
			tablehead="Conv"
			description="0 if solution converged, otherwise an error flag (see
			note or table 1 in the tutorial)." note="conv"/>

		<param name="rv"
			ucd="stat.fit" unit="km/s"
			tablehead="RV"
			description="Empirical adjustment for RV (obtained by optimizing line
				overlap)."/>

		<param name="fwhm"
			tablehead="FWHM_inst"
			description="A posteriori full width half maximum of
				the instrument profile."
			ucd="spect.line.width;instr"
			unit="Angstrom" >
		</param>

		<param name="snr"
			ucd="stat.snr"
			tablehead="S/N"
			description="Estimated signal to noise ratio of incoming spectrum."/>

		<param name="chisq"
			ucd="stat.fit.chi2"
			tablehead="χ²"
			description="χ² between incoming and modelled spectrum.">
		</param>

		<column name="element" type="text"
			ucd="phys.atmol.element"
			tablehead="Element"
			description="Element symbol"
			verbLevel="10"/>
		<column name="ab"
			ucd="phys.abund"
			tablehead="[El/H]"
			description="Element abundance, logarithm of particle number
				relative to 1e12 H particles."
			verbLevel="10"/>
		<column name="ab_low"
			ucd="phys.abund"
			tablehead="[El/H]-"
			description="Lower limit of 68% confidence
				interval of element abundance"
			verbLevel="10"/>
		<column name="ab_up"
			ucd="phys.abund"
			tablehead="[El/H]+"
			description="Upper limit of 68% confidence
				interval of element abundance"
			verbLevel="10"/>
		<column name="nlines" type="integer" required="True"
			ucd="stat.fit.param"
			tablehead="#lines"
			description="Number of lines evaluated for this element."
			verbLevel="10"/>

		<meta name="note" tag="conv">
The possible values of the convergence flag are:

=== =========================================================================================
0   SP Ace successfully converged
1   normalization loop did not converge within 30 loops
2   stellar parameters out of the limits covered by the GCOG library
3   FWHM does not converge
4   RV too far from zero (beyond 1FWHM in wavelength)
5   improper input parameters in minimization routine lmdif1
6   TGM minimization routine exceeded the maximum number of iterations
7   ABD minimization routine exceeded the maximum number of iterations
8   TGM outer loop did not converge
9   SP Ace cannot open the spectrum (maybe wrong name or address?)
10  SP Ace cannot open the GCOG library (maybe wrong name or address?)
11  SP Ace cannot open the space 6degpoly.dat file (maybe wrong address of the GCOG library?)
=== =========================================================================================
		</meta>
	</table>

	<table id="resultspectrum">
		<meta name="description">The model spectrum as computed by SP_Ace;
		all fluxes are continuum-normalized.</meta>
		<meta name="utype">spec:Spectrum</meta>

		<param name="email" type="text"
			utype="spec:Curation.Contact.Email">gavo@ari.uni-heidelberg.de</param>
		<param name="fluxcalib" type="text"
			utype="spec:Spectrum.Char.FluxAxis.Accuracy.Calibration"
			>NORMALIZED</param>

		<column name="lambda"
			unit="1e-10m" ucd="em.wl"
			utype="spec:data.SpectralAxis.Value"
			description="Wavelength as in input spectrum."/>
		<column name="observed"
			ucd="phot.flux;arith.ratio"
			utype="spec:data.FluxAxis.Value"
			tablehead="Observed"
			description="Observed flux from the uploaded spectrum."/>
		<column name="renormalized"
			ucd="phot.flux;arith.ratio"
			utype="spec:data.FluxAxis.Value"
			tablehead="Renormalized"
			description="Input flux after renormalization."/>
		<column name="best"
			ucd="phot.flux;arith.ratio"
			utype="spec:data.FluxAxis.Value"
			tablehead="Best"
			description="Flux from the best matching model spectrum."/>
		<column name="continuum"
			ucd="stat.fit.param"
			tablehead="Cont."
			description="Continuum level adopted for re-normalization."/>
		<column name="weight"
			ucd="stat.weight;phot.flux"
			tablehead="Weight"
			description="Pixel weight. For lines with NLTE effects, unidentified
				lines, or lines with inaccurate correction for the opacity of
				the neighbour lines, the weights of the correspondent pixels
				are zero by default. Cosmic rays detected by the code or lines
				rejected by the user have also weight=0."/>
		<column name="snr"
			ucd="stat.snr"
			tablehead="S/N"
			description="Local signal to noise ratio at this spectal point."/>
		
	</table>

	<data id="parse_resultspectrum">
		<sources pattern="space_model.dat"/>
		<reGrammar names="lambda,observed,renormalized,best,continuum,weight,
			snr"/>
		<make table="resultspectrum"/>
	</data>

	<data id="import_programResult">
		<sources pattern="test/space_TGM_ABD.dat"/>
		<customGrammar module="res/resultgrammar"/>
		<make table="abundances">
			<rowmaker idmaps="*">
				<LOOP listItems="ab ab_low ab_up nlines">
					<events>
						<map key="\item" nullExcs="ValueError"/>
					</events>
				</LOOP>
			</rowmaker>

			<parmaker idmaps="*">
				<map key="rv" source="RV" nullExcs="ValueError"/>
				<map key="fwhm" source="FWHM" nullExcs="ValueError"/>
				<map key="snr" nullExcs="ValueError">vars["S/N"]</map>
				<LOOP listItems="teff teff_up teff_low logg logg_up logg_low
						metals metals_up metals_low">
					<events>
						<map key="\item" nullExcs="ValueError"/>
					</events>
				</LOOP>
			</parmaker>
		</make>
	</data>

	<service id="dist" allowed="static">
		<meta name="title">SP_ACE software distribution</meta>
		<property key="staticData">data</property>
		<property key="indexFile">res/download.shtml</property>
		<nullCore/>
	</service>

	<service id="c" allowed="form,api,static">
		<property key="staticData">test_data</property>
		<template key="form">res/form.html</template>
		<meta name="shortName">sp_ace</meta>

		<publish render="form" sets="local, ivo_managed"/>
		<publish render="api" sets="ivo_managed"/>

		<customRF name="conv_info">
			# requires the result table in tag.slotData
			convFlag = tag.slotData.getParam("conv")
			
			if convFlag==0:
				return ctx.tag["Converged normally"]

			else:
				return ctx.tag(style="padding:3pt;background-color:#ffaaaa;"
						"display:inline-block")[
					T.strong[{
						0: "SP Ace successfully converged",
						1: "Normalization loop did not converge within 30 loops",
						2: "Stellar parameters out of the limits covered by"
							" the GCOG library",
						3: "FWHM does not converge",
						4: "RV too far from zero (beyond 1FWHM in wavelength)",
						5: "improper input parameters in minimization routine lmdif1",
						6: "TGM minimization routine exceeded the maximum number"
							" of iterations",
						7: "ABD minimization routine exceeded the maximum number of"
							"iterations",
						8: "TGM outer loop did not converge",
						9: "SP Ace cannot open the spectrum (maybe wrong"
							" name or address?)",
						10: "SP Ace cannot open the GCOG library (maybe wrong "
							"name or address?)",
						11: "SP Ace cannot open the space 6degpoly.dat file (maybe"
							" wrong address of the GCOG library?)"}.get(convFlag,
								"Unknown disaster.  Please report.")]]
		</customRF>

		<customCore module="res/spacecore">
			<outputTable original="abundances"/>
		</customCore>
		<FEED source="//pql#DALIPars"/>
	</service>

	<regSuite>
		<regTest title="Form interface shows table and params">
			<url httpMethod="POST" parSet="form">
				<httpUpload name="spectrum" fileName="spectrum.asc"
					>This is not a spectrum.  Please just test.
				</httpUpload>
				c/form
			</url>
			<code>
				self.assertHasStrings(
					"5662.0",
					"5827.0",
					"[El/H]",
					"-0.73", "-0.81", "-0.65", "415",
					"Result Spectrum&lt;/h3>",
					"4800.35", "0.924")
			</code>
		</regTest>

		<regTest title="SP_ACE error reporting">
			<url httpMethod="POST" UPLOAD="spectrum,param:spectrum">
				<httpUpload name="spectrum" fileName="spectrum.asc"
					>foo bar
					bad input
				</httpUpload>
				c/api
			</url>
			<code>
				self.assertHasStrings("&lt;VOTABLE", 'value="ERROR"',
					"Field spectrum: Computation failed: No readable spectrum or"
					" wrong wave_lims")
			</code>
		</regTest>

		<regTest title="API runs and delivers expected results" tags="bigserver">
			<url httpMethod="POST" fwhm="0.45" wave_lims="5212 5300"
				RESPONSEFORMAT="votabletd" UPLOAD="spectrum,param:spectrum">
				<httpUpload name="spectrum" fileName="spectrum.asc"
					source="test_data/fast_spectrum.txt"/>c/api</url>
			<code><![CDATA[
				self.assertHasStrings(
					"<VOTABLE",
					'<RESOURCE type="results">',
					'value="5590.0"',
					'unit="K"')
				row = self.getFirstVOTableRow(rejectExtras=False)
				self.assertEqual(row["element"], "Fe")
				self.assertAlmostEqual(row["ab"], -0.75)
				self.assertEqual(row["nlines"], 41)
				
				# now see if there's the table with the result spectrum in there
				self.assertHasStrings('<TABLE name="resultspectrum"',
					'<TD>5208.8</TD>')
			]]></code>
		</regTest>

		<regTest title="A low-res spectrum yields about the right results"
				tags="bigserver">
			<url parSet="form" httpMethod="POST">
				<httpUpload name="spectrum" fileName="spectrum.asc"
					source="test_data/low-res-example.asc"/>c/form</url>
			<code><![CDATA[
				# All these are rather shaky and actually may wiggle a bit
				# depending on compiler versions, architecture, and the
				# phase of the moon.
				self.assertHasStrings(
					"4121.0",          # Temperature
					"<strong>1.08</strong>",  # chisquare
					"<td>-0.16</td>" # Al abundance
				)
			]]></code>
		</regTest>
	</regSuite>
</resource>
