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

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

Latest working version with install method.
Can accept more than one file but doesn't combine variables yet.

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"]=="PointValueAndMetadata":
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":["/tmp/tmp.nc"], "fileVariable_1.2":"var1",
318                    "graphicalOutputType":"Animation_1.2"})
319
320    o=OptionHandler("jane", ["dset1", "dset2"], {"sessionID":"324242",
321                       "fileURIList":["/tmp/tmp.nc"], "fileVariable_1.2":"var1",
322                       "graphicalOutputType":"2DPlot_1.2"})
323    print o.options
324
325    p=OptionHandler("jane", ["dset1", "dset2"], {'continentsSwitch':'on', 'status': 'constructing', 'username': 'jane', 'accessTime': 1142324428.122052, 'projection': 'standard', 'fileVariable_1.2': 'var1', 'fileURIList': ['/tmp/tmp.nc'], 'userRoles': [], 'sessionID': 'session_20060314082027136', 'plotType': 'boxfill', 'fileFormat': 'GIF', 'getOutput': 'getOutput', 'imageSize': '800x600'})
326    print p.options
Note: See TracBrowser for help on using the repository browser.