<resource schema="__system">
	<!-- TODO: Updater für coverage schreiben -->
	<meta name="creationDate">2022-02-10T13:26:00Z</meta>
	<meta name="subject">spectral-line-identification</meta>
	<meta name="description">A mixin and other support material for
		LineTAP.</meta>

	<STREAM id="linetap-columns">
		<column name="title" type="text" required="True"
				ucd="meta.id"
				tablehead="Line name"
				description="Human-readable line designation.">
			<property name="std">1</property>
		</column>
		<column name="vacuum_wavelength" type="double precision" required="True"
				ucd="em.wl" unit="Angstrom"
				description="Vacuum wavelength of the transition">
			<property name="std">1</property>
		</column>
		<column name="vacuum_wavelength_error" type="double precision"
			ucd="stat.error;em.wl" unit="Angstrom"
			description="Total error in vacuum_wavelength">
			<property name="std">1</property>
		</column>

		<column name="method" type="text"
				ucd="meta.code.class"
				description="Method the wavelength was obtained with
					(XSAMS controlled vocabulary)">
			<values>
				<option>observed</option>
				<option>theory</option>
				<option>ritz</option>
			</values>
			<property name="std">1</property>
		</column>

		<column name="element" type="text"
				ucd="phys.atmol.element"
				tablehead="Element"
				description="Element name for atomic transitions,
					NULL otherwise.">
			<property name="std">1</property>
		</column>
		<column name="ion_charge" type="integer" required="True"
				ucd="phys.electCharge"
				description="Total charge (ionisation level) of the emitting
					particle.">
			<property name="std">1</property>
			</column>
		<column name="mass_number" type="integer"
				ucd="phys.atmol.weight"
				description="Number of nucleons in the atom or molecule">
			<values nullLiteral="-1"/>
			<property name="std">1</property>
		</column>

		<column name="upper_energy" type="double precision"
				ucd="phys.energy;phys.atmol.initial" unit="J"
				description="Energy of the upper state">
			<property name="std">1</property>
		</column>
		<column name="lower_energy" type="double precision"
				ucd="phys.energy;phys.atmol.final" unit="J"
				description="Energy of the lower state">
			<property name="std">1</property>
		</column>

		<column name="inchi" type="text" required="True"
				ucd="meta.id;phys.atmol;meta.main"
				description="International Chemical Identifier InChI.">
			<property name="std">1</property>
		</column>
		<column name="inchikey" type="text" required="True"
				ucd="meta.id;phys.atmol"
				description="The InChi key (hash) generated from inchi.">
			<property name="std">1</property>
		</column>
		
		<column name="einstein_a" type="double precision"
				ucd="phys.atmol.transProb"
				description="Einstein A coefficient of the radiative transition.">
			<property name="std">1</property>
		</column>

<!-- May 2022: We believe A_ik is good enough for our use cases.  Do away
  with the other strength measures if people do not complain very loudly.
		<column name="oscillator_strength" type="double precision"
				ucd="phys.atmol.oscStrength"
				description="Oscillator strength of the radiative transition.">
			<property name="std">1</property>
		</column>
		<column name="weighted_oscillator_strength" type="double precision"
				ucd="phys.atmol.wOscStrength"
				description="Weighted oscillator strength of the radiative
					transition">
			<property name="std">1</property>
		</column>
		<column name="line_strength" type="double precision"
				ucd="spect.line.strength"
				description="Total absorption by a spectra line">
			<property name="std">1</property>
		</column> -->

		<column name="xsams_uri" type="text"
				ucd="meta.ref"
				description="A URI for a full XSAMS description of this line.">
			<property name="std">1</property>
		</column>
		<column name="line_reference" type="text" required="True"
				ucd="meta.ref"
				description="Reference to the source of the line data; this could
					be a bibcode, a DOI, or a plain URI.">
			<property name="std">1</property>
		</column>
	</STREAM>

	<mixinDef id="table-0">
		<doc><![CDATA[
			This mixin makes a table suitable for publication as a LineTAP
			table.

			It provides all standard columns, makes sure it is on disk and
			available through TAP, adds the most common indexes, and gives it the
			utype required by the standard.

			It is recommended to fill this table with a rowmaker using the
			`//linetap#populate-0`_ apply.
		]]></doc>

		<events>
			<adql>True</adql>
			<onDisk>True</onDisk>
			<meta name="utype">ivo://ivoa.net/std/linetap#lines-1.0</meta>

			<FEED source="linetap-columns"/>
		</events>
	</mixinDef>

	<procDef type="apply" id="populate-0">
		<doc><![CDATA[
			Fills the columns of a LineTAP table, typically created using
			`the //linetap#table-0 mixin`_.  The values are left in
			vars, so you need to copy them into the finished record,
			probably through ``idmaps="*"``.
		]]></doc>
		<setup imports="gavo.protocols.linetap">
			<LOOP>
				# turn our LineTAP columns into apply params
				<codeItems>
					mixin = context.getById("table-0")
					dicts = [{}]
					for type, name, content, _ in mixin.events.events_:
						if type=="value":
							dicts[-1][name] = content
							
						elif type=="start":
							dicts.append({})

						elif type=="end":
							res = dicts.pop()
							if name=="column":
								res["default"] = (
									"" if res.get("required", False) else "None")
								if res.get("unit"):
									res["description"] += " (in {})".format(res["unit"])

								yield res
				</codeItems>
				<events>
					<par key="\name" description="\description"
						late="True">\default</par>
				</events>
			</LOOP>
			<!-- The InChIKey we generally compute ourselves, so give it
				a different default and comment -->
			<par key="inchikey"
				description="The hashed InChI; the proc will generally compute
					the hash from the InChI itself, so you will usually want to
					leave this empty." late="True">base.NotGiven</par>
			<code>
				INCHILIB = linetap.getILib()
			</code>
		</setup>
		<code>
			if inchikey is base.NotGiven:
				inchikey = INCHILIB.getInChIKey(inchi)
			vars.update(locals())
		</code>
	</procDef>

	<procDef type="apply" id="InChIForAtom">
		<doc><![CDATA[
			Puts the InChI of a simple (possibly ionised) atom into
			the inchi var.  The intended use is like this::

				<apply procDef="InChIForAtom">
					<bind name="element">@element</bind>
					<bind name="charge">@ion_charge</bind>
				</apply>

				<apply procDef="//linetap#populate-0">
					...
					<bind name="inchi">@inchi</bind>
				</apply>

			The apply caches the computed InChI; there is no need to do extra
			caching.
		]]></doc>
		<setup imports="gavo.protocols.linetap, functools">
			<par key="element" description="The standard element symbol (H, He,...)
				to generate an InChI for" late="True"/>
			<par key="charge" description="The charge of the atom in elementary
				charges" late="True">0</par>
			<code>
				INCHILIB = linetap.getILib()

				def getInChI(element, charge):
					iin = INCHILIB.getInput([
						INCHILIB.getAtom(element, charge=charge)])
					
					return INCHILIB.getInChI(iin)

				getInChI = functools.cache(getInChI)
			</code>
		</setup>
		<code>
			@inchi = getInChI(element, charge)
		</code>
	</procDef>
</resource>
