| 1 | # Datasets/HYCOM.py - Grids representing HYCOM datasets.
|
|---|
| 2 | #
|
|---|
| 3 | # Copyright (C) 2010 Jason J. Roberts
|
|---|
| 4 | #
|
|---|
| 5 | # This program is free software; you can redistribute it and/or
|
|---|
| 6 | # modify it under the terms of the GNU General Public License
|
|---|
| 7 | # as published by the Free Software Foundation; either version 2
|
|---|
| 8 | # of the License, or (at your option) any later version.
|
|---|
| 9 | #
|
|---|
| 10 | # This program is distributed in the hope that it will be useful,
|
|---|
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 13 | # GNU General Public License (available in the file LICENSE.TXT)
|
|---|
| 14 | # for more details.
|
|---|
| 15 | #
|
|---|
| 16 | # You should have received a copy of the GNU General Public License
|
|---|
| 17 | # along with this program; if not, write to the Free Software
|
|---|
| 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|---|
| 19 |
|
|---|
| 20 | import datetime
|
|---|
| 21 |
|
|---|
| 22 | from GeoEco.Datasets import Dataset, QueryableAttribute, Grid
|
|---|
| 23 | from GeoEco.Datasets.OPeNDAP import THREDDSCatalog, OPeNDAPURL, OPeNDAPGrid
|
|---|
| 24 | from GeoEco.Datasets.Virtual import TimeSeriesGridStack, GridSliceCollection, MaskedGrid, ClippedGrid, RotatedGlobalGrid
|
|---|
| 25 | from GeoEco.DynamicDocString import DynamicDocString
|
|---|
| 26 | from GeoEco.Internationalization import _
|
|---|
| 27 | from GeoEco.Types import *
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 | class _HYCOMGridGOMl0043D(OPeNDAPGrid):
|
|---|
| 31 | __doc__ = DynamicDocString()
|
|---|
| 32 |
|
|---|
| 33 | def __init__(self, url, variableName, timeout, cacheDirectory):
|
|---|
| 34 | self._CachedTCenterCoords = None
|
|---|
| 35 | super(_HYCOMGridGOMl0043D, self).__init__(OPeNDAPURL(url, timeout=timeout, cacheDirectory=cacheDirectory),
|
|---|
| 36 | variableName,
|
|---|
| 37 | 'Grid',
|
|---|
| 38 | lazyPropertyValues={'SpatialReference': Dataset.ConvertSpatialReference('proj4', '+proj=merc +ellps=sphere +a=6371001 +b=6371001', 'obj'),
|
|---|
| 39 | 'Dimensions': 'tyx',
|
|---|
| 40 | 'CoordDependencies': (None, None, None),
|
|---|
| 41 | 'CoordIncrements': (None, 4447.7949713872476, 4447.7949713872476), # t increment is None because, sadly, HYCOM omits slices when their system occasionally fails to generate data for a day
|
|---|
| 42 | 'TCornerCoordType': 'center',
|
|---|
| 43 | 'PhysicalDimensions': 'tyx',
|
|---|
| 44 | 'PhysicalDimensionsFlipped': (False, False, False),
|
|---|
| 45 | 'UnscaledDataType': 'float32',
|
|---|
| 46 | 'UnscaledNoDataValue': 1.2676506002282294e+030,
|
|---|
| 47 | 'ScalingFunction': None})
|
|---|
| 48 |
|
|---|
| 49 | def _GetLazyPropertyPhysicalValue(self, name):
|
|---|
| 50 | if name == 'CornerCoords':
|
|---|
| 51 | return (self._GetCoords('t', 0, [0], [0], -0.5), 2045985.6431758059, -10897097.679898757) # Center of lower-left cell, in degrees: 98.0 W, 18.091648101806641 N
|
|---|
| 52 | return super(_HYCOMGridGOMl0043D, self)._GetLazyPropertyPhysicalValue(name)
|
|---|
| 53 |
|
|---|
| 54 | def _GetCoords(self, coord, coordNum, slices, sliceDims, fixedIncrementOffset):
|
|---|
| 55 | if coord != 't':
|
|---|
| 56 | raise RuntimeError(_('_HYCOMGridGOMl0043D._GetCoords() called with coord == \'%(coord)s\'. This should never happen. Please contact the author of this tool for assistance.') % {u'coord': coord})
|
|---|
| 57 | if self._CachedTCenterCoords is None:
|
|---|
| 58 | import numpy
|
|---|
| 59 | self.ParentCollection._Open()
|
|---|
| 60 | self._CachedTCenterCoords = numpy.array(map(lambda days: datetime.timedelta(days) + datetime.datetime(1900, 12, 31), list(self.ParentCollection._PydapDataset['MT'][:])), dtype='object')
|
|---|
| 61 | if slices is None:
|
|---|
| 62 | result = self._CachedTCenterCoords.copy()
|
|---|
| 63 | else:
|
|---|
| 64 | result = self._CachedTCenterCoords.__getitem__(*slices)
|
|---|
| 65 | if fixedIncrementOffset != 0:
|
|---|
| 66 | result += datetime.timedelta(fixedIncrementOffset)
|
|---|
| 67 | return result
|
|---|
| 68 |
|
|---|
| 69 |
|
|---|
| 70 | class HYCOMGOMl0043D(Grid):
|
|---|
| 71 | __doc__ = DynamicDocString()
|
|---|
| 72 |
|
|---|
| 73 | def _GetVariableName(self):
|
|---|
| 74 | return self._VariableName
|
|---|
| 75 |
|
|---|
| 76 | VariableName = property(_GetVariableName, doc=DynamicDocString())
|
|---|
| 77 |
|
|---|
| 78 | def _GetStartYear(self):
|
|---|
| 79 | return self._StartYear
|
|---|
| 80 |
|
|---|
| 81 | StartYear = property(_GetStartYear, doc=DynamicDocString())
|
|---|
| 82 |
|
|---|
| 83 | def _GetEndYear(self):
|
|---|
| 84 | return self._EndYear
|
|---|
| 85 |
|
|---|
| 86 | EndYear = property(_GetEndYear, doc=DynamicDocString())
|
|---|
| 87 |
|
|---|
| 88 | def __init__(self, variableName, startYear=None, endYear=None, timeout=600, cacheDirectory=None):
|
|---|
| 89 | self.__doc__.Obj.ValidateMethodInvocation()
|
|---|
| 90 |
|
|---|
| 91 | # Perform additional validation
|
|---|
| 92 |
|
|---|
| 93 | if startYear is None:
|
|---|
| 94 | startYear = 2003
|
|---|
| 95 | elif startYear > (datetime.datetime.now() + datetime.timedelta(5)).year:
|
|---|
| 96 | raise ValueError(_(u'The start year must be less than or equal to %(max)i.') % {u'max': (datetime.datetime.now() + datetime.timedelta(5)).year})
|
|---|
| 97 |
|
|---|
| 98 | if endYear is not None and endYear < startYear:
|
|---|
| 99 | raise ValueError(_(u'The end year must be greater than or equal to the start year. If the start year is not specified, the end year must be greater than or equal to 2003.'))
|
|---|
| 100 |
|
|---|
| 101 | # Initialize our properties.
|
|---|
| 102 |
|
|---|
| 103 | self._VariableName = variableName
|
|---|
| 104 | self._StartYear = startYear
|
|---|
| 105 | self._EndYear = endYear
|
|---|
| 106 | self._Timeout = timeout
|
|---|
| 107 | self._CacheDirectory = cacheDirectory
|
|---|
| 108 | self._DisplayName = _(u'%(name)s grid of the HYCOM + NCODA Gulf of Mexico 1/25 degree Analysis (GOMl0.04) aggregated OPeNDAP datasets') % {u'name': variableName}
|
|---|
| 109 | self._OpenURL = None
|
|---|
| 110 | self._OpenGrid = None
|
|---|
| 111 |
|
|---|
| 112 | # Initialize the base class.
|
|---|
| 113 |
|
|---|
| 114 | super(HYCOMGOMl0043D, self).__init__(queryableAttributes=(QueryableAttribute(u'VariableName', _(u'Dataset variable'), UnicodeStringTypeMetadata(allowedValues=[u'emp', u'mld', u'mlp', u'qtot', u'ssh', u'surface_salinity_trend', u'surface_temperature_trend'], makeLowercase=True)),),
|
|---|
| 115 | queryableAttributeValues={u'VariableName': variableName},
|
|---|
| 116 | lazyPropertyValues={'SpatialReference': Dataset.ConvertSpatialReference('proj4', '+proj=merc +ellps=sphere +a=6371001 +b=6371001', 'obj'),
|
|---|
| 117 | 'Dimensions': u'tyx',
|
|---|
| 118 | 'CoordDependencies': (None, None, None),
|
|---|
| 119 | 'CoordIncrements': (1.0, 4447.7949713872476, 4447.7949713872476),
|
|---|
| 120 | 'TIncrementUnit': u'day',
|
|---|
| 121 | 'TSemiRegularity': None,
|
|---|
| 122 | 'TCountPerSemiRegularPeriod': None,
|
|---|
| 123 | 'TCornerCoordType': u'center',
|
|---|
| 124 | 'CornerCoords': (datetime.datetime(startYear, 1, 1), 2045985.6431758059, -10897097.679898757), # Center of lower-left cell, in degrees: 98.0 W, 18.091648101806641 N
|
|---|
| 125 | 'PhysicalDimensions': u'tyx',
|
|---|
| 126 | 'PhysicalDimensionsFlipped': (False, False, False),
|
|---|
| 127 | 'UnscaledDataType': u'float32',
|
|---|
| 128 | 'UnscaledNoDataValue': 1.2676506002282294e+030,
|
|---|
| 129 | 'ScalingFunction': None})
|
|---|
| 130 |
|
|---|
| 131 | def _GetDisplayName(self):
|
|---|
| 132 | return self._DisplayName
|
|---|
| 133 |
|
|---|
| 134 | def _GetLazyPropertyPhysicalValue(self, name):
|
|---|
| 135 |
|
|---|
| 136 | # The only property that we can retrieve here is the shape.
|
|---|
| 137 | # For the t axis, add the number of days in the years leading
|
|---|
| 138 | # up to the final year to the number of days available from
|
|---|
| 139 | # HYCOM in the final year. For the x and y axes, just use
|
|---|
| 140 | # hardcoded values.
|
|---|
| 141 |
|
|---|
| 142 | if name == 'Shape':
|
|---|
| 143 | if self._EndYear is not None and self._EndYear < datetime.datetime.now().year:
|
|---|
| 144 | return ((datetime.datetime(self._EndYear + 1, 1, 1) - datetime.datetime(self._StartYear, 1, 1)).days, 385, 541)
|
|---|
| 145 |
|
|---|
| 146 | endYearGrid = _HYCOMGridGOMl0043D('http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_30.1/%i' % datetime.datetime.now().year, self._VariableName, self._Timeout, self._CacheDirectory)
|
|---|
| 147 | endDay = endYearGrid.CenterCoords['t', -1]
|
|---|
| 148 |
|
|---|
| 149 | if endDay.month == 12 and endDay.day == 31:
|
|---|
| 150 | endYearGrid = _HYCOMGridGOMl0043D('http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_30.1/%i' % datetime.datetime.now().year + 1, self._VariableName, self._Timeout, self._CacheDirectory)
|
|---|
| 151 | endDay = endYearGrid.CenterCoords['t', -1]
|
|---|
| 152 |
|
|---|
| 153 | return ((endDay - datetime.datetime(self._StartYear, 1, 1)).days + 1, 385, 541)
|
|---|
| 154 |
|
|---|
| 155 | raise AttributeError(_(u'\'%(class)s\' object has no lazy property named \'%(name)s\'') % {u'class': self.__class__.__name__, u'name': name})
|
|---|
| 156 |
|
|---|
| 157 | def _ReadNumpyArray(self, sliceList):
|
|---|
| 158 |
|
|---|
| 159 | # For many OPeNDAP datasets, we would be able to request the
|
|---|
| 160 | # entire 3D slab directly. This won't work for the HYCOM
|
|---|
| 161 | # GOMl0.04 dataset, for two reasons: 1) The dataset is split
|
|---|
| 162 | # OPeNDAP URLs for each year, and 2) HYCOM omits slices when
|
|---|
| 163 | # their system occasionally fails to generate data for a day,
|
|---|
| 164 | # so most years do not have a full 365 (or 366) slices. To
|
|---|
| 165 | # deal with this, we have to loop over the requested range of
|
|---|
| 166 | # time indices and issue OPeNDAP requests to the proper URLs
|
|---|
| 167 | # and per-URL time indices.
|
|---|
| 168 | #
|
|---|
| 169 | # First, allocate the array we will return. We'll populate
|
|---|
| 170 | # this as we go along. (I prefer this approach rather than
|
|---|
| 171 | # growing an array through concatenation because it avoids
|
|---|
| 172 | # repeatedly allocating and copying memory.)
|
|---|
| 173 |
|
|---|
| 174 | import numpy
|
|---|
| 175 | result = numpy.zeros((sliceList[0].stop - sliceList[0].start, sliceList[1].stop - sliceList[1].start, sliceList[2].stop - sliceList[2].start), dtype=str(self.UnscaledDataType))
|
|---|
| 176 |
|
|---|
| 177 | # Loop over the requested t indices, populating the result
|
|---|
| 178 | # array.
|
|---|
| 179 |
|
|---|
| 180 | i = 0
|
|---|
| 181 | tCoords = self.CenterCoords['t', sliceList[0]]
|
|---|
| 182 |
|
|---|
| 183 | while i < len(tCoords):
|
|---|
| 184 |
|
|---|
| 185 | # Open the _HYCOMGridGOMl0043D for the next block of t
|
|---|
| 186 | # coordinates. These grids are 1 year long, except in 2010
|
|---|
| 187 | # when HYCOM switched to an improved configuration after
|
|---|
| 188 | # six months.
|
|---|
| 189 |
|
|---|
| 190 | if tCoords[i] < datetime.datetime(2010, 7, 1):
|
|---|
| 191 | url = 'http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_20.1/%i' % tCoords[i].year
|
|---|
| 192 | else:
|
|---|
| 193 | url = 'http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_30.1/%i' % tCoords[i].year
|
|---|
| 194 |
|
|---|
| 195 | if self._OpenURL != url:
|
|---|
| 196 | self._OpenGrid = _HYCOMGridGOMl0043D(url, self._VariableName, self._Timeout, self._CacheDirectory)
|
|---|
| 197 | self._OpenURL = url
|
|---|
| 198 |
|
|---|
| 199 | if tCoords[i] >= datetime.datetime(2010, 1, 1) and tCoords[i] <= datetime.datetime(2010, 6, 30):
|
|---|
| 200 | lastDayOfDataset = datetime.datetime(2010, 6, 30)
|
|---|
| 201 | else:
|
|---|
| 202 | lastDayOfDataset = datetime.datetime(tCoords[i].year, 12, 31)
|
|---|
| 203 |
|
|---|
| 204 | # Read the necessary data from this grid as one 3D slab.
|
|---|
| 205 |
|
|---|
| 206 | import bisect
|
|---|
| 207 |
|
|---|
| 208 | gridTStart = bisect.bisect_left(self._OpenGrid.CenterCoords['t'].tolist(), tCoords[i])
|
|---|
| 209 | gridTStop = bisect.bisect_right(self._OpenGrid.CenterCoords['t'].tolist(), tCoords[-1])
|
|---|
| 210 | gridTCoords = self._OpenGrid.CenterCoords['t', gridTStart:gridTStop]
|
|---|
| 211 | data = self._OpenGrid.UnscaledData.__getitem__((slice(gridTStart, gridTStop), sliceList[1], sliceList[2]))
|
|---|
| 212 |
|
|---|
| 213 | # Iterate through the t indices, copying out time slices
|
|---|
| 214 | # when they are available, otherwise setting slices to the
|
|---|
| 215 | # UnscaledNoDataValue.
|
|---|
| 216 |
|
|---|
| 217 | j = 0
|
|---|
| 218 |
|
|---|
| 219 | while i < len(tCoords) and tCoords[i] <= lastDayOfDataset:
|
|---|
| 220 | if j < len(gridTCoords) and gridTCoords[j] == tCoords[i]:
|
|---|
| 221 | result[i] = data[j]
|
|---|
| 222 | j += 1
|
|---|
| 223 | else:
|
|---|
| 224 | result[i] = self.UnscaledNoDataValue
|
|---|
| 225 | i += 1
|
|---|
| 226 |
|
|---|
| 227 | # Return successfully.
|
|---|
| 228 |
|
|---|
| 229 | return result, self.UnscaledNoDataValue
|
|---|
| 230 |
|
|---|
| 231 | @classmethod
|
|---|
| 232 | def CreateArcGISRasters(cls, variableName,
|
|---|
| 233 | outputWorkspace, mode=u'add', rasterNameExpressions=['%(VariableName)s', '%%Y', '%(VariableName)s_%%Y%%j.img'],
|
|---|
| 234 | spatialExtent=None, linearUnit=u'Degrees', startDate=None, endDate=None,
|
|---|
| 235 | timeout=600, cacheDirectory=None,
|
|---|
| 236 | calculateStatistics=True, buildPyramids=False):
|
|---|
| 237 | cls.__doc__.Obj.ValidateMethodInvocation()
|
|---|
| 238 |
|
|---|
| 239 | # Construct a HYCOMGOMl0043D and clip it if requested.
|
|---|
| 240 |
|
|---|
| 241 | if startDate is not None:
|
|---|
| 242 | startYear = startDate.year
|
|---|
| 243 | else:
|
|---|
| 244 | startYear = None
|
|---|
| 245 |
|
|---|
| 246 | if endDate is not None:
|
|---|
| 247 | endYear = endDate.year
|
|---|
| 248 | else:
|
|---|
| 249 | endYear = None
|
|---|
| 250 |
|
|---|
| 251 | grid = HYCOMGOMl0043D(variableName, startYear=startYear, endYear=endYear, timeout=timeout, cacheDirectory=cacheDirectory)
|
|---|
| 252 |
|
|---|
| 253 | xMin, yMin, xMax, yMax = None, None, None, None
|
|---|
| 254 | if spatialExtent is not None:
|
|---|
| 255 | from GeoEco.Types import EnvelopeTypeMetadata
|
|---|
| 256 | xMin, yMin, xMax, yMax = EnvelopeTypeMetadata.ParseFromArcGISString(spatialExtent)
|
|---|
| 257 |
|
|---|
| 258 | if linearUnit == u'Degrees':
|
|---|
| 259 | osr = cls._osr()
|
|---|
| 260 | transformer = osr.CoordinateTransformation(Dataset.ConvertSpatialReference('proj4', '+proj=latlong +ellps=sphere +a=6371001 +b=6371001', 'obj'), grid.GetSpatialReference('obj'))
|
|---|
| 261 | xMin, yMin = transformer.TransformPoint(xMin, yMin)
|
|---|
| 262 | xMax, yMax = transformer.TransformPoint(xMax, yMax)
|
|---|
| 263 |
|
|---|
| 264 | cls._LogWarning(_(u'The HYCOM OPeNDAP server often requires five to ten minutes to return the first time slice. Please be patient. This tool cannot be cancelled until the first one is returned. After the first one is returned, the rest will go much faster and you will be able to cancel the tool, if desired. If this tool fails with to a timeout error, increase the timeout value and try again.'))
|
|---|
| 265 |
|
|---|
| 266 | if spatialExtent is not None or startDate is not None or endDate is not None:
|
|---|
| 267 | grid = ClippedGrid(grid, u'Map coordinates', xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, tMin=startDate, tMax=endDate)
|
|---|
| 268 |
|
|---|
| 269 | # Construct an ArcGISWorkspace instance and import time slices
|
|---|
| 270 | # from the HYCOMGOMl0043D instance.
|
|---|
| 271 |
|
|---|
| 272 | from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISRaster
|
|---|
| 273 |
|
|---|
| 274 | workspace = ArcGISWorkspace(outputWorkspace,
|
|---|
| 275 | ArcGISRaster,
|
|---|
| 276 | pathCreationExpressions=rasterNameExpressions,
|
|---|
| 277 | cacheTree=True,
|
|---|
| 278 | queryableAttributes=(QueryableAttribute(u'VariableName', _(u'Variable'), UnicodeStringTypeMetadata(allowedValues=[u'emp', u'mld', u'mlp', u'qtot', u'ssh', u'surface_salinity_trend', u'surface_temperature_trend'], makeLowercase=True)),
|
|---|
| 279 | QueryableAttribute(u'DateTime', _(u'Date'), DateTimeTypeMetadata())))
|
|---|
| 280 |
|
|---|
| 281 | workspace.ImportDatasets(GridSliceCollection(grid, tQACoordType=u'center').QueryDatasets(), mode, calculateStatistics=calculateStatistics, buildPyramids=buildPyramids)
|
|---|
| 282 |
|
|---|
| 283 | # Return successfully.
|
|---|
| 284 |
|
|---|
| 285 | return outputWorkspace
|
|---|
| 286 |
|
|---|
| 287 |
|
|---|
| 288 | class _HYCOMGridGOMl0044D(OPeNDAPGrid):
|
|---|
| 289 | __doc__ = DynamicDocString()
|
|---|
| 290 |
|
|---|
| 291 | def __init__(self, url, variableName, timeout, cacheDirectory):
|
|---|
| 292 | self._CachedTCenterCoords = None
|
|---|
| 293 | super(_HYCOMGridGOMl0044D, self).__init__(OPeNDAPURL(url, timeout=timeout, cacheDirectory=cacheDirectory),
|
|---|
| 294 | variableName,
|
|---|
| 295 | 'Grid',
|
|---|
| 296 | lazyPropertyValues={'SpatialReference': Dataset.ConvertSpatialReference('proj4', '+proj=merc +ellps=sphere +a=6371001 +b=6371001', 'obj'),
|
|---|
| 297 | 'Dimensions': 'tzyx',
|
|---|
| 298 | 'CoordDependencies': (None, None, None, None),
|
|---|
| 299 | 'CoordIncrements': (None, None, 4447.7949713872476, 4447.7949713872476), # t increment is None because, sadly, HYCOM omits slices when their system occasionally fails to generate data for a day
|
|---|
| 300 | 'TCornerCoordType': 'center',
|
|---|
| 301 | 'PhysicalDimensions': 'tzyx',
|
|---|
| 302 | 'PhysicalDimensionsFlipped': (False, False, False, False),
|
|---|
| 303 | 'UnscaledDataType': 'float32',
|
|---|
| 304 | 'UnscaledNoDataValue': 1.2676506002282294e+030,
|
|---|
| 305 | 'ScalingFunction': None})
|
|---|
| 306 |
|
|---|
| 307 | def _GetLazyPropertyPhysicalValue(self, name):
|
|---|
| 308 | if name == 'CornerCoords':
|
|---|
| 309 | return (self._GetCoords('t', 0, [0], [0], -0.5), 0.0, 2045985.6431758059, -10897097.679898757) # Center of lower-left cell, in degrees: 98.0 W, 18.091648101806641 N
|
|---|
| 310 | return super(_HYCOMGridGOMl0044D, self)._GetLazyPropertyPhysicalValue(name)
|
|---|
| 311 |
|
|---|
| 312 | def _GetCoords(self, coord, coordNum, slices, sliceDims, fixedIncrementOffset):
|
|---|
| 313 | if coord not in ['t', 'z']:
|
|---|
| 314 | raise RuntimeError(_('_HYCOMGridGOMl0044D._GetCoords() called with coord == \'%(coord)s\'. This should never happen. Please contact the author of this tool for assistance.') % {u'coord': coord})
|
|---|
| 315 |
|
|---|
| 316 | import numpy
|
|---|
| 317 |
|
|---|
| 318 | if coord == 't':
|
|---|
| 319 | if self._CachedTCenterCoords is None:
|
|---|
| 320 | self.ParentCollection._Open()
|
|---|
| 321 | self._CachedTCenterCoords = numpy.array(map(lambda days: datetime.timedelta(days) + datetime.datetime(1900, 12, 31), list(self.ParentCollection._PydapDataset['MT'][:])), dtype='object')
|
|---|
| 322 | if slices is None:
|
|---|
| 323 | result = self._CachedTCenterCoords.copy()
|
|---|
| 324 | else:
|
|---|
| 325 | result = self._CachedTCenterCoords.__getitem__(*slices)
|
|---|
| 326 | if fixedIncrementOffset != 0:
|
|---|
| 327 | result += datetime.timedelta(fixedIncrementOffset)
|
|---|
| 328 | return result
|
|---|
| 329 |
|
|---|
| 330 | zCoords = [0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 125.0, 150.0, 200.0, 250.0, 300.0, 400.0, 500.0, 600.0, 700.0, 800.0, 900.0, 1000.0, 1100.0, 1200.0, 1300.0, 1400.0, 1500.0, 1750.0, 2000.0, 2500.0, 3000.0, 3500.0, 4000.0, 4500.0, 5000.0, 5500.0]
|
|---|
| 331 | if fixedIncrementOffset == -0.5:
|
|---|
| 332 | zCoords = [0.0] + map(lambda a, b: (a+b)/2., zCoords[:-1], zCoords[1:])
|
|---|
| 333 | elif fixedIncrementOffset == 0.5:
|
|---|
| 334 | zCoords = map(lambda a, b: (a+b)/2., zCoords[:-1], zCoords[1:]) + [11000.0]
|
|---|
| 335 | if slices is None:
|
|---|
| 336 | return numpy.array(zCoords)
|
|---|
| 337 | return numpy.array(zCoords).__getitem__(*slices)
|
|---|
| 338 |
|
|---|
| 339 |
|
|---|
| 340 | class HYCOMGOMl0044D(Grid):
|
|---|
| 341 | __doc__ = DynamicDocString()
|
|---|
| 342 |
|
|---|
| 343 | def _GetVariableName(self):
|
|---|
| 344 | return self._VariableName
|
|---|
| 345 |
|
|---|
| 346 | VariableName = property(_GetVariableName, doc=DynamicDocString())
|
|---|
| 347 |
|
|---|
| 348 | def _GetStartYear(self):
|
|---|
| 349 | return self._StartYear
|
|---|
| 350 |
|
|---|
| 351 | StartYear = property(_GetStartYear, doc=DynamicDocString())
|
|---|
| 352 |
|
|---|
| 353 | def _GetEndYear(self):
|
|---|
| 354 | return self._EndYear
|
|---|
| 355 |
|
|---|
| 356 | EndYear = property(_GetEndYear, doc=DynamicDocString())
|
|---|
| 357 |
|
|---|
| 358 | def __init__(self, variableName, startYear=None, endYear=None, timeout=600, cacheDirectory=None):
|
|---|
| 359 | self.__doc__.Obj.ValidateMethodInvocation()
|
|---|
| 360 |
|
|---|
| 361 | # Perform additional validation
|
|---|
| 362 |
|
|---|
| 363 | if startYear is None:
|
|---|
| 364 | startYear = 2003
|
|---|
| 365 | elif startYear > (datetime.datetime.now() + datetime.timedelta(5)).year:
|
|---|
| 366 | raise ValueError(_(u'The start year must be less than or equal to %(max)i.') % {u'max': (datetime.datetime.now() + datetime.timedelta(5)).year})
|
|---|
| 367 |
|
|---|
| 368 | if endYear is not None and endYear < startYear:
|
|---|
| 369 | raise ValueError(_(u'The end year must be greater than or equal to the start year. If the start year is not specified, the end year must be greater than or equal to 2003.'))
|
|---|
| 370 |
|
|---|
| 371 | # Initialize our properties.
|
|---|
| 372 |
|
|---|
| 373 | self._VariableName = variableName
|
|---|
| 374 | self._StartYear = startYear
|
|---|
| 375 | self._EndYear = endYear
|
|---|
| 376 | self._Timeout = timeout
|
|---|
| 377 | self._CacheDirectory = cacheDirectory
|
|---|
| 378 | self._DisplayName = _(u'%(name)s grid of the HYCOM + NCODA Gulf of Mexico 1/25 degree Analysis (GOMl0.04) aggregated OPeNDAP datasets') % {u'name': variableName}
|
|---|
| 379 | self._OpenURL = None
|
|---|
| 380 | self._OpenGrid = None
|
|---|
| 381 |
|
|---|
| 382 | # Initialize the base class.
|
|---|
| 383 |
|
|---|
| 384 | super(HYCOMGOMl0044D, self).__init__(queryableAttributes=(QueryableAttribute(u'VariableName', _(u'Dataset variable'), UnicodeStringTypeMetadata(allowedValues=[u'salinity', u'temperature', u'u', u'v', u'w'], makeLowercase=True)),),
|
|---|
| 385 | queryableAttributeValues={u'VariableName': variableName},
|
|---|
| 386 | lazyPropertyValues={'SpatialReference': Dataset.ConvertSpatialReference('proj4', '+proj=merc +ellps=sphere +a=6371001 +b=6371001', 'obj'),
|
|---|
| 387 | 'Dimensions': u'tzyx',
|
|---|
| 388 | 'CoordDependencies': (None, None, None, None),
|
|---|
| 389 | 'CoordIncrements': (1.0, None, 4447.7949713872476, 4447.7949713872476),
|
|---|
| 390 | 'TIncrementUnit': u'day',
|
|---|
| 391 | 'TSemiRegularity': None,
|
|---|
| 392 | 'TCountPerSemiRegularPeriod': None,
|
|---|
| 393 | 'TCornerCoordType': u'center',
|
|---|
| 394 | 'CornerCoords': (datetime.datetime(startYear, 1, 1), 0.0, 2045985.6431758059, -10897097.679898757), # Center of lower-left cell, in degrees: 98.0 W, 18.091648101806641 N
|
|---|
| 395 | 'PhysicalDimensions': u'tzyx',
|
|---|
| 396 | 'PhysicalDimensionsFlipped': (False, False, False, False),
|
|---|
| 397 | 'UnscaledDataType': u'float32',
|
|---|
| 398 | 'UnscaledNoDataValue': 1.2676506002282294e+030,
|
|---|
| 399 | 'ScalingFunction': None})
|
|---|
| 400 |
|
|---|
| 401 | def _GetDisplayName(self):
|
|---|
| 402 | return self._DisplayName
|
|---|
| 403 |
|
|---|
| 404 | def _GetLazyPropertyPhysicalValue(self, name):
|
|---|
| 405 |
|
|---|
| 406 | # The only property that we can retrieve here is the shape.
|
|---|
| 407 | # For the t axis, add the number of days in the years leading
|
|---|
| 408 | # up to the final year to the number of days available from
|
|---|
| 409 | # HYCOM in the final year. For the x and y axes, just use
|
|---|
| 410 | # hardcoded values.
|
|---|
| 411 |
|
|---|
| 412 | if name == 'Shape':
|
|---|
| 413 | if self._EndYear is not None and self._EndYear < datetime.datetime.now().year:
|
|---|
| 414 | return ((datetime.datetime(self._EndYear + 1, 1, 1) - datetime.datetime(self._StartYear, 1, 1)).days, 40, 385, 541)
|
|---|
| 415 |
|
|---|
| 416 | endYearGrid = _HYCOMGridGOMl0044D('http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_30.1/%i' % datetime.datetime.now().year, self._VariableName, self._Timeout, self._CacheDirectory)
|
|---|
| 417 | endDay = endYearGrid.CenterCoords['t', -1]
|
|---|
| 418 |
|
|---|
| 419 | if endDay.month == 12 and endDay.day == 31:
|
|---|
| 420 | endYearGrid = _HYCOMGridGOMl0044D('http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_30.1/%i' % datetime.datetime.now().year + 1, self._VariableName, self._Timeout, self._CacheDirectory)
|
|---|
| 421 | endDay = endYearGrid.CenterCoords['t', -1]
|
|---|
| 422 |
|
|---|
| 423 | return ((endDay - datetime.datetime(self._StartYear, 1, 1)).days + 1, 40, 385, 541)
|
|---|
| 424 |
|
|---|
| 425 | raise AttributeError(_(u'\'%(class)s\' object has no lazy property named \'%(name)s\'') % {u'class': self.__class__.__name__, u'name': name})
|
|---|
| 426 |
|
|---|
| 427 | def _GetCoords(self, coord, coordNum, slices, sliceDims, fixedIncrementOffset):
|
|---|
| 428 | if coord != 'z':
|
|---|
| 429 | raise RuntimeError(_('HYCOMGOMl0044D._GetCoords() called with coord == \'%(coord)s\'. This should never happen. Please contact the author of this tool for assistance.') % {u'coord': coord})
|
|---|
| 430 | zCoords = [0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 125.0, 150.0, 200.0, 250.0, 300.0, 400.0, 500.0, 600.0, 700.0, 800.0, 900.0, 1000.0, 1100.0, 1200.0, 1300.0, 1400.0, 1500.0, 1750.0, 2000.0, 2500.0, 3000.0, 3500.0, 4000.0, 4500.0, 5000.0, 5500.0]
|
|---|
| 431 | if fixedIncrementOffset == -0.5:
|
|---|
| 432 | zCoords = [0.0] + map(lambda a, b: (a+b)/2., zCoords[:-1], zCoords[1:])
|
|---|
| 433 | elif fixedIncrementOffset == 0.5:
|
|---|
| 434 | zCoords = map(lambda a, b: (a+b)/2., zCoords[:-1], zCoords[1:]) + [11000.0]
|
|---|
| 435 | import numpy
|
|---|
| 436 | if slices is None:
|
|---|
| 437 | return numpy.array(zCoords)
|
|---|
| 438 | return numpy.array(zCoords).__getitem__(*slices)
|
|---|
| 439 |
|
|---|
| 440 | def _ReadNumpyArray(self, sliceList):
|
|---|
| 441 |
|
|---|
| 442 | # For many OPeNDAP datasets, we would be able to request the
|
|---|
| 443 | # entire 4D slab directly. This won't work for the HYCOM
|
|---|
| 444 | # GOMl0.04 dataset, for two reasons: 1) The dataset is split
|
|---|
| 445 | # OPeNDAP URLs for each year, and 2) HYCOM omits slices when
|
|---|
| 446 | # their system occasionally fails to generate data for a day,
|
|---|
| 447 | # so most years do not have a full 365 (or 366) slices. To
|
|---|
| 448 | # deal with this, we have to loop over the requested range of
|
|---|
| 449 | # time indices and issue OPeNDAP requests to the proper URLs
|
|---|
| 450 | # and per-URL time indices.
|
|---|
| 451 | #
|
|---|
| 452 | # First, allocate the array we will return. We'll populate
|
|---|
| 453 | # this as we go along. (I prefer this approach rather than
|
|---|
| 454 | # growing an array through concatenation because it avoids
|
|---|
| 455 | # repeatedly allocating and copying memory.)
|
|---|
| 456 |
|
|---|
| 457 | import numpy
|
|---|
| 458 | result = numpy.zeros((sliceList[0].stop - sliceList[0].start, sliceList[1].stop - sliceList[1].start, sliceList[2].stop - sliceList[2].start, sliceList[3].stop - sliceList[3].start), dtype=str(self.UnscaledDataType))
|
|---|
| 459 |
|
|---|
| 460 | # Loop over the requested t indices, populating the result
|
|---|
| 461 | # array.
|
|---|
| 462 |
|
|---|
| 463 | i = 0
|
|---|
| 464 | tCoords = self.CenterCoords['t', sliceList[0]]
|
|---|
| 465 |
|
|---|
| 466 | while i < len(tCoords):
|
|---|
| 467 |
|
|---|
| 468 | # Open the _HYCOMGridGOMl0044D for the next block of t
|
|---|
| 469 | # coordinates. These grids are 1 year long, except in 2010
|
|---|
| 470 | # when HYCOM switched to an improved configuration after
|
|---|
| 471 | # five months.
|
|---|
| 472 |
|
|---|
| 473 | if tCoords[i] < datetime.datetime(2010, 7, 1):
|
|---|
| 474 | url = 'http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_20.1/%i' % tCoords[i].year
|
|---|
| 475 | else:
|
|---|
| 476 | url = 'http://tds.hycom.org/thredds/dodsC/GOMl0.04/expt_30.1/%i' % tCoords[i].year
|
|---|
| 477 |
|
|---|
| 478 | if self._OpenURL != url:
|
|---|
| 479 | self._OpenGrid = _HYCOMGridGOMl0044D(url, self._VariableName, self._Timeout, self._CacheDirectory)
|
|---|
| 480 | self._OpenURL = url
|
|---|
| 481 |
|
|---|
| 482 | if tCoords[i] >= datetime.datetime(2010, 1, 1) and tCoords[i] <= datetime.datetime(2010, 6, 30):
|
|---|
| 483 | lastDayOfDataset = datetime.datetime(2010, 6, 30)
|
|---|
| 484 | else:
|
|---|
| 485 | lastDayOfDataset = datetime.datetime(tCoords[i].year, 12, 31)
|
|---|
| 486 |
|
|---|
| 487 | # Read the necessary data from this grid as one 4D slab.
|
|---|
| 488 |
|
|---|
| 489 | import bisect
|
|---|
| 490 |
|
|---|
| 491 | gridTStart = bisect.bisect_left(self._OpenGrid.CenterCoords['t'].tolist(), tCoords[i])
|
|---|
| 492 | gridTStop = bisect.bisect_right(self._OpenGrid.CenterCoords['t'].tolist(), tCoords[-1])
|
|---|
| 493 | gridTCoords = self._OpenGrid.CenterCoords['t', gridTStart:gridTStop]
|
|---|
| 494 | data = self._OpenGrid.UnscaledData.__getitem__((slice(gridTStart, gridTStop), sliceList[1], sliceList[2], sliceList[3]))
|
|---|
| 495 |
|
|---|
| 496 | # Iterate through the t indices, copying out time slices
|
|---|
| 497 | # when they are available, otherwise setting slices to the
|
|---|
| 498 | # UnscaledNoDataValue.
|
|---|
| 499 |
|
|---|
| 500 | j = 0
|
|---|
| 501 |
|
|---|
| 502 | while i < len(tCoords) and tCoords[i] <= lastDayOfDataset:
|
|---|
| 503 | if j < len(gridTCoords) and gridTCoords[j] == tCoords[i]:
|
|---|
| 504 | result[i] = data[j]
|
|---|
| 505 | j += 1
|
|---|
| 506 | else:
|
|---|
| 507 | result[i] = self.UnscaledNoDataValue
|
|---|
| 508 | i += 1
|
|---|
| 509 |
|
|---|
| 510 | # Return successfully.
|
|---|
| 511 |
|
|---|
| 512 | return result, self.UnscaledNoDataValue
|
|---|
| 513 |
|
|---|
| 514 | @classmethod
|
|---|
| 515 | def CreateArcGISRasters(cls, variableName,
|
|---|
| 516 | outputWorkspace, mode=u'add', rasterNameExpressions=['%(VariableName)s', '%%Y', 'Depth_%(Depth)04.0fm', '%(VariableName)s_%%Y%%j_%(Depth)04.0fm.img'],
|
|---|
| 517 | spatialExtent=None, linearUnit=u'Degrees', minDepth=None, maxDepth=None, startDate=None, endDate=None,
|
|---|
| 518 | timeout=600, cacheDirectory=None,
|
|---|
| 519 | calculateStatistics=True, buildPyramids=False):
|
|---|
| 520 | cls.__doc__.Obj.ValidateMethodInvocation()
|
|---|
| 521 |
|
|---|
| 522 | # Construct a HYCOMGOMl0044D and clip it if requested.
|
|---|
| 523 |
|
|---|
| 524 | if startDate is not None:
|
|---|
| 525 | startYear = startDate.year
|
|---|
| 526 | else:
|
|---|
| 527 | startYear = None
|
|---|
| 528 |
|
|---|
| 529 | if endDate is not None:
|
|---|
| 530 | endYear = endDate.year
|
|---|
| 531 | else:
|
|---|
| 532 | endYear = None
|
|---|
| 533 |
|
|---|
| 534 | grid = HYCOMGOMl0044D(variableName, startYear=startYear, endYear=endYear, timeout=timeout, cacheDirectory=cacheDirectory)
|
|---|
| 535 |
|
|---|
| 536 | xMin, yMin, xMax, yMax = None, None, None, None
|
|---|
| 537 | if spatialExtent is not None:
|
|---|
| 538 | from GeoEco.Types import EnvelopeTypeMetadata
|
|---|
| 539 | xMin, yMin, xMax, yMax = EnvelopeTypeMetadata.ParseFromArcGISString(spatialExtent)
|
|---|
| 540 |
|
|---|
| 541 | if linearUnit == u'Degrees':
|
|---|
| 542 | osr = cls._osr()
|
|---|
| 543 | transformer = osr.CoordinateTransformation(Dataset.ConvertSpatialReference('proj4', '+proj=latlong +ellps=sphere +a=6371001 +b=6371001', 'obj'), grid.GetSpatialReference('obj'))
|
|---|
| 544 | xMin, yMin = transformer.TransformPoint(xMin, yMin)
|
|---|
| 545 | xMax, yMax = transformer.TransformPoint(xMax, yMax)
|
|---|
| 546 |
|
|---|
| 547 | cls._LogWarning(_(u'The HYCOM OPeNDAP server often requires five to ten minutes to return the first time slice. Please be patient. This tool cannot be cancelled until the first one is returned. After the first one is returned, the rest will go much faster and you will be able to cancel the tool, if desired. If this tool fails with to a timeout error, increase the timeout value and try again.'))
|
|---|
| 548 |
|
|---|
| 549 | if spatialExtent is not None or minDepth is not None or maxDepth is not None or startDate is not None or endDate is not None:
|
|---|
| 550 | grid = ClippedGrid(grid, u'Map coordinates', xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, zMin=minDepth, zMax=maxDepth, tMin=startDate, tMax=endDate)
|
|---|
| 551 |
|
|---|
| 552 | # Construct an ArcGISWorkspace instance and import time slices
|
|---|
| 553 | # from the HYCOMGOMl0044D instance.
|
|---|
| 554 |
|
|---|
| 555 | from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISRaster
|
|---|
| 556 |
|
|---|
| 557 | workspace = ArcGISWorkspace(outputWorkspace,
|
|---|
| 558 | ArcGISRaster,
|
|---|
| 559 | pathCreationExpressions=rasterNameExpressions,
|
|---|
| 560 | cacheTree=True,
|
|---|
| 561 | queryableAttributes=(QueryableAttribute(u'VariableName', _(u'Variable'), UnicodeStringTypeMetadata(allowedValues=[u'salinity', u'temperature', u'u', u'v', u'w'], makeLowercase=True)),
|
|---|
| 562 | QueryableAttribute(u'DateTime', _(u'Date'), DateTimeTypeMetadata()),
|
|---|
| 563 | QueryableAttribute(u'Depth', _(u'Depth'), FloatTypeMetadata())))
|
|---|
| 564 |
|
|---|
| 565 | workspace.ImportDatasets(GridSliceCollection(grid, tQACoordType=u'center', zQACoordType=u'center').QueryDatasets(), mode, calculateStatistics=calculateStatistics, buildPyramids=buildPyramids)
|
|---|
| 566 |
|
|---|
| 567 | # Return successfully.
|
|---|
| 568 |
|
|---|
| 569 | return outputWorkspace
|
|---|
| 570 |
|
|---|
| 571 |
|
|---|
| 572 | ###############################################################################
|
|---|
| 573 | # Metadata: module
|
|---|
| 574 | ###############################################################################
|
|---|
| 575 |
|
|---|
| 576 | from GeoEco.ArcGIS import ArcGISDependency
|
|---|
| 577 | from GeoEco.Dependencies import PythonAggregatedModuleDependency
|
|---|
| 578 | from GeoEco.Datasets.ArcGIS import _UseUnscaledDataDescription, _CalculateStatisticsDescription, _BuildRATDescription, _BuildPyramidsDescription
|
|---|
| 579 | from GeoEco.Metadata import *
|
|---|
| 580 | from GeoEco.Types import *
|
|---|
| 581 |
|
|---|
| 582 | AddModuleMetadata(shortDescription=_(u'Grids representing HYCOM datasets.'))
|
|---|
| 583 |
|
|---|
| 584 | ###############################################################################
|
|---|
| 585 | # Metadata: _HYCOMGridGOMl0043D class
|
|---|
| 586 | ###############################################################################
|
|---|
| 587 |
|
|---|
| 588 | AddClassMetadata(_HYCOMGridGOMl0043D,
|
|---|
| 589 | shortDescription=_(u'An OPeNDAPGrid for a 3D variable of a HYCOM GOMl0.04 OPeNDAP URL.')
|
|---|
| 590 | longDescription=_(
|
|---|
| 591 | u"""This class is intended for private use within GeoEco and is not
|
|---|
| 592 | intended for external callers."""))
|
|---|
| 593 |
|
|---|
| 594 | ###############################################################################
|
|---|
| 595 | # Metadata: HYCOMGOMl0043D class
|
|---|
| 596 | ###############################################################################
|
|---|
| 597 |
|
|---|
| 598 | _HYCOMGOMl004_LongDescription = _(
|
|---|
| 599 | u"""At the time this %(name)s was developed, the
|
|---|
| 600 | `HYCOM + NCODA Gulf of Mexico 1/25 Degree Analysis (GLMl0.04) <http://www.hycom.org/dataserver/goml0pt04/>`_
|
|---|
| 601 | consisted of two gridded datasets:
|
|---|
| 602 |
|
|---|
| 603 | * expt_20.1 - The 20.1 experiment running from 1 January 2003 through
|
|---|
| 604 | 30 June 2010.
|
|---|
| 605 |
|
|---|
| 606 | * expt_30.1 - The 30.1 experiment running from 1 July 2010 and running
|
|---|
| 607 | to the present day plus five days.
|
|---|
| 608 |
|
|---|
| 609 | The datasets have identical spatiotemporal extents and resolutions and
|
|---|
| 610 | the same oceanographic variables. This %(name)s treats them as one
|
|---|
| 611 | continuous dataset and takes time slices prior to 1 July 2010 from
|
|---|
| 612 | expt_20.1 and on or after that date from expt_30.1. (On the HYCOM
|
|---|
| 613 | server, the datasets actually overlap slightly, with expt_20.1 ending
|
|---|
| 614 | slightly after 30 June 2010 and expt_30.1 starting slightly before 1
|
|---|
| 615 | July 2010. The %(name)s ignores the overlapping time slices and
|
|---|
| 616 | switches from expt_20.1 to expt_30.1 on 1 July.)
|
|---|
| 617 |
|
|---|
| 618 | The grids are in Mercator projection based on a sphere with radius
|
|---|
| 619 | 6371001 m, with square cells approximately 4.5 km on a side. The
|
|---|
| 620 | geographic extent is approximately 98 to 76 W, 18 to 32 N. The time
|
|---|
| 621 | step is 1 day, with time slices representing the instantaneous
|
|---|
| 622 | condition of the ocean estimated at 00:00 UTC on each day.
|
|---|
| 623 |
|
|---|
| 624 | The HYCOM documentation states that HYCOM provides a five day forecast
|
|---|
| 625 | and five day hindcast from the current date, although we have
|
|---|
| 626 | regularly observed netCDF files on their servers that suggested this
|
|---|
| 627 | window actually extends seven days in both directions. HYCOM revises
|
|---|
| 628 | the data within this window daily, using the latest ocean observations
|
|---|
| 629 | assimilated from buoys, satellites, and other sensors. Use caution
|
|---|
| 630 | when working with time slices close to the current date, as it appears
|
|---|
| 631 | that time slices continue to be revised until they are 7 days older
|
|---|
| 632 | than the current date.
|
|---|
| 633 |
|
|---|
| 634 | Occasionally, HYCOM fails to generate data for a time slice,
|
|---|
| 635 | presumably due to an outage or other problem in their data processing
|
|---|
| 636 | infrastructure. For example, in 2004, HYCOM failed to generate data
|
|---|
| 637 | for three of the 366 time slices of that year. Although HYCOM omits
|
|---|
| 638 | these time slices from their server, this %(name)s represents them as
|
|---|
| 639 | grids filled with the No Data value.
|
|---|
| 640 |
|
|---|
| 641 | The datasets include both 3D variables (dimensions x, y, and time) and
|
|---|
| 642 | 4D variables (dimensions x, y, depth, and time). The 4D variables are
|
|---|
| 643 | estimated at 40 depth levels: 0, 5, 10, 15, 20, 25, 30, 40, 50, 60,
|
|---|
| 644 | 70, 80, 90, 100, 125, 150, 200, 250, 300, 400, 500, 600, 700, 800,
|
|---|
| 645 | 900, 1000, 1100, 1200, 1300, 1400, 1500, 1750, 2000, 2500, 3000, 3500,
|
|---|
| 646 | 4000, 4500, 5000, and 5500 m.
|
|---|
| 647 |
|
|---|
| 648 | This %(name)s accesses the HYCOM datasets using the
|
|---|
| 649 | `OPeNDAP <http://opendap.org/>`_ protocol, allowing slices of data to
|
|---|
| 650 | be retrieved very efficiently. However, during periods of high load,
|
|---|
| 651 | the HYCOM OPeNDAP server often requires five to ten minutes to return
|
|---|
| 652 | the first slice of data. Please be patient; after the first one is
|
|---|
| 653 | returned, the rest will go much faster. During periods of extreme
|
|---|
| 654 | load, the tool may fail with a timeout error. If this happens,
|
|---|
| 655 | increase the timeout value and try again, or wait until later when the
|
|---|
| 656 | server is less busy."""),
|
|---|
| 657 |
|
|---|
| 658 | AddClassMetadata(HYCOMGOMl0043D,
|
|---|
| 659 | shortDescription=_(u'Represents a HYCOM GOMl0.04 3D variable as a Grid Dataset.'),
|
|---|
| 660 | longDescription=_HYCOMGOMl004_LongDescription % {u'name': 'class'})
|
|---|
| 661 |
|
|---|
| 662 | # Constructor
|
|---|
| 663 |
|
|---|
| 664 | AddMethodMetadata(HYCOMGOMl0043D.__init__,
|
|---|
| 665 | shortDescription=_(u'Constructs a new HYCOMGOMl0043D instance.'),
|
|---|
| 666 | isExposedToPythonCallers=True,
|
|---|
| 667 | dependencies=[PythonAggregatedModuleDependency('numpy')])
|
|---|
| 668 |
|
|---|
| 669 | AddArgumentMetadata(HYCOMGOMl0043D.__init__, u'self',
|
|---|
| 670 | typeMetadata=ClassInstanceTypeMetadata(cls=HYCOMGOMl0043D),
|
|---|
| 671 | description=_(u'HYCOMGOMl0043D instance.'))
|
|---|
| 672 |
|
|---|
| 673 | AddArgumentMetadata(HYCOMGOMl0043D.__init__, u'variableName',
|
|---|
| 674 | typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'emp', u'mld', u'mlp', u'qtot', u'ssh', u'surface_salinity_trend', u'surface_temperature_trend'], makeLowercase=True),
|
|---|
| 675 | description=_(
|
|---|
| 676 | u"""HYCOM GOMl0.04 3D variable (dimensions x, y, and time), one of:
|
|---|
| 677 |
|
|---|
| 678 | * emp - Water flux into the ocean, in kg/m2/s.
|
|---|
| 679 |
|
|---|
| 680 | * mld - Mixed layer thickness, in m, defined as the depth at which the
|
|---|
| 681 | temperature change from the surface temperature is 0.02 degrees C.
|
|---|
| 682 |
|
|---|
| 683 | * mlp - Mixed layer thickness, in m, defined as the depth at which the
|
|---|
| 684 | pressure change from the surface pressure is 0.03 kg/m3.
|
|---|
| 685 |
|
|---|
| 686 | * qtot - Surface downward heat flux, in w/m2.
|
|---|
| 687 |
|
|---|
| 688 | * ssh - Sea surface height, in m, above the HYCOM reference spheroid.
|
|---|
| 689 |
|
|---|
| 690 | * surface_salinity_trend - Surface salinity trend, in psu/day.
|
|---|
| 691 |
|
|---|
| 692 | * surface_temperature_trend - Surface temperature trend, in degrees
|
|---|
| 693 | C/day.
|
|---|
| 694 |
|
|---|
| 695 | Please see the HYCOM documentation for more information about these
|
|---|
| 696 | variables."""),
|
|---|
| 697 | arcGISDisplayName=_(u'Dataset variable'))
|
|---|
| 698 |
|
|---|
| 699 | AddArgumentMetadata(HYCOMGOMl0043D.__init__, u'startYear',
|
|---|
| 700 | typeMetadata=IntegerTypeMetadata(canBeNone=True, minValue=2003),
|
|---|
| 701 | description=_(
|
|---|
| 702 | u"""Starting year for this grid. This parameter is optional; if a
|
|---|
| 703 | value is not specified, 2003 will be used."""))
|
|---|
| 704 |
|
|---|
| 705 | AddArgumentMetadata(HYCOMGOMl0043D.__init__, u'endYear',
|
|---|
| 706 | typeMetadata=IntegerTypeMetadata(canBeNone=True),
|
|---|
| 707 | u"""Ending year for this grid. This parameter is optional; if a value
|
|---|
| 708 | is not specified, the grid will extend to the maximum temporal extent
|
|---|
| 709 | of the HYCOM data. If you do not need data for the current year,
|
|---|
| 710 | specify an earlier year for this parameter. This will make it
|
|---|
| 711 | unnecessary to query the HYCOM server to determine the maximum
|
|---|
| 712 | temporal extent."""))
|
|---|
| 713 |
|
|---|
| 714 | CopyArgumentMetadata(THREDDSCatalog.__init__, u'timeout', HYCOMGOMl0043D.__init__, u'timeout')
|
|---|
| 715 |
|
|---|
| 716 | AddArgumentMetadata(HYCOMGOMl0043D.__init__, u'cacheDirectory',
|
|---|
| 717 | typeMetadata=DirectoryTypeMetadata(canBeNone=True),
|
|---|
| 718 | description=_(
|
|---|
| 719 | u"""Directory to cache OPeNDAP datasets.
|
|---|
| 720 |
|
|---|
| 721 | A cache directory can dramatically speed up scenarios that involve
|
|---|
| 722 | accessing the same subsets the HYCOM data over and over again. When
|
|---|
| 723 | OPeNDAP data is requested from the HYCOM server, the cache directory
|
|---|
| 724 | will be checked for data that was downloaded and cached during prior
|
|---|
| 725 | requests. If cached data exists that can fulfill part of the current
|
|---|
| 726 | request, the request will be serviced by reading from cache files
|
|---|
| 727 | rather than the OPeNDAP server. If the entire request can be serviced
|
|---|
| 728 | from the cache, the OPeNDAP server will not be accessed at all and the
|
|---|
| 729 | request will be completed extremely quickly. Any parts of the request
|
|---|
| 730 | that cannot be serviced from the cache will be downloaded from the
|
|---|
| 731 | OPeNDAP server and added to the cache, speeding up future requests for
|
|---|
| 732 | the same data.
|
|---|
| 733 |
|
|---|
| 734 | If you use a cache directory, be aware of these common pitfalls:
|
|---|
| 735 |
|
|---|
| 736 | * The HYCOM documentation states that HYCOM provides a five day forecast
|
|---|
| 737 | and five day hindcast from the current date, although we have
|
|---|
| 738 | regularly observed netCDF files on their servers that suggested this
|
|---|
| 739 | window actually extends seven days in both directions. HYCOM revises
|
|---|
| 740 | the data within this time window daily, using the latest ocean
|
|---|
| 741 | observations assimilated from buoys, satellites, and other sensors.
|
|---|
| 742 | We recommend you do not cache data in this time window. The caching
|
|---|
| 743 | algorithm cannot detect whether cached data should be replaced with
|
|---|
| 744 | revised versions available on the server.
|
|---|
| 745 |
|
|---|
| 746 | * The caching algorithm permits the cache to grow to infinite size and
|
|---|
| 747 | never deletes any cached data. If you access a large amount of data
|
|---|
| 748 | it will all be added to the cache. Be careful that you do not fill
|
|---|
| 749 | up your hard disk. To mitigate this, manually delete the entire
|
|---|
| 750 | cache or selected directories or files within it.
|
|---|
| 751 |
|
|---|
| 752 | * The caching algorithm stores data in uncompressed files, so that
|
|---|
| 753 | subsets of those files may be quickly accessed. To save space on
|
|---|
| 754 | your hard disk, you can enable compression of the cache directory
|
|---|
| 755 | using the operating system. On Windows, right click on the directory
|
|---|
| 756 | in Windows Explorer, select Properties, click Advanced, and enable
|
|---|
| 757 | "Compress contents to save disk space".
|
|---|
| 758 | """),
|
|---|
| 759 | arcGISDisplayName=_(u'Cache directory'),
|
|---|
| 760 | arcGISCategory=_(u'OPeNDAP options'))
|
|---|
| 761 |
|
|---|
| 762 | AddResultMetadata(HYCOMGOMl0043D.__init__, u'grid',
|
|---|
| 763 | typeMetadata=ClassInstanceTypeMetadata(cls=HYCOMGOMl0043D),
|
|---|
| 764 | description=_(u'HYCOMGOMl0043D instance.'))
|
|---|
| 765 |
|
|---|
| 766 | # Public method: HYCOMGOMl0043D.CreateArcGISRasters
|
|---|
| 767 |
|
|---|
| 768 | AddMethodMetadata(HYCOMGOMl0043D.CreateArcGISRasters,
|
|---|
| 769 | shortDescription=_(u'Downloads a HYCOM GOMl0.04 3D variable and creates ArcGIS rasters.'),
|
|---|
| 770 | longDescription=_HYCOMGOMl004_LongDescription % {u'name': 'tool'})
|
|---|
| 771 | isExposedByCOM=True,
|
|---|
| 772 | isExposedAsArcGISTool=True,
|
|---|
| 773 | arcGISDisplayName=_(u'Download HYCOM GOMl0.04 3D Variable to ArcGIS Rasters'),
|
|---|
| 774 | arcGISToolCategory=_(u'Data Products\\HYCOM Consortium\\HYCOM + NCODA Gulf of Mexico 1/25 Degree Analysis (GLMl0.04)'),
|
|---|
| 775 | dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
|
|---|
| 776 |
|
|---|
| 777 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'cls',
|
|---|
| 778 | typeMetadata=ClassOrClassInstanceTypeMetadata(cls=HYCOMGOMl0043D),
|
|---|
| 779 | description=_(u'HYCOMGOMl0043D class or instance.'))
|
|---|
| 780 |
|
|---|
| 781 | CopyArgumentMetadata(HYCOMGOMl0043D.__init__, u'variableName', HYCOMGOMl0043D.CreateArcGISRasters, u'variableName')
|
|---|
| 782 |
|
|---|
| 783 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'outputWorkspace',
|
|---|
| 784 | typeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
|
|---|
| 785 | description=_(
|
|---|
| 786 | u"""Directory or geodatabase to receive the rasters.
|
|---|
| 787 |
|
|---|
| 788 | Unless you have a specific reason to store the rasters in a
|
|---|
| 789 | geodatabase, we recommend you store them in a directory because it
|
|---|
| 790 | will be much faster and allows the rasters to be organized in a tree.
|
|---|
| 791 | If you do store the rasters in a geodatabase, you must change the
|
|---|
| 792 | Raster Name Expressions parameter; see below for more
|
|---|
| 793 | information."""),
|
|---|
| 794 | arcGISDisplayName=_(u'Output workspace'))
|
|---|
| 795 |
|
|---|
| 796 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'mode',
|
|---|
| 797 | typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Add', u'Replace'], makeLowercase=True),
|
|---|
| 798 | description=_(
|
|---|
| 799 | u"""Overwrite mode, one of:
|
|---|
| 800 |
|
|---|
| 801 | * Add - create rasters that do not exist and skip those that already
|
|---|
| 802 | exist. This is the default.
|
|---|
| 803 |
|
|---|
| 804 | * Replace - create rasters that do not exist and overwrite those that
|
|---|
| 805 | already exist.
|
|---|
| 806 |
|
|---|
| 807 | 'Add' is appropriate when working with HYCOM data older than one week
|
|---|
| 808 | from the current date. When working with newer data, consider using
|
|---|
| 809 | 'Replace'. The HYCOM documentation states that HYCOM provides a five
|
|---|
| 810 | day forecast and five day hindcast from the current date, although we
|
|---|
| 811 | have regularly observed netCDF files on their servers that suggested
|
|---|
| 812 | this window actually extends seven days in both directions. HYCOM
|
|---|
| 813 | revises the data within this window daily, using the latest ocean
|
|---|
| 814 | observations assimilated from buoys, satellites, and other sensors.
|
|---|
| 815 | Therefore, by using 'Replace' when working with data within this
|
|---|
| 816 | window, you will be sure to overwrite obsolete data with the latest
|
|---|
| 817 | estimates.
|
|---|
| 818 |
|
|---|
| 819 | The ArcGIS Overwrite Outputs geoprocessing setting has no effect on
|
|---|
| 820 | this tool. If 'Replace' is selected the rasters will be overwritten,
|
|---|
| 821 | regardless of the ArcGIS Overwrite Outputs setting."""),
|
|---|
| 822 | arcGISDisplayName=_(u'Overwrite mode'))
|
|---|
| 823 |
|
|---|
| 824 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'rasterNameExpressions',
|
|---|
| 825 | typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(), minLength=1),
|
|---|
| 826 | description=_(
|
|---|
| 827 | u"""List of expressions specifying how the output rasters should be
|
|---|
| 828 | named.
|
|---|
| 829 |
|
|---|
| 830 | The default expression assumes you are storing rasters in a file
|
|---|
| 831 | system directory and creates them in a tree structure with names that
|
|---|
| 832 | imitate those used by the original data provider. When storing rasters
|
|---|
| 833 | in a directory, the final expression specifies the file name of the
|
|---|
| 834 | raster and any preceding expressions specify subdirectories. The
|
|---|
| 835 | extension of the final expression determines the output raster format:
|
|---|
| 836 | .asc for ArcInfo ASCII Grid, .bmp for BMP, .gif for GIF, .img for an
|
|---|
| 837 | ERDAS IMAGINE file, .jpg for JPEG, .jp2 for JPEG 2000, .png for PNG,
|
|---|
| 838 | .tif for GeoTIFF, or no extension for ArcInfo Binary Grid. The default
|
|---|
| 839 | expression uses .img.
|
|---|
| 840 |
|
|---|
| 841 | When storing rasters in a geodatabase, you should provide only one
|
|---|
| 842 | expression. That expression specifies the raster's name.
|
|---|
| 843 |
|
|---|
| 844 | Each expression may contain any sequence of characters permitted by
|
|---|
| 845 | the output workspace. Each expression may optionally contain one or
|
|---|
| 846 | more of the following case-sensitive codes. The tool replaces the
|
|---|
| 847 | codes with appropriate values when creating each raster:
|
|---|
| 848 |
|
|---|
| 849 | * %(VariableName)s - dataset variable represented in the output
|
|---|
| 850 | raster.
|
|---|
| 851 |
|
|---|
| 852 | * %%Y - four-digit year of the raster.
|
|---|
| 853 |
|
|---|
| 854 | * %%m - two-digit month of the first day of the raster.
|
|---|
| 855 |
|
|---|
| 856 | * %%d - two-digit day of the month of the first day of the raster.
|
|---|
| 857 |
|
|---|
| 858 | * %%j - three-digit day of the year of the first day of the raster.
|
|---|
| 859 | """),
|
|---|
| 860 | arcGISDisplayName=_(u'Raster name expressions'))
|
|---|
| 861 |
|
|---|
| 862 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'spatialExtent',
|
|---|
| 863 | typeMetadata=EnvelopeTypeMetadata(canBeNone=True),
|
|---|
| 864 | description=_(
|
|---|
| 865 | u"""Spatial extent of the output rasters, in the units specified by
|
|---|
| 866 | the Linear Units parameter.
|
|---|
| 867 |
|
|---|
| 868 | If you do not specify a spatial extent, it will default to
|
|---|
| 869 | approximately 98 to 76 W, 18 to 32 N. The rasters can only be clipped
|
|---|
| 870 | in whole grid cells. The values you provide will be rounded off to the
|
|---|
| 871 | closest cell."""),
|
|---|
| 872 | arcGISDisplayName=_(u'Spatial extent'),
|
|---|
| 873 | arcGISCategory=_(u'Spatiotemporal extent'))
|
|---|
| 874 |
|
|---|
| 875 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'linearUnit',
|
|---|
| 876 | typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Degrees', u'Meters'], makeLowercase=True),
|
|---|
| 877 | description=_(
|
|---|
| 878 | u"""Specifies the unit of the Spatial Extent parameter, one of:
|
|---|
| 879 |
|
|---|
| 880 | * Degrees - Decimal degrees.
|
|---|
| 881 |
|
|---|
| 882 | * Meters - Meters, in the coordinate system of the output rasters.
|
|---|
| 883 | """),
|
|---|
| 884 | arcGISDisplayName=_(u'Linear unit'),
|
|---|
| 885 | arcGISCategory=_(u'Spatiotemporal extent'))
|
|---|
| 886 |
|
|---|
| 887 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'startDate',
|
|---|
| 888 | typeMetadata=DateTimeTypeMetadata(canBeNone=True),
|
|---|
| 889 | description=_(
|
|---|
| 890 | u"""Start date for the rasters to create.
|
|---|
| 891 |
|
|---|
| 892 | Rasters will be created for images that occur on or after the start
|
|---|
| 893 | date and on or before the end date. The HYCOM GOMl0.04 dataset
|
|---|
| 894 | provides a five-day forecast; its temporal extent ranges from 1
|
|---|
| 895 | January 2003 to today's date plus five days. If you do not specify a
|
|---|
| 896 | start date, 1 January 2003 will be used."""),
|
|---|
| 897 | arcGISDisplayName=_(u'Start date'),
|
|---|
| 898 | arcGISCategory=_(u'Spatiotemporal extent'))
|
|---|
| 899 |
|
|---|
| 900 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'endDate',
|
|---|
| 901 | typeMetadata=DateTimeTypeMetadata(canBeNone=True),
|
|---|
| 902 | description=_(
|
|---|
| 903 | u"""End date for the rasters to create.
|
|---|
| 904 |
|
|---|
| 905 | Rasters will be created for images that occur on or after the start
|
|---|
| 906 | date and on or before the end date. The HYCOM GOMl0.04 dataset
|
|---|
| 907 | provides a five-day forecast; its temporal extent ranges from 1
|
|---|
| 908 | January 2003 to today's date plus five days. If you do not specify an
|
|---|
| 909 | end date, the most recent day available will be used (typically
|
|---|
| 910 | today's date plus five days)."""),
|
|---|
| 911 | arcGISDisplayName=_(u'End date'),
|
|---|
| 912 | arcGISCategory=_(u'Spatiotemporal extent'))
|
|---|
| 913 |
|
|---|
| 914 | CopyArgumentMetadata(HYCOMGOMl0043D.__init__, u'timeout', HYCOMGOMl0043D.CreateArcGISRasters, u'timeout')
|
|---|
| 915 | CopyArgumentMetadata(HYCOMGOMl0043D.__init__, u'cacheDirectory', HYCOMGOMl0043D.CreateArcGISRasters, u'cacheDirectory')
|
|---|
| 916 |
|
|---|
| 917 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'calculateStatistics',
|
|---|
| 918 | typeMetadata=BooleanTypeMetadata(),
|
|---|
| 919 | description=_CalculateStatisticsDescription,
|
|---|
| 920 | arcGISDisplayName=_(u'Calculate statistics'),
|
|---|
| 921 | arcGISCategory=_(u'Additional raster processing options'))
|
|---|
| 922 |
|
|---|
| 923 | AddArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'buildPyramids',
|
|---|
| 924 | typeMetadata=BooleanTypeMetadata(),
|
|---|
| 925 | description=_BuildPyramidsDescription,
|
|---|
| 926 | arcGISDisplayName=_(u'Build pyramids'),
|
|---|
| 927 | arcGISCategory=_(u'Additional raster processing options'))
|
|---|
| 928 |
|
|---|
| 929 | AddResultMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'updatedOutputWorkspace',
|
|---|
| 930 | typeMetadata=ArcGISWorkspaceTypeMetadata(),
|
|---|
| 931 | description=_(u'Updated output workspace.'),
|
|---|
| 932 | arcGISDisplayName=_(u'Updated output workspace'),
|
|---|
| 933 | arcGISParameterDependencies=[u'outputWorkspace'])
|
|---|
| 934 |
|
|---|
| 935 | ###############################################################################
|
|---|
| 936 | # Metadata: _HYCOMGridGOMl0044D class
|
|---|
| 937 | ###############################################################################
|
|---|
| 938 |
|
|---|
| 939 | AddClassMetadata(_HYCOMGridGOMl0044D,
|
|---|
| 940 | shortDescription=_(u'An OPeNDAPGrid for a 4D variable of a HYCOM GOMl0.04 OPeNDAP URL.')
|
|---|
| 941 | longDescription=_(
|
|---|
| 942 | u"""This class is intended for private use within GeoEco and is not
|
|---|
| 943 | intended for external callers."""))
|
|---|
| 944 |
|
|---|
| 945 | ###############################################################################
|
|---|
| 946 | # Metadata: HYCOMGOMl0044D class
|
|---|
| 947 | ###############################################################################
|
|---|
| 948 |
|
|---|
| 949 | AddClassMetadata(HYCOMGOMl0044D,
|
|---|
| 950 | shortDescription=_(u'Represents a HYCOM GOMl0.04 3D variable as a Grid Dataset.'),
|
|---|
| 951 | longDescription=_HYCOMGOMl004_LongDescription % {u'name': 'class'})
|
|---|
| 952 |
|
|---|
| 953 | # Constructor
|
|---|
| 954 |
|
|---|
| 955 | AddMethodMetadata(HYCOMGOMl0044D.__init__,
|
|---|
| 956 | shortDescription=_(u'Constructs a new HYCOMGOMl0044D instance.'),
|
|---|
| 957 | isExposedToPythonCallers=True,
|
|---|
| 958 | dependencies=[PythonAggregatedModuleDependency('numpy')])
|
|---|
| 959 |
|
|---|
| 960 | AddArgumentMetadata(HYCOMGOMl0044D.__init__, u'self',
|
|---|
| 961 | typeMetadata=ClassInstanceTypeMetadata(cls=HYCOMGOMl0044D),
|
|---|
| 962 | description=_(u'HYCOMGOMl0044D instance.'))
|
|---|
| 963 |
|
|---|
| 964 | AddArgumentMetadata(HYCOMGOMl0044D.__init__, u'variableName',
|
|---|
| 965 | typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'salinity', u'temperature', u'u', u'v', u'w'], makeLowercase=True),
|
|---|
| 966 | description=_(
|
|---|
| 967 | u"""HYCOM GOMl0.04 4D variable (dimensions x, y, depth, and time), one
|
|---|
| 968 | of:
|
|---|
| 969 |
|
|---|
| 970 | * salinity - Sea water salinity, in psu.
|
|---|
| 971 |
|
|---|
| 972 | * temperature - Sea water potential temperature, in degrees C.
|
|---|
| 973 |
|
|---|
| 974 | * u - Eastward sea water velocity, in m/s.
|
|---|
| 975 |
|
|---|
| 976 | * v - Northward sea water velocity, in m/s.
|
|---|
| 977 |
|
|---|
| 978 | * w - Upward sea water velocity, in m/s.
|
|---|
| 979 |
|
|---|
| 980 | Please see the HYCOM documentation for more information about these
|
|---|
| 981 | variables."""),
|
|---|
| 982 | arcGISDisplayName=_(u'Dataset variable'))
|
|---|
| 983 |
|
|---|
| 984 | CopyArgumentMetadata(HYCOMGOMl0043D.__init__, u'startYear', HYCOMGOMl0044D.__init__, u'startYear')
|
|---|
| 985 | CopyArgumentMetadata(HYCOMGOMl0043D.__init__, u'endYear', HYCOMGOMl0044D.__init__, u'endYear')
|
|---|
| 986 | CopyArgumentMetadata(HYCOMGOMl0043D.__init__, u'timeout', HYCOMGOMl0044D.__init__, u'timeout')
|
|---|
| 987 | CopyArgumentMetadata(HYCOMGOMl0043D.__init__, u'cacheDirectory', HYCOMGOMl0044D.__init__, u'cacheDirectory')
|
|---|
| 988 |
|
|---|
| 989 | CopyResultMetadata(HYCOMGOMl0043D.__init__, u'grid', HYCOMGOMl0044D.__init__, u'grid')
|
|---|
| 990 |
|
|---|
| 991 | # Public method: HYCOMGOMl0044D.CreateArcGISRasters
|
|---|
| 992 |
|
|---|
| 993 | AddMethodMetadata(HYCOMGOMl0044D.CreateArcGISRasters,
|
|---|
| 994 | shortDescription=_(u'Downloads a HYCOM GOMl0.04 4D variable and creates ArcGIS rasters.'),
|
|---|
| 995 | longDescription=_HYCOMGOMl004_LongDescription % {u'name': 'class'})
|
|---|
| 996 | isExposedByCOM=True,
|
|---|
| 997 | isExposedAsArcGISTool=True,
|
|---|
| 998 | arcGISDisplayName=_(u'Download HYCOM GOMl0.04 4D Variable to ArcGIS Rasters'),
|
|---|
| 999 | arcGISToolCategory=_(u'Data Products\\HYCOM Consortium\\HYCOM + NCODA Gulf of Mexico 1/25 Degree Analysis (GLMl0.04)'),
|
|---|
| 1000 | dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
|
|---|
| 1001 |
|
|---|
| 1002 | AddArgumentMetadata(HYCOMGOMl0044D.CreateArcGISRasters, u'cls',
|
|---|
| 1003 | typeMetadata=ClassOrClassInstanceTypeMetadata(cls=HYCOMGOMl0044D),
|
|---|
| 1004 | description=_(u'HYCOMGOMl0044D class or instance.'))
|
|---|
| 1005 |
|
|---|
| 1006 | CopyArgumentMetadata(HYCOMGOMl0044D.__init__, u'variableName', HYCOMGOMl0044D.CreateArcGISRasters, u'variableName')
|
|---|
| 1007 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'outputWorkspace', HYCOMGOMl0044D.CreateArcGISRasters, u'outputWorkspace')
|
|---|
| 1008 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'mode', HYCOMGOMl0044D.CreateArcGISRasters, u'mode')
|
|---|
| 1009 |
|
|---|
| 1010 | AddArgumentMetadata(HYCOMGOMl0044D.CreateArcGISRasters, u'rasterNameExpressions',
|
|---|
| 1011 | typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(), minLength=1),
|
|---|
| 1012 | description=_(
|
|---|
| 1013 | u"""List of expressions specifying how the output rasters should be
|
|---|
| 1014 | named.
|
|---|
| 1015 |
|
|---|
| 1016 | The default expression assumes you are storing rasters in a file
|
|---|
| 1017 | system directory and creates them in a tree structure with names that
|
|---|
| 1018 | imitate those used by the original data provider. When storing rasters
|
|---|
| 1019 | in a directory, the final expression specifies the file name of the
|
|---|
| 1020 | raster and any preceding expressions specify subdirectories. The
|
|---|
| 1021 | extension of the final expression determines the output raster format:
|
|---|
| 1022 | .asc for ArcInfo ASCII Grid, .bmp for BMP, .gif for GIF, .img for an
|
|---|
| 1023 | ERDAS IMAGINE file, .jpg for JPEG, .jp2 for JPEG 2000, .png for PNG,
|
|---|
| 1024 | .tif for GeoTIFF, or no extension for ArcInfo Binary Grid. The default
|
|---|
| 1025 | expression uses .img.
|
|---|
| 1026 |
|
|---|
| 1027 | When storing rasters in a geodatabase, you should provide only one
|
|---|
| 1028 | expression. That expression specifies the raster's name.
|
|---|
| 1029 |
|
|---|
| 1030 | Each expression may contain any sequence of characters permitted by
|
|---|
| 1031 | the output workspace. Each expression may optionally contain one or
|
|---|
| 1032 | more of the following case-sensitive codes. The tool replaces the
|
|---|
| 1033 | codes with appropriate values when creating each raster:
|
|---|
| 1034 |
|
|---|
| 1035 | * %(VariableName)s - dataset variable represented in the output
|
|---|
| 1036 | raster.
|
|---|
| 1037 |
|
|---|
| 1038 | * %(Depth)f - depth of the output raster. The f may be preceded by
|
|---|
| 1039 | Python's string formatting codes. Please see the Python
|
|---|
| 1040 | documentation for more information.
|
|---|
| 1041 |
|
|---|
| 1042 | * %%Y - four-digit year of the raster.
|
|---|
| 1043 |
|
|---|
| 1044 | * %%m - two-digit month of the first day of the raster.
|
|---|
| 1045 |
|
|---|
| 1046 | * %%d - two-digit day of the month of the first day of the raster.
|
|---|
| 1047 |
|
|---|
| 1048 | * %%j - three-digit day of the year of the first day of the raster.
|
|---|
| 1049 | """),
|
|---|
| 1050 | arcGISDisplayName=_(u'Raster name expressions'))
|
|---|
| 1051 |
|
|---|
| 1052 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'spatialExtent', HYCOMGOMl0044D.CreateArcGISRasters, u'spatialExtent')
|
|---|
| 1053 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'linearUnit', HYCOMGOMl0044D.CreateArcGISRasters, u'linearUnit')
|
|---|
| 1054 |
|
|---|
| 1055 | AddArgumentMetadata(HYCOMGOMl0044D.CreateArcGISRasters, u'minDepth',
|
|---|
| 1056 | typeMetadata=FloatTypeMetadata(minValue=0.0, maxValue=5500.0, canBeNone=True),
|
|---|
| 1057 | description=_(
|
|---|
| 1058 | u"""Minimum depth, in meters, for the rasters to create.
|
|---|
| 1059 |
|
|---|
| 1060 | The value must be between 0 and 5500, inclusive. Rasters will be
|
|---|
| 1061 | created for images with depths that are greater than or equal to the
|
|---|
| 1062 | minimum depth and less than or equal to the maximum depth. If you do
|
|---|
| 1063 | not specify a minimum depth, 0 will be used."""),
|
|---|
| 1064 | arcGISDisplayName=_(u'Minimum depth'),
|
|---|
| 1065 | arcGISCategory=_(u'Spatiotemporal extent'))
|
|---|
| 1066 |
|
|---|
| 1067 | AddArgumentMetadata(HYCOMGOMl0044D.CreateArcGISRasters, u'maxDepth',
|
|---|
| 1068 | typeMetadata=FloatTypeMetadata(minValue=0.0, maxValue=5500.0, canBeNone=True),
|
|---|
| 1069 | description=_(
|
|---|
| 1070 | u"""Maximum depth, in meters, for the rasters to create.
|
|---|
| 1071 |
|
|---|
| 1072 | The value must be between 0 and 5500, inclusive. Rasters will be
|
|---|
| 1073 | created for images with depths that are greater than or equal to the
|
|---|
| 1074 | minimum depth and less than or equal to the maximum depth. If you do
|
|---|
| 1075 | not specify a maximum depth, 5500 will be used. This depth encompasses
|
|---|
| 1076 | the deepest HYCOM layer."""),
|
|---|
| 1077 | arcGISDisplayName=_(u'Maximum depth'),
|
|---|
| 1078 | arcGISCategory=_(u'Spatiotemporal extent'))
|
|---|
| 1079 |
|
|---|
| 1080 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'startDate', HYCOMGOMl0044D.CreateArcGISRasters, u'startDate')
|
|---|
| 1081 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'endDate', HYCOMGOMl0044D.CreateArcGISRasters, u'endDate')
|
|---|
| 1082 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'timeout', HYCOMGOMl0044D.CreateArcGISRasters, u'timeout')
|
|---|
| 1083 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'cacheDirectory', HYCOMGOMl0044D.CreateArcGISRasters, u'cacheDirectory')
|
|---|
| 1084 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'calculateStatistics', HYCOMGOMl0044D.CreateArcGISRasters, u'calculateStatistics')
|
|---|
| 1085 | CopyArgumentMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'buildPyramids', HYCOMGOMl0044D.CreateArcGISRasters, u'buildPyramids')
|
|---|
| 1086 |
|
|---|
| 1087 | CopyResultMetadata(HYCOMGOMl0043D.CreateArcGISRasters, u'updatedOutputWorkspace', HYCOMGOMl0044D.CreateArcGISRasters, u'updatedOutputWorkspace')
|
|---|
| 1088 |
|
|---|
| 1089 | ###############################################################################
|
|---|
| 1090 | # Names exported by this module
|
|---|
| 1091 | ###############################################################################
|
|---|
| 1092 |
|
|---|
| 1093 | __all__ = ['HYCOMGOMl0043D', 'HYCOMGOMl0044D']
|
|---|