def adaptTable(origTable, newColumns):
    """returns a Data instance created from origTable with columns taken from
	newColumns.

	The adaptation works like this:

	(1) if names and units of newColumns are a subset of origTable.columns,
	return a table with the rows from origTable and the columns from
	newColumns.

	(1a) if origTable has a noPostprocess attribute, proceed to (4)

	(2) if names of newColumns are a subset of origTable.columns match
	but one or more units don't, set up a conversion routine and create
	new rows, combining them with newColumns to the result.

	(3) else raise an error.

	(4) Finally, stick the whole thing into a data container.

	This stinks.  I'm plotting to do away with it.
	"""
    if hasattr(origTable, "noPostprocess"):
        colDiffs = None
        newTd = origTable.tableDef

    else:
        colDiffs = base.computeColumnConversions(newColumns,
                                                 origTable.tableDef.columns)
        newTd = origTable.tableDef.copy(origTable.tableDef.parent)
        newTd.columns = newColumns

    if not colDiffs:
        newTable = table.InMemoryTable(newTd, rows=origTable.rows)
        newTable.meta_ = origTable.meta_
        newTable._params = origTable._params

    else:  # we need to do work
        newTd.copyMetaFrom(origTable.tableDef)
        rmk = rscdef.RowmakerDef(None)
        for col in newColumns:
            exprStart = ""
            if col.name in colDiffs:
                exprStart = "%s*" % colDiffs[col.name]
            rmk.feedObject(
                "map",
                rmkdef.MapRule(
                    rmk,
                    dest=col.name,
                    content_="%svars[%s]" %
                    (exprStart, repr(col.name))).finishElement(None))
        newTable = table.InMemoryTable(newTd, validate=False)
        mapper = rmk.finishElement(None).compileForTableDef(newTd)
        for r in origTable:
            newTable.addRow(mapper(r, newTable))
        newTable._params = origTable._params

    return rsc.wrapTable(newTable, rdSource=origTable.tableDef)
def makeVOTable(data, ctx=None, **kwargs):
	"""returns a votable.V.VOTABLE object representing data.

	data can be an rsc.Data or an rsc.Table.  data can be a data or a table
	instance, tablecoding any key in votable.tableEncoders.

	You may pass a VOTableContext object; if you don't a context
	with all defaults will be used.

	A deprecated alternative is to directly pass VOTableContext constructor
	arguments as additional keyword arguments.  Don't do this, though,
	we'll probably remove the option to do so at some point.
	
	You will usually pass the result to votable.write.  The object returned
	contains DelayedTables, i.e., most of the content will only be realized at
	render time.
	"""
	ctx = ctx or VOTableContext(**kwargs)

	data = rsc.wrapTable(data)
	if ctx.version==(1,1):
		vot = V.VOTABLE11()
	elif ctx.version==(1,2):
		vot = V.VOTABLE12()
	elif ctx.version==(1,3):
		vot = V.VOTABLE()
	elif ctx.version==(1,4):
		vot = V.VOTABLE()     # TODO: When 1.4 XSD comes out, actually implement
	else:
		raise votable.VOTableError("No toplevel element for VOTable version %s"%
			ctx.version)

	vot[_iterToplevelMeta(ctx, data)]
	vot[_makeResource(ctx, data)]

	if ctx.produceVODML:
		if ctx.modelsUsed:
			# if we declare any models, we'll need vo-dml
			ctx.addVODMLPrefix("vo-dml")
		for model in ctx.modelsUsed.values():
			vot[model.getVOT(ctx)]

	if ctx.suppressNamespace:  
		# use this for "simple" table with nice element names
		vot._fixedTagMaterial = ""

	# What follows is a hack around the insanity of stuffing
	# unused namespaces and similar detritus into VOTable's roots.
	rootAttrs = data.getMeta("_votableRootAttributes")
	if rootAttrs:
		rootHacks = [vot._fixedTagMaterial]+[
			item.getContent() for item in rootAttrs]
		vot._fixedTagMaterial = " ".join(s for s in rootHacks if s)

	return vot
