source: TI03-DataExtractor/trunk/pydxs/OutputManager.py @ 1715

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/trunk/pydxs/OutputManager.py@1715
Revision 1715, 21.0 KB checked in by astephen, 13 years ago (diff)

Merged with titania version.

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"""
6OutputManager.py
7================
8
9This module holds the OutputManager class used to generate products
10in the Data Extractor.
11
12"""
13
14# Import required modules
15import os
16import re
17import cdms
18import vcs
19import sys
20import time
21
22# Import package modules including global variables
23from common import *
24from serverConfig import *
25from localRules import *
26from NumericalOperations import *
27from DXDMLHandler import *
28from CDMSDataHandler import *
29from CDMSOutputHandler import *
30from CSMLDataHandler import *
31from CSMLOutputHandler import *
32from ECMWFGRIB1NoSubsetDataHandler import *
33from ECMWFGRIB1NoSubsetOutputHandler import *
34from MIDASDataHandler import *
35from MIDASOutputHandler import *
36from DatasetFormatDecider import *
37from FileNames import *
38from DXErrors import *
39import dxvv
40
41# Make sure CDMS automatic bounds generation is set to OFF
42#cdms.setAutoBounds("off")
43
44#global ONE_FILE_PER_TIMESTEP   
45#ONE_FILE_PER_TIMESTEP=0
46
47
48class OutputManager:
49    """
50    Class to control generation of output variables as selected.
51    Externally called as:
52   
53    x=OutputManager(request)
54    x.getOutputFilePaths()
55    x.createOutputs()
56    """
57
58    def __init__(self, sessionObject):
59        """
60        Takes in request object and sets up processing.
61        """
62        self.bag=sessionObject
63        self.outputDir=checkSubDirectory(self.bag["username"]) 
64        self.DXDML=DXDMLHandler()
65        self.varDict={}
66                       
67
68    def _getDatasetDetails(self, varCodes):
69        """
70        Returns the datasetURI for a given variable code.
71        """
72        match=re.match("variable_(\d+)\.(\d+)\.(\d+)", varCodes)
73        if not match:
74            raise DXProcessingError, "Cannot match variable code: "+varCodes
75
76        (dsgCode, dsCode, varCode)=intAll(match.groups())
77        dsURICodes="%s.%s" % (dsgCode, dsCode)
78       
79        dsg=self.bag["datasetGroup_%s" % dsgCode]
80        ds=self.bag["dataset_%s.%s" % (dsgCode, dsCode)]       
81       
82        if self.bag.has_key("datasetURI_%s" % dsURICodes):
83            datasetURI=self.bag["datasetURI_%s" % dsURICodes]
84        else:
85            datasetURI=self.DXDML.getDatasetURI(dsg, ds)
86         
87        return (dsg, ds, datasetURI)
88
89
90    def getOutputInfoDict(self):
91        """
92        Returns output file dictionary including output paths, sizes
93        and estimated duration for producing the output.
94        """
95        if self.varDict!={}:
96            return self.varDict
97        if self.bag.has_key("numericalOperation"):
98            self._handleNumericalOperation(mode="file names")
99        else:
100            self._loopThroughVariables(mode="file names")
101        return self.varDict
102       
103
104    def getOutputFilePathDict(self):
105        """
106        Returns a dictionary of output files with variable IDs as keys.
107        """
108        dct=self.getOutputInfoDict()
109        pathdict={}
110        for key in dct.keys():
111            varID=dct[key][1]
112            paths=dct[key][4]
113            pathdict["%s-%s"%(varID,key)]=paths
114        return pathdict
115
116
117    def getOutputSizes(self):
118        """
119        Returns a dictionary of the sizes of output variables with IDs as keys.
120        """
121        dct=self.getOutputInfoDict()
122        sizedict={}
123        for key in dct.keys():
124            varID=dct[key][1]
125            size=dct[key][2]
126            sizedict["%s-%s"%(varID,key)]=size
127        return sizedict
128       
129
130    def getOutputDurationEstimates(self):
131        """
132        Returns a dictionary of the estimated durations to produce the requested
133        outputs, with variable IDs as keys.
134        """
135        dct=self.getOutputInfoDict()
136        durationdict={}
137        for key in dct.keys():
138            varID=dct[key][1]
139            size=dct[key][2]
140            format=dct[key][3]
141            multiplier=1
142            if format=="NASA Ames":
143                multiplier=3
144
145            if format=="ASCII text":
146                multiplier=multiplier*5
147
148            dur=size*TIMING_SCALE_FACTOR*multiplier
149            if dur<5: dur=3
150            durationdict["%s-%s"%(varID,key)]=dur
151        return durationdict
152
153
154    def createOutputs(self):
155        """
156        Calls the appropriate methods to create output files.
157        """
158        if self.bag.has_key("numericalOperation"):
159            self._handleNumericalOperation(mode="create outputs")
160        else:
161            self._loopThroughVariables(mode="create outputs")
162
163
164    def _adjustFileSizeByFormat(self, size, outputFormat):
165        """
166        Returns the size of an output file adjusted according to the format used.
167        """
168        if outputFormat=="NASA Ames":   
169            size=size*5 
170        return size
171
172           
173    def _loopThroughVariables(self, mode):
174        """
175        Loop through the selected variables to generate the output
176        file paths or data.
177        """
178        varKeys=getSortedKeysLike(self.bag, "variable_")
179        self.varDict={}
180
181        varCount=0
182
183        # Check number of datasets is not over limit
184        if len(varKeys)>MAX_NUM_DATASETS:
185            raise Exception, "You have requested more variables than the current DX limit (%s). Please go back and reduce the size of your request." % MAX_NUM_DATASETS
186
187        # Loop through all variables
188        for varKey in varKeys:
189            varCodes=varKey.split("_")[-1]
190            varID=self.bag[varKey]
191           
192            (datasetGroup, dataset, datasetURI)=self._getDatasetDetails(varKey)
193
194            dataFileHandler=DatasetFormatDecider(datasetGroup, dataset, datasetURI).datasetFormat
195            outputFormat=self.bag["outputFormat_%s" % varCodes]
196            #print dataFileHandler
197           
198            axisSelectionDict=getDictSubsetMatching(self.bag, "axis_%s" % varCodes)
199
200            timeStepStringList=dataFileHandler.getSelectedTimeSteps(datasetURI, varID, axisSelectionDict)
201           
202            sizeOfRequest=dataFileHandler.getSelectedVariableSubsetSize(datasetURI, varID, axisSelectionDict)
203            sizeOfRequest=self._adjustFileSizeByFormat(sizeOfRequest, outputFormat)
204           
205            if sizeOfRequest>(REQUEST_SIZE_LIMIT*(2**20)):
206                raise Exception, "Your request is above the current size limit for the DX (of %s MB), please submit smaller requests." % REQUEST_SIZE_LIMIT
207
208            print "\n"*10, sizeOfRequest, REQUEST_SIZE_LIMIT*(2**20)       
209           
210            # Now split depending on single or multiple output
211            if sizeOfRequest>(MAX_FILE_SIZE*(2**20)) or ONE_FILE_PER_TIMESTEP==1:
212                   
213                print "\n\n\n", MAX_FILE_SIZE, (MAX_FILE_SIZE*(2**20)), sizeOfRequest, ONE_FILE_PER_TIMESTEP
214               
215                # If only need to generate file names - multiple files
216                if mode=="file names":
217                    fileNamer=FileNames(datasetGroup=datasetGroup, dataset=dataset, timeSteps=timeStepStringList, 
218                                    fileFormat=outputFormat, variables=[varID],
219                                    basedir=self.outputDir)
220
221                    outputFilePathList=fileNamer.createFileNameList()
222
223                    if isinstance(dataFileHandler, CSMLDataHandler):
224                        # CSML special case, just make first file the xml with copy of first .nc name
225                        ncPath=outputFilePathList[0]
226                        csmlPath=os.path.splitext(ncPath)[0]+".xml"
227                        outputFilePathList.insert(0, csmlPath)
228
229                # Otherwise create the outputs - multiple files
230                # CSML not supported via this route yet
231                # MIDAS not supported via this route yet
232                elif mode=="create outputs":
233                    # Now get the real data
234                   
235                    outputHandler=self._getOutputHandler(outputFormat, dataFileHandler)
236                    outputFilePathList=[]
237                   
238                    for timeStep in timeStepStringList:
239                        fileNamer=FileNames(datasetGroup=datasetGroup, dataset=dataset, timeSteps=[timeStep], 
240                                    fileFormat=outputFormat, variables=[varID],
241                                    basedir=self.outputDir)
242                        outputFilePath=fileNamer.createFileNameList()[0]
243                        outputFilePathList.append(outputFilePath)
244                                               
245                        if varID[-5:]=="_dxvv":
246                            # Check if virtual variable being used
247                            vvd=dxvv.VVDict()
248                            procClass=vvd.getProcessingClass(varID, datasetURI)
249                            exec "vvHandler=dxvv.%s" % procClass
250                            data=vvHandler(varID, datasetURI, axisSelectionDict, timeStep).var
251                            print data
252                        else: 
253                            data=dataFileHandler.readVariableSubsetIntoMemory(datasetURI, varID, axisSelectionDict, timeStep)
254                       
255                        outputFileHandler=outputHandler(outputFilePath)
256                        globalAttributes=dataFileHandler.getCFGlobalAttributes(datasetURI)
257                        outputFileHandler.writeVariableAndGlobalAttributes(data, globalAttributes)
258                        outputFileHandler.closeFile()
259                        print "\nWrote variable '%s' to output file: %s" % (varID, outputFilePath)             
260                        fixFilePermissions(outputFilePath) #added as fix?               
261
262            # Else if only producing one output file
263            # or NetCDF and CSML in the case of CSML   
264            else:
265                if len(timeStepStringList)==0:
266                    timeStepStringList=[]
267                elif len(timeStepStringList)==1:
268                    timeStepStringList=timeStepStringList
269                else:
270                    ts0="%.4d%.2d%.2d%.2d" % tuple(getDateTimeComponents(timeStepStringList[0])[:4])
271                    ts1="%.4d%.2d%.2d%.2d" % tuple(getDateTimeComponents(timeStepStringList[-1])[:4])
272                    timeStepStringList=["%s-%s" % (ts0,ts1)]
273                           
274                # File names are created here as well - should really cache this
275                print "Work out file name as only one file..."
276                fileNamer=FileNames(datasetGroup=datasetGroup, dataset=dataset, timeSteps=timeStepStringList, 
277                                    fileFormat=outputFormat, variables=[varID],
278                                    basedir=self.outputDir)
279             
280                outputFilePathList=fileNamer.createFileNameList()
281                #print outputFilePathList               
282
283                # If CSML - single output file - for creating file names
284                if isinstance(dataFileHandler, CSMLDataHandler):
285                    ncPath=outputFilePathList[0]
286                    csmlPath=os.path.splitext(ncPath)[0]+".xml"
287                    outputFilePathList.insert(0, csmlPath)
288                               
289                # If creating outputs - single output file
290                # or CSML/NetCDF supporting CSML
291                if mode=="create outputs":
292                    # Now get the real data
293                    outputHandler=self._getOutputHandler(outputFormat, dataFileHandler)         
294                    outputFilePath=outputFilePathList[0]
295                   
296
297                    # CSML route
298                    if isinstance(dataFileHandler, CSMLDataHandler):
299                        # CSML needs subsetting in one go
300                        dataFileHandler.subsetVariableToCSMLNC(datasetURI, varID, axisSelectionDict, csmlPath, ncPath)
301                        fixFilePermissions(csmlPath)
302                        fixFilePermissions(ncPath)
303                        print "\nWrote variable '%s' to output files: %s, %s" % (varID, csmlPath, ncPath)
304
305                    # MIDAS handler here
306                    elif isinstance(dataFileHandler, MIDASDataHandler):
307                        # MIDAS does subsetting in one go
308                        dataFileHandler.subsetMIDASToASCIIFile(datasetURI, axisSelectionDict, outputFilePath, region=None)
309                        fixFilePermissions(outputFilePath) 
310                        print "\nWrote MIDAS subset to output file: %s" % outputFilePath
311
312                    # CDMS route - including virtual variables
313                    else:
314                        if varID[-5:]=="_dxvv":
315                            # Check if virtual variable being used
316                            vvd=dxvv.VVDict()
317                            procClass=vvd.getProcessingClass(varID, datasetURI)
318                            exec "vvHandler=dxvv.%s" % procClass
319                            data=vvHandler(varID, datasetURI, axisSelectionDict).var
320                            print data
321                        else:
322                            data=dataFileHandler.readVariableSubsetIntoMemory(datasetURI, varID, axisSelectionDict)
323                       
324                        outputFileHandler=outputHandler(outputFilePath)
325                        globalAttributes=dataFileHandler.getCFGlobalAttributes(datasetURI)
326                        outputFileHandler.writeVariableAndGlobalAttributes(data, globalAttributes)
327                        outputFileHandler.closeFile()
328                        print "\nWrote variable '%s' to output file: %s" % (varID, outputFilePath)                 
329                        fixFilePermissions(outputFilePath) 
330                   
331   
332            self.varDict[varCount]=(datasetURI, varID, sizeOfRequest, outputFormat, outputFilePathList[:])
333            print "\n\n", outputFilePathList, "\n\n"
334            varCount=varCount+1
335            print "\n\nHERE IS THE VARDICT...\n\n", self.varDict
336
337
338    def _getOutputHandler(self, outputFormat, dataHandler):
339        """
340        Get output handler.
341        """
342        #if outputFormat not in OUTPUT_FORMATS:
343        #    raise DXOptionHandlingError, "Output format '%s' is not supported." % outputFormat
344           
345        if isinstance(dataHandler, CDMSDataHandler):
346            if outputFormat=="NetCDF":     
347                outputHandler=CDMSOutputHandler
348            elif outputFormat=="NASA Ames":
349                outputHandler==NASAAmesOutputHandler
350        elif isinstance(dataHandler, CSMLDataHandler):
351            outputHandler=CSMLOutputHandler
352        elif isinstance(dataHandler, MIDASDataHandler):
353            outputHandler=MIDASOutputHandler
354           
355        return outputHandler
356       
357
358    def _handleNumericalOperation(self, mode):
359        """
360        If a numerical operation is defined then don't loop through
361        variables, only output one calculated variable to keep simple.
362        """
363        print "Performing a numerical operation, only one output variable is supported when this option is selected...\n\n"
364        opController=NumericalOperations(self.bag["numericalOperation"])
365        usedVariableIndices=opController.variableIndices
366        opMethod=opController.opMethod.__name__
367       
368        varKeys=getSortedKeysLike(self.bag, "variable_")
369       
370        usedVars=[]
371        indx=0
372        for var in varKeys:
373            if indx in usedVariableIndices:
374                usedVars.append(var)
375               
376        self.varDict={}
377        varGrids=[]
378        arrayShapes=[]
379        arraySizes=[]
380        fileVarSelectorList=[]
381
382        outputFilePathList=None
383        for varKey in usedVars:
384            varCodes=varKey.split("_")[-1]
385            varID=self.bag[varKey]
386           
387            (datasetGroup, dataset, datasetURI)=self._getDatasetDetails(varKey)
388            dataFileHandler=DatasetFormatDecider(datasetGroup, dataset, datasetURI).datasetFormat
389            outputFormat=self.bag["outputFormat_%s" % varCodes]
390           
391            if outputFilePathList==None: 
392                outputFileName="%s_%s.%s" % (opMethod, os.getpid(), mapFileFormatToExtension(outputFormat))         
393                outputFilePathList=[os.path.join(self.outputDir, outputFileName)]
394           
395            if not isinstance(dataFileHandler, CDMSDataHandler):
396                raise DXOptionHandlingError, """The DX can currently only perform numerical operations on CDMS-type variables.
397                    You have selected a non-CDMS variable: '%s'.""" % (varID)
398           
399            axisSelectionDict=getDictSubsetMatching(self.bag, "axis_%s" % varCodes)
400            fileVarSelectorList.append([datasetURI, varID, axisSelectionDict])
401
402            (arrayShape, gridShape, size)=dataFileHandler.getSelectedVariableArrayDetails(datasetURI, varID, axisSelectionDict)
403            #print gridShape, arrayShape
404            varGrids.append(gridShape)
405            arrayShapes.append(arrayShape)
406            arraySizes.append(size)
407
408        print "Now compare grid shapes of variables..."
409        lenGrids=len(varGrids)
410        noneList=lenGrids*[None]
411
412        if noneList==varGrids:
413            gridsPresent="no"
414        elif None in varGrids:
415            raise DXOptionHandlingError, "Variable axes are different and cannot therefore be used in a mathematical operation."
416        else:
417            gridsPresent="yes"
418
419        refshape=arrayShapes[0]
420        for shape in arrayShapes[1:]:
421   
422            if len(shape)!=len(refshape):
423                raise DXOptionHandlingError, "Shapes of chosen variables are incompatible for mathematical operation."
424            if gridsPresent=="no":
425                if shape!=refshape:
426                    raise DXOptionHandlingError, "Axis lengths of chosen variables are different and cannot therefore be used in a mathematical operation."
427                elif gridsPresent=="yes":
428                    if shape[:-2]!=refshape[:-2]:
429                        raise DXOptionHandlingError, "Axis lengths of chosen variables are different and cannot therefore be used in a mathematical operation."
430
431        outputSize=arraySizes[0]
432        for sz in arraySizes[1:]:
433            if sz<outputSize:
434                outputSize=sz
435
436        if mode=="create outputs":
437            varsToUse=[]
438            print "Fetch each var from file..."
439            for (datasetURI, varID, axisSelectionDict) in fileVarSelectorList:
440                varsToUse.append(dataFileHandler.readVariableSubsetIntoMemory(datasetURI, varID, axisSelectionDict))
441               
442            data=opController.performOperation(varsToUse)
443           
444            # Now write the data
445            outputHandler=self._getOutputHandler(outputFormat, dataFileHandler) 
446            outputFilePath=outputFilePathList[0]               
447            outputFileHandler=outputHandler(outputFilePath)
448            outputFileHandler.writeVariableAndGlobalAttributes(data, {})
449            outputFileHandler.closeFile()
450            print "\nWrote variable '%s' to output file: %s" % (data.id, outputFilePath)
451        outputVarID=opMethod
452        self.varDict[0]=(datasetURI, outputVarID, outputSize, outputFormat, outputFilePathList[:])
453
454
455           
456                   
457   
458
459if __name__=="__main__":
460    #print "Setting ONE_FILE_PER_TIMESTEP=1"
461    x=OutputManager({"username":"jane", "datasetGroup_1":"Test Data Group 1",
462                     "dataset_1.3":"Test Dataset 1", "variable_1.3.1":"twotimespqn_dxvv",
463                     "axis_1.3.1.1":("1999-01-01T00:00:00", "1999-01-01T06:00:00"),
464                     "outputFormat_1.3.1":"NetCDF",
465                     "datasetGroup_2":"Test Data Group 2",
466                     "dataset_2.1":"Test Dataset 2", "variable_2.1.1":"var2",
467                     "axis_2.1.1.1":("2004-01-01T12:00:00", "2004-01-01T12:00:00"),
468                     "outputFormat_2.1.1":"NetCDF"}) 
469    print x.getOutputFilePathDict()   
470    print x.createOutputs()
471    sys.exit()
472    #ONE_FILE_PER_TIMESTEP=1
473    x=OutputManager({"username":"jane", "datasetGroup_1":"Test Data Group 1",
474                     "dataset_1.3":"Test Dataset 1", "variable_1.3.1":"pqn",
475                     "outputFormat_1.3.1":"NetCDF"})
476    print x.getOutputFilePathDict()   
477                 
478    x=OutputManager({"username":"jane", "datasetGroup_1":"Test Data Group 1",
479                     "dataset_1.3":"Test Dataset 1", "variable_1.3.1":"pqn",
480                     "axis_1.3.1.1":("1999-01-01T00:00:00", "1999-01-01T06:00:00"),
481                     "outputFormat_1.3.1":"NetCDF",
482                     "datasetGroup_2":"Test Data Group 2",
483                     "dataset_2.1":"Test Dataset 2", "variable_2.1.1":"var2",
484                     "axis_2.1.1.1":("2004-01-01T12:00:00", "2004-01-01T12:00:00"),
485                     "outputFormat_2.1.1":"NetCDF"})
486
487    print x.getOutputFilePathDict()   
488   
489    print "\n\n\n"
490    x=OutputManager({"username":"jane", "datasetGroup_1":"Test Data Group 1",
491                     "dataset_1.3":"Test Dataset 1", "variable_1.3.1":"pqn",
492                     "axis_1.3.1.1":("1999-01-01T00:00:00", "1999-01-01T06:00:00"),
493                     "outputFormat_1.3.1":"NetCDF",
494                     "datasetGroup_2":"Test Data Group 2",
495                     "dataset_2.1":"Test Dataset 2", "variable_2.1.1":"var2",
496                     "axis_2.1.1.1":("2004-01-01T12:00:00", "2004-01-01T12:00:00"),
497                     "axis_2.1.1.2":(30,-30),
498                     "outputFormat_2.1.1":"NetCDF"})
499
500    x.createOutputs()       
501   
502    print "Setting ONE_FILE_PER_TIMESTEP=0"
503    ONE_FILE_PER_TIMESTEP=0
504    x=OutputManager({"username":"jane", "datasetGroup_1":"Test Data Group 1",
505                     "dataset_1.3":"Test Dataset 1", "variable_1.3.1":"pqn",
506                     "axis_1.3.1.1":("1999-01-01T00:00:00", "1999-01-01T06:00:00"),
507                     "outputFormat_1.3.1":"NetCDF",
508                     "datasetGroup_2":"Test Data Group 2",
509                     "dataset_2.1":"Test Dataset 2", "variable_2.1.1":"var2",
510                     "axis_2.1.1.1":("2004-01-01T12:00:00", "2004-01-01T12:00:00"),
511                     "axis_2.1.1.2":(30,-30),
512                     "outputFormat_2.1.1":"NetCDF"})
513    print x.getOutputFilePathDict()       
514   
515    x=OutputManager({"username":"jane", "datasetGroup_1":"Test Data Group 1",
516                     "dataset_1.3":"Test Dataset 1", "variable_1.3.1":"pqn",
517                     "axis_1.3.1.1":("1999-01-01T00:00:00", "1999-01-01T06:00:00"),
518                     "outputFormat_1.3.1":"NetCDF",
519                     "datasetGroup_2":"Test Data Group 2",
520                     "dataset_2.1":"Test Dataset 2", "variable_2.1.1":"var2",
521                     "axis_2.1.1.1":("2004-01-01T12:00:00", "2004-01-01T12:00:00"),
522                     "axis_2.1.1.2":(30,-30),
523                     "outputFormat_2.1.1":"NetCDF"})
524    x.createOutputs()   
525    print x.getOutputFilePathDict() 
526    print x.getOutputInfoDict()
527    print x.getOutputDurationEstimates()
528    print x.getOutputSizes()
529   
530    print "\n\n\n"
531    print "DIFFERENCING VARS..."
532    x=OutputManager({"username":"jane", "datasetGroup_1":"Test Data Group 1",
533                     "dataset_1.3":"Test Dataset 1", "variable_1.3.1":"pqn",
534                     "axis_1.3.1.1":("1999-01-01T00:00:00", "1999-01-01T06:00:00"),
535                     "outputFormat_1.3.1":"NetCDF",
536                     "datasetGroup_2":"Test Data Group 2",
537                     "dataset_2.1":"Test Dataset 2", "variable_2.1.1":"var2",
538                     "axis_2.1.1.1":("2004-01-01T12:00:00", "2004-01-01T12:00:00"),
539                     "axis_2.1.1.2":(30,-30),
540                     "outputFormat_2.1.1":"NetCDF",
541                     "numericalOperation":"(var2)-(var1)"})     
542   
543    x.getOutputFilePathDict()
544    x.createOutputs()
545
546    print "TRYING REAL TEST.................."
547    x=OutputManager({'username':None, 'variable_1.1.1':'pqn', 
548                     'outputFormat_1.1.1':'NetCDF', 'userRoles':[], 
549                     'datasetGroup_1':'Test Data Group 1', 
550                     'axis_1.1.1.3':(-30, 30), 'dataset_1.1':'Test Dataset 1'})
551    print x.getOutputFilePathDict()
552   
553    ONE_FILE_PER_TIMESTEP=0   
554    print "\n\nCSML test!\n"
555    x=OutputManager({'username':None, 'variable_1.1.1':'var2', 
556                     'outputFormat_1.1.1':'CSML/NetCDF', 'userRoles':[], 
557                     'datasetGroup_1':'CSML test dataset group', 
558                     'axis_1.1.1.3':(0, 35), 'dataset_1.1':'CSML test dataset great test'})
559    print "\nGet output file path dict...", x.getOutputFilePathDict()
560    print "\nCREATE CSML Outputs...", x.createOutputs()
Note: See TracBrowser for help on using the repository browser.