source: TI03-DataExtractor/trunk/pydxs/CSMLDataHandler.py @ 794

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/trunk/pydxs/CSMLDataHandler.py@794
Revision 794, 6.7 KB checked in by astephen, 13 years ago (diff)

Unstable but latest version with multi-variable support and split hooks
for CDML and CSML.

Line 
1#   Copyright (C) 2004 CCLRC & NERC( Natural Environment Research Council ).
2#   This software may be distributed under the terms of the
3#   Q Public License, version 1.0 or later. http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
4
5"""
6CSMLDataHandler.py
7==================
8
9CSMLDataHandler module for the dx package.
10
11This module holds the CSMLDataHandler class that is used
12to hold and access information about datasets held in CSML
13format visible to the dx package.
14
15"""
16
17# Import required modules
18import shelve
19import os
20#import CSML
21import re
22
23# Import global variables
24from serverConfig import *
25from common import *
26from DXDMLHandler import DXDMLHandler
27from DXErrors import *
28
29
30class CSMLDataHandler:
31    """
32    A group of methods to connect to a dataset group or
33    dataset to extract information about the contents.
34    """
35 
36    def __init__(self):
37        """
38        Set up instance variables.
39        """
40        self.DXDML=DXDMLHandler()
41        self.file=None
42        self.datasetURI=None
43   
44   
45    def _openDataFile(self, datasetGroup=None, dataset=None, datasetURI=None):
46        """
47        Opens a file and allocates to file handle called: self.file.
48        """
49        if datasetURI:
50            cdmlfile=datasetURI
51        else:
52            for item in self.DXDML.getDatasetsAndDatasetURIs(datasetGroup):
53                if item[0]==dataset:
54                    csmlfile=item[1]
55        try:
56            self.file=CSML.CSMLFile(csmlfile)
57        except IOError, error:
58            raise DXDataIOError, error
59
60
61    def _getVariable(self, variable):
62        """
63        Gets variable metadata object from a data file.
64        """
65        varname=variable
66        try:
67            rtvalue=self.file[varname]
68        except:
69            raise "Cannot find variable %s in file %s" % (varname, self.file.id)
70        return rtvalue
71
72
73    def getVariables(self, datasetGroup=None, dataset=None, datasetURI=None):
74        """
75        Returns a list of variables for the given dataset
76        group/dataset combination or datasetURI. The variable name used is selected
77        hierarchically depending on the available attributes. Each returned item in
78        the list includes a [<long_name>, <id>].
79        """       
80        self._openDataFile(datasetGroup, dataset, datasetURI)
81        vars=self.file.listvariables()
82        rtvars=[]
83        vcount=0
84        for var in vars:
85           longname=self.file.getFeatureInstanceLongName(var)
86           rtvars.append([name, v.id]) 
87
88        return rtvars
89
90
91    def getDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
92        """
93        Returns the combined horizontal, vertical and temporal domains.
94        """ 
95        (northernExtent, westernExtent, southernExtent, easternExtent) = self.getHorizontalDomain(datasetGroup, dataset, variable, datasetURI)
96        (vertical_domain, vertical_units) = self.getVerticalSpatialDomain(datasetGroup, dataset, variable, datasetURI)
97        (start_time, end_time, interval) = self.getTemporalDomain(datasetGroup, dataset, variable, datasetURI)
98        return ((northernExtent, westernExtent, southernExtent, easternExtent), (vertical_domain, vertical_units), (start_time, end_time, interval))
99
100
101    def getHorizontalDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
102        """
103        Returns the horizontal domain as (northernExtent, westernExtent, southernExtent, easternExtent).
104        """
105        self._openDataFile(datasetGroup, dataset, datasetURI)
106        var=self._getVariable(variable)
107        lat=list(var.getLatitude()[:])
108        if lat[-1]<lat[0]: lat.reverse()
109        (southernExtent, northernExtent)=(lat[0], lat[-1])
110        lon=var.getLongitude()[:]
111        (westernExtent, easternExtent)=(lon[0], lon[-1])
112        return (northernExtent, westernExtent, southernExtent, easternExtent)
113
114
115    def getVerticalSpatialDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
116        """
117        Returns the vertical domain as a tuple containing
118        a list of levels (or "Single level" string) and the units.
119        """
120        self._openDataFile(datasetGroup, dataset, datasetURI)
121        var=self._getVariable(variable)
122        try:
123            levels=var.getLevel()
124            vertical_units=levels.units
125            vertical_domain=tuple(map(lambda x: float(x), levels[:]))
126     
127        except:
128            vertical_domain=("Single level",)
129            vertical_units=None
130        return (vertical_domain, vertical_units)
131
132
133    def getTemporalDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
134        """
135        Returns the temporal domain as a tuple of (start time, end time,
136        (interval value, interval units)).
137        """
138        self._openDataFile(datasetGroup, dataset, datasetURI)
139        var=self._getVariable(variable)
140        time_axis=var.getTime()
141        time_keys=("year", "month", "day", "hour", "minute", "second")
142        start_time_components=time_axis.asComponentTime()[0]
143        end_time_components=time_axis.asComponentTime()[-1]
144        start_time=[]
145        end_time=[]
146        for key in time_keys:
147            start_time.append(getattr(start_time_components, key))
148            end_time.append(getattr(end_time_components, key)) 
149        time_units=time_axis.units.split()[0]
150        if time_units[-1]=="s":  time_units=time_units[:-1]
151        if len(time_axis)>1:
152            interval_value=abs(time_axis[1]-time_axis[0])
153        else:
154            interval_value=1  # To stop loops breaking later!
155        return (start_time, end_time, (interval_value, time_units)) 
156
157
158    def getCFGlobalAttributes(self, datafile):
159        """
160        Gets any CF metadta global attributes that are available
161        from the source dataset/file.
162        """
163        # Make sure data file is open
164        if self.file==None: self._openDataFile(datafile)
165        gatts={}
166
167        for gatt in CF_METADATA_GLOBAL_ATTRIBUTE_KEYS:
168            if hasattr(self.file, gatt):
169                gatts[gatt]=self.file.__getattr__(gatt)
170       
171        return gatts
172
173
174if __name__=="__main__":       
175    a=CSMLDataHandler()
176    print a.getVariables(datasetGroup='Test Data Group 3', dataset='Test Dataset 3')
177    print a.getVariables(datasetGroup='Test Data Group 3', datasetURI='file:/usr/local/dx/testdata/testdata3.xml')   
178    print a.getDomain('Test Data Group 3', 'Test Dataset 3', "var3")
179    print a.getHorizontalDomain('Test Data Group 3', 'Test Dataset 3', "var3")
180    print a.getVerticalSpatialDomain('Test Data Group 3', 'Test Dataset 3', "var3")
181    print a.getTemporalDomain('Test Data Group 3', 'Test Dataset 3', "var3")
182    print a.getCFGlobalAttributes("file:/usr/local/dx/testdata/testdata3.xml")
Note: See TracBrowser for help on using the repository browser.