<resource schema="flare_survey">
	<meta name="title">Plates From Münster Flare Star Survey 1986-1991</meta>
	<meta name="description">
		From 1986 through 1991, the Astronomical Institute of Münster University
		performed a  search for flare stars in several southern associations and
		open stellar clusters using the GPO telescope (d=40 cm, WFPDB identifier
		ESO040); the fields suveyed include Coalsack, M42, B228 Lup, the Chameleon
		T1 association, omicron Vel cluster, R CrA association, the Pipe nebula
		(B59 Oph), and the Sco-Oph association.  This was done primarily through
		multiple exposures.  The files published here are plate scans done in 2017.

		The obscore collection name for these files is Muenster Flare Survey.
	</meta>
	<meta name="creationDate">2017-10-04T12:21:00Z</meta>
	<meta name="schema-rank">1000</meta>

	<meta name="subject">flare-stars</meta>
	<meta name="subject">uv-ceti-stars</meta>
	<meta name="subject">astrophotography</meta>

	<meta name="creator">Tsvetkov, M.</meta>
	<meta name="instrument">40cm GPO</meta>
	<meta name="facility">ESO La Silla</meta>

	<meta name="source">1990IAUS..137...85A</meta>
	<meta name="contentLevel">Research</meta>
	<meta name="type">Catalog</meta>

	<meta name="servedBy">ivo://org.gavo.dc/hppunion/q/im</meta>
	
	<meta name="coverage.waveband">Optical</meta>

	<table id="data" onDisk="True" mixin="//siap#pgs">
		<mixin
			accessURL="datalink_url"
			productSubtype="kind"
			calibLevel="1"
			collectionName="'Muenster Flare Survey'"
			expTime="total_exptime"
			facilityName="'ESO La Silla'"
			size="10"
			tMin="dateObs"
			tMax="dateObs+obs_duration"
			>//obscore#publishSIAP</mixin>

		<meta name="_associatedDatalinkService">
			<meta name="serviceId">mdl</meta>
			<meta name="idColumn">pub_did</meta>
		</meta>
		<meta name="_associatedDatalinkService">
			<meta name="serviceId">tsdl</meta>
			<meta name="idColumn">pub_did</meta>
		</meta>
		<meta name="shortName">flare_survey.dat</meta>

		<index columns="object"/>

		<publish sets="ivo_managed" services="//tap#run,hppunion/q#im"/>

		<column name="kind" type="text"
			ucd="meta.code;obs"
			tablehead="Kind"
			description="Direct observation, stellar tracks, or multiple exposure?"
			verbLevel="5"/>
		<column name="object" type="text"
			ucd="meta.id;src"
			tablehead="Target"
			description="Name of the target object (mostly, cluster or association)"
			verbLevel="5"/>
		<column name="obs_duration"
			unit="s" ucd="time.interval;obs.exposure"
			tablehead="Obs. duration"
			description="Time between first shutter open and last shutter close
				(for multiply exposed plates, this is not the total exposure time)"
			verbLevel="5"/>
		<column name="total_exptime"
			unit="s" ucd="time.duration;obs.exposure"
			tablehead="Exp. time"
			description="Length of exposure (non-contiguous for multiply
				exposed plates"
			verbLevel="5"/>
		<column name="emulsion" type="text"
			ucd="instr.plate.emulsion"
			tablehead="Emulsion"
			description="Photographic emulsion used."
			verbLevel="5"/>
		<column name="pub_did" type="text"
			ucd="meta.id;meta.main"
			tablehead="PubDID"
			description="Publisher data set id; this is an identifier for
				the dataset in question and can be used to retrieve the data through,
				e.g., datalink."
			verbLevel="1"/>
		<column name="datalink_url" type="text"
			ucd="meta.ref.url"
			tablehead="Datalink"
			description="URL to a datalink document for this plate
				(ancillary files, cutouts)"
			displayHint="type=url"
			verbLevel="15">
			<property name="targetType"
				>application/x-votable+xml;content=datalink</property>
			<property name="targetTitle">Datalink</property>
		</column>
		<column name="wfpdb_id" type="text"
			ucd="meta.id"
			tablehead="WFPDB"
			description="Plate identifier as in the WFPDB"
			verbLevel="15"/>
	</table>

	<coverage>
		<updater sourceTable="data" mocOrder="4"/>
		<temporal>44608 48452.3</temporal>
		<spatial>3/577,590,667,671 4/1338-1339,1342,1425,1428,1802-1803,1824-1826,2320,2326-2327,2329,2332-2333,2355,2364,2366,2370,2570,2601-2603,2677,2679-2680,2682-2683,2688-2690,2772,2982-2983,2988-2989,2994,3000</spatial>
		<spectral>2.79781e-19 5.84249e-19</spectral>
	</coverage>

	<data id="import" recreateAfter="hppunion/q#import">
		<sources pattern="data/plates/*.fits"/>

		<fitsProdGrammar qnd="False">
			<rowfilter procDef="//products#define">
				<bind key="table">"\schema.data"</bind>
			</rowfilter>
		</fitsProdGrammar>

		<make table="data">

			<rowmaker>
			<var name="platenum">@PLATENUM.lstrip('0')</var>

 				<apply name="uniformise_emulsion" procDef="//procs#dictMap">
 					<bind name="key">"EMULSION"</bind>
 					<bind name="mapping">{
						"KODAKIIa0": "KODAKIIaO",
						"KODAKIIaO": "KODAKIIaO",
						"KODAK IIaO": "KODAKIIaO",
						"KODAK  098": "KODAK098",
						"KODAK 098": "KODAK098",
						"KODAK IIIaJ": "KODAK IIIaJ",
						"KODAK IIa0": "KODAKIIaO",
						"": None,
 					}</bind>
 				</apply>

 				<apply name="uniformise_filter" procDef="//procs#dictMap">
 					<bind name="key">"FILTER"</bind>
 					<bind name="mapping">{
						"RG630": "RG630",
						"R630":"RG630",
						"": None,
						}</bind>
 				</apply>

				<apply name="make_title">
					<code>
						@bandpass = "+".join(
							a for a in [@EMULSION, @FILTER] if a is not None)
						
						if @platenum in set(['13819', '13780', '13793']):
							@kind = "TRACK"
						elif @MULTIEXP>1:
							@kind = "MULTIPLE"
						else:
							@kind = "DIRECT"

						@title = "flare survey %s %s %s"%(@OBJECT, @kind, @DATE_OBS)

					</code>
				</apply>

				<apply procDef="//siap#setMeta">
					<bind key="bandpassId">@bandpass</bind>
					<bind key="dateObs">parseISODT(@DATE_OBS+"T"+@TIME_OBS)</bind>
					<bind key="pixflags">"C"</bind>
					<bind key="title">@title</bind>
				</apply>

				<apply procDef="//siap#computePGS">
					<bind key="missingIsError">False</bind>
				</apply>

				<apply name="set_emergency_wcs">
					<!-- if the previous step has not yielded wcs keys, fill
					in some emergency info (but we don't do coverage here
					since we don't want SIAP to match these. -->
					<code>
						if "CTYPE1" not in vars:
							result["centerAlpha"] = hmsToDeg(@RA, ":")
							result["centerDelta"] = dmsToDeg(@DEC, ":")
							result["pixelSize"] = [@NAXIS1, @NAXIS2]
							result["pixelScale"] = [@FOV1/@NAXIS1, @FOV2/@NAXIS2]
							result["nAxes"] = 2
							result["wcs_equinox"] = 2000.0
					</code>
				</apply>

				<apply procDef="//siap#getBandFromFilter"/>

				<apply name="compute_times">
					<code>
						start_time = parseISODT(@DATE_OBS+"T"+@TIME_OBS)
						end_time = parseISODT(@DATE_OBS+"T"+@TIME_END)
						if start_time>end_time:
							end_time = end_time+datetime.timedelta(days=1)
						@obs_duration = (end_time-start_time).total_seconds()
					</code>
				</apply>

				<map key="kind">{0: "DIRECT", 1: "MULTIPLE"}[not not
					@MULTIEXP>1]</map>
				<map key="object" source="OBJECT"/>
				<map key="total_exptime">@EXPTIME*60</map>
				<map key="obs_duration"/>
				<map key="emulsion" source="EMULSION"/>
				<map key="datalink_url"
					>\dlMetaURI{mdl} if @kind=="DIRECT" else \dlMetaURI{tsdl}</map>
				<map key="pub_did">\standardPubDID</map>
				<map key="wfpdb_id">@PLATE_ID</map>
			</rowmaker>
		</make>
	</data>

	
	<procDef id="make_env_prev" type="metaMaker">
		<doc>A common meta maker for the datalink services, linking
			to ancillary files by plate number.
		</doc>
		<code>
			stem = descriptor.accref.split("/")[-1].split(".")[0]
			yield descriptor.makeLinkFromFile(
				"data/static/photos/{}.jpg".format(stem),
				semantics="#preview-image",
				description="Mid-resolution plate photo.",
				contentQualifier="#image")
			yield descriptor.makeLinkFromFile(
				"data/static/envelopes/{}e.jpg".format(stem),
				semantics="#documentation",
				description="Photo of the plate envelope.",
				contentQualifier="#image")
		</code>
	</procDef>

	<service id="tsdl" allowed="dlmeta,static">
		<property key="staticData">data/static</property>

		<meta name="title">Münster Flares Time Series Datalink</meta>
		<meta name="description">This service produces datalinks for
			multiple-epoch exposures of the Münster flare survey plates.
			Most importantly, this links to the master plates with the astrometry,
			but there are also links to plates in other epochs and to envelopes
			and plate photos.
		</meta>
		
		<datalinkCore>
			<descriptorGenerator procDef="//soda#fits_genDesc">
				<bind key="qnd">False</bind>
			</descriptorGenerator>

			<metaMaker>
				<code>
					with base.getTableConn() as conn:
						for row in conn.queryToDicts(
								"SELECT accref, kind, accsize, dateobs FROM \schema.data"
								" WHERE object=%(object)s",
								{"object": descriptor.hdr["OBJECT"]}):
							if row["kind"]=="DIRECT":
								yield descriptor.makeLink(
									getDatalinkMetaLink(
										rd.getById("mdl"), row["accref"]),
									semantics="#calibration",
									description="A master frame containing a single, direct"
										" exposure of this field.",
									contentType="application/fits",
									contentLength=row["accsize"],
									contentQualifier="#image")

							else:
								continue # for now, suppress the other time series;
								# it's too much for current clients.
								if row["accref"]!=descriptor.accref:
									yield descriptor.makeLink(
										getDatalinkMetaLink(
											rd.getById("tsdl"), row["accref"]),
										semantics="#counterpart",
										description="%s multiple times exposures on this field."%
											mjdToDateTime(row["dateobs"]).strftime("%Y-%m-%d"),
										contentType=self.datalinkType,
										contentLength=row["accsize"])

				</code>
			</metaMaker>

			<metaMaker procDef="make_env_prev"/>
		</datalinkCore>
	</service>

	<service id="mdl" allowed="dlget,dlmeta,static">
		<property key="staticData">data/static</property>

		<meta name="title">Münster Flares Master Datalink</meta>
		<meta name="description">This service produces datalinks for
			the reference images of the Münster flare survey plates.
			Most importantly, this links to the related time series exposures,
			but there are also links to plates in other epochs and to envelopes
			and plate photos.
		</meta>
	
		<datalinkCore>
			<descriptorGenerator procDef="//soda#fits_genDesc">
				<bind key="qnd">False</bind>
			</descriptorGenerator>

			<metaMaker>
				<code>
					with base.getTableConn() as conn:
						for row in conn.queryToDicts(
								"SELECT accref, kind, accsize, dateobs FROM flare_survey.data"
								" WHERE object=%(object)s",
								{"object": descriptor.hdr["OBJECT"]}):
							if row["kind"]!="DIRECT":
								yield descriptor.makeLink(
									getDatalinkMetaLink(
										rd.getById("tsdl"), row["accref"]),
									semantics="#counterpart",
									description="%s multiple timed exposures for this field."%
										mjdToDateTime(row["dateobs"]).strftime("%Y-%m-%d"),
									contentType=self.datalinkType,
									contentLength=row["accsize"],
									contentQualifier="#image")
				</code>
			</metaMaker>

			<metaMaker procDef="make_env_prev"/>

			<descriptorGenerator procDef="//soda#fits_genDesc" name="genFITSDesc">
				<bind key="accrefPrefix">'\schema/data'</bind>
				<bind key="qnd">False</bind>
			</descriptorGenerator>
			<FEED source="//soda#fits_standardDLFuncs"/>
		</datalinkCore>
	</service>

	<service id="web" allowed="form">
		<meta name="title">Münster Flare Plates Web Service</meta>
		<meta name="shortName">MS Flares Web</meta>

		<publish render="form" sets="local"/>

		<dbCore queriedTable="data">
			<condDesc original="//siap#humanInput"/>
			<condDesc buildFrom="dateObs"/>
			<condDesc>
				<inputKey original="object" multiplicity="multiple" showItems="5">
					<values fromdb="object from \schema.data"/>
				</inputKey>
			</condDesc>
		</dbCore>

		<outputTable>
			<LOOP listItems="datalink_url accsize kind accref dateObs
				centerAlpha centerDelta
				object wfpdb_id imageTitle instId total_exptime
				obs_duration">
				<events>
					<outputField original="\item"/>
				</events>
			</LOOP>
		</outputTable>
	</service>

	<regSuite title="Muenster flares">
		<regTest title="Obscore has Muenster flare direct observations">
			<url parSet="TAP"
				QUERY="SELECT * FROM ivoa.obscore WHERE
					obs_collection='Muenster Flare Survey'
					AND dataproduct_subtype='DIRECT'
					AND t_min between 44608 AND 44608.1">/tap/sync</url>
			<code>
				row = self.getFirstVOTableRow()
				self.assertEqual(row["s_xel1"], 6942)
				self.assertEqual(row["obs_title"],
					'flare survey M42-43 DIRECT 1981-01-04')
				self.assertAlmostEqual(row["em_max"], 5e-7)
				self.assertAlmostEqual(row["t_max"], 46408.0409722)
				self.assertEqual(row["t_exptime"], 1800.)
				self.assertTrue("dlmeta?ID=" in row["access_url"],
					"access URL is not a datalink?")
			</code>
		</regTest>

		<regTest title="hppunion has Muenster flare time series observations">
			<url parSet="TAP"
				QUERY="SELECT * FROM hppunion.main WHERE
					instid='40cm GPO'
					AND dateobs between 46072.0715 and 46072.0716">/tap/sync</url>
			<code>
				row = self.getFirstVOTableRow()
				self.assertEqual(row["bandpassId"], "KODAK098+RG630")
				self.assertEqual(row["object"], "M42-43")
			</code>
		</regTest>

		<regTest title="Muenster direct observation datalink has extra links">
			<url
				ID="ivo://org.gavo.dc/~?flare_survey/data/plates/ESO040_004362.fits"
				>mdl/dlmeta</url>
			<code>
				rows = self.getVOTableRows()
				bySemantics = {}
				for row in rows:
					bySemantics.setdefault(
						(row["access_url"] and row["access_url"].split("/", 3)[-1],
							row["semantics"]), []
							).append(row)
				
				self.assertEqual(bySemantics[
					("flare_survey/q/tsdl/dlmeta?ID=ivo%3A%2F%2Forg.gavo.dc%2F~%3Fflare_survey%2Fdata%2Fplates%2FESO040_007815.fits",
						"#counterpart")][0]["description"],
					"1985-01-07 multiple timed exposures for this field.")
				self.assertEqual(bySemantics[
					("flare_survey/q/mdl/static/photos/ESO040_004362.jpg",
					"#preview-image")][0]["description"],
					"Mid-resolution plate photo.")
			</code>
		</regTest>

		<regTest title="Muenster time series datalink has extra links">
			<url
				ID="ivo://org.gavo.dc/~?flare_survey/data/plates/ESO040_007815.fits"
				>tsdl/dlmeta</url>
			<code>
				rows = self.getVOTableRows()
				bySemantics = {}
				for row in rows:
					bySemantics.setdefault(
						(row["access_url"] and row["access_url"].split("/", 3)[-1],
							row["semantics"]), []
							).append(row)

				mrow = bySemantics[
					("flare_survey/q/mdl/dlmeta?ID=ivo%3A%2F%2Forg.gavo.dc%2F~%3Fflare_survey%2Fdata%2Fplates%2FESO040_004362.fits",
						"#calibration")][0]
				self.assertEqual(mrow["description"],
					"A master frame containing a single, direct exposure of this field.")
				self.assertEqual(bySemantics[
					("flare_survey/q/tsdl/static/photos/ESO040_007815.jpg",
					"#preview-image")][0]["description"],
					"Mid-resolution plate photo.")
				self.assertEqual(bySemantics[
					("flare_survey/q/tsdl/static/envelopes/ESO040_007815e.jpg",
					"#documentation")][0]["description"],
					"Photo of the plate envelope.")
			</code>
		</regTest>

	</regSuite>
</resource>