Пример #3
0
def _makeDataFor(resultTable):
	"""returns an rsc.Data instance containing resultTable and some
	additional metadata.
	"""
	resData = rsc.wrapTable(resultTable)
	resData.addMeta("info", "Query successful",
		infoName="QUERY_STATUS", infoValue="OK")
	resData.addMeta("_type", "results")
	# setLimit is the effective maximum number of rows returned
	# as determined by adqlglue.morphADQL (or similar functions)
	resData.setLimit = getattr(resultTable.tableDef, "setLimit", None)
	return resData
def writeDataAsFITS(data, outputFile, acquireSamples=False):
	"""a formats.common compliant data writer.

	This will write out table params as header cards.  To serialise
	those yourself (as is required for spectral data model compliant
	tables), set an attribute IgnoreTableParams (with an arbitrary
	value) on the table.
	"""
	data = rsc.wrapTable(data)
	fitsName = makeFITSTableFile(data, acquireSamples)
	try:
		src = open(fitsName)
		utils.cat(src, outputFile)
		src.close()
	finally:
		os.unlink(fitsName)
Пример #5
0
    def _run_queryData(self, service, inputTable, queryMeta):
        format = inputTable.getParam("FORMAT") or ""
        if format.lower() == "metadata":
            return self._makeMetadata(service)

        limits = [
            q for q in (inputTable.getParam("MAXREC", None),
                        inputTable.getParam("TOP")) if q
        ]
        if not limits:
            limits = [base.getConfig("ivoa", "dalDefaultLimit")]
        limit = min(min(limits), base.getConfig("ivoa", "dalHardLimit"))
        queryMeta["dbLimit"] = limit

        res = svcs.DBCore.run(self, service, inputTable, queryMeta)
        if len(res) == limit:
            queryStatus = "OVERFLOW"
            queryStatusBody = (
                "Exactly %s rows were returned.  This means your"
                " query probably reached the match limit.  Increase MAXREC." %
                limit)
        else:
            queryStatus = "OK"
            queryStatusBody = ""

        self._addPreviewLinks(res)

        # We wrap our result into a data instance since we need to set the
        #	result type
        data = rsc.wrapTable(res)
        data.setMeta("_type", "results")
        data.addMeta("_votableRootAttributes",
                     'xmlns:ssa="http://www.ivoa.net/xml/DalSsap/v1.0"')

        # The returnRaw property is a hack, mainly for unit testing;
        # The renderer would have to add the QUERY_STATUS here.
        if service.getProperty("returnData", False):
            return data

        # we fix tablecoding to td for now since nobody seems to like
        # binary tables and we don't have huge tables here.
        votCtx = votablewrite.VOTableContext(tablecoding="td")

        vot = votablewrite.makeVOTable(data, votCtx)
        pubDIDId = votCtx.getIdFor(res.tableDef.getColumnByName("ssa_pubDID"))
        resElement = vot.getChildDict()["RESOURCE"][0]
        resElement[
            V.INFO(name="SERVICE_PROTOCOL", value=self.ssapVersion)["SSAP"],
            V.INFO(name="QUERY_STATUS", value=queryStatus)[queryStatusBody]]

        datalinkId = service.getProperty("datalink", None)
        if datalinkId and res:
            dlService = self.rd.getById(datalinkId)
            dlCore = getDatalinkCore(dlService, res)

            # new and shiny datalink (keep)
            # (we're just using endpoint 0; it should a the sync service)
            dlEndpoint = dlCore.datalinkEndpoints[0]
            vot[dlEndpoint.asVOT(votCtx,
                                 dlService.getURL(dlEndpoint.rendName),
                                 linkIdTo=pubDIDId)]

            # Also point to the dl metadata service
            vot[V.RESOURCE(type="meta", utype="adhoc:service")[
                V.PARAM(name="standardID",
                        datatype="char",
                        arraysize="*",
                        value="ivo://ivoa.net/std/DataLink#links-1.0"),
                V.PARAM(name="accessURL",
                        datatype="char",
                        arraysize="*",
                        value=self.rd.getById(datalinkId).getURL("dlmeta")),
                V.GROUP(name="inputParams")[V.PARAM(
                    name="ID",
                    datatype="char",
                    arraysize="*",
                    ref=pubDIDId,
                    ucd="meta.id;meta.main"
                )[V.LINK(content_role="ddl:id-source", value="#" +
                         pubDIDId)]]]]

        return "application/x-votable+xml", votable.asString(vot)