<?xml version="1.0" encoding="utf-8"?>

<resource schema="maidanak">

	<meta name="title">Maidanak Observatory Lens Images</meta>
	<meta name="copyright" format="plain">The data from Maydanak observatory
have been obtained in a German-Uzbek collaboration
(Heidelberg, Potsdam, Tashkent) and are not in the public domain. If you
want to use the data for your research, send a request to Robert Schmidt
at the Astronomisches Rechen-Institut/Zentrum für Astronomie der
Universität Heidelberg, rschmidt(AT)ari.uni-heidelberg.de.</meta>
	<meta name="creationDate">2007-06-06T12:00:00Z</meta>
	<meta name="schema-rank">1000</meta>
	<meta name="description">Observations of (mainly) lensed quasars
		from Maidanak Observatory, Uzbekhistan</meta>

	<meta name="subject">quasars</meta>
	<meta name="subject">observational-cosmology</meta>
	<meta name="subject">strong-gravitational-lensing</meta>

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

	<meta name="_related" title="Lens Image Collection">/lensdemo/view/q/form</meta>
	<meta name="_related" title="Maidanak Object query">/maidanak/res/rawframes/q/form</meta>
	<meta name="_related" title="Maidanak SIAP query">/maidanak/res/rawframes/siap/form</meta>

	<table id="reduced" adql="True" onDisk="True" mixin="//siap#pgs">
		<meta name="_associatedDatalinkService">
			<meta name="serviceId">dl</meta>
			<meta name="idColumn">pub_did</meta>
		</meta>
		<meta name="description">
			Reduced frames of lensed quasar observations from Maidanak Observatory.
			See the referenceURL for details on the reduction procedure and
			calibration data.
		</meta>
		<register services="lensunion/q#im"/>

		<index columns="dateObs"/>
		<index columns="bandpassLo"/>
		<index columns="bandpassHi"/>

		<mixin
			collectionName="'Maidanak Lenses'"
			facilityName="'Maidanak Observatory'"
			targetName="object"
			targetClass="'GravLens'"
			expTime="exposure"
			createDIDIndex="true"
		>//obscore#publishSIAP</mixin>
		<column name="filename"  type="text"
			required="true" tablehead="Original Filename" ucd="meta.id"
			description="File name as supplied by the observatory -- unreliable"/>
		<column name="type"  type="text"
			required="true" tablehead="Obs. Type"
			ucd="meta.code.class"
			description="Type of observation (science, flat, bias, calib...)"/>
		<column name="object"  type="text"
				tablehead="Target Object"
				description="Object being observed, Simbad-resolvable form"
				ucd="meta.id;meta.main">
		</column>
		<column name="raw_object"  type="text"
			tablehead="Target Object (Header)" ucd="meta.id"
			description="Target object as supplied by the observatory"/>
		<column name="observatory"  type="text"
			tablehead="Observed at" ucd="meta.id;instr.obsty"
			description="Observatory the image was obtained at"/>
		<column name="telescope"  type="text"
			tablehead="Telescope" ucd="instr.tel"
			description="Telescope used to obtain the image"/>
		<column name="instrument"  type="text"
			tablehead="Instrument" ucd="instr.setup"
			description="Identifier of the detecting instrument"/>
		<column name="detector"  type="text"
			tablehead="Detector" ucd="meta.id;instr.det"
			description="Internal detector ID"/>
		<column name="exposure"  type="real"
			tablehead="Exp. time" ucd="time.duration;obs.exposure"
			unit="s" description="Exposure time"/>
		<column name="startTime"  type="timestamp"
			tablehead="UT at start"
			description="Start of exposure in UT" ucd="time.start"/>
		<column name="endTime"  type="timestamp"
			tablehead="UT at end"
			description="End of exposure in UT" ucd="time.end"/>
		<column name="chipid"  type="text"
			tablehead="Chip" description="Detector Chip" ucd="meta.id;instr.det"/>
		<column name="p_dewar"  type="real"
			tablehead="Dewar pressure"
			description="Dewar Pressure (unreliable)"
			ucd="phys.pressure;instr.param"/>
		<column name="ari_raw"  type="text"
			description="Raw object name assigned at ARI"
			tablehead="Object (Raw)" ucd="meta.id"/>
		<column name="pub_did" type="text"
			ucd="meta.ref.ivoid"
			description="Publisher dataset Identifier"
			tablehead="PubDID"/>
	</table>

	<coverage>
		<updater sourceTable="reduced"/>
			<spectral>1.71245e-19 4.13843e-19</spectral>
			<temporal>51238.7 53615</temporal>
			<spatial>4/1045,1047 5/1816,1856,2162,2298,3497,4213,4215,4221,4386,4392,4394,4480,4489,4507,4804,8959 6/2329-2331,4574,4593,4596-4598,5066-5067,5088-5089,5710-5711,5732-5733,5817,5819-5820,5922-5923,5928,6133,6135,7217,7219-7220,7222,7272,8193,8195,8198,8297,8299,8302,8360,8362,8385,8388,8449,8452-8454,8705,8707,8710,8713,8901,8903,8912,8914,9323,9326,9409,9411-9412,9639,9645,9648,9650,10214,10217,10219-10220,10689-10692,10694,11339,11342,11361,11364,11607,11613,12024-12026,12028,13195-13196,13198,14057-14059,14646-14647,14652-14653,15350-15351,15356-15357,15662-15663,15748-15749,16034,16043,16046,16300-16301,16306,16312,16709,16711,16717,16719,16741,16848-16849,16851,16857,16859,16892-16893,16895,17237,17418,17440,17442,17448,17450,17508,17510-17511,17536,17538-17539,17580,17582,17924,17926,17928-17929,17931-17932,17934-17935,17953,17964-17965,17967,17978,22114-22115,22120-22121,22123,22558-22559,22580-22581,23337,23339-23340,23342,25239,25244-25245,25247,25288,25934-25935,25957,25959,25964-25965,25967,25971,25976-25978,25980,26027,26030,26109,26111,26369,26372,27126-27127,27132-27133,27315-27316,27318-27319,27324,27518,27604-27606,27746-27747,27752-27753,28043,28046,28065,28249-28251,28254,30215,30221,30223,30226,30232-30234,30438-30439,30445,30450,31662,35830-35831,35833-35835,44763,44785,44788,48735,48757,48928,48930</spatial>
	</coverage>

	<table id="provenance" onDisk="True">
		<meta name="description">
			A map from reduced files to their sources.

			This is an internal table used by the datalink service.
		</meta>
		<column name="accref" type="text"
			tablehead="Accref"
			description="Access reference to the reduced file"/>
		<column name="flat" type="text"
			tablehead="Flat used"
			description="Path to the superflat used for the reduction."/>
		<column name="raw_file" type="text"
			tablehead="Raw"
			description="The raw data used for the reduction."/>
	</table>

	<procDef id="resolveStem" type="apply">
		<doc>A base procDef to resolve stems to file name paths.
		That's necessary here because paths got lost in reduction,
		but stem names were done in a way that we can hopefully
		be sure what file in a hierarchy was actually used.
		</doc>
		<setup>
			<par name="root"/>
			<code>
				stemToSource = {}
				for dirpath, dirnames, filenames in os.walk(
						rd.getAbsPath(root)):
					dirpath = getInputsRelativePath(dirpath)
					for name in filenames:
						stemToSource[name.split(".")[0]
							] = os.path.join(dirpath, name)
			</code>
		</setup>
	</procDef>

	<rowmaker id="make_reduced">
		<var name="utStart">parseTime(@TM_START, "!!secondsSinceMidnight")</var>
		<var name="utEnd">parseTime(@TM_END, "!!secondsSinceMidnight")</var>
		<var name="dateObs">parseDate(@DATE_OBS)</var>

		<apply procDef="//procs#mapValue" name="mapFilter">
			<bind key="sourceName">"maidanak/res/filtermap.txt"</bind>
			<bind key="destination">"filter"</bind>
			<bind key="value">vars["FILTER"]</bind>
		</apply>

		<apply procDef="//siap#setMeta" name="siapMeta">
			<bind key="title">"Maidanak %s %s %s"%(@ARI_OBJC,
				@dateObs, @filter)</bind>
			<bind key="instrument">@TELESCOP</bind>
			<bind key="dateObs">vars["dateObs"]+vars["utStart"]+(
				vars["utEnd"]-vars["utStart"])/2</bind>
			<bind key="bandpassId">@filter</bind>
		</apply>

		<apply procDef="//siap#computePGS" name="siapCompute"/>

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

		<map dest="startTime">@dateObs+@utStart</map>
		<map dest="endTime">@dateObs+@utEnd</map>

		<simplemaps>filename:FILENAME, type:ARI_TYPE,
			observatory: OBSERVAT,
			telescope: TELESCOP, instrument: INSTRUME, detector: DETNAME,
			exposure: EXPTIME, chipid: CHIPID, p_dewar: P_DEWAR,
			ari_raw: ARI_RAW</simplemaps>
		<map dest="object" src="ARI_OBJC"/>
		<map dest="raw_object" src="OBJECT"/>
		<map dest="pub_did">\standardPubDID</map>
	</rowmaker>

	<data id="content">
		<sources pattern="data/red_*.gz" recurse="True"/>

		<fitsProdGrammar qnd="True">
			<rowfilter procDef="//products#define">
				<setup><code>
					<![CDATA[
					def getEmbargo(row):
						res = '2008-12-31'
						if (row.get("ARI_TYPE")!="SCIENCE" or
								row["ARI_OBJC"]=='Q2237+0305'
								or row["ARI_OBJC"]=='SBSS 1520+530'):
							if '2003-01-01'<=row['DATE_OBS']<='2003-12-31':
								res = '2005-12-31'
						return res
					]]>
				</code></setup>
				<bind key="owner">"maidanak"</bind>
				<bind key="embargo">getEmbargo(row)</bind>
				<bind key="table">"maidanak.reduced"</bind>
			</rowfilter>

			<ignoreOn>
				<keyIs name="noUnknownObjects"
					key="ARI_OBJC" value="UNKNOWN"/>
				<not>
					<keyPresent name="typeGiven" key="ARI_TYPE"/>
				</not>
				<not>
					<keyPresent name="hasSrc" key="FILENAME"/>
				</not>
				<!-- MIDAS inserted dummy values for calibration (curse them),
				checking for proper projection kicks them out -->
				<not>
					<keyIs name="noUnresolved"
						key="CTYPE1" value="RA---TAN-SIP"/>
				</not>
			</ignoreOn>

		</fitsProdGrammar>

		<make table="reduced" rowmaker="make_reduced"/>

		<make table="provenance">
			<rowmaker idmaps="*">
				<apply name="findRaw" procDef="resolveStem">
					<bind name="root">"raw"</bind>
					<code>
						srcKey = re.sub("^red_", "", \srcstem).lower()
						@raw_file = stemToSource.get(srcKey)
						mat = re.search("'FLATFIELD'.*?\\n *([a-z0-9._]+)",
							str(vars["header_"]["HISTORY"]))

						if mat:
							@flat = stemToSource.get(
								mat.group(1).split(".")[0], mat.group(1))
						else:
							@flat = None
					</code>
				</apply>
				<map key="accref" source="prodtblAccref"/>
			</rowmaker>
		</make>
		
		<recreateAfter>lensunion/q#import</recreateAfter>
	</data>

	<dbCore id="qsiap" queriedTable="reduced">
		<condDesc original="//siap#protoInput"/>
		<condDesc original="//siap#humanInput"/>
		<condDesc>
			<inputKey original="bandpassId" showItems="3" id="filterInput"
					multiplicity="multiple">
				<values fromdb="bandpassId FROM maidanak.reduced"/>
			</inputKey>
		</condDesc>
		<condDesc buildFrom="dateObs"/>
	</dbCore>

	<service id="siap" allowed="siap.xml,form" core="qsiap">
		<publish render="form" sets="local"/>
		<meta name="shortName">mdk_siap</meta>
		<meta name="title">Maidanak Observatory SIAP Query</meta>
		<meta name="sia.type">Pointed</meta>
		<meta name="testQuery.pos.ra">340</meta>
		<meta name="testQuery.pos.dec">3</meta>
		<meta name="testQuery.size.ra">1</meta>
		<meta name="testQuery.size.dec">1</meta>
	</service>

	<dbCore id="qcore" queriedTable="reduced">
		<condDesc>
			<inputKey original="object" showItems="5"
					required="true" type="text" multiplicity="multiple">
				<values fromdb="object FROM maidanak.reduced WHERE type='SCIENCE'"/>
			</inputKey>
		</condDesc>
		<condDesc buildFrom="startTime"/>
		<condDesc buildFrom="filterInput"/>
	</dbCore>

	<service id="q" core="qcore">
		<publish render="form" sets="local"/>
		<meta name="shortName">mdk_object</meta>
		<meta name="title">Maidanak Observatory Object Query</meta>
		<meta name="description">Observations of (mainly) lensed quasars
			accessible through a selection of the target object</meta>
		<outputTable namePath="reduced">
			<outputField original="startTime" displayHint="type=humanDate"/>
			<LOOP listItems="object exposure bandpassId accref accsize">
				<events>
					<outputField original="\item"/>
				</events>
			</LOOP>
		</outputTable>
	</service>

	<service id="dl" allowed="dlmeta,dlget">
		<meta name="title">Maidanak Reduced Data Datalink</meta>
		<datalinkCore>
			<metaMaker semantics="#progenitor">
				<code>
					yield descriptor.makeLink(
						makeAbsoluteURL("\rdId/raw-dl/dlmeta?ID="+descriptor.accref),
						contentType="application/x-votable+xml;content=datalink",
						description="Raw data and calibration files",
						contentLength=5000)
				</code>
			</metaMaker>
		</datalinkCore>
	</service>

	<service id="make-bias" allowed="qp">
		<meta name="description">A service that produces bias frames
			for raw exposures.  These are FITSes having the mean value of the
			overscan area of the accompanying raw file throughout.
		</meta>
		<property key="queryField">accref</property>

		<pythonCore>
			<inputTable>
				<inputKey name="accref" type="text" required="True"
					description="The accref of the *processed* frame to compute
						 the bias frame for."/>
			</inputTable>
			<coreProc>
				<setup imports="numpy, io, gzip, gavo.utils.pyfits"><code>
					def guessBiasVal(fName):
						"""guesses the bias value from the overscan pixels.

						Regrettably, the XOVERSC header is always 0.  We assume the
						10 border pixels are always overscan.  Experimentally, that
						seems to be the case (we've tried on almost all frames).
						"""
						hdus = pyfits.open(fName)
						pixels = hdus[0].data
						if pixels.shape[0]>2000:
							# that's probably data already reduced
							raise ValueError("No raw data available")

						biasAvg = (numpy.average(pixels[:,:10])
							+numpy.average(pixels[:,-10:]))/2
						hdus.close()
						return pixels.shape, biasAvg
				</code></setup>
				<code>
				# Regrettably, the XOVERSC header always has a 0 insize
				# unreliable at best.
				with base.getTableConn() as conn:
					rawPath = os.path.join(base.getConfig("inputsDir"),
						next(conn.query("SELECT raw_file"
							" FROM \schema.provenance"
							" WHERE accref=%(accref)s",
							{"accref": inputTable.args["accref"]}))[0])
					
				shape, val = guessBiasVal(rawPath)

				hdu = pyfits.PrimaryHDU(numpy.ones(shape, numpy.float32
					)*numpy.float32(val))
				hdu.header["history"] = "Bias frame for {}".format(
					os.path.basename(rawPath))
				hdu.header["history"] = ("Computed by maidanak/rawframes"
					" make-bias based on the overscan pixels found in the file")
				
				serialized = io.BytesIO()
				pyfits.HDUList([hdu]).writeto(serialized)
				return "application/fits+gzip", gzip.compress(serialized.getvalue())
				</code>
			</coreProc>
		</pythonCore>
	</service>

	<service id="raw-dl" allowed="dlmeta,static">
		<meta name="title">Maidanak Raw Data Datalink</meta>
		<property key="staticData">raw</property>

		<datalinkCore>
			<descriptorGenerator original="//datalink#fromtable">
				<bind key="tableName">"\schema.provenance"</bind>
				<bind key="idColumn">"accref"</bind>
			</descriptorGenerator>	

			<metaMaker semantics="#this">
				<code>
					yield descriptor.makeLinkFromFile(
						os.path.join(base.getConfig("inputsDir"),
							descriptor.metadata["raw_file"]),
						description="Original, unreduced observation",
						contentType="application/fits+gzip",
						contentQualifier="#image")
				</code>
			</metaMaker>

			<metaMaker semantics="#flat">
				<code>
					yield descriptor.makeLinkFromFile(
						os.path.join(base.getConfig("inputsDir"),
							descriptor.metadata["flat"]),
						description="Recommended superflat for the time at which #this"
							" was taken",
						contentType="application/fits+gzip")
				</code>
			</metaMaker>

			<metaMaker semantics="#bias">
				<code>
					yield descriptor.makeLink(
						makeAbsoluteURL("\rdId/make-bias/qp/"
							+descriptor.metadata["accref"]),
						description="Bias frame derived from the overscan regions"
							" at both ends of the raw exposure",
						contentType="application/fits+gzip",
						contentLength=100000)
				</code>
			</metaMaker>

			<metaMaker semantics="#derivation">
				<code>
					accref = descriptor.metadata["accref"]
					yield descriptor.makeLink(
						makeAbsoluteURL("/getproduct/"+accref),
						description="This dataset, reduced with #flat and #bias",
						contentType="application/fits+gzip",
						contentLength=os.path.getsize(
							os.path.join(base.getConfig("inputsDir"),
								accref)),
						contentQualifier="#image")
				</code>
			</metaMaker>
		</datalinkCore>
	</service>

	<regSuite title="Maidanak SIAP">
		<regTest title="Maidanak SIAP successful query with request INFO">
			<url POS="340.12,3.3586" SIZE="0.1" INTERSECT="OVERLAPS"
				RESPONSEFORMAT="votabletd" MAXREC="10">siap/siap.xml</url>
			<code><![CDATA[
				self.assertHasStrings('</TR></TABLEDATA>')
				self.assertXpath('//v:INFO[@name="request"]', {
					"value": EqualingRE(r".*/maidanak/res/rawframes/siap/siap.xml\\?POS=340.12%2C3.3586&SIZE=0.1&INTERSECT=OVERLAPS&RESPONSEFORMAT=votabletd&MAXREC=10"),})
			]]></code>
		</regTest>

		<regTest title="Maidanak SIAP binary result delivery works">
			<url POS="340.12,3.3586" SIZE="0.1" INTERSECT="OVERLAPS"
				MAXREC="10" RESPONSEFORMAT="votable">siap/siap.xml</url>
			<code>
				self.assertHasStrings('STREAM encoding="base64">AAA')
			</code>
		</regTest>

		<regTest title="Maidanak SIAP returns accref.">
			<url POS="340.12,3.3586" SIZE="0.1" INTERSECT="OVERLAPS"
				RESPONSEFORMAT="votabletd" MAXREC="10">siap/siap.xml</url>
			<code>
				self.assertHasStrings('&lt;TD>AZT 22')
			</code>
		</regTest>

		<regTest title="SIAP error document">
			<url POS="q2237%2B0305" SIZE="0.a1" INTERSECT="OVERLAPS"
				RESPONSEFORMAT="votabletd" MAXREC="10">siap/siap.xml</url>
			<code>
				self.assertHasStrings('name="QUERY_STATUS" value="ERROR"')
				self.assertXpath('//v:INFO[@name="request"]', {
					"value": EqualingRE(r"http.*/maidanak/res/rawframes/siap/siap.xml\\?POS=q2237%252B0305&amp;SIZE=0.a1&amp;INTERSECT=OVERLAPS&amp;RESPONSEFORMAT=votabletd&amp;MAXREC=10")})
			</code>
		</regTest>

		<regTest title="Maidanak product delivery"
			url="/getproduct/maidanak/data/Q2237p0305/Johnson_R/
				red_kk050001.fits.gz?siap=true">
			<code>
				self.assertHasStrings(b'\\x1f\\x8b\\x08\\x08')
			</code>
		</regTest>

		<regTest title="Maidanak SIAP metadata query"
				url="siap/siap.xml?FORMAT=METADATA">
			<code>
				self.assertXpath("//v:FIELD[@name='wcs_cdmatrix']", {
					"datatype": "double",
					"ucd": "VOX:WCS_CDMatrix",
					"arraysize": "*",
					"unit": "deg/pixel"})
				self.assertXpath("//v:INFO[@name='QUERY_STATUS']", {
					"value": "OK",
					None: "OK",})
				self.assertXpath("//v:PARAM[@name='INPUT:POS']", {
					"datatype": "char",
					"ucd": "pos.eq"})
			</code>
		</regTest>
	</regSuite>

	<regSuite title="Maidanak Web">
		<regTest title="Simbad resolution of positions works">
			<url parSet="form" hPOS="M1" hSIZE="0.5" hINTERSECT="OVERLAPS"
				>siap/form</url>
			<code><![CDATA[
				'<div class="resmeta">', '<p>Matched:'
			]]></code>
		</regTest>
	</regSuite>

	<regSuite title="Maidanak DaCHS regression">
		<regTest id="tartest" title="Tar output declared in header">
			<url hPOS="q2237+0305" hSIZE="1" hINTERSECT="OVERLAPS"
				hFORMAT="application/fits" dateObs="2001-01-01 .. 2005-10-10"
				MAXREC="1" _FORMAT="tar" _DBOPTIONS_ORDER="dateObs"
				parSet="form" httpMethod="HEAD"
				>siap/form</url>
			<code>
				self.assertHeader("content-disposition",
					"attachment; filename=truncated_data.tar")
				self.assertHeader("content-type", "application/x-tar")
			</code>
		</regTest>
		<regTest title="Tar output looks plausible">
			<url parSet="form" MAXREC="1" hSIZE="1"
				_DBOPTIONS_ORDER="dateObs" _FORMAT="tar"
				dateObs="2001-01-01 .. 2005-10-10"
				hFORMAT="application/fits" hPOS="q2237+0305" hINTERSECT="OVERLAPS"
				>siap/form</url>
			<code>
				self.assertHasStrings("dc_data/",
					# end of tar header, start of gzipped file
					b"\\0\\0\\0\\0\\0\\0\\x1f\\x8b\\x08\\x08")
			</code>
		</regTest>

		<regTest title="PMH GetRecord response looks all right in oai_dc">
			<url verb="GetRecord" metadataPrefix="oai_dc"
				identifier="ivo://org.gavo.dc/maidanak/res/rawframes/reduced"
				>/oai.xml</url>
			<code>
				self.assertHasStrings('oai:GetRecord>', 'dc:title')
			</code>
		</regTest>

		<regTest title="OAI ListMetadataFormats validates">
			<url verb="ListMetadataFormats"
				identifier="ivo://org.gavo.dc/maidanak/res/rawframes/siap"
				>/oai.xml</url>
			<code>
				self.assertValidatesXSD()
			</code>
		</regTest>

		<regTest title="OAI GetRecord validates in oai_dc">
			<url verb="GetRecord" metadataPrefix="oai_dc"
				identifier="ivo://org.gavo.dc/maidanak/res/rawframes/siap"
				>/oai.xml</url>
			<code>
				self.assertValidatesXSD()
			</code>
		</regTest>

		<regTest title="OAI GetRecord validates in ivo_vor">
			<url verb="GetRecord" metadataPrefix="ivo_vor"
				identifier="ivo://org.gavo.dc/maidanak/res/rawframes/siap"
				>/oai.xml</url>
			<code>
				self.assertValidatesXSD()
			</code>
		</regTest>

		<regTest title="Preview looks like a JPEG">
			<!-- Due to preview caching, this test is only effective when
			tester and testee share the file system; otherwise, you'll get
			cached responses only. -->
			<url width="200" preview="True"
				>/getproduct/maidanak/data/QSO_B1422p231/Johnson_V/red_mf290044.fits.gz</url>
			<code>
				self.assertHasStrings("JFIF")
				from gavo.protocols import products
				try:
					os.unlink(
						products.PreviewCacheManager.getCacheName(
							"maidanak/data/QSO_B1422p231"
							"/Johnson_V/red_mf290044.fits.gz"))
				except IOError:
					pass
			</code>
		</regTest>

		<regTest title="Info page looks ok"
			url="siap/info">
			<code>
				self.assertHasStrings("SIAP Query", "siap.xml", "form",
					"Other services", "SIZE&lt;/td>", "Verb. Level")
			</code>
		</regTest>
	</regSuite>

	<regSuite title="Maidanak datalink" id="cur">
		<regTest title="Maidanak reduced datalink delivers progenitor link.">
			<url ID="maidanak/data/Q2237p0305/Johnson_R/red_kk050001.fits.gz"
				>dl/dlmeta</url>
			<code>
				bySemantics = dict((r["semantics"], r) for r in self.getVOTableRows())
				progRow = bySemantics["#progenitor"]
				self.assertTrue(progRow["access_url"].endswith(
					"/maidanak/res/rawframes/raw-dl/dlmeta?ID=maidanak/data/Q2237p0305/Johnson_R/red_kk050001.fits.gz"))
				self.assertTrue(progRow["description"], "Raw data and"
					" calibration files")
			</code>
		</regTest>	

		<regTest title="Maidanak raw datalink returns links">
			<url ID="maidanak/data/Q2237p0305/Johnson_R/red_kk050001.fits.gz">raw-dl/dlmeta</url>
			<code>
				bySemantics = dict((r["semantics"], r) for r in self.getVOTableRows())

				self.assertEqual(bySemantics["#this"]["access_url"],
					EqualingRE("http.*/raw-dl/static/cd005/nov0501/q2237/kk050001.gz"))
				self.assertEqual(bySemantics["#this"]["content_type"],
					"application/fits+gzip")
				self.assertEqual(bySemantics["#this"]["content_length"], 1766879)
				self.assertEqual(bySemantics["#this"]["content_qualifier"],
					"#image")

				self.assertEqual(bySemantics["#flat"]["access_url"],
					EqualingRE("http.*/maidanak/res/rawframes/"
						"raw-dl/static/cd010/superfla/sfr.fit.gz"))
				self.assertEqual(bySemantics["#flat"]["content_type"],
					"application/fits+gzip")
				self.assertEqual(bySemantics["#flat"]["content_length"],
					5025753)

				self.assertEqual(bySemantics["#derivation"]["access_url"],
					EqualingRE("http.*/getproduct/maidanak/data/Q2237p0305"
						"/Johnson_R/red_kk050001.fits.gz"))
				self.assertEqual(bySemantics["#derivation"]["content_type"],
					"application/fits+gzip")
				self.assertEqual(bySemantics["#derivation"]["content_length"],
					5282044)

				self.assertEqual(bySemantics["#bias"]["access_url"],
					EqualingRE("http.*/make-bias/qp/maidanak/data/Q2237p0305"
						"/Johnson_R/red_kk050001.fits.gz"))
				self.assertEqual(bySemantics["#bias"]["content_type"],
					"application/fits+gzip")
				self.assertEqual(bySemantics["#bias"]["content_length"],
					100000)
			</code>
		</regTest>

		<regTest title="Maidanak bias frames look right">
			<url>make-bias/qp/maidanak/data/Q2237p0305/Johnson_R/red_kk050001.fits.gz</url>
			<code>
				import gzip
				self.data = gzip.decompress(self.data)
				self.assertHasStrings("BITPIX  =                  -32",
					"NAXIS1  =                 2030",
					"NAXIS2  =                  800",
					"Bias frame for kk050001.gz",
					b"C\\xbb\\x07RC\\xbb\\x07")
			</code>
		</regTest>

		<regTest title="Maidanak flatfield is accessible">
			<url>raw-dl/static/cd010/superfla/sfr.fit.gz</url>
			<code>
				import gzip
				self.data = gzip.decompress(self.data)
				self.assertHasStrings(
					"NAXIS1  =                 2000",
					"DATE    = '2001-12-09T20:22:10'")
			</code>
		</regTest>

		<regTest title="Maidanak raw data is accessible">
			<url>raw-dl/static/cd005/nov0501/q2237/kk050001.gz</url>
			<code>
				import gzip
				self.data = gzip.decompress(self.data)
				self.assertHasStrings(
					"NAXIS1  =                 2030",
					"DATE    =  '2001-11-05'")
			</code>
		</regTest>
	
	</regSuite>

</resource>
