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

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

Version with overlay of trajectories on top of model fields draft version working before any rigourous testing.

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 *
27from CombinedPlotManager import *
28
29class OptionHandler:
30    """
31    Handles which options to return based on exising selections.
32    """
33
34    def __init__(self, userRoles, username, sessionObj):
35        """
36        Method to initialise class.
37        """
38        self.userRoles=userRoles
39        self.username=username
40        self.bag=sessionObj
41        self._translateFileURIList()
42       
43        self._getOptions()
44   
45 
46    def _translateFileURIList(self):
47        """
48        Translates remote paths to local paths.
49        """
50        flist=self.bag["fileURIList"]
51       
52        for i in range(len(flist)):
53            fileURI=flist[i]
54            if fileURI.find("http")>-1:
55                fileURI=translateURI(fileURI)
56                flist[i]=fileURI
57
58        self.bag["fileURIList"]=flist   
59       
60   
61    def _getOptions(self):
62        """
63        Works out what options the user should be provided with next.
64        """
65        fileURIList=self.bag["fileURIList"]
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        # Will need external caller to access and save varDict so make instance attribute
161        self.varDict={}
162       
163        # Get list of selected variables
164        for key in self.bag.keys():
165            match=fvpattern.match(key)
166            if match:
167                fileIndex, varIndex=match.groups()
168                # Probably don't need to match varIndex
169                fileIndex=int(fileIndex)
170                varIndex=int(varIndex)
171                fileURI=fileURIs[fileIndex-1]
172               
173                varID=self.bag[key]
174               
175                # Cope with system that wants auto-selected variable!
176                if varID=="SELECT_AUTOMATICALLY":
177                    cdmsFile=cdms.open(fileURI)
178                    varList=cdmsFile.listvariables()
179                    for varname in varList:
180                        if varname.split("_")[0]!="bounds" and varname.split("_")[-1]!="bnds":
181                            varID=varname
182                            self.bag["fileVariable_%s.%s" % (fileIndex, varIndex)]=varID
183                            break
184                    else:
185                        raise GSOptionHandlingError, "Could not find a suitable variable to select automatically in file '%s'." % fileURIs[fileIndex-1]
186                    cdmsFile.close()
187
188                analyser=VariableAnalyser(fileURI, varID)
189                plotOpts=analyser.plotOpts
190                domainDict=analyser.domainDict
191               
192                suffix="%s.%s" % (fileIndex, varIndex)
193               
194                self.varDict[suffix]={"id":varID,
195                                      "domain":domainDict}
196
197                optionCategories.append("graphicalOutputType_%s" % suffix)             
198                optsSubList=[]
199                optsStringsSubList=[]
200       
201                for plotOpt in plotOpts:
202                    optsSubList.append(plotOpt[0])
203                    optsStringsSubList.append(plotOpt[1]) 
204
205                options.append(optsSubList[:])
206                optionStrings.append(optsStringsSubList[:])
207       
208        # Call combined plot manager to work out what plots can be combined
209        # via overlays or combining parameters
210        cbm=CombinedPlotManager(self.varDict, fileList=self.bag["fileURIList"])
211        combinedOptions=cbm.combinedPlotOptions
212        if len(combinedOptions)>0:
213            for co in combinedOptions:
214                optionCategories+=[co[0]]
215                options+=[co[1]]
216                optionStrings+=[co[2]]
217           
218        #optionCategories.append("graphicalOutputType_1.1-2.1")
219        #options.append(["MultipleTrajectoriesOver2DLatLonPlot"])
220        #optionStrings.append(["""DONT FORGET TO COMBINE STIRNGS with 'Overlay of' dada on blahblah... Multiple Trajectories for variable 'sdfsd' from file 'dfsd' plotted over 2D Plot for variable 'var2' from file  'sdfdsfsf'"""]) 
221        return [[optionCategories], [options], [optionStrings]]
222             
223
224    def _getAnimationAxes(self):
225        """
226        Analyses the available variable to return axes that can be
227        selected for animations.
228        """     
229        # Get items needed for working out which file to open
230        (fileNames, varIDs, graphicalOutputType, suffix)=self._getSelectedItemsForAnalysis()   
231        # For animation there can only be one filename and varID
232        fileName=fileNames[0]
233        varID=varIDs[0]
234       
235        if graphicalOutputType!="Animation":
236            raise GSOptionHandlingError, "Matched animation output type from axes without it being selected!"
237       
238        cdmsfile=cdms.open(fileName)
239        var=cdmsfile[varID]
240       
241        axes=var.getAxisList()
242
243        optionCategories=[]
244        options=[]
245        optionStrings=[]
246       
247        axisCounter=1
248        for axis in axes:
249            if len(axis)<2: continue
250            optionCategories.append("animationAxis_%s" % axisCounter)
251            options.append([axis.id, len(axis)])
252            optionStrings.append([getBestName(axis), ""])
253            axisCounter=axisCounter+1
254       
255        return [[optionCategories], [options], [optionStrings]] 
256       
257
258    def _getPlotConfigurationOptions(self):
259        """
260        Returns the available plot configuration options in terms of:
261        plot type, file format, projection, continents flag, image size.
262        """                 
263        optionCategories=[]
264        options=[]
265        optionStrings=[]
266       
267        # Get selections for stuff needed here
268        (fileNames, varIDs, graphicalOutputType, suffix)=self._getSelectedItemsForAnalysis()
269       
270        if graphicalOutputType=="Animation":
271            # Check didn't use same axes
272            [x,y,loop]=(self.bag["axisXForAnimation"], self.bag["axisYForAnimation"], self.bag["axisLoopForAnimation"])
273            animationAxes=(loop, y, x)
274            if x==y or (y==loop or x==loop):
275                raise GSSelectionError, "You cannot select the same physical axis for more than one plotting axis. Please go back and re-select."
276        else:
277            animationAxes=None
278       
279        # Get the variable (and domain) dictionary from the session object
280        varDict=self.bag["varDict"]             
281       
282        """for count in range(len(fileNames)):
283            fileName=fileNames[count]
284            varID=varIDs[count]
285            domainDict=varDict[ """
286       
287        nvars=len(fileNames)
288       
289        if nvars>1:
290            cbm=CombinedPlotManager(varDict, required="plotConfigurationDict",                          graphicalOutputType=graphicalOutputType)
291            plotDict=cbm.plotConfigurationDict
292        else:
293            #analyser=VariableAnalyser(fileNames[0], varIDs[0], graphicalOutputType, animationAxes)
294            varID=varIDs[0]
295            analyser=VariableAnalyser(graphicalOutputType=graphicalOutputType,                           domainDict=varDict[suffix]["domain"], animationAxes=animationAxes)
296            plotDict=analyser.plotConfigurationDict
297       
298        # Sort keys in useful order
299        okeys=plotDict.keys()
300        for key in ["continentsSwitch", "projection", "fileFormat", "plotType"]:
301            if key in okeys:
302                okeys.remove(key)
303                okeys.insert(0, key)
304       
305        for key in okeys:
306            optionCategories.append("%s_%s" % (key, suffix))
307            optsSubList=[]
308            optsStringsSubList=[]
309           
310            for subList in plotDict[key]:
311                optsSubList.append(subList[0])
312                optsStringsSubList.append(subList[1])
313               
314            options.append(optsSubList[:])
315            optionStrings.append(optsStringsSubList[:])     
316
317            """optCategories.append(["jljljljlj","OIIIIIIIIIIII"])
318            options.append(["jljljljlj","OIIIIIIIIIIII"])
319            optionStrings.append(["jljljljlj","OIIIIIIIIIIII"])  """ 
320        return [[optionCategories], [options], [optionStrings]]
321
322
323    def _getSelectedItemsForAnalysis(self):
324        """
325        Works out the file name and variable ID selected by the user from
326        the contents of the session object.
327        """
328        # Start with list of fileURIs - sorted
329        fileURIs=self.bag["fileURIList"]
330        fileURIs.sort()
331
332        gpattern=re.compile(r"(%s)_(\d+)\.?(\d+)?-?(\d+)?\.?(\d+)?" % GRAPHICAL_OUTPUT_TYPES_OR_STRING)
333       
334        suffix=self.bag["graphicalOutputType"].split("_")[-1]
335       
336        match=gpattern.match(self.bag["graphicalOutputType"])
337        if not match:
338            raise GSOptionHandlingError, "Cannot find a match for graphical output type."
339         
340        (graphicalOutputType, fileIndex1, varIndex1, fileIndex2, varIndex2)=match.groups()
341
342        fileIndices=[fileIndex1, fileIndex2]
343        varIndices=[varIndex1, varIndex2]
344       
345        #if fileIndex2:
346        #    raise GSOptionHandlingError, "Cannot yet handle multiple feature graphical outputs, sorry!"
347       
348        fileNames=[]
349        varIDs=[]
350       
351        for i in range(len(fileIndices)):
352            if fileIndices[i]==None: break
353            findex=int(fileIndices[i])
354            fileName=fileURIs[findex-1]
355            varIndex=int(varIndices[i])
356            varID=self.bag["fileVariable_%s.%s" % (findex, varIndex)]
357            fileNames.append(fileName)
358            varIDs.append(varID)
359           
360        """   
361        fileIndex1=int(fileIndex1)
362        fileName=fileURIs[fileIndex1-1]
363        varIndex1=int(varIndex1)
364        varID=self.bag["fileVariable_%s.%s" % (fileIndex1, varIndex1)]
365
366        suffix="_%s.%s" % (fileIndex1, varIndex1)"""
367
368        return (fileNames, varIDs, graphicalOutputType, suffix)
369
370   
371           
372if __name__=="__main__":
373    a=OptionHandler("jane", ["dset1", "dset2"], {"sessionID":"324242",
374                    "fileURIList":["/data/var1.nc"], "fileVariable_1.2":"pqn",
375                    "graphicalOutputType":"Animation_1.2"})
376    print a.options
377   
378    print "HERE -1:"
379    b=OptionHandler("jane", ["dset1", "dset2"], {"sessionID":"324242",
380                    "fileURIList":["/data/var1.nc","/data/var2.nc"], 
381                    "fileVariable_1.1":"pqn",
382                    "fileVariabel_2.1":"var2"})
383    print b.options   
384 
385 
386    print "HERE:"
387    o=OptionHandler("jane", ["dset1", "dset2"], {"sessionID":"324242",
388                       "fileURIList":["/data/var1.nc"], "fileVariable_1.2":"pqn",
389                       "graphicalOutputType":"2DPlot_1.2",
390                       "varDict":{"1.2":{"name":"pqn",
391                                "domain":{"ordered_axes":["time","latitude","longitude"],
392                                        "time":["time","time",[0,4]],
393                                        "latitude":["latitude","latitude",[0,90]],
394                                        "longitude":["longitude","longitude",[0,359]],
395                                        "grots":["2DLatLonPlot"]}}}})
396    print o.options
397   
398    print "HERE 1:"
399   
400    o=OptionHandler("jane", ["dset1", "dset2"], {"sessionID":"324242",                          "fileURIList":["/data/var1.nc", "/data/var2.nc"], "fileVariable_1.1":"pqn",             "fileVariable_2.1":"var2",
401        "graphicalOutputType":"MultipleTrajectoriesOver2DLatLonPlot_1.1-2.1",
402                       "varDict":{"1.1":{"name":"pqn",
403                                "domain":{"ordered_axes":["time","latitude","longitude"],
404                                        "time":["time","time",[0,4]],
405                                        "latitude":["latitude","latitude",[0,90]],
406                                        "longitude":["longitude","longitude",[0,359]],
407                                        "grots":["2DLatLonPlot"]}},
408                                "2.1":{"name":"var2",
409                                "domain":{"ordered_axes":["time","latitude","longitude"],
410                                        "time":["time","time",[0,4]],
411                                        "latitude":["latitude","latitude",[0,90]],
412                                        "longitude":["longitude","longitude",[0,359]],
413                                        "grots":["2DLatLonPlot"]}}}})
414    print o.options   
415   
416    print "HERE 2:"
417    o=OptionHandler("jane", ["dset1", "dset2"], {"sessionID":"324242",
418                       "fileURIList":["/data/var1.nc", "/data/var2.nc"], "fileVariable_1.1":"pqn",
419                       "fileVariable_2.1":"var2"})
420    """                "graphicalOutputType":"MultipleTrajectoriesOver2DLatLonPlot_1.1-2.1",
421                       "varDict":{"1.1":{"name":"pqn",
422                                "domain":{"ordered_axes":["time","latitude","longitude"],
423                                        "time":["time","time",[0,4]],
424                                        "latitude":["latitude","latitude",[0,90]],
425                                        "longitude":["longitude","longitude",[0,359]],
426                                        "grots":["2DLatLonPlot"]}},
427                                "2.1":{"name":"var2",
428                                "domain":{"ordered_axes":["time","latitude","longitude"],
429                                        "time":["time","time",[0,4]],
430                                        "latitude":["latitude","latitude",[0,90]],
431                                        "longitude":["longitude","longitude",[0,359]],
432                                        "grots":["2DLatLonPlot"]}}}})"""
433    print o.options   
434    sys.exit()
435    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'})
436    print p.options
437   
438    point=OptionHandler("jane", ["dset1", "dset2"], {'sessionID':"423432",
439        'fileURIList':["/data/dx/0d.nc"], "fileVariable_1.1":"t"})
440    print point.options
441   
442    point=OptionHandler("jane", ["dset1", "dset2"], {'sessionID':"423432",
443        'fileURIList':["/data/dx/0d.nc"], "fileVariable_1.1":"t",
444        "graphicalOutputType":"PointValueAndMetadata"})
445    print point.options   
Note: See TracBrowser for help on using the repository browser.