source: TI03-DataExtractor/branches/titania_install/pygss/OptionHandler.py @ 1520

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/branches/titania_install/pygss/OptionHandler.py@1610
Revision 1520, 10.7 KB checked in by astephen, 14 years ago (diff)

This is the live version on titania - changes have been made so safest to SVN it.

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"""
6OptionHandler.py
7================
8
9Holds the OptionHandler class that is used to generate available
10option lists to send to the user via whichever presentation layer
11is being used.
12
13"""
14
15# Import required modules
16import os, re
17import cdms
18import vcs
19import sys
20
21# Import package modules including global variables
22from common import *
23from serverConfig import *
24from ResourceAccess import ResourceAccess
25from GSErrors import *
26from VariableAnalyser import *
27
28class OptionHandler:
29    """
30    Handles which options to return based on exising selections.
31    """
32
33    def __init__(self, username, userRoles, sessionObj):
34        """
35        Method to initialise class.
36        """
37        self.userRoles=userRoles
38        self.username=username
39        self.bag=sessionObj
40        self._translateFileURIList()
41       
42        self._getOptions()
43   
44 
45    def _translateFileURIList(self):
46        """
47        Translates remote paths to local paths.
48        """
49        flist=self.bag["fileURIList"]
50       
51        for i in range(len(flist)):
52            fileURI=flist[i]
53            if fileURI.find("http")>-1:
54                fileURI=translateURI(fileURI)
55                flist[i]=fileURI
56
57        self.bag["fileURIList"]=flist   
58       
59   
60    def _getOptions(self):
61        """
62        Works out what options the user should be provided with next.
63        """
64        fileURIList=self.bag["fileURIList"]
65
66        if RESTRICTED_DATA==1:
67            for fileURI in fileURIList:
68                if ResourceAccess(self.username, self.userRoles, fileURI).status!=1:
69                    raise GSSecurityError, "User does not have permission to access file: "+fileURI
70               
71        print "\n\n\n", self.bag
72        # User is allowed to see data so need work out which options to provide
73        if keyPatternMatch(self.bag, "fileVariable_")==0:       
74            self.options=self._getFileVariableLists(fileURIList)
75                   
76        elif keyPatternMatch(self.bag, "graphicalOutputType")==0:       
77            self.options=self._analyseChosenVariables()         
78       
79        elif type(self.bag["graphicalOutputType"])==type([1,2]):
80            raise GSSelectionError, "GeoSPlAT cannot yet handle multiple variables, please go back and select only one."
81           
82        elif keyPatternMatch(self.bag, "axisLoopForAnimation")==0 and \
83                self.bag["graphicalOutputType"].find("Animation_")>-1:
84            self.options=self._getAnimationAxes()
85           
86        elif keyPatternMatch(self.bag, "plotType")==0:
87            if self.bag["graphicalOutputType"].find("PointValueAndMetadata")>-1:
88                self.options=[[[]],[[]],[[]]] 
89            else:
90                self.options=self._getPlotConfigurationOptions()
91        else:   
92            self.options=[[[]],[[]],[[]]]
93               
94               
95    def _getFileVariableLists(self, fileURIList):
96        """
97        Gets the variables from a set of files and returns an object listing like:
98        [optionCategories, options, optionStrings] - such as:
99        [[["fileVariables_1", "fileVariables_2"]],
100        [[[fileURI1, ["v", "u"]], [fileURI2, ["t", "w"]]]],
101        [[[fileURI1, ["windv", "windu"]], [fileURI2, ["tmp", "wwind"]]]]]
102        The over-use of square brackets suits ZSI!
103        """
104        varDict={}
105
106        for fileURI in fileURIList:
107            try:
108                f=cdms.open(fileURI)
109            except Exception, error:
110                raise GSDataIOError, error
111            varList=f.listvariables()
112            for id in varList:
113                if id.split("_")[0]=="bounds" or id.split("_")[-1]=="bnds": 
114                    print "Ignoring variables that are bounds:", id
115                    continue
116                varMetadata=f[id]
117                longName=getBestName(varMetadata)
118                if not varDict.has_key(fileURI):
119                    varDict[fileURI]=[]
120                varDict[fileURI].append([id, longName])
121           
122            f.close()
123           
124        keys=varDict.keys()
125        keys.sort()
126       
127        optionCategories=["fileVariable_%s" % i for i in range(1, len(keys)+1)]
128        options=[]
129        optionStrings=[]
130        counter=0
131        for fileURI in keys:
132            options.append([fileURI, []])
133            optionStrings.append([fileURI, []])
134            for varInfo in varDict[fileURI]:
135                (id, longname)=varInfo[:2]
136                options[counter][1].append(id)
137                optionStrings[counter][1].append(longname)
138            counter=counter+1
139           
140        print [[optionCategories], [options], [optionStrings]] 
141
142        return [[optionCategories], [options], [optionStrings]]
143
144
145    def _analyseChosenVariables(self):
146        """
147        Analyses all selected variables and packages returned values
148        into appropriate list of lists.
149        """
150        # Start with list of fileURIs - sorted
151        fileURIs=self.bag["fileURIList"]
152        fileURIs.sort()
153       
154        fvpattern=re.compile(r"fileVariable_(\d+)\.?(\d+)?")
155       
156        optionCategories=[]
157        options=[]
158        optionStrings=[]
159       
160        # Get list of selected variables
161
162        for key in self.bag.keys():
163            match=fvpattern.match(key)
164            if match:
165                fileIndex, varIndex=match.groups()
166                # Probably don't need to match varIndex
167                fileIndex=int(fileIndex)
168                varIndex=int(varIndex)
169                fileURI=fileURIs[fileIndex-1]
170               
171                varID=self.bag[key]
172               
173                # Cope with system that wants auto-selected variable!
174                if varID=="SELECT_AUTOMATICALLY":
175                    cdmsFile=cdms.open(fileURI)
176                    varList=cdmsFile.listvariables()
177                    for varname in varList:
178                        if varname.split("_")[0]!="bounds" and varname.split("_")[-1]!="bnds":
179                            varID=varname
180                            self.bag["fileVariable_%s.%s" % (fileIndex, varIndex)]=varID
181                            break
182                    else:
183                        raise GSOptionHandlingError, "Could not find a suitable variable to select automatically in file '%s'." % fileURIs[fileIndex-1]
184                    cdmsFile.close()
185
186                analyser=VariableAnalyser(fileURI, varID)
187                plotOpts=analyser.plotOpts
188
189                optionCategories.append("graphicalOutputType_%s.%s" % (fileIndex, varIndex))           
190                optsSubList=[]
191                optsStringsSubList=[]
192       
193                for plotOpt in plotOpts:
194                    optsSubList.append(plotOpt[0])
195                    optsStringsSubList.append(plotOpt[1]) 
196
197                options.append(optsSubList[:])
198                optionStrings.append(optsStringsSubList[:])
199
200        return [[optionCategories], [options], [optionStrings]]
201             
202
203    def _getAnimationAxes(self):
204        """
205        Analyses the available variable to return axes that can be
206        selected for animations.
207        """     
208        # Get items needed for working out which file to open
209        (fileName, varID, graphicalOutputType, suffix)=self._getSelectedItemsForAnalysis()   
210       
211        if graphicalOutputType!="Animation":
212            raise "Matched animation output type from axes without it being selected!"
213       
214        cdmsfile=cdms.open(fileName)
215        var=cdmsfile[varID]
216       
217        axes=var.getAxisList()
218
219        optionCategories=[]
220        options=[]
221        optionStrings=[]
222       
223        axisCounter=1
224        for axis in axes:
225            if len(axis)<2: continue
226            optionCategories.append("animationAxis_%s" % axisCounter)
227            options.append([axis.id, len(axis)])
228            optionStrings.append([getBestName(axis), ""])
229            axisCounter=axisCounter+1
230       
231        return [[optionCategories], [options], [optionStrings]] 
232       
233
234    def _getPlotConfigurationOptions(self):
235        """
236        Returns the available plot configuration options in terms of:
237        plot type, file format, projection, continents flag, image size.
238        """                 
239        optionCategories=[]
240        options=[]
241        optionStrings=[]
242
243        # Get selections for stuff needed here
244        (fileName, varID, graphicalOutputType, suffix)=self._getSelectedItemsForAnalysis()
245       
246        if graphicalOutputType=="Animation":
247            # Check didn't use same axes
248            [x,y,loop]=(self.bag["axisXForAnimation"], self.bag["axisYForAnimation"], self.bag["axisLoopForAnimation"])
249            animationAxes=(loop, y, x)
250            if x==y or (y==loop or x==loop):
251                raise GSSelectionError, "You cannot select the same physical axis for more than one plotting axis. Please go back and re-select."
252        else:
253            animationAxes=None
254       
255               
256        analyser=VariableAnalyser(fileName, varID, graphicalOutputType, animationAxes)
257        plotDict=analyser.plotConfigurationDict
258       
259        # Sort keys in useful order
260        okeys=plotDict.keys()
261        for key in ["continentsSwitch", "projection", "fileFormat", "plotType"]:
262            if key in okeys:
263                okeys.remove(key)
264                okeys.insert(0, key)
265       
266        for key in okeys:
267            optionCategories.append(key+suffix)
268            optsSubList=[]
269            optsStringsSubList=[]
270           
271            for subList in plotDict[key]:
272                optsSubList.append(subList[0])
273                optsStringsSubList.append(subList[1])
274               
275            options.append(optsSubList[:])
276            optionStrings.append(optsStringsSubList[:])     
277
278        return [[optionCategories], [options], [optionStrings]]
279        """
280        return [[["plotType_2.1", "fileFormat_2.1", "projection_2.1", "continentsSwitch_2.1", "imageSize_2.1"]],
281      [[["boxfill", "isofill"],["gif", "postscript"],["standard","mollweide"],["UNAVAILABLE"],["800x600","400x300"]]],
282      [[["Boxfill", "Isofill (filled contours)"], ["GIF", "Postscript"],["Standard", "Mollweide"],["UNAVAILABLE"],
283      ["800 x 600","400 x 300"]]], ["securityo"]]"""
284
285
286    def _getSelectedItemsForAnalysis(self):
287        """
288        Works out the file name and variable ID selected by the user from
289        the contents of the session object.
290        """
291        # Start with list of fileURIs - sorted
292        fileURIs=self.bag["fileURIList"]
293        fileURIs.sort()
294
295        gpattern=re.compile(r"(PointValueAndMetadata|YvsXGraph|2DPlot|Animation)_(\d+)\.?(\d+)?-?(\d+)?\.?(\d+)?")
296       
297        match=gpattern.match(self.bag["graphicalOutputType"])
298        if not match:
299            raise GSOptionHandlingError, "Cannot find a match for graphical output type."
300         
301        (graphicalOutputType, fileIndex1, varIndex1, fileIndex2, varIndex2)=match.groups()
302
303        if fileIndex2: 
304            raise GSOptionHandlingError, "Cannot yet handle multiple feature graphical outputs, sorry!"
305       
306        fileIndex1=int(fileIndex1)
307        fileName=fileURIs[fileIndex1-1]
308        varIndex1=int(varIndex1)
309        varID=self.bag["fileVariable_%s.%s" % (fileIndex1, varIndex1)]
310
311        suffix="_%s.%s" % (fileIndex1, varIndex1)
312
313        return (fileName, varID, graphicalOutputType, suffix)
314                 
315           
316if __name__=="__main__":
317    """   
318    a=OptionHandler("astephen", ["dset1", "dset2"], {"sessionID":"324242",
319                    "fileURIList":["/requests/astephen/dx_output/output_20060113015128.nc"], "fileVariable_1.2":"pqn_minus_var3",
320                    "graphicalOutputType":"Animation_1.2"})
321    print a.options
322    """
323
324    o=OptionHandler("jane", ["dset1", "dset2"], {"sessionID":"324242",
325                       "fileURIList":["/data/var1.nc"], "fileVariable_1.2":"pqn",
326                       "graphicalOutputType":"2DPlot_1.2"})
327    print o.options
328
329    p=OptionHandler("jane", ["dset1", "dset2"], {'continentsSwitch':'on', 'status': 'constructing', 'username': 'jane', 'accessTime': 1142324428.122052, 'projection': 'standard', 'fileVariable_1.2': 'pqn', 'fileURIList': ['/data/var1.nc'], 'userRoles': [], 'sessionID': 'session_20060314082027136', 'plotType': 'boxfill', 'fileFormat': 'GIF', 'getOutput': 'getOutput', 'imageSize': '800x600'})
330    print p.options
331   
332    point=OptionHandler("jane", ["dset1", "dset2"], {'sessionID':"423432",
333        'fileURIList':["/data/dx/0d.nc"], "fileVariable_1.1":"t"})
334    print point.options
335   
336    point=OptionHandler("jane", ["dset1", "dset2"], {'sessionID':"423432",
337        'fileURIList':["/data/dx/0d.nc"], "fileVariable_1.1":"t",
338        "graphicalOutputType":"PointValueAndMetadata"})
339    print point.options   
Note: See TracBrowser for help on using the repository browser.