Changeset 949

Show
Ignore:
Timestamp:
04/04/12 15:01:12 (14 months ago)
Author:
jjr8
Message:

Working on GHRSSTLevel4.

Location:
MGET/Branches/Jason/PythonPackage/src/GeoEco
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • MGET/Branches/Jason/PythonPackage/src/GeoEco/DataProducts/NASA/PODAAC.py

    r927 r949  
    2424from GeoEco.Datasets.Collections import DirectoryTree 
    2525from GeoEco.Datasets.GDAL import GDALDataset 
    26 from GeoEco.Datasets.OPeNDAP import THREDDSCatalog 
    27 from GeoEco.Datasets.Virtual import TimeSeriesGridStack, GridSliceCollection, MaskedGrid, ClippedGrid, RotatedGlobalGrid, ClimatologicalGridCollection 
     26from GeoEco.Datasets.OPeNDAP import THREDDSCatalog, OPeNDAPURL, OPeNDAPGrid 
     27from GeoEco.Datasets.Virtual import TimeSeriesGridStack, GridSliceCollection, MaskedGrid, ClippedGrid, RotatedGlobalGrid, ClimatologicalGridCollection, DerivedGrid 
    2828from GeoEco.DynamicDocString import DynamicDocString 
    2929from GeoEco.Internationalization import _ 
     
    104104 
    105105    def __getattribute__(self, name): 
    106         if name.startswith('__') or name in ['_WrappedGrid', '_GetTimeCoordsFromQueryableAttributeValues', '_GetQueryableAttributesForTimeSlices', '_GetLazyPropertyValuesForTimeSlices', 'CreateArcGISRasters', 'InterpolateAtArcGISPoints', 'CreateCayulaCornillonFrontsAsArcGISRasters']: 
     106        if name.startswith('__') or name in ['_WrappedGrid', '_GetTimeCoordsFromQueryableAttributeValues', '_GetQueryableAttributesForTimeSlices', '_GetLazyPropertyValuesForTimeSlices', 'CreateArcGISRasters', 'CreateClimatologicalArcGISRasters', 'InterpolateAtArcGISPoints', 'CreateCayulaCornillonFrontsAsArcGISRasters']: 
    107107            return object.__getattribute__(self, name) 
    108108        return object.__getattribute__(object.__getattribute__(self, '_WrappedGrid'), name) 
    109109 
    110110    def __setattr__(self, name, value): 
    111         if name.startswith('__') or name in ['_WrappedGrid', '_GetTimeCoordsFromQueryableAttributeValues', '_GetQueryableAttributesForTimeSlices', '_GetLazyPropertyValuesForTimeSlices', 'CreateArcGISRasters', 'InterpolateAtArcGISPoints', 'CreateCayulaCornillonFrontsAsArcGISRasters']: 
     111        if name.startswith('__') or name in ['_WrappedGrid', '_GetTimeCoordsFromQueryableAttributeValues', '_GetQueryableAttributesForTimeSlices', '_GetLazyPropertyValuesForTimeSlices', 'CreateArcGISRasters', 'CreateClimatologicalArcGISRasters', 'InterpolateAtArcGISPoints', 'CreateCayulaCornillonFrontsAsArcGISRasters']: 
    112112            object.__setattr__(self, name, value) 
    113113        else: 
     
    457457        # Return successfully. 
    458458 
     459        return outputWorkspace 
     460 
     461 
     462class _GHRSSTLevel4THREDDSCatalog(THREDDSCatalog): 
     463    __doc__ = DynamicDocString() 
     464 
     465    def __init__(self, displayName=None, timeout=60, maxRetryTime=120, cacheDirectory=None): 
     466        super(_GHRSSTLevel4THREDDSCatalog, self).__init__('http://podaac-opendap.jpl.nasa.gov/opendap/allData/ghrsst/data/L4/catalog.xml', 
     467                                                          [r'(?P<AreaCode>[^\-]+)', 
     468                                                           r'(?P<RDACCode>[^\-]+)', 
     469                                                           r'(?P<ProductCode2>[^\-]+)', 
     470                                                           r'(?P<Year>\d\d\d\d)', 
     471                                                           r'(?P<DayOfYear>\d\d\d)', 
     472                                                           r'(?P<Year>\d\d\d\d)(?P<Month>\d\d)(?P<Day>\d\d)-(?P<RDACCode>[^\-]+)-L4(?P<ProductType>[^\-]+)-(?P<AreaCode>[^\-]+)-v(?P<GDSVersion>\d\d)-fv(?P<FileVersion>[^\-]+)-(?P<ProductCode>[^\-]+)(?:\.nc|\.nc\.bz2|\.nc\.gz)'], 
     473                                                          displayName=displayName, 
     474                                                          timeout=timeout, 
     475                                                          maxRetryTime=maxRetryTime, 
     476                                                          queryableAttributes=(QueryableAttribute(u'RDACCode', _(u'RDAC code'), UnicodeStringTypeMetadata()), 
     477                                                                               QueryableAttribute(u'ProductType', _(u'Product type'), UnicodeStringTypeMetadata()), 
     478                                                                               QueryableAttribute(u'AreaCode', _(u'Area code'), UnicodeStringTypeMetadata()), 
     479                                                                               QueryableAttribute(u'GDSVersion', _(u'GDS version'), IntegerTypeMetadata()), 
     480                                                                               QueryableAttribute(u'FileVersion', _(u'File version'), UnicodeStringTypeMetadata()), 
     481                                                                               QueryableAttribute(u'ProductCode', _(u'Product code'), UnicodeStringTypeMetadata()), 
     482                                                                               QueryableAttribute(u'ProductCode2', _(u'Product code 2'), UnicodeStringTypeMetadata()), 
     483                                                                               QueryableAttribute(u'DateTime', _(u'Start date'), DateTimeTypeMetadata())), 
     484                                                          cacheDirectory=cacheDirectory) 
     485 
     486    def _ConstructOPeNDAPURL(self, url, timeout, maxRetryTime, queryableAttributeValues, cacheDirectory): 
     487        return _GHRSSTLevel4OPeNDAPURL(url, 
     488                                       timeout=timeout, 
     489                                       maxRetryTime=maxRetryTime, 
     490                                       parentCollection=self, 
     491                                       queryableAttributeValues=queryableAttributeValues, 
     492                                       lazyPropertyValues={'VariableTypes': ['Grid', 'Grid'], 
     493                                                           'VariableNames': ['analysed_sst', 'analysis_error']}, 
     494                                       cacheDirectory=cacheDirectory) 
     495 
     496 
     497class _GHRSSTLevel4OPeNDAPURL(OPeNDAPURL): 
     498    __doc__ = DynamicDocString() 
     499 
     500    def _ConstructOPeNDAPGrid(self, variableName, variableType): 
     501        return _GHRSSTLevel4OPeNDAPGrid(self, variableName, variableType) 
     502 
     503 
     504class _GHRSSTLevel4OPeNDAPGrid(OPeNDAPGrid): 
     505    __doc__ = DynamicDocString() 
     506 
     507    def __init__(self, opendapURLObj, variableName, variableType): 
     508        self.__doc__.Obj.ValidateMethodInvocation() 
     509 
     510        # Perform additional validation. 
     511         
     512        if variableName not in ['analysed_sst', 'analysis_error']: 
     513            raise ValueError(_(u'This tool does not support the "%(variableName)s" variable. The supported variables are "analysed_sst" and "analysis_error".') % {u'variableName': variableName}) 
     514 
     515        # Initialize the base class. 
     516         
     517        super(_GHRSSTLevel4OPeNDAPGrid, self).__init__(opendapURLObj, 
     518                                                       variableName, 
     519                                                       variableType, 
     520                                                       lazyPropertyValues={'SpatialReference': Dataset.ConvertSpatialReference('proj4', '+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs', 'obj'), 
     521                                                                           'Dimensions': u'tyx', 
     522                                                                           'TIncrement': 1, 
     523                                                                           'TIncrementUnit': 'day', 
     524                                                                           'TSemiRegularity': None, 
     525                                                                           'TCountPerSemiRegularPeriod': None, 
     526                                                                           'TCornerCoordType': 'min', 
     527                                                                           'CoordDependencies': (None, None, None), 
     528                                                                           'PhysicalDimensions': u'tyx', 
     529                                                                           'PhysicalDimensionsFlipped': (False, False, False)}) 
     530 
     531    def _GetLazyPropertyPhysicalValue(self, name): 
     532 
     533        # If the caller is asking for the CoordIncrements or 
     534        # CornerCoords, calculate them from the lon and lat OPeNDAP 
     535        # variables, which give the center coordinates of the cells. 
     536 
     537        self.ParentCollection._Open() 
     538 
     539        if name in ['CoordIncrements', 'CornerCoords']: 
     540            lon = self.ParentCollection._PydapDataset['lon'] 
     541            lat = self.ParentCollection._PydapDataset['lat'] 
     542 
     543            if lon[0] > lon[-1]: 
     544                self.SetLazyPropertyValue('CoordIncrements', (1., (lat[-1] - lat[0]) / (lat.shape[0] - 1), (lon[-1] + 360. - lon[0]) / (lon.shape[0] - 1)))     # For datasets such as ABOM-L4HRfnd-AUS-RAMSSA_09km that cross the 180th meridian, use a 0-to-360 coordinate system 
     545            else: 
     546                self.SetLazyPropertyValue('CoordIncrements', (1., (lat[-1] - lat[0]) / (lat.shape[0] - 1), (lon[-1] - lon[0]) / (lon.shape[0] - 1))) 
     547 
     548            self.SetLazyPropertyValue('CornerCoords', (datetime.datetime(1980, 1, 1), lat[0], lon[0]))      # Use fake time coordinate; the true time coordinates are parsed from the file name.  
     549 
     550            return self.GetLazyPropertyValue(name) 
     551 
     552        # If the caller is asking for the scaled data type, scaling 
     553        # function, or unscaling function, determine these from the 
     554        # data type and add_offset and scale_factor attributes of this 
     555        # OPeNDAP variable. 
     556 
     557        if name in ['ScaledDataType', 'ScalingFunction', 'UnscalingFunction']: 
     558            v = self._GetOPeNDAPVariable() 
     559            if self.GetLazyPropertyValue('UnscaledDataType').startswith('float') or not hasattr(v, 'scale_factor') or not hasattr(v, 'add_offset'): 
     560                return None 
     561 
     562            import numpy 
     563 
     564            self.SetLazyPropertyValue('ScaledDataType', u'float32') 
     565            self.SetLazyPropertyValue('ScalingFunction', lambda data: numpy.cast['float32'](v.scale_factor*data + v.add_offset)) 
     566            self.SetLazyPropertyValue('UnscalingFunction', lambda data: numpy.cast[str(self.GetLazyPropertyValue('UnscaledDataType'))](numpy.round((data - v.add_offset)/v.scale_factor))) 
     567 
     568            return self.GetLazyPropertyValue(name) 
     569 
     570        # If the caller is asking for the UnscaledNoDataValue, get it 
     571        # from the _FillValue attribute of this OPeNDAP variable. 
     572 
     573        if name == 'UnscaledNoDataValue': 
     574            v = self._GetOPeNDAPVariable() 
     575            if not hasattr(v, '_FillValue'): 
     576                return None 
     577            if not self.GetLazyPropertyValue('UnscaledDataType').startswith('float'): 
     578                return int(v._FillValue) 
     579            return v._FillValue 
     580 
     581        # If the caller is asking for the ScaledNoDataValue, calculate 
     582        # it. 
     583         
     584        if name == 'ScaledNoDataValue': 
     585            scalingFunction = self.GetLazyPropertyValue('ScalingFunction') 
     586            unscaledNoDataValue = self.GetLazyPropertyValue('UnscaledNoDataValue') 
     587            if scalingFunction is None or unscaledNoDataValue is None: 
     588                return None 
     589            return scalingFunction(unscaledNoDataValue) 
     590 
     591        # Otherwise let the base class get this property. 
     592         
     593        return super(_GHRSSTLevel4OPeNDAPGrid, self)._GetLazyPropertyPhysicalValue(name) 
     594 
     595 
     596class GHRSSTLevel4(Grid): 
     597    __doc__ = DynamicDocString() 
     598 
     599    def __init__(self, variableName, rdacCode, productType, areaCode, gdsVersion, fileVersion, productCode, productCode2=None, convertToCelsius=True, timeout=60, maxRetryTime=300, cacheDirectory=None): 
     600        self.__doc__.Obj.ValidateMethodInvocation() 
     601 
     602        # Construct a _GHRSSTLevel4THREDDSCatalog and wrap it in a 
     603        # TimeSeriesGridStack to create a 3D grid with dimensions tyx. 
     604 
     605        if productCode2 is None: 
     606            productCode2 = productCode 
     607 
     608        if rdacCode == 'REMSS' and areaCode == 'GLOB' and productCode == 'mw_ir_rt_OI': 
     609            datasetSpecificExpression = 'AND (Year > 2008 OR Year = 2008 AND DayOfYear >= 199)'     # Hack to speed up querying for mw_ir_rt_OI, which is stored in same directory as mw_ir_OI but starts at a much later date. 
     610        else: 
     611            datasetSpecificExpression = '' 
     612 
     613        grid = TimeSeriesGridStack(_GHRSSTLevel4THREDDSCatalog(_('GHRSST L4 product %s-L4%s-%s-%s hosted by NASA PO.DAAC') % (rdacCode, productType, areaCode, productCode), timeout, maxRetryTime, cacheDirectory), 
     614                                   expression = "VariableName = '%s' AND RDACCode = '%s' AND ProductType = '%s' AND AreaCode = '%s' AND GDSVersion = %i AND FileVersion = '%s' AND ProductCode = '%s' AND ProductCode2 = '%s' %s" % (variableName, rdacCode, productType, areaCode, gdsVersion, fileVersion, productCode, productCode2, datasetSpecificExpression), 
     615                                   reportProgress=False) 
     616 
     617        # If the caller requested that we convert Kelvin temperatures 
     618        # to Celsius, wrap the grid. 
     619 
     620        if convertToCelsius: 
     621            qav = {} 
     622            for qa in grid.GetAllQueryableAttributes(): 
     623                qav[qa.Name] = grid.GetQueryableAttributeValue(qa.Name) 
     624             
     625            grid = DerivedGrid([grid], 
     626                               'self._Grids[0].Data.__getitem__(tuple(sliceList)) - 273.15', 
     627                               grid.DisplayName, 
     628                               grid.DataType, 
     629                               grid.NoDataValue - 273.15, 
     630                               queryableAttributes=tuple(grid.GetAllQueryableAttributes()), 
     631                               queryableAttributeValues=qav) 
     632 
     633        # Assign our _WrappedGrid instance variable. 
     634 
     635        self._WrappedGrid = grid 
     636 
     637    def __getattribute__(self, name): 
     638        if name.startswith('__') or name in ['_WrappedGrid', '_PODAAC_Products', '_RotateAndClip', 'CreateArcGISRasters', 'CreateClimatologicalArcGISRasters', 'InterpolateAtArcGISPoints', 'CreateCayulaCornillonFrontsAsArcGISRasters']: 
     639            return object.__getattribute__(self, name) 
     640        return object.__getattribute__(object.__getattribute__(self, '_WrappedGrid'), name) 
     641 
     642    def __setattr__(self, name, value): 
     643        if name.startswith('__') or name in ['_WrappedGrid', '_PODAAC_Products', '_RotateAndClip', 'CreateArcGISRasters', 'CreateClimatologicalArcGISRasters', 'InterpolateAtArcGISPoints', 'CreateCayulaCornillonFrontsAsArcGISRasters']: 
     644            object.__setattr__(self, name, value) 
     645        else: 
     646            setattr(object.__getattribute__(self, '_WrappedGrid'), name, value) 
     647 
     648    # In the lists below the items are [rdacCode, productType, areaCode, gdsVersion, fileVersion, productCode, productCode2] 
     649 
     650    _PODAAC_Products = {u'ABOM-L4HRfnd-AUS-RAMSSA_09km': ['ABOM', 'HRfnd', 'AUS', 1, '01_0', 'RAMSSA_09km', 'RAMSSA_09km'], 
     651                        u'ABOM-L4LRfnd-GLOB-GAMSSA_28km': ['ABOM', 'LRfnd', 'GLOB', 1, '01_0', 'GAMSSA_28km', 'GAMSSA_28km'], 
     652                        u'DMI-L4UHfnd-NSEABALTIC-DMI_OI': ['DMI', 'UHfnd', 'NSEABALTIC', 1, '01', 'DMI_OI', 'DMI_OI'], 
     653                        u'EUR-L4UHRfnd-MED-ODYSSEA': ['EUR', 'UHRfnd', 'MED', 1, '01', 'ODYSSEA', 'ODYSSEA'], 
     654                        u'EUR-L4UHRfnd-NWE-ODYSSEA': ['EUR', 'UHRfnd', 'NWE', 1, '01', 'ODYSSEA', 'ODYSSEA'], 
     655                        u'JPL-L4UHfnd-GLOB-MUR': ['JPL', 'UHfnd', 'GLOB', 1, '03', 'MUR', 'MUR'], 
     656                        u'JPL_OUROCEAN-L4UHfnd-GLOB-G1SST': ['JPL_OUROCEAN', 'UHfnd', 'GLOB', 1, '01_0', 'G1SST', 'G1SST'], 
     657                        u'NAVO-L4HR1m-GLOB-K10_SST': ['NAVO', 'HR1m', 'GLOB', 1, '01_0', 'K10_SST', 'K10_SST'], 
     658                        u'NCDC-L4LRblend-GLOB-AVHRR_AMSR_OI': ['NCDC', 'LRblend', 'GLOB', 1, '02_0', 'AVHRR_AMSR_OI', 'AVHRR_AMSR_OI'], 
     659                        u'NCDC-L4LRblend-GLOB-AVHRR_OI': ['NCDC', 'LRblend', 'GLOB', 1, '02_0', 'AVHRR_OI', 'AVHRR_OI'], 
     660                        #u'REMSS-L4HRfnd-GLOB-mw_ir_OI': ['REMSS', 'HRfnd', 'GLOB', 1, '01', 'mw_ir_OI', 'mw_ir_OI'],               # PO.DAAC's copy of this dataset is not up to date. I emailed them and they are working on it. 
     661                        #u'REMSS-L4HRfnd-GLOB-mw_ir_rt_OI': ['REMSS', 'HRfnd', 'GLOB', 1, '01', 'mw_ir_rt_OI', 'mw_ir_OI'],         # PO.DAAC's copy of this dataset is not up to date. I emailed them and they are working on it. 
     662                        u'UKMO-L4HRfnd-GLOB-OSTIA': ['UKMO', 'HRfnd', 'GLOB', 1, '02', 'OSTIA', 'OSTIA']} 
     663 
     664    @classmethod 
     665    def _RotateAndClip(cls, grid, rotationOffset, spatialExtent, startDate, endDate): 
     666        if rotationOffset is not None: 
     667            grid = RotatedGlobalGrid(grid, rotationOffset, u'Map units') 
     668 
     669        xMin, yMin, xMax, yMax = None, None, None, None 
     670        if spatialExtent is not None: 
     671            from GeoEco.Types import EnvelopeTypeMetadata 
     672            xMin, yMin, xMax, yMax = EnvelopeTypeMetadata.ParseFromArcGISString(spatialExtent) 
     673 
     674        if spatialExtent is not None or startDate is not None or endDate is not None: 
     675            if startDate is not None: 
     676                startDate = datetime.datetime(startDate.year, startDate.month, startDate.day, 0, 0, 0) 
     677            if endDate is not None: 
     678                endDate = datetime.datetime(endDate.year, endDate.month, endDate.day, 23, 59, 59) 
     679                 
     680            grid = ClippedGrid(grid, u'Map coordinates', xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, tMin=startDate, tMax=endDate) 
     681             
     682        return grid 
     683 
     684    @classmethod 
     685    def CreateArcGISRasters(cls, product, variableName, 
     686                            outputWorkspace, mode=u'add', rasterNameExpressions=[u'%(AreaCode)s', u'%(RDACCode)s', u'%(ProductCode)s', u'%(VariableName)s', u'%%Y', u'%%Y%%m%%d-%(RDACCode)s-L4%(ProductType)s-%(AreaCode)s-v%(GDSVersion)02i-fv%(FileVersion)s-%(ProductCode)s-%(VariableName)s.img'], rasterCatalog=None, 
     687                            rotationOffset=None, spatialExtent=None, startDate=None, endDate=None,  
     688                            timeout=60, maxRetryTime=300, cacheDirectory=None, 
     689                            convertToCelsius=True, useUnscaledData=False, calculateStatistics=True, buildRAT=False, buildPyramids=False): 
     690        cls.__doc__.Obj.ValidateMethodInvocation() 
     691        [rdacCode, productType, areaCode, gdsVersion, fileVersion, productCode, productCode2] = cls._PODAAC_Products[product] 
     692        grid = cls(variableName, rdacCode, productType, areaCode, gdsVersion, fileVersion, productCode, productCode2, convertToCelsius and variableName == u'analysed_sst' and not useUnscaledData, timeout, maxRetryTime, cacheDirectory) 
     693        try: 
     694            from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISRaster 
     695            grid = cls._RotateAndClip(grid, rotationOffset, spatialExtent, startDate, endDate) 
     696            workspace = ArcGISWorkspace(outputWorkspace, ArcGISRaster, pathCreationExpressions=rasterNameExpressions, cacheTree=True, queryableAttributes=tuple(grid.GetAllQueryableAttributes() + [QueryableAttribute(u'DateTime', _(u'Date'), DateTimeTypeMetadata())])) 
     697            workspace.ImportDatasets(GridSliceCollection(grid, tQACoordType=u'min').QueryDatasets(), mode, useUnscaledData=useUnscaledData, calculateStatistics=calculateStatistics, buildRAT=buildRAT, buildPyramids=buildPyramids) 
     698            if rasterCatalog is not None: 
     699                workspace.ToRasterCatalog(rasterCatalog, grid.GetSpatialReference(u'ArcGIS'), tQACoordType=u'min', tCoordFunction=lambda qav: [qav[u'DateTime'], qav[u'DateTime'] + datetime.timedelta(0.5), qav[u'DateTime'] + datetime.timedelta(1) - datetime.timedelta(seconds=1)], overwriteExisting=True) 
     700        finally: 
     701            grid.Close() 
    459702        return outputWorkspace 
    460703 
     
    8561099 
    8571100'Add' should be appropriate for nearly all situations. One situation 
    858 in which 'Replace' is appropriate is when NASA reprocesses the entire 
    859 dataset with improved algorithms and releases updated images. In that 
    860 case, you may wish to recreate all of your rasters using the updated 
    861 data. 
     1101in which 'Replace' is appropriate is when the data publisher 
     1102reprocesses the entire dataset with improved algorithms and releases 
     1103updated images. In that case, you may wish to recreate all of your 
     1104rasters using the updated data. 
    8621105 
    8631106The ArcGIS Overwrite Outputs geoprocessing setting has no effect on 
     
    9891232    description=_( 
    9901233u"""Spatial extent of the output rasters, in degrees. If not provided, 
    991 the spatial extent will be the entire planet. 
     1234the spatial extent will not be clipped. 
    9921235 
    9931236This parameter is applied after the rotation parameter and uses 
     
    18812124 
    18822125############################################################################### 
     2126# Metadata: _GHRSSTLevel4THREDDSCatalog class 
     2127############################################################################### 
     2128 
     2129AddClassMetadata(_GHRSSTLevel4THREDDSCatalog, 
     2130    shortDescription=_(u'THREDDSCatalog for the NASA JPL PO.DAAC GHRSST L4 datasets.'), 
     2131    longDescription=_( 
     2132u"""This class is not intended to be used directly by external 
     2133callers. Use GHRSSTLevel4 instead.""")) 
     2134 
     2135############################################################################### 
     2136# Metadata: _GHRSSTLevel4OPeNDAPURL class 
     2137############################################################################### 
     2138 
     2139AddClassMetadata(_GHRSSTLevel4OPeNDAPURL, 
     2140    shortDescription=_(u'OPeNDAPURL for a NASA JPL PO.DAAC GHRSST L4 file.'), 
     2141    longDescription=_( 
     2142u"""This class is not intended to be used directly by external 
     2143callers. Use GHRSSTLevel4 instead.""")) 
     2144 
     2145############################################################################### 
     2146# Metadata: _GHRSSTLevel4OPeNDAPGrid class 
     2147############################################################################### 
     2148 
     2149AddClassMetadata(_GHRSSTLevel4OPeNDAPGrid, 
     2150    shortDescription=_(u'OPeNDAPGrid for a variable of a NASA JPL PO.DAAC GHRSST L4 file.'), 
     2151    longDescription=_( 
     2152u"""This class is not intended to be used directly by external 
     2153callers. Use GHRSSTLevel4 instead.""")) 
     2154 
     2155# Constructor 
     2156 
     2157AddMethodMetadata(_GHRSSTLevel4OPeNDAPGrid.__init__, 
     2158    shortDescription=_(u'Constructs a new _GHRSSTLevel4OPeNDAPGrid instance.')) 
     2159 
     2160AddArgumentMetadata(_GHRSSTLevel4OPeNDAPGrid.__init__, u'self', 
     2161    typeMetadata=ClassInstanceTypeMetadata(cls=_GHRSSTLevel4OPeNDAPGrid), 
     2162    description=_(u'_GHRSSTLevel4OPeNDAPGrid instance.')) 
     2163 
     2164AddArgumentMetadata(_GHRSSTLevel4OPeNDAPGrid.__init__, u'opendapURLObj', 
     2165    typeMetadata=ClassInstanceTypeMetadata(cls=_GHRSSTLevel4OPeNDAPURL), 
     2166    description=_(u'_GHRSSTLevel4OPeNDAPURL instance that contains us.')) 
     2167 
     2168AddArgumentMetadata(_GHRSSTLevel4OPeNDAPGrid.__init__, u'variableName', 
     2169    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'analysed_sst', u'analysis_error']), 
     2170    description=_(u'OPeNDAP variable name.')) 
     2171 
     2172AddArgumentMetadata(_GHRSSTLevel4OPeNDAPGrid.__init__, u'variableType', 
     2173    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Grid']), 
     2174    description=_(u'OPeNDAP variable type.')) 
     2175 
     2176AddResultMetadata(_GHRSSTLevel4OPeNDAPGrid.__init__, u'grid', 
     2177    typeMetadata=ClassInstanceTypeMetadata(cls=_GHRSSTLevel4OPeNDAPGrid), 
     2178    description=_(u'_GHRSSTLevel4OPeNDAPGrid instance.')) 
     2179 
     2180############################################################################### 
     2181# Metadata: GHRSSTLevel4 class 
     2182############################################################################### 
     2183 
     2184_GHRSSTLevel4_LongDescription = _( 
     2185u"""The `Group for High-Resolution Sea Surface Temperature (GHRSST) <http://www.ghrsst.org/>`_ 
     2186provides a new generation of global high-resolution (<10km) SST 
     2187products to the operational oceanographic, meteorological, climate and 
     2188general scientific community. The overall aim of the GHRSST is to 
     2189provide the best quality sea surface temperature data for applications 
     2190in short, medium and decadal/climate time scales in the most cost 
     2191effective and efficient manner through international collaboration and 
     2192scientific innovation. 
     2193 
     2194This %(name)s accesses L4 gap-free gridded SST products published in 
     2195near real time by the GHRSST GDAC Global Data Assembly Center (GDAC) 
     2196at the `NASA JPL Physical Oceanography Distributed Active Archive Center (PO.DAAC) <http://podaac.jpl.nasa.gov/SeaSurfaceTemperature/GHRSST>`_. 
     2197These products provide regional and global daily cloud-free estimates 
     2198of SST at spatial resolutions ranging from 0.25 degrees to down 1 km. 
     2199To fill in cloudy areas, data from multiple satellite and in-situ 
     2200sensors are combined and regions without any data are filled in 
     2201various interpolation and modeling techniques. 
     2202 
     2203All products accessed by this %(name)s are published at a daily 
     2204timestep. Some products are updated on a continual basis and available 
     2205in near real time; others are updated infrequently and are intended 
     2206mainly for historical analysis. The temporal extent, spatial 
     2207resolution and extent, and sensors and interpolation technique used 
     2208vary by product. All products use the WGS 1984 geographic coordinate 
     2209system. GHRSST temperatures are published in kelvin. By default, this 
     2210%(name)s converts them to degrees Celsius but provides an option to 
     2211obtain the original kelvin values. 
     2212 
     2213All products are obtained from PO.DAAC using the OPeNDAP protocol. 
     2214This %(name)s supports most but not all of the GHRSST L4 products 
     2215hosted by PO.DAAC. If you see a product on PO.DAAC that is not 
     2216available with this tool, please contact the MGET development team for 
     2217assistance.""") 
     2218 
     2219AddClassMetadata(GHRSSTLevel4, 
     2220    shortDescription=_(u'A Grid representing a GHRSST L4 product hosted by NASA JPL PO.DAAC.'), 
     2221    longDescription=_GHRSSTLevel4_LongDescription % {u'name': 'class'}) 
     2222 
     2223# Constructor 
     2224 
     2225AddMethodMetadata(GHRSSTLevel4.__init__, 
     2226    shortDescription=_(u'Constructs a new GHRSSTLevel4 instance.')) 
     2227 
     2228AddArgumentMetadata(GHRSSTLevel4.__init__, u'self', 
     2229    typeMetadata=ClassInstanceTypeMetadata(cls=GHRSSTLevel4), 
     2230    description=_(u'GHRSSTLevel4 instance.')) 
     2231 
     2232AddArgumentMetadata(GHRSSTLevel4.__init__, u'variableName', 
     2233    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'analysed_sst', u'analysis_error']), 
     2234    description=_( 
     2235u"""GHRSST variable to access, one of: 
     2236 
     2237* analysed_sst - GHRSST product-specific estimate of SST. 
     2238 
     2239* analysis_error - GHRSST product-specific estimate of of the error in 
     2240  the SST estimate. 
     2241 
     2242Please see the product documentation for details about what these 
     2243variables mean and how they were calculated. These variable names are 
     2244case-sensitive."""), 
     2245    arcGISDisplayName=_(u'GHRSST variable')) 
     2246 
     2247AddArgumentMetadata(GHRSSTLevel4.__init__, u'rdacCode', 
     2248    typeMetadata=UnicodeStringTypeMetadata(), 
     2249    description=_( 
     2250u"""The code of the GHRSST Regional Data Access Center (RDAC) that 
     2251produced the product. These codes are case-sensitive, typically upper 
     2252case, and assigned by GHRSST.""")) 
     2253 
     2254AddArgumentMetadata(GHRSSTLevel4.__init__, u'productType', 
     2255    typeMetadata=UnicodeStringTypeMetadata(), 
     2256    description=_( 
     2257u"""GHRSST product type code. These codes are case-sensitive, assigned 
     2258by GHRSST, and indicate the overall resolution and type of SST 
     2259estimated by the product. Typical codes include "LRfnd", "HRfnd", 
     2260"UHfnd", "HR1m", and "LRblend".""")) 
     2261 
     2262AddArgumentMetadata(GHRSSTLevel4.__init__, u'areaCode', 
     2263    typeMetadata=UnicodeStringTypeMetadata(), 
     2264    description=_( 
     2265u"""The region code of the the product. These codes are 
     2266case-sensitive, typically upper case, and assigned by GHRSST. A list 
     2267of codes may be seen on the PO.DAAC OPeNDAP server at 
     2268http://podaac-opendap.jpl.nasa.gov/opendap/hyrax/allData/ghrsst/data/L4/""")) 
     2269 
     2270AddArgumentMetadata(GHRSSTLevel4.__init__, u'gdsVersion', 
     2271    typeMetadata=IntegerTypeMetadata(minValue=1), 
     2272    description=_( 
     2273u"""Version of the GHRSST Data Specification (GDS) used by the 
     2274product. At the time of this writing, all products accessed by this 
     2275function were at GDS version 1.""")) 
     2276 
     2277AddArgumentMetadata(GHRSSTLevel4.__init__, u'fileVersion', 
     2278    typeMetadata=UnicodeStringTypeMetadata(), 
     2279    description=_( 
     2280u"""Version of the file. This is a case-sensitive string that is 
     2281product specific and assigned by the RDAC that produced the 
     2282product.""")) 
     2283 
     2284AddArgumentMetadata(GHRSSTLevel4.__init__, u'productCode', 
     2285    typeMetadata=UnicodeStringTypeMetadata(), 
     2286    description=_( 
     2287u"""The RDAC-assigned product code that appears at the end of the 
     2288GHRSST file name.""")) 
     2289 
     2290AddArgumentMetadata(GHRSSTLevel4.__init__, u'productCode2', 
     2291    typeMetadata=UnicodeStringTypeMetadata(canBeNone=True), 
     2292    description=_( 
     2293u"""The RDAC-assigned product code that appears in the PO.DAAC OPeNDAP 
     2294catalog structure below the RDAC level. For example, in the URL 
     2295http://podaac-opendap.jpl.nasa.gov/opendap/hyrax/allData/ghrsst/data/L4/GLOB/REMSS/mw_ir_OI/2012/001/20120103-REMSS-L4HRfnd-GLOB-v01-fv03-mw_ir_rt_OI.nc.gz, 
     2296the productCode is "mw_ir_rt_OI" while the productCode2 is "mw_ir_OI". 
     2297 
     2298Typically the productCode2 is the same as the same as the productCode, 
     2299in which case you should omit the productCode2 (leave it None). Only a 
     2300few products have a different productCode2.""")) 
     2301 
     2302AddArgumentMetadata(GHRSSTLevel4.__init__, u'convertToCelsius', 
     2303    typeMetadata=BooleanTypeMetadata(), 
     2304    description=_( 
     2305u"""If True (the default), temperature values will be converted from 
     2306kelvin to degrees Celsius. If False, temperature values will be in the 
     2307original kelvin values."""), 
     2308    arcGISDisplayName=_(u'Use unscaled data'), 
     2309    arcGISCategory=_(u'Additional raster processing options')) 
     2310 
     2311CopyArgumentMetadata(THREDDSCatalog.__init__, u'timeout', GHRSSTLevel4.__init__, u'timeout') 
     2312CopyArgumentMetadata(THREDDSCatalog.__init__, u'maxRetryTime', GHRSSTLevel4.__init__, u'maxRetryTime') 
     2313CopyArgumentMetadata(THREDDSCatalog.__init__, u'cacheDirectory', GHRSSTLevel4.__init__, u'cacheDirectory') 
     2314 
     2315AddResultMetadata(GHRSSTLevel4.__init__, u'grid', 
     2316    typeMetadata=ClassInstanceTypeMetadata(cls=GHRSSTLevel4), 
     2317    description=_(u'GHRSSTLevel4 instance.')) 
     2318 
     2319# Public method: GHRSSTLevel4.CreateArcGISRasters 
     2320 
     2321AddMethodMetadata(GHRSSTLevel4.CreateArcGISRasters, 
     2322    shortDescription=_(u'Creates rasters for a GHRSST L4 product hosted by NASA JPL PO.DAAC.'), 
     2323    longDescription=_GHRSSTLevel4_LongDescription % {u'name': 'tool'}, 
     2324    isExposedToPythonCallers=True, 
     2325    isExposedByCOM=True, 
     2326    isExposedAsArcGISTool=True, 
     2327    arcGISDisplayName=_(u'Create Rasters for GHRSST L4 SST'), 
     2328    arcGISToolCategory=_(u'Data Products\\NASA JPL PO.DAAC\\GHRSST L4 SST'), 
     2329    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')]) 
     2330 
     2331AddArgumentMetadata(GHRSSTLevel4.CreateArcGISRasters, u'cls', 
     2332    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=GHRSSTLevel4), 
     2333    description=_(u'GHRSSTLevel4 class or instance.')) 
     2334 
     2335AddArgumentMetadata(GHRSSTLevel4.CreateArcGISRasters, u'product', 
     2336    typeMetadata=UnicodeStringTypeMetadata(allowedValues=sorted(GHRSSTLevel4._PODAAC_Products.keys())), 
     2337    description=_( 
     2338u"""GHRSST L4 product to access. Currently, the following products are 
     2339supported: 
     2340 
     2341* `ABOM-L4HRfnd-AUS-RAMSSA_09km <http://podaac.jpl.nasa.gov/dataset/UKMO-L4HRfnd-GLOB-OSTIA>`_. 
     2342* `ABOM-L4LRfnd-GLOB-GAMSSA_28km <http://podaac.jpl.nasa.gov/dataset/ABOM-L4LRfnd-GLOB-GAMSSA_28km>`_. 
     2343* `DMI-L4UHfnd-NSEABALTIC-DMI_OI <http://podaac.jpl.nasa.gov/dataset/DMI-L4UHfnd-NSEABALTIC-DMI_OI>`_. 
     2344* `EUR-L4UHRfnd-MED-ODYSSEA <http://podaac.jpl.nasa.gov/dataset/EUR-L4UHRfnd-MED-ODYSSEA>`_. 
     2345* `EUR-L4UHRfnd-NWE-ODYSSEA <http://podaac.jpl.nasa.gov/dataset/EUR-L4UHRfnd-NWE-ODYSSEA>`_. 
     2346* `JPL-L4UHfnd-GLOB-MUR <http://podaac.jpl.nasa.gov/dataset/JPL-L4UHfnd-GLOB-MUR>`_. 
     2347* `JPL_OUROCEAN-L4UHfnd-GLOB-G1SST <http://podaac.jpl.nasa.gov/dataset/JPL_OUROCEAN-L4UHfnd-GLOB-G1SST>`_. 
     2348* `NAVO-L4HR1m-GLOB-K10_SST <http://podaac.jpl.nasa.gov/dataset/NAVO-L4HR1m-GLOB-K10_SST>`_. 
     2349* `NCDC-L4LRblend-GLOB-AVHRR_AMSR_OI <http://podaac.jpl.nasa.gov/dataset/NCDC-L4LRblend-GLOB-AVHRR_AMSR_OI>`_. 
     2350* `NCDC-L4LRblend-GLOB-AVHRR_OI <http://podaac.jpl.nasa.gov/dataset/NCDC-L4LRblend-GLOB-AVHRR_OI>`_. 
     2351* `UKMO-L4HRfnd-GLOB-OSTIA <http://podaac.jpl.nasa.gov/dataset/UKMO-L4HRfnd-GLOB-OSTIA>`_. 
     2352 
     2353All products use the WGS 1984 geographic coordinate system and are 
     2354published at a daily timestep. Some products are updated on a 
     2355continual basis and available in near real time; others are updated 
     2356infrequently and are intended mainly for historical analysis. The 
     2357temporal extent, spatial resolution and extent, and sensors and 
     2358interpolation technique used vary by product. Please see the products' 
     2359documentation for details. 
     2360 
     2361This tool supports most but not all of the GHRSST L4 products hosted 
     2362by PO.DAAC. If you see a product on PO.DAAC that is not available with 
     2363this tool, please contact the MGET development team for 
     2364assistance."""), 
     2365    arcGISDisplayName=_(u'GHRSST L4 product')) 
     2366 
     2367CopyArgumentMetadata(GHRSSTLevel4.__init__, u'variableName', GHRSSTLevel4.CreateArcGISRasters, u'variableName') 
     2368 
     2369CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'outputWorkspace', GHRSSTLevel4.CreateArcGISRasters, u'outputWorkspace') 
     2370CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'mode', GHRSSTLevel4.CreateArcGISRasters, u'mode') 
     2371 
     2372AddArgumentMetadata(GHRSSTLevel4.CreateArcGISRasters, u'rasterNameExpressions', 
     2373    typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(), minLength=1), 
     2374    description=_( 
     2375u"""List of expressions specifying how the output rasters should be 
     2376named. 
     2377 
     2378The default expression assumes you are storing rasters in a file 
     2379system directory and creates them in a tree structure with names that 
     2380imitate those used by NASA. When storing rasters in a directory, the 
     2381final expression specifies the file name of the raster and any 
     2382preceding expressions specify subdirectories. The extension of the 
     2383final expression determines the output raster format: .asc for ArcInfo 
     2384ASCII Grid, .bmp for BMP, .gif for GIF, .img for an ERDAS IMAGINE 
     2385file, .jpg for JPEG, .jp2 for JPEG 2000, .png for PNG, .tif for 
     2386GeoTIFF, or no extension for ArcInfo Binary Grid. The default 
     2387expression uses .img. 
     2388 
     2389When storing rasters in a geodatabase, you should provide only one 
     2390expression. That expression specifies the raster's name. 
     2391 
     2392Each expression may contain any sequence of characters permitted by 
     2393the output workspace. Each expression may optionally contain one or 
     2394more of the following case-sensitive codes. The tool replaces the 
     2395codes with appropriate values when creating each raster: 
     2396 
     2397* %(AreaCode)s - GHRSST abbreviation indicating the spatial extent of 
     2398  the product, such as "GLOB" for global extent or "AUS" for 
     2399  Australia. 
     2400 
     2401* %(RDACCode)s - GHRSST abbreviation for the Regonal Data Assembly 
     2402  Center (RDAC) that produced the product. 
     2403 
     2404* %(ProductCode)s - name of the product, assigned by the RDAC. 
     2405 
     2406* %(VariableName)s - GHRSST variable represented in the output raster, 
     2407  either "analysed_sst" or "analysis_error". 
     2408 
     2409* %(ProductType)s - GHRSST product type code that indicates the 
     2410  overall resolution and type of SST estimated by the product. For 
     2411  example, "UHfnd" indicates ultra-high resolution (< 5 km spatial 
     2412  resolution) foundational SST. Please see the GHRSST documentation 
     2413  for the formal meanings of these codes. 
     2414 
     2415* %(GDSVersion)02i - version of the GHRSST Data Specification (GDS) 
     2416  used by the product. At the time of this writing, all products 
     2417  accessed by this function were at GDS version 1, which will be 
     2418  rendered as 01 by the expression %(GDSVersion)02i. 
     2419 
     2420* %(FileVersion)s - version of the data file itself. This is 
     2421  product-specific and assigned by the RDAC that produced the product. 
     2422 
     2423* %%Y - four-digit year of the raster. 
     2424 
     2425* %%m - two-digit month of the first day of the raster. 
     2426 
     2427* %%d - two-digit day of the month of the first day of the raster. 
     2428 
     2429* %%j - three-digit day of the year of the first day of the raster. 
     2430"""), 
     2431    arcGISDisplayName=_(u'Raster name expressions')) 
     2432 
     2433CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'rasterCatalog', GHRSSTLevel4.CreateArcGISRasters, u'rasterCatalog') 
     2434CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'rotationOffset', GHRSSTLevel4.CreateArcGISRasters, u'rotationOffset') 
     2435CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'spatialExtent', GHRSSTLevel4.CreateArcGISRasters, u'spatialExtent') 
     2436CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'startDate', GHRSSTLevel4.CreateArcGISRasters, u'startDate') 
     2437CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'endDate', GHRSSTLevel4.CreateArcGISRasters, u'endDate') 
     2438CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'timeout', GHRSSTLevel4.CreateArcGISRasters, u'timeout') 
     2439CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'maxRetryTime', GHRSSTLevel4.CreateArcGISRasters, u'maxRetryTime') 
     2440CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'cacheDirectory', GHRSSTLevel4.CreateArcGISRasters, u'cacheDirectory') 
     2441 
     2442CopyArgumentMetadata(GHRSSTLevel4.__init__, u'convertToCelsius', GHRSSTLevel4.CreateArcGISRasters, u'convertToCelsius') 
     2443 
     2444CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'useUnscaledData', GHRSSTLevel4.CreateArcGISRasters, u'useUnscaledData') 
     2445CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'calculateStatistics', GHRSSTLevel4.CreateArcGISRasters, u'calculateStatistics') 
     2446CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'buildRAT', GHRSSTLevel4.CreateArcGISRasters, u'buildRAT') 
     2447CopyArgumentMetadata(MODISL3SSTTimeSeries.CreateArcGISRasters, u'buildPyramids', GHRSSTLevel4.CreateArcGISRasters, u'buildPyramids') 
     2448 
     2449AddResultMetadata(GHRSSTLevel4.CreateArcGISRasters, u'updatedOutputWorkspace', 
     2450    typeMetadata=ArcGISWorkspaceTypeMetadata(), 
     2451    description=_(u'Updated output workspace.'), 
     2452    arcGISDisplayName=_(u'Updated output workspace'), 
     2453    arcGISParameterDependencies=[u'outputWorkspace']) 
     2454 
     2455############################################################################### 
    18832456# Metadata: QuikSCATL3TimeSeries class 
    18842457############################################################################### 
     
    19032476 
    19042477__all__ = ['MODISL3SSTTimeSeries', 
    1905 ##           'MODISL3SSTTimeSlicesInDirectory', 
     2478           'GHRSSTLevel4' 
    19062479           'QuikSCATL3TimeSeries', 
    19072480           'QuikSCATL3TimeSlicesInDirectory'] 
  • MGET/Branches/Jason/PythonPackage/src/GeoEco/Datasets/Collections.py

    r927 r949  
    176176            if 'Year' not in dateTimeComponents: 
    177177                raise TypeError(_(u'This dataset collection includes a queryable attribute with the data type DateTimeTypeMetadata but %(param)s does not include a path component for the year.') % {u'param': param}) 
    178                  
    179             # Validate that Month and DayOfYear are not both 
    180             # specified, and that Day and DayOfYear are not both 
    181             # specified. 
    182  
    183             if 'Month' in dateTimeComponents and 'DayOfYear' in dateTimeComponents: 
    184                 raise TypeError(_(u'%(param)s includes path components for both the month and the day of the year. This is not allowed. Please choose one or the other.') % {u'param': param}) 
    185  
    186             if 'Day' in dateTimeComponents and 'DayOfYear' in dateTimeComponents: 
    187                 raise TypeError(_(u'%(param)s includes path components for both the day of the month and the day of the year. This is not allowed. Please choose one or the other.') % {u'param': param}) 
    188178 
    189179            # Validate that if Day is specified, Month is also 
     
    309299                foundAll = True 
    310300                for dtComp in self._DateTimeComponents: 
    311                     if dtComp not in componentAttrValues: 
     301                    if dtComp not in componentAttrValues and not (dtComp in ['Month', 'Day'] and 'DayOfYear' in componentAttrValues or dtComp == 'DayOfYear' and 'Month' in componentAttrValues and 'Day' in componentAttrValues): 
    312302                        foundAll = False 
    313303                        break 
     
    342332                        continue 
    343333                         
    344                     if 'DayOfYear' in componentAttrValues: 
     334                    if 'DayOfYear' in componentAttrValues and not ('Month' in componentAttrValues and 'Day' in componentAttrValues): 
    345335                        try: 
    346336                            dt += datetime.timedelta(days=componentAttrValues['DayOfYear'] - 1) 
  • MGET/Branches/Jason/PythonPackage/src/GeoEco/Datasets/OPeNDAP.py

    r939 r949  
    321321 
    322322    def _ConstructFoundObject(self, pathComponents, attrValues, options): 
    323         lazyPropertyValues = {} 
    324         if self.GetLazyPropertyValue('VariableNames') is not None: 
    325             lazyPropertyValues['VariableNames'] = self.GetLazyPropertyValue('VariableNames') 
    326         if self.GetLazyPropertyValue('VariableTypes') is not None: 
    327             lazyPropertyValues['VariableTypes'] = self.GetLazyPropertyValue('VariableTypes') 
    328  
    329         return OPeNDAPURL(self._OPeNDAPURLForPath['/'.join(pathComponents)], timeout=self._Timeout, maxRetryTime=self._MaxRetryTime, parentCollection=self, queryableAttributeValues=attrValues, lazyPropertyValues=lazyPropertyValues, cacheDirectory=self.CacheDirectory) 
     323        return self._ConstructOPeNDAPURL(self._OPeNDAPURLForPath['/'.join(pathComponents)], self._Timeout, self._MaxRetryTime, attrValues, self.CacheDirectory) 
     324 
     325    def _ConstructOPeNDAPURL(self, url, timeout, maxRetryTime, queryableAttributeValues, cacheDirectory): 
     326        return OPeNDAPURL(url, timeout=timeout, maxRetryTime=maxRetryTime, parentCollection=self, queryableAttributeValues=queryableAttributeValues, cacheDirectory=cacheDirectory) 
    330327 
    331328 
     
    469466            if result: 
    470467                if variableTypes[i] == 'Grid': 
    471                     datasetsFound.append(OPeNDAPGrid(self, variableNames[i], variableTypes[i])) 
     468                    datasetsFound.append(self._ConstructOPeNDAPGrid(variableNames[i], variableTypes[i])) 
    472469                else: 
    473470                    raise NotImplementedError(_(u'Only OPeNDAP Grid variables are supported at this time.')) 
     
    477474 
    478475        return datasetsFound 
     476 
     477    def _ConstructOPeNDAPGrid(self, variableName, variableType): 
     478        return OPeNDAPGrid(self, variableName, variableType) 
    479479 
    480480    def _Open(self): 
  • MGET/Branches/Jason/PythonPackage/src/GeoEco/Datasets/Virtual.py

    r939 r949  
    124124        # are stacking a collection of 2D (yx) or 3D (zyx) grids into 
    125125        # a 3D (tyx) or 4D (tzyx) stack. 
    126  
    127         if 't' not in self._CachedOldestGrid.Dimensions: 
     126        # 
     127        # As a special case, we treat a 3D (txy) or 4D (tzxy) grid 
     128        # with one time slice as a 2D (xy) or 3D (zxy) grid. 
     129 
     130        if 't' not in self._CachedOldestGrid.Dimensions or self._CachedOldestGrid.Shape[0] == 1: 
    128131 
    129132            # Handle properties that are not identical to but are 
     
    131134 
    132135            if name == 'Dimensions': 
    133                 return 't' + self._CachedOldestGrid.Dimensions 
     136                if self._CachedOldestGrid.Dimensions[0] != 't': 
     137                    return 't' + self._CachedOldestGrid.Dimensions 
     138                return self._CachedOldestGrid.Dimensions 
    134139 
    135140            if name == 'PhysicalDimensions': 
    136                 return 't' + self._CachedOldestGrid.Dimensions      # Transposing of the underlying time slices is done when we fetch each slice, thus they are all properly ordered by the time we receive them. 
     141                if self._CachedOldestGrid.Dimensions[0] != 't': 
     142                    return 't' + self._CachedOldestGrid.Dimensions      # Transposing of the underlying time slices is done when we fetch each slice, thus they are all properly ordered by the time we receive them. 
     143                return self._CachedOldestGrid.Dimensions 
    137144 
    138145            if name == 'PhysicalDimensionsFlipped': 
    139                 return tuple([False] * (len(self._CachedOldestGrid.Dimensions) + 1))      # Flipping of the underlying time slices is done when we fetch each slice, thus they are all properly oriented by the time we receive them. 
     146                if self._CachedOldestGrid.Dimensions[0] != 't': 
     147                    return tuple([False] * (len(self._CachedOldestGrid.Dimensions) + 1))      # Flipping of the underlying time slices is done when we fetch each slice, thus they are all properly oriented by the time we receive them. 
     148                return tuple([False] * len(self._CachedOldestGrid.Dimensions)) 
    140149 
    141150            if name == 'CoordDependencies': 
    142                 return tuple([None] + list(self._CachedOldestGrid.CoordDependencies)) 
     151                if self._CachedOldestGrid.Dimensions[0] != 't': 
     152                    return tuple([None] + list(self._CachedOldestGrid.CoordDependencies)) 
     153                return tuple([None] + list(self._CachedOldestGrid.CoordDependencies[1:])) 
    143154 
    144155            if name == 'CoordIncrements': 
    145                 return tuple([self._CachedOldestGrid.GetLazyPropertyValue('TIncrement')] + list(self._CachedOldestGrid.CoordIncrements)) 
     156                if self._CachedOldestGrid.Dimensions[0] != 't': 
     157                    return tuple([self._CachedOldestGrid.GetLazyPropertyValue('TIncrement')] + list(self._CachedOldestGrid.CoordIncrements)) 
     158                return tuple([self._CachedOldestGrid.GetLazyPropertyValue('TIncrement')] + list(self._CachedOldestGrid.CoordIncrements[1:])) 
    146159 
    147160            if name == 'CornerCoords': 
    148                 return tuple([self._CachedOldestGrid.GetQueryableAttributeValue(self._DateTimeAttrName)] + list(self._CachedOldestGrid.GetLazyPropertyValue('CornerCoords'))) 
     161                if self._CachedOldestGrid.Dimensions[0] != 't': 
     162                    return tuple([self._CachedOldestGrid.GetQueryableAttributeValue(self._DateTimeAttrName)] + list(self._CachedOldestGrid.GetLazyPropertyValue('CornerCoords'))) 
     163                return tuple([self._CachedOldestGrid.GetQueryableAttributeValue(self._DateTimeAttrName)] + list(self._CachedOldestGrid.GetLazyPropertyValue('CornerCoords')[1:])) 
    149164 
    150165            # Handle the shape. This is more complicated because we 
     
    229244                    # Set and return the shape. 
    230245 
    231                     shape = tuple([i+1] + list(self._CachedOldestGrid.Shape)) 
     246                    if self._CachedOldestGrid.Dimensions[0] != 't': 
     247                        shape = tuple([i+1] + list(self._CachedOldestGrid.Shape)) 
     248                    else: 
     249                        shape = tuple([i+1] + list(self._CachedOldestGrid.Shape[1:])) 
     250 
    232251                    self.SetLazyPropertyValue('Shape', shape) 
     252 
    233253                    return shape 
    234254 
     
    317337                 
    318338            if i < len(self._CachedDatasets) and self._CachedDatasets[i].GetQueryableAttributeValue(self._DateTimeAttrName) == tCoords[t]: 
    319                 data[t] = self._CachedDatasets[i].UnscaledData.__getitem__(tuple(sliceList[1:])) 
     339                if self._CachedDatasets[i].Dimensions[0] != 't': 
     340                    data[t] = self._CachedDatasets[i].UnscaledData.__getitem__(tuple(sliceList[1:])) 
     341                else: 
     342                    data[t] = self._CachedDatasets[i].UnscaledData.__getitem__(tuple([0] + sliceList[1:])) 
    320343            elif self._CachedOldestGrid.UnscaledNoDataValue is not None: 
    321344                if tCornerCoordType == 'min':