source: TI04-geosplat/trunk/pygss/OptionHandler.py @ 1243

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI04-geosplat/trunk/pygss/OptionHandler.py@1243
Revision 1243, 10.6 KB checked in by astephen, 14 years ago (diff)

Latest version - close to alpha release.

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