source: TI03-DataExtractor/branches/old_stuff/dx/datasetdb.py @ 793

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/branches/old_stuff/dx/datasetdb.py@793
Revision 793, 8.8 KB checked in by astephen, 13 years ago (diff)

Put all the old code in the old_stuff branch.

  • Property svn:executable set to *
Line 
1"""
2datasets.py
3===========
4
5Datasets module for the dx package.
6
7This module holds the Datasetdb class that is used
8to hold and access information about datasets visible
9to the dx package.
10
11"""
12
13# Import required modules
14import shelve
15import os
16import cdtime
17import cdms
18import re
19
20# Import global variables
21from config import *
22
23class Datasetdb:
24    """
25    Datasetdb class - a group of methods to connect to a dataset group or
26    dataset to extract information about the contents.
27    """
28 
29    def __init__(self):
30        """
31        __init__ method - set up instance variables.
32        """
33        self.file=None
34        self.datasetURI=None
35   
36    def _openCdmsFile(self):
37        """
38        _openCdmsFile method - opens a CDMS file and allocates to file handle
39        self.file.
40        """
41        if self.datasetURI:
42            cdmlfile=self.datasetURI
43        else:
44            for item in DATASETS[self.datasetGroup]:
45                if item[0]==self.dataset:
46                    cdmlfile=item[1]
47        self.file=cdms.open(cdmlfile)
48
49    def _getVariable(self):
50        """
51        _getVariable method - gets variable metadata information from a CDML file.
52        """
53        try:
54            varname=re.match(".+\[\s*(\w+)\s*\]", self.variable).group(1)
55        except:
56            raise "Cannot match the pattern for the variables %s " % self.variable
57        try:
58            rtvalue=self.file[varname]
59        except:
60            raise "Cannot find variable %s in file %s" % (varname, self.file.id)
61        return rtvalue
62
63    def getDatasetURIList(self):
64        """
65        getDatasetURILList method - gets a list of all the datasetURIs visible
66        to this version of dx (in the config.py file).
67        """
68        rtlist=[]
69        for dset in DATASETS.keys():
70            for dataset in DATASETS[dset]:
71                URI_dset_dsetGrp=(DATASET[1], DATASET[0], dset)
72                rtlist.append(URI_dset_dsetGrp)
73        return rtlist
74
75    def getDatasetGroupFromURI(self, datasetURI):
76        """
77        getDatasetGroupFromURI method - gets the id of the dataset group from a
78        datasetURI (if it is known to the dx).
79        """ 
80        URI_list=self.getDatasetURIList()
81        for URI in URI_list:
82            if URI[0]==datasetURI:
83                return URI[2]
84        return None
85
86    def getProtectID(datasetGroup=None, datasetURI=None):
87        """
88        getProtectID method - returns the security group for a given dataset group or
89        datasetURI (if known to the dx).
90        """ 
91        if not datasetGroup and not datasetURI:
92            raise "You must provide either dataset group ID or dataset URI as argument."
93        if datasetURI:
94            datasetGroup=self.getDatasetGroupFromURI(datasetURI)         
95        protect_id=DATASET_GROUPS[datasetGroup]
96        return protect_id
97
98    def getDatasetGroups(self):
99        """
100        getDatasetGroups method - returns the dataset groups that the dx knows about.
101        """
102        return DATASET_GROUPS
103
104    def getDatasets(self, datasetGroup):
105        """
106        getDatasets method - returns the datasets associated with the dataset group
107        argument.
108        """
109        self.datasetGroups=DATASET_GROUPS
110        return DATASETS[datasetGroup]
111
112    def getVariables(self, datasetGroup=None, dataset=None, datasetURI=None):
113        """
114        getVariables method - returns a list of variables ior the given dataset
115        group/dataset combination or datasetURI. The variable name used is selected
116        hierarchically depending on the available attributes.
117        """
118        (self.datasetGroup, self.dataset, self.datasetURI)=(datasetGroup, dataset, datasetURI)
119        self._openCdmsFile()
120        vars=self.file.variables
121        rtvars=[]
122        vcount=0
123        for var in vars:
124           v=self.file[var]
125           if not hasattr(v, "standard_name"): 
126               if not hasattr(v, "long_name"):
127                   if not hasattr(v, "title"):
128                       if not hasattr(v, "name"):
129                           if hasattr(v, "id"):
130                               name=v.id
131                           else:
132                               vcount=vcount+1
133                               name="unnamed_var_%s" % vcount
134                       else:
135                           name=v.name
136                   else:
137                       name=v.title
138               else:
139                   name=v.long_name
140           else:
141               name=v.standard_name
142           # Fix name to remove leading asterisks and lower case surface start.
143           name=name.replace("_", " ")
144           if name[:2]=="**": name=(name[2:]).strip()
145           if name[:7]=="surface": name=(name[7:]).strip()
146           # Remove variables they are actually bounds on axes or coefficients in formulae
147           if v.id not in ("bounds_longitude", "bounds_latitude", "bounds_level", "bounds_time", "p0"):
148               if re.match("hybrid_\w(_\d+)?", v.id)==None and re.match("(lon|lat)(\d+)_bounds?", v.id)==None: 
149                   # and land sea mask (HiGEM) is not yet working
150                   if not (self.datasetGroup=="HiGEM" and v.id in ("lsm","ocean_depth", "sealand")):
151                       rtvars.append("%s  <B>[ %s ]</B>" % (name, v.id)) 
152
153        return rtvars
154
155    def getDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
156        """
157        getDomain method - returns the combined horizontal, vertical and temporal domains.
158        """ 
159        (northernExtent, westernExtent, southernExtent, easternExtent) = self.getHorizontalSpatialDomain(datasetGroup, dataset, variable, datasetURI)
160        (vertical_domain, vertical_units) = self.getVerticalSpatialDomain(datasetGroup, dataset, variable, datasetURI)
161        (start_time, end_time, interval) = self.getTemporalDomain(datasetGroup, dataset, variable, datasetURI)
162        return ((northernExtent, westernExtent, southernExtent, easternExtent), (vertical_domain, vertical_units), (start_time, end_time, interval))
163
164    def getHorizontalSpatialDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
165        (self.datasetGroup, self.dataset, self.variable, self.datasetURI)=(datasetGroup, dataset, variable, datasetURI)
166        # Get the start and end date and time
167        self._openCdmsFile()
168        var=self._getVariable()
169        lat=list(var.getLatitude()[:])
170        if lat[-1]<lat[0]: lat.reverse()
171        (southernExtent, northernExtent)=(lat[0], lat[-1])
172        lon=var.getLongitude()[:]
173        (westernExtent, easternExtent)=(lon[0], lon[-1])
174        return (northernExtent, westernExtent, southernExtent, easternExtent)
175
176    def getVerticalSpatialDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
177        """
178        getVerticalSpatialDomain method - returns the vertical domain as a tuple containing
179        a list of levels (or "Single level" string) and the units.
180        """
181        (self.datasetGroup, self.dataset, self.variable, self.datasetURI)=(datasetGroup, dataset, variable, datasetURI)
182        self._openCdmsFile()
183        var=self._getVariable()
184        try:
185            levels=var.getLevel()
186            vertical_units=levels.units
187            vertical_domain=tuple(map(lambda x: float(x), levels[:]))
188        except:
189            vertical_domain=("Single level",)
190            vertical_units=None
191        return (vertical_domain, vertical_units)
192
193    def getTemporalDomain(self, datasetGroup=None, dataset=None, variable=None, datasetURI=None):
194        """
195        getTemporalDomain method - returns the temporal domain as a tuple of (start time, end time,
196        (interval value, interval units)).
197        """
198        (self.datasetGroup, self.dataset, self.variable, self.datasetURI)=(datasetGroup, dataset, variable, datasetURI)
199        self._openCdmsFile()
200        var=self._getVariable()
201        time_axis=var.getTime()
202        cdtime_keys=("year", "month", "day", "hour", "minute", "second")
203        start_time_components=time_axis.asComponentTime()[0]
204        end_time_components=time_axis.asComponentTime()[-1]
205        start_time=[]
206        end_time=[]
207        for key in cdtime_keys:
208            start_time.append(getattr(start_time_components, key))
209            end_time.append(getattr(end_time_components, key)) 
210        time_units=time_axis.units.split()[0]
211        if time_units[-1]=="s":  time_units=time_units[:-1]
212        if len(time_axis)>1:
213            interval_value=abs(time_axis[1]-time_axis[0])
214        else:
215            interval_value=1  # To stop loops breaking later!
216        return (start_time, end_time, (interval_value, time_units)) 
217
218    def getCFGlobalAttributes(self, datafile):
219        """
220        getCFGlobalAttributes method - gets any CF metadta global attributes that are available
221        from the source dataset/file.
222        """
223        self.datasetURI=datafile
224        # Make sure data file is open
225        if self.file==None: self._openCdmsFile()
226        gatts={}
227        for gatt in CF_METADATA_GLOBAL_ATTRIBUTES:
228            if hasattr(self.file, gatt):
229                gatts[gatt]=self.file.__getattr__(gatt)
230
231        return gatts
232       
Note: See TracBrowser for help on using the repository browser.