<resource schema="xpparams2" resdir=".">
	<meta name="creationDate">2025-11-26T10:38:00Z</meta>
	<meta name="schema-rank">20</meta>

	<meta name="title">Three-dimensional maps of the interstellar
		dust extinction curve within the Milky Way galaxy</meta>
	<meta name="description" format="rst">
		We measure the extinction curves of 220 million stars with Gaia XP spectra
		and near-infrared photometry from 2MASS and WISE. We use a data-driven
		model that is developed from :bibcode:`2023MNRAS.524.1855Z`, with variable
		extinction curves, to determine stellar parameters and extinction curves
		simultaneously.

		For bulk downloads and the trained model, see
		https://doi.org/10.5281/zenodo.10719756.
	</meta>
	<meta name="subject">stellar-properties</meta>
	<meta name="subject">milky-way-galaxy</meta>
	<meta name="subject">sky-surveys</meta>

	<meta name="creator">Zhang, X.; Green, G.</meta>

	<meta name="instrument">Gaia RP/BP Spectrometer</meta>
	<meta name="facility">Gaia</meta>

	<meta name="source">2025Sci...387.1209Z</meta>
	<meta name="contentLevel">Research</meta>
	<meta name="type">Catalog</meta>

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

	<meta name="isNewVersionOf" ivoId="ivo://org.gavo.dc/xpparams/q/cone"
		>Parameters of 220 million stars from Gaia</meta>

	<meta name="_longdoc" format="rst"> <![CDATA[
		Example: A Dust Map
		-------------------
		As an example of what one can do with this data, consider the following
		ADQL query to generate an all-sky maps of the mean extinction and means of
		ξ and R(55) for stars at a distance between 400 pc and 600 pc::

			SELECT
				source_id/140737488355328 AS hpx,
				avg(ext/(err_ext*err_ext+0.0001)) AS mean_ext_num,
				avg(1/(err_ext*err_ext+0.0001)) AS mean_ext_denom,
				avg(xi/(err_xi*err_xi+0.0001)) as mean_xi_num,
				avg(1/(err_xi*err_xi+0.0001)) as mean_xi_denom,
				avg(r55*r55*r55/(err_r55*err_r55+0.0001)) as mean_inv_r55_num,
				avg(r55*r55*r55*r55/(err_r55*err_r55+0.0001)) as mean_inv_r55_denom
			FROM xpparams2.main
			WHERE
				mod_parallax BETWEEN 1.67 and 2.5
				AND quality_flags < 8
				AND mod_parallax/err_mod_parallax > 5
				AND err_ext < 0.5
			GROUP BY hpx

		This exploits the fact that Gaia source ids can be `converted to
		HEALPixes`_ to produce a map and shows how to do useful quality cuts
		that allow relatively careless use of the data.  Note that we
		calculate means weighted by the inverse variance for robustness.

		If you use TOPCAT to execute this on the GAVO DC TAP service (select
		Asynchronous mode and make sure you set Max Rows to something more than
		50000, because that is how many pixels our map will have), you can
		do a sphere plot, then add a Healpix control.  In it, select the table
		resulting from this query, manually set the HEALPix level to 6 and
		configure the Axis to Aitoff projection in the Galactic system to
		arrive such a plot of ``mean_ext_num/mean_ext_denom``:

		.. _converted to HEALPixes: https://dc.g-vo.org/gedr3dist/q/cone/info#note-id
		
		.. image:: /static/img/xpparams2_ext_map.png

		With this data, you can also get an idea of what sort of dust there is via
		the R(55) (or, if you prefer, ξ) parameter. Because 1/R(55) is better
		behaved than R(55) (as the extinction curve flattens and then tilts
		slightly blueward, the parameter R(55) first goes to infinity and then
		discontinuously jumps to negative infinity), we calculate the
		inverse-variance-weighted mean of 1/R(55). Below are plots of ξ (top) and
		R(55) (calculated by inverting the 1/R(55) map):
		
		.. image:: /static/img/xpparams2_xi_map.png

		.. image:: /static/img/xpparams2_r55_map.png

		Note that in regions of low extinction, the measurements of ξ (and
		consequently R(55)) are noisy, and should be treated with caution.

		Example: Metallicity of a Globular Cluster
		------------------------------------------

		Try the following query yielding data on Omega Cen and illustrating how
		to match with the local Gaia DR3 catalogue in order to constrain proper
		motions::

			SELECT
				xpp.*,
				g.pmra, g.pmdec, g.phot_g_mean_mag, g.phot_bp_mean_mag,
				g.phot_rp_mean_mag
			FROM xpparams2.main as xpp JOIN gaia.edr3lite as g USING (source_id)
			WHERE
				distance(xpp.ra, xpp.dec, 201.697, -47.479472)<0.5
				AND distance(g.pmra, g.pmdec, -3.24, -6.73)<1.25
				AND xpp.quality_flags < 8
				AND xpp.mod_parallax/xpp.err_mod_parallax > 5.
				AND xpp.feh_confidence > 0.5
				AND xpp.err_fe_h < 0.2

		Again in TOPCAT, try a 3d plot of RA, Dec and 1/mod_parallax. You will want
		to manually cut the parallax axis a bit to get rid of (presumably spurious)
		background stars.  Make fe_h the aux axis in the “Form“ tab.  If you look
		“from above“, you will see that the quality cuts have punched a hole into
		the (crowded) cluster.  If you look from the side, you can see that the cluster stars
		are (by and large) rather metal-poor compared to foreground stars:


		.. image:: /static/img/xpparams-omegacen.png

		Converting between ξ and R(55)
		------------------------------

		We have used C source code to turn the ξ as used by
		:bibcode:`2025Sci...387.1209Z` into the more common slope parameter R(55).
		Since it may be useful in other contexts, too, here is
		`extinction_curve.c`_ and `extinction_curve.h`_.

		.. _extinction_curve.c: /\rdId/cone/static/extinction_curve.c
		.. _extinction_curve.h: /\rdId/cone/static/extinction_curve.h

	]]></meta>

	<table id="main" onDisk="True" mixin="//scs#q3cindex" adql="True">
		<primary>source_id</primary>
		<index columns="teff"/>
		<index columns="fe_h"/>
		<index columns="logg"/>
		<index columns="mod_parallax"/>

		 <column name="source_id" type="bigint" required="True"
			ucd="meta.id;meta.main"
			tablehead="Source Id"
			description="Gaia DR3 unique source identifier.  You can match this
				against gaia.dr3lite on this TAP service."
			verbLevel="1">
			<property name="statisticsTarget">10000</property>
		</column>

		<column name="ra" type="double precision"
			unit="deg" ucd="pos.eq.ra;meta.main"
			tablehead="RA"
			description="Gaia ICRS right ascension for this object."
			verbLevel="1" displayHint="sf=7"/>
		<column name="dec" type="double precision"
			unit="deg" ucd="pos.eq.dec;meta.main"
			tablehead="Dec"
			description="Gaia ICRS declination for this object."
			verbLevel="1" displayHint="sf=7"/>

		<column name="teff"
			unit="K" ucd="phys.temperature.effective"
			tablehead="Teff"
			description="Estimated effective Temperature.  Note that
				the raw HDF5 files released by Zhang et al. (2023) give
				Teff in a different unit (Kilokelvin)."
			verbLevel="5"/>
		<column name="fe_h"
			ucd="phys.abund.Fe"
			tablehead="[Fe/H]"
			description="Log of Fe/H in solar units"
			verbLevel="5"/>
		<column name="logg"
			ucd="phys.gravity"
			tablehead="log(g)"
			description="Log of surface gravity in solar units"
			verbLevel="5"/>
		<column name="xi"
			ucd="stat.fit.param;phys.absorption"
			tablehead="ξ"
			description="Parameter used by 2025Sci...387.1209Z to parameterize the
				shape of the extinction curve. For convenience, a conversion to R(55)
				is given as a separate column in this table._"
			verbLevel="15"/>
		<column name="r55"
			ucd="stat.fit.param;phys.absorption"
			tablehead="R(55)"
			description="Parameter describing the inverse slope of the extinction
				curve, defined by R(55) := A(550 nm) / [A(440 nm) - A(550 nm)].
				This parameter can be approximately converted to the more
				traditional R(V) parameter by R(V) = 1.1*R(55) + 0.07. Note that
				this conversion is dependent on the specific B and V bandpasses
				and on stellar type!"
			verbLevel="15"/>

		<column name="ext"
			unit="mag" ucd="phys.absorption"
			tablehead="Ext."
			description="Estimated extinction parameter.  To convert to the extension
				at a particular wavelength, multiply this by that wavelength's
				value in the extinction curve, available at
				https://zenodo.org/record/7811871/files/extinction_curve.txt?download=1
				and in the footnote."
			verbLevel="5"
			note="R"/>
		<column name="mod_parallax"
			unit="mas" ucd="pos.parallax"
			tablehead="Est. Par."
			description="Parallax estimated from the model."
			verbLevel="5"/>

		<column name="err_teff"
			unit="K" ucd="stat.error;phys.temperature.effective"
			tablehead="Err. Teff"
			description="Error in estimated effective temperature.  Note that
			the raw HDF5 files released by 2025Sci...387.1209Z give the error in
			Teff in a different unit (Kilokelvin)."
			verbLevel="15"/>
		<column name="err_fe_h"
			ucd="stat.error;phys.abund.Fe"
			tablehead="Err. [Fe/H]"
			description="Error in fe_h"
			verbLevel="15"/>
		<column name="err_logg"
			ucd="stat.error;phys.gravity"
			tablehead="Err. log(g)"
			description="Error in log_g"
			verbLevel="15"/>
		<column name="err_xi"
			ucd="stat.error;stat.fit.param;phys.absorption"
			tablehead="Err. ξ"
			description="Error in xi"
			verbLevel="15"/>
		<column name="err_r55"
			ucd="stat.error;stat.fit.param;phys.absorption"
			tablehead="Err. R(55)"
			description="Error in r55"
			verbLevel="5"/>

		<column name="err_ext"
			unit="mag" ucd="stat.error;phys.absorption"
			tablehead="Err. Ext."
			description="Error in ext"
			verbLevel="15"/>
		<column name="err_mod_parallax"
			unit="mas" ucd="stat.error;pos.parallax"
			tablehead="Err. Par."
			description="Error in the parallax estimated from the model."
			verbLevel="15"/>

		<column name="chi2_opt"
			ucd="stat.fit.chi2"
			tablehead="χ²"
			description="χ² of the best-fit solution.
				Divide by 61 to obtain χ² per degree of freedom."
			verbLevel="15"/>
		<column name="ln_prior"
			ucd="stat.fit.goodness"
			tablehead="ln(prior)"
			description="Natural log of the GMM prior on stellar type, at the
				location of the optimal solution."
			verbLevel="15"/>

		<column name="teff_confidence"
			ucd="stat.fit.goodness"
			tablehead="Conf. T"
			description="A neural-network-based estimate of the confidence in the
				effective temperature estimate, on a scale of 0 (no confidence) to 1
				(high confidence)."
			verbLevel="15"/>
		<column name="feh_confidence"
			ucd="stat.fit.goodness"
			tablehead="Conf. [Fe/H]"
			description="A neural-network-based estimate of the confidence in the
				[Fe/H] estimate, on a scale of 0 (no confidence) to 1
				(high confidence)."
			verbLevel="15"/>
		<column name="logg_confidence"
			ucd="stat.fit.goodness"
			tablehead="Conf. logg"
			description="A neural-network-based estimate of the confidence in the
				log(g) estimate, on a scale of 0 (no confidence) to 1
				(high confidence)."
			verbLevel="15"/>
		<column name="quality_flags" type="smallint" required="True"
			ucd="meta.code.qual"
			tablehead="Quality Flags"
			description='The three least significant bits represent whether the
				confidence in effective temperature, [Fe/H] and log(g) is less than
				0.5, respectively. The 4th bit is set if chi2_opt/61 > 2. The 5th bit
				is set if ln_prior &lt; -7.43. The 6th bit is set if our parallax
				estimate is more than 10 sigma from the GDR3 measurement (using
				reported parallax uncertainties from GDR3). The two most significant
				bits are always unset.  We recommend a cut of quality_flags &lt; 8 (the
				"basic reliability cut"), although a stricter cut of quality_flags == 0
				ensures higher reliability at the cost of lower completeness.'
			verbLevel="5"/>

		<meta name="note" tag="R">
