The resource descriptor (RD file) can include procedure coded in python. We test here a access to a remote webservice at IMCCE to retrieve ephemeris parameters for a given target, observer and observation date.
As the IMCCE/Miriade web services are using SAOP interface, we use the ZEEP python package to query the service. The IMCCE/Miriade web services interfaces are described on each service page on the Miriade portal.
The example presented below is used in a prototype service built for IRTF (Mauna Kea Observatory telescope) NIR images in support of the NASA Juno Mission. You can try out the service following instructions available here.
Procedure Definition
The definition of the procedure in the RD file is done using the <procDef>
element. The next code snippet is used for IRTF observations of Jupiter.
<resource schema='irtf_orton'> <!-- -- Place the <procDef> element after the <meta> elements --> <procDef type="apply" id="miriadeEphemph"> <setup> <!-- input parameters to be set with <bind> elements in <apply> element --> <par key="ignoreUnknowns" description="Return Nones for unknown objects? (if false, ValidationErrors will be raised)">True</par> <par key="logUnknowns" description="Write unresolved object names to the info log">False</par> <par key="target_name" late="True" description="The observed target name (Default is Jupiter).">'p:jupiter'</par> <par key="observer" late="True" description="The observer name (Default is Mauna Kea Observatory, for IRTF).">'@568'</par> <par key="obs_time" late="True" description="Observation date time."/> <!-- any piece of python code to be run before the main procedure, like importing modules --> <code> import zeep </code> </setup> <code> ## This is the beginning of the core python code, indentation matters as in python. # Initializing some parameters slat, slon, olat, olon = None, None, None, None np_pos, phase, rap, hemis1, hemis2 = None, None, None, None, None try: # Initialize SOAP client using zeep module client = zeep.Client('http://vo.imcce.fr/webservices/miriade/miriade.wsdl') # Setting up request parameters (as defined on service description page) # NB: Here we will use the ephemph webservice. request = {'name': target_name, 'type':'', 'epoch':obs_time.isoformat(), 'nbd':1, 'step':'', 'tscale':'', 'so':1, 'observer':observer, 'mime':'text', 'view':'none', 'rv':0, 'anim':0, 'print':1, 'visu':'', 'output':'--iso,--coord:eq', 'get':''} # Retrieving response from webservice response = client.service.ephemph(request) # Each line of the output text is separated by ';' characters, # and the data line is the first line not starting with '#' # The next command split lines and retrieves the first data line for line in (item for item in response['result'].split(';') if item[0] != '#'): break # splitting results columns data = line.split() olon = float(data[3]) # Sub-Observer Longitude in Jovian System III (Sub-Earth Point) olat = float(data[4]) # Sub-Observer Latitude in Jovian System III (Sub-Earth Point) slon = float(data[7]) # Sub-Solar Longitude in Jovian System III slat = float(data[8]) # Sub-Solar Latitude in Jovian System III np_pos = float(data[9]) # Angle between planetary North pole and celestial North Pole phase = float(data[11]) # Phase angle rap = float(data[12]) # Apparent radius of target # in case of APIS extension, we need to tell what is the primary hemisphere (best view) if olat >= 0: hemis1 = 'north' hemis2 = 'south' else: hemis1 = 'south' hemis2 = 'north' except KeyError: if logUnknowns: base.ui.notifyInfo("Identifier did not resolve: %s"%identifier) if not ignoreUnknowns: raise base.Error("resolveObject could not resolve object" " %s."%identifier) # Preparing output: whatever you put into the vars dictionary can be used outside the procedure. # E.g.: vars["subsolar_longitude"] is defined here, and can be used as @subsolar_longitude outside vars["subsolar_longitude"] = slon vars["subsolar_latitude"] = slat vars["subobserver_longitude"] = olon vars["subobserver_latitude"] = olat vars["np_pos"] = np_pos vars["phase"] = phase vars["rap"] = rap vars["hemis1"] = hemis1 vars["hemis2"] = hemis2 </code> </procDef> <!-- -- Any other RD stuff... --> </resource>
Using Procedures
Then to use the procedure, we use the <apply>
element, with proper configuration. The procedure is used here inside a <rowmaker>
element. The <bind>
elements allow to link content (constant values or computed values) to input parameters.
<apply procDef="miriadeEphemph"> <bind key="target_name">'p:jupiter'</bind> <bind key="observer">'@568'</bind> <bind key="obs_time">parseISODT('T'.join([@DATE_OBS,@TIME_OBS]))</bind> </apply>