This table is originally at
https://zenodo.org/record/7811871/files/extinction_curve.txt?download=1.

==========  ======================
wavelength  extinction_curve
392.0       4.004029750823975
402.0       3.932934284210205
412.0       3.8616459369659424
422.0       3.790104627609253
432.0       3.66058611869812
442.0       3.6425302028656006
452.0       3.5208635330200195
462.0       3.42183256149292
472.0       3.3702077865600586
482.0       3.31054949760437
492.0       3.2349464893341064
502.0       3.103348970413208
512.0       3.028446674346924
522.0       2.913299798965454
532.0       2.8309452533721924
542.0       2.766111135482788
552.0       2.658158779144287
562.0       2.5784859657287598
572.0       2.5361363887786865
582.0       2.4805185794830322
592.0       2.412776470184326
602.0       2.356668472290039
612.0       2.313209056854248
622.0       2.272326707839966
632.0       2.2307708263397217
642.0       2.1915647983551025
652.0       2.156630516052246
662.0       2.1017379760742188
672.0       2.040684938430786
682.0       2.0002477169036865
692.0       1.9592469930648804
702.0       1.9099318981170654
712.0       1.8628478050231934
722.0       1.8250858783721924
732.0       1.7893791198730469
742.0       1.7572511434555054
752.0       1.7151219844818115
762.0       1.7081632614135742
772.0       1.6803325414657593
782.0       1.6145453453063965
792.0       1.566452145576477
802.0       1.5282924175262451
812.0       1.4971987009048462
822.0       1.4678758382797241
832.0       1.4417716264724731
842.0       1.4134937524795532
852.0       1.3825805187225342
862.0       1.3539363145828247
872.0       1.3050405979156494
882.0       1.2772356271743774
892.0       1.2389837503433228
902.0       1.2139592170715332
912.0       1.193802833557129
922.0       1.155206322669983
932.0       1.143110990524292
942.0       1.113704800605774
952.0       1.075573444366455
962.0       1.0743821859359741
972.0       1.0339452028274536
982.0       0.9810613989830017
992.0       1.0053104162216187
1235.0      0.6821472644805908
1662.0      0.4082775115966797
2159.0      0.2695426046848297
3352.6      0.13694290816783905
4602.8      0.09808244556188583
==========  ======================
		</meta>
	</table>

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

	<data id="import">
		<sources pattern="zenodo/xpparams_v2*.h5"/>

		<directGrammar id="boost" type="hdf5rootarrs"
				cBooster="res/boosterfunc.c">
			<property name="dataset">/</property>
		</directGrammar>
		
		<make table="main">
			<rowmaker idmaps="*">
			</rowmaker>
		</make>
	</data>

	<table id="covs" onDisk="true" primary="source_id" adql="True">
		<meta name="description" format="rst">
		A table of covariances (as upper triangle
		matrices) for the stellar parameters in \schema.main).  This is
		intended for use as in::

			SELECT ..., cov_triu
			FROM \schema.main NATURAL JOIN \schema.covs
			WHERE ...
		
		If you only need particular elements of the covariance matrix,
		you can subscript cov_triu, perhaps as in
		``cov_triu[4] AS teff_xi_cov``.
		</meta>

		<column original="main.source_id"/>
		<column name="triu" type="real[21]"
			ucd="stat.covariance"
			tablehead="Cov"
			description="Upper triangle of the covariance matrix of the stellar
				parameters from xpparams2.main.  The variables are, in sequence: T_eff,
				[Fe/H], logg, ξ, E, and parallax."/>
	</table>

	<data id="import-cov">
		<sources pattern="zenodo/xpparams_cov_v2*.h5"/>

		<directGrammar id="covboost" type="hdf5rootarrs"
				cBooster="res/covboosterfunc.c">
		</directGrammar>
		
		<make table="covs"/>
	</data>
	

	<service id="cone" allowed="form,scs.xml,static">
		<property name="staticData">res</property>
		<meta name="shortName">XP ap-pars2</meta>
		<meta name="testQuery">
			<meta name="ra">81.1106109</meta>
			<meta name="dec">2.77958655</meta>
			<meta name="sr">0.001</meta>
		</meta>

		<publish render="form" sets="ivo_managed, local"/>
		<publish render="scs.xml" sets="ivo_managed"/>
		<scsCore queriedTable="main">
			<FEED source="//scs#coreDescs"/>
			<condDesc inputOptional="True" buildFrom="quality_flags">
				<phraseMaker>
					<code>
						if inPars[inputKeys[0].name] is None:
							if inputKeys[0].xtype=="interval":
								inPars["quality_flags"] = [0, 8]
							else:
								inPars["quality_flags"] = "&lt; 8"
						yield base.getSQLForField(inputKeys[0], inPars, outPars)
					</code>
				</phraseMaker>
			</condDesc>
		</scsCore>
	</service>

	<regSuite title="xpparams regression">
		<regTest title="xpparams2 SCS honours quality flags">
			<url RA="44"
					DEC="1" SR="0.1"
				>cone/scs.xml</url>
			<code>
				rows = self.getVOTableRows()
				# the following assertion is for the default quality cut to be
				# active (without it, it's 11 rows)
				self.assertEqual(len(rows), 9)
				self.assertAlmostEqual(rows[0]["teff"]-4257.20703125, 0, 3)
				self.assertAlmostEqual(rows[1]["logg"], 4.427849769592285)
				self.assertEqual(rows[2]["source_id"], '307077277479552')
			</code>
		</regTest>

		<regTest title="xpparams2 cone form honours quality flags">
			<url parSet="form"
				hscs_pos="44 1" hscs_sr="6" quality_flags="&lt; 20"
				>cone/form</url>
			<code>
				self.assertHasStrings(
					# the following assertion is for quality_flags &lt; 20 being evaluated
					"Matched: 10",
					"4257.207", # Teff of 0
					"44.0346107", # RA of 1
					"209.05", # dist of 2
				)
			</code>
		</regTest>

	</regSuite>
</resource>
