root/MGET/Branches/Jason/PythonPackage/src/GeoEco/DataProducts/NOAA/OSCAR.py @ 913

Revision 913, 68.5 KB (checked in by jjr8, 15 months ago)

Continued work on:
* #518: MGET tools should utilize the ArcGIS progress bar (ArcGIS 9.3 and higher)
* #519: Ocean currents tools (Aviso, OSCAR, HYCOM, ROMS-CoSiNE) should calculate eddy kinetic energy, current direction, and current magnitude grids

Line 
1# OSCAR.py - Provides methods for working with ocean currents data
2# from OSCAR (http://www.oscar.noaa.gov/).
3#
4# Copyright (C) 2011 Jason J. Roberts
5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License
8# as published by the Free Software Foundation; either version 2
9# of the License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License (available in the file LICENSE.TXT)
15# for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
21import datetime
22
23from GeoEco.DataManagement.ArcGISRasters import ArcGISRaster
24from GeoEco.Datasets import Dataset, QueryableAttribute, Grid
25from GeoEco.Datasets.OPeNDAP import THREDDSCatalog, OPeNDAPURL, OPeNDAPGrid
26from GeoEco.DynamicDocString import DynamicDocString
27from GeoEco.Internationalization import _
28
29
30class _OSCAR5DayThirdDegreeCurrents4D(OPeNDAPGrid):
31    __doc__ = DynamicDocString()
32
33    def __init__(self, vectorComponent, timeout, maxRetryTime, cacheDirectory):
34        self._CachedTCenterCoords = None
35        super(_OSCAR5DayThirdDegreeCurrents4D, self).__init__(OPeNDAPURL('http://dapper.pmel.noaa.gov/dapper/oscar/world_sfc-third.nc', timeout=timeout, maxRetryTime=maxRetryTime, cacheDirectory=cacheDirectory),
36                                                              vectorComponent,
37                                                              'Grid',
38                                                              lazyPropertyValues={'SpatialReference': Dataset.ConvertSpatialReference('proj4', '+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs', 'obj'),
39                                                                                  'Dimensions': 'tzyx',
40                                                                                  'CoordDependencies': (None, None, None, None),
41                                                                                  'CoordIncrements': (None, 1., 1./3., 1./3.),
42                                                                                  'TCornerCoordType': 'center',
43                                                                                  'PhysicalDimensions': 'tzyx',
44                                                                                  'PhysicalDimensionsFlipped': (False, False, False, False),
45                                                                                  'UnscaledDataType': 'float32',
46                                                                                  'UnscaledNoDataValue': -9999.,        # OSCAR uses NaN; we must convert it to -9999 because some callers cannot deal with NaN
47                                                                                  'ScalingFunction': None})
48       
49    def _GetLazyPropertyPhysicalValue(self, name):
50
51        # If the caller wants the CornerCoords, get the t coordinate
52        # from the server (in case they change it) and use hard-coded
53        # values for the rest (I feel confident they won't change
54        # these).
55       
56        if name == 'CornerCoords':
57            return (self._GetCoords('t', 0, [0], [0], 0.), 15.0, -80., 20.)       # Center of lower-left cell: 15 m deep, latitude -80, longitude +20
58
59        # If the caller wants the shape, get it from the server but
60        # take care to reduce the longitude shape so it does not
61        # exceed 360 degrees. (OSCAR goes from 20 to 420, with 40
62        # degrees of duplicated data.)
63
64        if name == 'Shape':
65            shape = super(_OSCAR5DayThirdDegreeCurrents4D, self)._GetLazyPropertyPhysicalValue('Shape')
66            return (shape[0], 1, 481, 1080)
67
68        # Otherwise get it from the server.
69
70        return super(_OSCAR5DayThirdDegreeCurrents4D, self)._GetLazyPropertyPhysicalValue(name)
71
72    def _GetCoords(self, coord, coordNum, slices, sliceDims, fixedIncrementOffset):
73        if coord != 't':
74            raise RuntimeError(_('_OSCAR5DayThirdDegreeCurrents4D._GetCoords() called with coord == \'%(coord)s\'. This should never happen. Please contact the author of this tool for assistance.') % {u'coord': coord})
75
76        import numpy
77
78        if self._CachedTCenterCoords is None:
79            self.ParentCollection._Open()
80            self._CachedTCenterCoords = numpy.array(map(lambda days: datetime.timedelta(int(days)) + datetime.datetime(1992, 10, 5), list(self.ParentCollection._PydapDataset['time'][:])), dtype='object')
81            self._CachedTMinCoords = numpy.array([self._CachedTCenterCoords[0] - (self._CachedTCenterCoords[1] - self._CachedTCenterCoords[0])/2] + map(lambda a, b: a + (b-a)/2, self._CachedTCenterCoords[:-1], self._CachedTCenterCoords[1:]))
82            self._CachedTMaxCoords = numpy.array(map(lambda a, b: a + (b-a)/2, self._CachedTCenterCoords[:-1], self._CachedTCenterCoords[1:]) + [self._CachedTCenterCoords[-1] + (self._CachedTCenterCoords[-1] - self._CachedTCenterCoords[-2])/2])
83
84        if slices is None:
85            if fixedIncrementOffset < 0:
86                return self._CachedTMinCoords.copy()
87            if fixedIncrementOffset == 0:
88                return self._CachedTCenterCoords.copy()
89            return self._CachedTMaxCoords.copy()
90           
91        if fixedIncrementOffset < 0:
92            return self._CachedTMinCoords.__getitem__(*slices)
93        if fixedIncrementOffset == 0:
94            return self._CachedTCenterCoords.__getitem__(*slices)
95        return self._CachedTMaxCoords.__getitem__(*slices)
96
97    def _ReadNumpyArray(self, sliceList):
98
99        # OSCAR uses NaN as the No Data value. Some of our callers
100        # cannot deal with that so we convert it to -9999.
101
102        import numpy
103
104        data, noDataValue = super(_OSCAR5DayThirdDegreeCurrents4D, self)._ReadNumpyArray(sliceList)
105        data[numpy.isnan(data)] = -9999.
106        return data, -9999.
107
108
109class OSCAR5DayThirdDegreeCurrents(Grid):
110    __doc__ = DynamicDocString()
111
112    def _GetParameter(self):
113        return self._Parameter
114
115    Parameter = property(_GetParameter, doc=DynamicDocString())
116
117    def __init__(self, parameter, timeout=60, maxRetryTime=120, cacheDirectory=None):
118        self.__doc__.Obj.ValidateMethodInvocation()
119
120        # Initialize our properties.
121
122        self._Parameter = parameter
123        self._Timeout = timeout
124        self._MaxRetryTime = maxRetryTime
125        self._CacheDirectory = cacheDirectory
126        self._Grid = None
127
128        if parameter == u'eke':
129            self._DisplayName = _(u'eddy kinetic energy calcuated from the OSCAR 5-day unfiltered 1/3 degree ocean surface currents')
130        elif parameter == u'dir':
131            self._DisplayName = _(u'direction of the OSCAR 5-day unfiltered 1/3 degree ocean surface currents')
132        elif parameter == u'mag':
133            self._DisplayName = _(u'magnitude of the OSCAR 5-day unfiltered 1/3 degree ocean surface currents')
134        else:
135            self._DisplayName = _(u'%(name)s component of the OSCAR 5-day unfiltered 1/3 degree ocean surface currents') % {u'name': parameter}
136
137        # Initialize the base class.
138
139        super(OSCAR5DayThirdDegreeCurrents, self).__init__(queryableAttributes=(QueryableAttribute(u'Parameter', _(u'Geophysical parameter'), UnicodeStringTypeMetadata(allowedValues=[u'dir', u'dir_anom', u'eke', u'mag', u'mag_anom', u'u', u'v', u'u_anom', u'v_anom'], makeLowercase=True)),),
140                                                           queryableAttributeValues={u'Parameter': parameter},
141                                                           lazyPropertyValues={'SpatialReference': Dataset.ConvertSpatialReference('proj4', '+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs', 'obj'),
142                                                                               'Dimensions': u'tyx',
143                                                                               'CoordDependencies': (None, None, None),
144                                                                               'CoordIncrements': (None, 1./3., 1./3.),
145                                                                               'TIncrementUnit': None,
146                                                                               'TSemiRegularity': None,
147                                                                               'TCountPerSemiRegularPeriod': None,
148                                                                               'TCornerCoordType': u'center',
149                                                                               'PhysicalDimensions': u'tyx',
150                                                                               'PhysicalDimensionsFlipped': (False, True, False),
151                                                                               'UnscaledDataType': u'float32',
152                                                                               'UnscaledNoDataValue': -9999.,
153                                                                               'ScalingFunction': None})
154
155    def _Close(self):
156        if hasattr(self, '_Grid') and self._Grid is not None:
157            self._Grid.Close()
158            self._Grid = None
159        super(OSCAR5DayThirdDegreeCurrents, self)._Close()
160
161    def _GetDisplayName(self):
162        return self._DisplayName
163       
164    def _GetLazyPropertyPhysicalValue(self, name):
165
166        # If the caller wants the CornerCoords or Shape, get them from
167        # the contained 4D grid, dropping the z dimension.
168
169        if name in ['CornerCoords', 'Shape']:
170            if self._Grid is None:
171                self._Grid = self._ConstructGridForParameter(self._Parameter, self._Timeout, self._MaxRetryTime, self._CacheDirectory)
172
173            if name == 'CornerCoords':
174                cornerCoords = self._Grid.GetLazyPropertyValue('CornerCoords')
175                return (cornerCoords[0], cornerCoords[2], cornerCoords[3])
176
177            if name == 'Shape':
178                shape = self._Grid.Shape
179                return (shape[0], shape[2], shape[3])
180
181        return None
182
183    def _GetCoords(self, coord, coordNum, slices, sliceDims, fixedIncrementOffset):
184
185        # Get the t coordinates from the contained grid.
186       
187        if coord != 't':
188            raise RuntimeError(_('OSCAR5DayThirdDegreeCurrents._GetCoords() called with coord == \'%(coord)s\'. This should never happen. Please contact the author of this tool for assistance.') % {u'coord': coord})
189
190        if self._Grid is None:
191            self._Grid = self._ConstructGridForParameter(self._Parameter, self._Timeout, self._MaxRetryTime, self._CacheDirectory)
192       
193        return self._Grid._GetCoords(coord, coordNum, slices, sliceDims, fixedIncrementOffset)
194
195    def _ReadNumpyArray(self, sliceList):
196
197        # The contained grid has four dimensions, while we only have
198        # three. We want to omit the z dimension because it always has
199        # a length of 1 (OSCAR only provides currents for the ocean
200        # surface.)
201        #
202        # Add a z slice to the caller's sliceList, retrieve the slice,
203        # and remove the z dimension from the returned 4D array before
204        # returning it.
205
206        if self._Grid is None:
207            self._Grid = self._ConstructGridForParameter(self._Parameter, self._Timeout, self._MaxRetryTime, self._CacheDirectory)
208
209        sliceList = [sliceList[0], slice(0, 1), sliceList[1], sliceList[2]]
210        data, noDataValue = self._Grid._ReadNumpyArray(sliceList)
211        return data.reshape(data.shape[0], data.shape[2], data.shape[3]), noDataValue
212
213    @classmethod
214    def _ConstructGridForParameter(cls, parameter, timeout, maxRetryTime, cacheDirectory):
215
216        # If the caller just wants u, v, u_anom, or v_anom, construct
217        # and return a _OSCAR5DayThirdDegreeCurrents4D instance.
218       
219        if parameter in [u'u', u'v', u'u_anom', u'v_anom']:
220            return _OSCAR5DayThirdDegreeCurrents4D(parameter, timeout, maxRetryTime, cacheDirectory)
221
222        # The caller wants something derived from both u and v. First
223        # create u and v component grids.
224
225        if parameter.endswith('_anom'):
226            uGrid = _OSCAR5DayThirdDegreeCurrents4D(u'u_anom', timeout, maxRetryTime, cacheDirectory)
227            vGrid = _OSCAR5DayThirdDegreeCurrents4D(u'v_anom', timeout, maxRetryTime, cacheDirectory)
228        else:
229            uGrid = _OSCAR5DayThirdDegreeCurrents4D(u'u', timeout, maxRetryTime, cacheDirectory)
230            vGrid = _OSCAR5DayThirdDegreeCurrents4D(u'v', timeout, maxRetryTime, cacheDirectory)
231
232        # Now construct and return the appropriate DerivedGrid
233        # instance.
234
235        qav = {}
236        for qa in uGrid.GetAllQueryableAttributes():
237            qav[qa.Name] = uGrid.GetQueryableAttributeValue(qa.Name)
238        qav[u'Parameter'] = parameter
239
240        from GeoEco.Datasets.Virtual import DerivedGrid
241
242        if parameter in [u'dir', u'dir_anom']:
243            return DerivedGrid([uGrid, vGrid],
244                               'numpy.arctan2(0 - self._Grids[0].Data.__getitem__(tuple(sliceList)), 0 - self._Grids[1].Data.__getitem__(tuple(sliceList))) / numpy.pi * 180 + 180',    # north = 0, east = 90, south = 180, west = 270
245                               _(u'OSCAR %(parameter)s') % {u'parameter': parameter},
246                               u'float32',
247                               noDataValue=uGrid.NoDataValue,
248                               queryableAttributes=tuple(uGrid.GetAllQueryableAttributes()),
249                               queryableAttributeValues=qav)
250
251        if parameter == u'eke':
252            return DerivedGrid([uGrid, vGrid],
253                               '0.5 * (self._Grids[0].Data.__getitem__(tuple(sliceList))**2 + self._Grids[1].Data.__getitem__(tuple(sliceList))**2)',
254                               _(u'OSCAR %(parameter)s') % {u'parameter': parameter},
255                               u'float32',
256                               noDataValue=uGrid.NoDataValue,
257                               queryableAttributes=tuple(uGrid.GetAllQueryableAttributes()),
258                               queryableAttributeValues=qav)
259
260        if parameter in [u'mag', u'mag_anom']:
261            return DerivedGrid([uGrid, vGrid],
262                               '(self._Grids[0].Data.__getitem__(tuple(sliceList))**2 + self._Grids[1].Data.__getitem__(tuple(sliceList))**2) ** 0.5',
263                               _(u'OSCAR %(parameter)s') % {u'parameter': parameter},
264                               u'float32',
265                               noDataValue=uGrid.NoDataValue,
266                               queryableAttributes=tuple(uGrid.GetAllQueryableAttributes()),
267                               queryableAttributeValues=qav)
268           
269        raise RuntimeError(_(u'Programming error in this tool: OSCAR5DayThirdDegreeCurrents._ConstructGridForParameter() does not recognize parameter "%(parameter)s". Please contact the author of this tool for assistance.') % {u'parameter': parameter})
270
271    @classmethod
272    def _RotateAndClip(cls, grid, rotationOffset, spatialExtent, startDate, endDate):
273        from GeoEco.Datasets.Virtual import RotatedGlobalGrid, ClippedGrid
274       
275        # Rotate the grid, if requested.
276       
277        if rotationOffset is not None:
278            grid = RotatedGlobalGrid(grid, rotationOffset, u'Map units')
279
280        # Clip the grid, if requested.
281       
282        if spatialExtent is not None or startDate is not None or endDate is not None:
283            xMin, yMin, xMax, yMax = None, None, None, None
284            if spatialExtent is not None:
285                from GeoEco.Types import EnvelopeTypeMetadata
286                xMin, yMin, xMax, yMax = EnvelopeTypeMetadata.ParseFromArcGISString(spatialExtent)
287
288            if startDate is not None:
289                startDate = datetime.datetime(startDate.year, startDate.month, startDate.day, 0, 0, 0)
290
291            if endDate is not None:
292                endDate = datetime.datetime(endDate.year, endDate.month, endDate.day, 23, 59, 59)
293               
294            grid = ClippedGrid(grid, u'Map coordinates', xMin=xMin, xMax=xMax, yMin=yMin, yMax=yMax, tMin=startDate, tMax=endDate)
295
296        # Return the grid.
297
298        return grid
299
300    @classmethod
301    def CreateArcGISRasters(cls, parameter,
302                            outputWorkspace, mode=u'add', rasterNameExpressions=['%(Parameter)s', '%%Y', '%(Parameter)s_%%Y%%j.img'],
303                            rotationOffset=None, spatialExtent=None, startDate=None, endDate=None,
304                            timeout=60, maxRetryTime=120, cacheDirectory=None,
305                            calculateStatistics=True, buildPyramids=False):
306        cls.__doc__.Obj.ValidateMethodInvocation()
307        grid = OSCAR5DayThirdDegreeCurrents(parameter, timeout, maxRetryTime, cacheDirectory)
308        try:
309            from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISRaster
310            from GeoEco.Datasets.Virtual import GridSliceCollection
311            grid = cls._RotateAndClip(grid, rotationOffset, spatialExtent, startDate, endDate)
312            workspace = ArcGISWorkspace(outputWorkspace, ArcGISRaster, pathCreationExpressions=rasterNameExpressions, cacheTree=True, queryableAttributes=tuple(grid.GetAllQueryableAttributes() + [QueryableAttribute(u'DateTime', _(u'Date'), DateTimeTypeMetadata())]))
313            workspace.ImportDatasets(GridSliceCollection(grid, tQACoordType=u'center').QueryDatasets(), mode, calculateStatistics=calculateStatistics, buildPyramids=buildPyramids)
314        finally:
315            grid.Close()
316        return outputWorkspace
317
318    @classmethod
319    def CreateClimatologicalArcGISRasters(cls, parameter,
320                                          statistic, binType,
321                                          outputWorkspace, mode=u'add', rasterNameExpressions=['%(Parameter)s', u'%(ClimatologyBinType)s_Climatology', u'%(Parameter)s_%(ClimatologyBinName)s_%(Statistic)s.img'],
322                                          binDuration=1, startDayOfYear=1,
323                                          rotationOffset=None, spatialExtent=None, startDate=None, endDate=None,
324                                          timeout=60, maxRetryTime=120, cacheDirectory=None,
325                                          calculateStatistics=True, buildPyramids=False):
326        cls.__doc__.Obj.ValidateMethodInvocation()
327        grid = OSCAR5DayThirdDegreeCurrents(parameter, timeout, maxRetryTime, cacheDirectory)
328        try:
329            from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISRaster
330            from GeoEco.Datasets.Virtual import ClimatologicalGridCollection
331            grid = cls._RotateAndClip(grid, rotationOffset, spatialExtent, startDate, endDate)
332            collection = ClimatologicalGridCollection(grid, statistic, binType, binDuration, startDayOfYear, reportProgress=True)
333            workspace = ArcGISWorkspace(outputWorkspace, ArcGISRaster, pathCreationExpressions=rasterNameExpressions, cacheTree=True, queryableAttributes=tuple(collection.GetAllQueryableAttributes()))
334            workspace.ImportDatasets(collection.QueryDatasets(), mode, calculateStatistics=calculateStatistics, buildPyramids=buildPyramids)
335        finally:
336            grid.Close()
337        return outputWorkspace
338
339    @classmethod
340    def CreateVectorsAsArcGISFeatureClasses(cls, outputWorkspace, mode=u'add', featureClassNameExpressions=['uv_vectors', '%%Y', 'uv_vectors_%%Y%%j.shp'],
341                                            scaleFactor=0.444, uniformLength=False,
342                                            rotationOffset=None, spatialExtent=None, startDate=None, endDate=None,
343                                            timeout=60, maxRetryTime=120, cacheDirectory=None):
344        cls.__doc__.Obj.ValidateMethodInvocation()
345
346        # Create u and v component grids.
347       
348        uGrid = OSCAR5DayThirdDegreeCurrents(u'u', timeout, maxRetryTime, cacheDirectory)
349        try:
350            vGrid = OSCAR5DayThirdDegreeCurrents(u'v', timeout, maxRetryTime, cacheDirectory)
351            try:
352                uGrid = cls._RotateAndClip(uGrid, rotationOffset, spatialExtent, startDate, endDate)
353                vGrid = cls._RotateAndClip(vGrid, rotationOffset, spatialExtent, startDate, endDate)
354
355                # Query for parallel lists of 2D u and v grid slices.
356
357                from GeoEco.Datasets.Virtual import GridSliceCollection
358
359                uSlices = GridSliceCollection(uGrid, tQACoordType=u'center').QueryDatasets()
360                vSlices = GridSliceCollection(vGrid, tQACoordType=u'center').QueryDatasets()
361
362                # Construct a list of
363                # ShapefileFromVectorComponentGrids from the slices.
364
365                from GeoEco.SpatialAnalysis.Lines import ShapefileFromVectorComponentGrids
366
367                queryableAttributes = tuple(uGrid.GetAllQueryableAttributes() + [QueryableAttribute(u'DateTime', _(u'Date'), DateTimeTypeMetadata())])
368                vectorShapefiles = []
369
370                for i in range(len(uSlices)):
371                    queryableAttributeValues = {}
372                    for qa in queryableAttributes:
373                        queryableAttributeValues[qa.Name] = uSlices[i].GetQueryableAttributeValue(qa.Name)
374
375                    vectorShapefiles.append(ShapefileFromVectorComponentGrids(uSlices[i], vSlices[i], scaleFactor, uniformLength, queryableAttributes=queryableAttributes, queryableAttributeValues=queryableAttributeValues))
376
377                # Import the ShapefileFromVectorComponentGrids into
378                # the output workspace.
379
380                from GeoEco.Datasets.ArcGIS import ArcGISWorkspace, ArcGISTable
381
382                workspace = ArcGISWorkspace(outputWorkspace, ArcGISTable, pathCreationExpressions=featureClassNameExpressions, cacheTree=True, queryableAttributes=queryableAttributes)
383                workspace.ImportDatasets(vectorShapefiles, mode)
384
385                # Return successfully.
386               
387                return outputWorkspace
388
389            finally:
390                vGrid.Close()
391        finally:
392            uGrid.Close()
393
394    @classmethod
395    def InterpolateAtArcGISPoints(cls, parameter,
396                                   points, valueField, tField, method=u'Nearest', where=None, noDataValue=None,
397                                   timeout=60, maxRetryTime=120, cacheDirectory=None,
398                                   orderByFields=None, numBlocksToCacheInMemory=128, xBlockSize=16, yBlockSize=16, tBlockSize=3):
399        cls.__doc__.Obj.ValidateMethodInvocation()
400        grid = OSCAR5DayThirdDegreeCurrents(parameter, timeout, maxRetryTime, cacheDirectory)
401        try:
402            if orderByFields is not None:
403                orderBy = u', '.join(map(lambda f: f + u' ASC', orderByFields))
404            else:
405                from GeoEco.ArcGIS import GeoprocessorManager
406                if GeoprocessorManager.GetArcGISMajorVersion() > 9 or GeoprocessorManager.GetArcGISMinorVersion() >= 2:
407                    orderBy = tField + u' ASC'
408                else:
409                    orderBy = None
410            from GeoEco.Datasets.ArcGIS import ArcGISTable
411            from GeoEco.SpatialAnalysis.Interpolation import Interpolator
412            Interpolator.InterpolateGridsValuesForTableOfPoints([grid], ArcGISTable(points), [valueField], tField=tField, where=where, orderBy=orderBy, method=method, noDataValue=noDataValue, gridsWrap=True, numBlocksToCacheInMemory=numBlocksToCacheInMemory, xBlockSize=xBlockSize, yBlockSize=yBlockSize, tBlockSize=tBlockSize)
413        finally:
414            grid.Close()
415        return points
416
417
418###############################################################################
419# Metadata: module
420###############################################################################
421
422from GeoEco.ArcGIS import ArcGISDependency
423from GeoEco.Datasets.ArcGIS import _CalculateStatisticsDescription, _BuildPyramidsDescription
424from GeoEco.Dependencies import PythonAggregatedModuleDependency
425from GeoEco.Metadata import *
426from GeoEco.OceanographicAnalysis.Eddies import OkuboWeissEddies, _OkuboWeissAlgorithmDescription, _OkuboWeissReferences
427from GeoEco.Types import *
428
429AddModuleMetadata(shortDescription=_(u'Methods for accessing the NOAA Ocean Surface Current Analyses - Real time (OSCAR) dataset (http://www.oscar.noaa.gov).'))
430
431###############################################################################
432# Metadata: _OSCAR5DayThirdDegreeCurrents4D class
433###############################################################################
434
435AddClassMetadata(_OSCAR5DayThirdDegreeCurrents4D,
436    shortDescription=_(u'An OPeNDAPGrid for the NOAA OSCAR 5-day unfiltered 1/3 degree ocean surface currents dataset.'),
437    longDescription=_(
438u"""This class is intended for private use within GeoEco and is not
439intended for external callers."""))
440
441_OSCAR_LongDescription = _(
442u"""The `NOAA Ocean Surface Current Analyses - Real Time (OSCAR) <http://www.oscar.noaa.gov/>`_
443project publishes global estimates of ocean surface currents by
444combining satellite observations from altimeters that measure the
445height of the sea surface (e.g. TOPEX/Poseidon), scatterometers that
446estimate ocean wind vectors (e.g. QuikSCAT), and sea surface
447temperature sensors (e.g. AVHRR). The goal is to provide ocean current
448estimates that are more accurate than those based on altimetry alone,
449particularly in tropical regions, by combining geostrophic, Ekman, and
450Stommel shear dynamics and a complementary term from the surface
451buoyancy gradient (Bonjean and Lagerloef, 2002).
452
453This %(name)s accesses a long term archive of OSCAR's 5-day unfiltered
4541/3 degree global product. This product begins 21 October 1992 and
455continues to be updated through the present day. Although the R in
456OSCAR stands for "real time", it does not appear that the archive is
457updated on a real time basis. The data may be weeks or months behind.
458
459Although the time increment for this product is listed as 5 days,
460images occasionally occur 6 days apart according to a regular pattern.
461
462This product is provided in a geographic projection with a cell size
463of 1/3 degree. It encompasses latitudes 80 N to 80 S and 360 degrees
464of longitude. The images are centered on approximately 160 W to
465provide an uninterrupted view of the tropical Indian, Pacific, and
466Atlantic Oceans.
467
468The OSCAR OPeNDAP dataset accessed by this %(name)s is
469http://dapper.pmel.noaa.gov/dapper/oscar/world_sfc-third.nc.
470
471**References**
472
473Bonjean, F. and Lagerloef, G.S.E. (2002) Diagnostic Model and Analysis
474of the Surface Currents in the Tropical Pacific Ocean. J. Physical
475Oceano. 32(10):2938-2954.
476
477Please see the `OSCAR Bibliography <http://www.oscar.noaa.gov/pubs.html>`_
478for a complete list of OSCAR publications. Bonjean and Lagerloef
479(2002) appears to be the seminal OSCAR paper.
480
481The OSCAR website requests that you acknowledge your use of the data.
482Please see the website for specific instructions (they may appear
483`here <http://www.oscar.noaa.gov/datadisplay/oscar_datadownload.php>`_).""")
484
485###############################################################################
486# Metadata: OSCAR5DayThirdDegreeCurrents class
487###############################################################################
488
489AddClassMetadata(OSCAR5DayThirdDegreeCurrents,
490    shortDescription=_(u'A 3D Grid representing the NOAA OSCAR 5-day unfiltered 1/3 degree ocean surface currents.'),
491    longDescription=_OSCAR_LongDescription % {u'name': 'class'})
492
493# Constructor
494
495AddMethodMetadata(OSCAR5DayThirdDegreeCurrents.__init__,
496    shortDescription=_(u'Constructs a new OSCAR5DayThirdDegreeCurrents instance.'),
497    isExposedToPythonCallers=True,
498    dependencies=[PythonAggregatedModuleDependency('numpy')])
499
500AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.__init__, u'self',
501    typeMetadata=ClassInstanceTypeMetadata(cls=OSCAR5DayThirdDegreeCurrents),
502    description=_(u'OSCAR5DayThirdDegreeCurrents instance.'))
503
504AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.__init__, u'parameter',
505    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'dir', u'dir_anom', u'eke', u'mag', u'mag_anom', u'u', u'v', u'u_anom', u'v_anom'], makeLowercase=True),
506    description=_(
507u"""Geophysical parameter to use, one of:
508
509* dir - Direction of water flow, in degrees. Due north is 0, due east
510  is 90, due south is 180, due west is 270.
511
512* dir_anom - Direction of water flow (from u_anom and v_anom).
513
514* eke - Eddy kinetic energy, in m^2/s^2, computed as 0.5*(u^2 + v^2).
515
516* mag - Absolute magnitude (or modulus) of the water velocity vector,
517  in m/s.
518
519* mag_anom - Absolute magnitude of water velocity (from u_anom and
520  v_anom).
521
522* u - Eastward sea water velocity, in m/s.
523
524* v - Northward sea water velocity, in m/s.
525
526* u_anom - Eastward sea water velocity anomaly, in m/s.
527
528* v_anom - Northward sea water velocity anomaly, in m/s.
529
530The anomalies are the difference between the velocity on that date and
531the long term mean velocity. The mean is usually computed over all of
532the years that have complete data. For example, at the time this tool
533was developed in late 2011, the mean was computed over 1993-2010,
534inclusive. (1992 and 2011 were excluded, presumably because they were
535incomplete years.)
536
537Please see the OSCAR documentation for more information about these
538variables."""),
539    arcGISDisplayName=_(u'Geophysical parameter'))
540
541CopyArgumentMetadata(THREDDSCatalog.__init__, u'timeout', OSCAR5DayThirdDegreeCurrents.__init__, u'timeout')
542CopyArgumentMetadata(THREDDSCatalog.__init__, u'maxRetryTime', OSCAR5DayThirdDegreeCurrents.__init__, u'maxRetryTime')
543CopyArgumentMetadata(THREDDSCatalog.__init__, u'cacheDirectory', OSCAR5DayThirdDegreeCurrents.__init__, u'cacheDirectory')
544
545AddResultMetadata(OSCAR5DayThirdDegreeCurrents.__init__, u'grid',
546    typeMetadata=ClassInstanceTypeMetadata(cls=OSCAR5DayThirdDegreeCurrents),
547    description=_(u'OSCAR5DayThirdDegreeCurrents instance.'))
548
549# Public method: OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters
550
551AddMethodMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters,
552    shortDescription=_(u'Creates rasters for NOAA OSCAR 5-day unfiltered 1/3 degree ocean surface currents.'),
553    longDescription=_OSCAR_LongDescription % {u'name': 'tool'},
554    isExposedToPythonCallers=True,
555    isExposedByCOM=True,
556    isExposedAsArcGISTool=True,
557    arcGISDisplayName=_(u'Create Rasters for OSCAR Currents'),
558    arcGISToolCategory=_(u'Data Products\\NOAA OSCAR'),
559    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
560
561AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cls',
562    typeMetadata=ClassOrClassInstanceTypeMetadata(cls=OSCAR5DayThirdDegreeCurrents),
563    description=_(u'OSCAR5DayThirdDegreeCurrents class or instance.'))
564
565CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.__init__, u'parameter', OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'parameter')
566
567AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'outputWorkspace',
568    typeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
569    description=_(
570u"""Directory or geodatabase to receive the rasters.
571
572Unless you have a specific reason to store the rasters in a
573geodatabase, we recommend you store them in a directory because it
574will be much faster and allows the rasters to be organized in a tree.
575If you do store the rasters in a geodatabase, you must change the
576Raster Name Expressions parameter; see below for more
577information."""),
578    arcGISDisplayName=_(u'Output workspace'))
579
580AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'mode',
581    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Add', u'Replace'], makeLowercase=True),
582    description=_(
583u"""Overwrite mode, one of:
584
585* Add - create rasters that do not exist and skip those that already
586  exist. This is the default.
587
588* Replace - create rasters that do not exist and overwrite those that
589  already exist.
590
591The ArcGIS Overwrite Outputs geoprocessing setting has no effect on
592this tool. If 'Replace' is selected the rasters will be overwritten,
593regardless of the ArcGIS Overwrite Outputs setting."""),
594    arcGISDisplayName=_(u'Overwrite mode'))
595
596AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'rasterNameExpressions',
597    typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(), minLength=1),
598    description=_(
599u"""List of expressions specifying how the output rasters should be
600named.
601
602The default expression assumes you are storing rasters in a file
603system directory and creates them in a tree structure with levels for
604the geophysical parameter and year. When storing rasters in a
605directory, the final expression specifies the file name of the raster
606and any preceding expressions specify subdirectories. The extension of
607the final expression determines the output raster format: .asc for
608ArcInfo ASCII Grid, .bmp for BMP, .gif for GIF, .img for an ERDAS
609IMAGINE file, .jpg for JPEG, .jp2 for JPEG 2000, .png for PNG, .tif
610for GeoTIFF, or no extension for ArcInfo Binary Grid. The default
611expression uses .img.
612
613When storing rasters in a geodatabase, you should provide only one
614expression. That expression specifies the raster's name.
615
616Each expression may contain any sequence of characters permitted by
617the output workspace. Each expression may optionally contain one or
618more of the following case-sensitive codes. The tool replaces the
619codes with appropriate values when creating each raster:
620
621* %(Parameter)s - Geophysical parameter represented by the the output
622  raster, either "dir", "dir_anom", "eke", "mag", "mag_anom", "u",
623  "v", "u_anom", or "v_anom".
624
625* %%Y - four-digit year of the raster.
626
627* %%m - two-digit month of the raster.
628
629* %%d - two-digit day of the month of the raster.
630
631* %%j - three-digit day of the year of the raster.
632"""),
633    arcGISDisplayName=_(u'Raster name expressions'))
634
635AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'rotationOffset',
636    typeMetadata=FloatTypeMetadata(canBeNone=True),
637    description=_(
638u"""Angle to rotate the outputs about the polar axis, in degrees. If
639not provided, the outputs will be centered on 160.16666666666666 W
640(the Pacific Ocean).
641
642Use this parameter to shift the center longitude of the outputs to a
643different location. Positive values shift it to the east, negative
644values to the west. For example, to center the outputs close to the
645Prime Meridian, provide -200 for this parameter. (Note that it is not
646possible to center the outputs exactly on the Prime Meridian because
647the OSCAR grid is offset by 1/6 degree from it.)
648
649The outputs can only be rotated in whole cells of the OSCAR grids,
650which are 1/3 degree wide. The value you provide will be rounded off
651to the closest cell."""),
652    arcGISDisplayName=_(u'Rotate by'),
653    arcGISCategory=_(u'Spatiotemporal extent'))
654
655AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'spatialExtent',
656    typeMetadata=EnvelopeTypeMetadata(canBeNone=True),
657    description=_(
658u"""Spatial extent of the outputs, in degrees.
659
660This parameter is applied after the rotation parameter and uses
661coordinates that result after rotation.
662
663The outputs can only be clipped in whole grid cells, which are 1/3
664degree wide. The values you provide will be rounded off to the closest
665cell."""),
666    arcGISDisplayName=_(u'Spatial extent'),
667    arcGISCategory=_(u'Spatiotemporal extent'))
668
669AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'startDate',
670    typeMetadata=DateTimeTypeMetadata(canBeNone=True),
671    description=_(
672u"""Start date for the outputs to create.
673
674Outputs will be created for images that occur on or after the start
675date and on or before the end date. If you do not provide a start
676date, the date of the first available image will be used, which is
677usually 21 October 1992.
678
679The time component of the start date is ignored."""),
680    arcGISDisplayName=_(u'Start date'),
681    arcGISCategory=_(u'Spatiotemporal extent'))
682
683AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'endDate',
684    typeMetadata=DateTimeTypeMetadata(canBeNone=True),
685    description=_(
686u"""End date for the outputs to create.
687
688Outputs will be created for images that occur on or after the start
689date and on or before the end date. If you do not specify an end date,
690the date of the most recent image will be used. The OSCAR OPeNDAP
691dataset that is accessed is a long term archive that may not be
692updated daily. For example, when this tool was written in late 2011,
693the archive ended in September 2011.
694
695The time component of the end date is ignored."""),
696    arcGISDisplayName=_(u'End date'),
697    arcGISCategory=_(u'Spatiotemporal extent'))
698
699CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.__init__, u'timeout', OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'timeout')
700CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.__init__, u'maxRetryTime', OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'maxRetryTime')
701CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.__init__, u'cacheDirectory', OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cacheDirectory')
702
703AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'calculateStatistics',
704    typeMetadata=BooleanTypeMetadata(),
705    description=_CalculateStatisticsDescription,
706    arcGISDisplayName=_(u'Calculate statistics'),
707    arcGISCategory=_(u'Additional raster processing options'))
708
709AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'buildPyramids',
710    typeMetadata=BooleanTypeMetadata(),
711    description=_BuildPyramidsDescription,
712    arcGISDisplayName=_(u'Build pyramids'),
713    arcGISCategory=_(u'Additional raster processing options'))
714
715AddResultMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'updatedOutputWorkspace',
716    typeMetadata=ArcGISWorkspaceTypeMetadata(),
717    description=_(u'Updated output workspace.'),
718    arcGISDisplayName=_(u'Updated output workspace'),
719    arcGISParameterDependencies=[u'outputWorkspace'])
720
721# Public method: OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters
722
723AddMethodMetadata(OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters,
724    shortDescription=_(u'Creates climatological rasters for NOAA OSCAR 5-day unfiltered 1/3 degree ocean surface currents.'),
725    longDescription=_OSCAR_LongDescription % {u'name': 'tool'},
726    isExposedToPythonCallers=True,
727    isExposedByCOM=True,
728    isExposedAsArcGISTool=True,
729    arcGISDisplayName=_(u'Create Climatological Rasters for OSCAR Currents'),
730    arcGISToolCategory=_(u'Data Products\\NOAA OSCAR'),
731    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
732
733CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cls', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'cls')
734CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'parameter', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'parameter')
735
736AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'statistic',
737    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Count', u'Maximum', u'Mean', u'Minimum', u'Range', u'Standard Deviation', u'Sum'], makeLowercase=True),
738    description=_(
739u"""Statistic to calculate for each cell, one of:
740
741* Count - number of images in which the cell had data.
742
743* Maximum - maximum value for the cell.
744
745* Mean - mean value for the cell, calculated as the sum divided by the
746  count.
747
748* Minimum - minimum value for the cell.
749
750* Range - range for the cell, calculated as the maximum minus the
751  minimum.
752
753* Standard Deviation - sample standard deviation for the cell
754  (i.e. the standard deviation estimated using Bessel's correction).
755  In order to calculate this, there must be at least two images with
756  data for the cell.
757
758* Sum - the sum for the cell.
759"""),
760    arcGISDisplayName=_(u'Statistic'))
761
762AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'binType',
763    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Daily', u'Monthly', u'Cumulative'], makeLowercase=True),
764    description=_(
765u"""Climatology bins to use, one of:
766
767* Daily - daily bins. Images will be classified into bins according to
768  their days of the year. The number of days in each bin is determined
769  by the Climatology Bin Duration parameter (which defaults to 1). The
770  number of bins is calculated by dividing 365 by the bin duration. If
771  there is no remainder, then that number of bins will be created;
772  images for the 366th day of leap years will be counted in the bin
773  that includes day 365. For example, if the bin duration is 15, 73
774  bins will be created. The first will be for days 1-5, the second
775  will be for days 5-10, and so on; the 73rd bin will be for days
776  361-365 during normal years and 361-366 during leap years. If
777  dividing 365 by the bin duration does yield a remainder, then one
778  additional bin will be created to hold the remaining days. For
779  example, if the bin duration is 8, 46 bins will be created. The
780  first will be for days 1-8, the second for days 9-16, and so on; the
781  46th will be for days 361-365 during normal years and 361-366 during
782  leap years.
783
784* Monthly - monthly bins. Images will be classified into bins according to
785  their months of the year. The number of months in each bin is
786  determined by the Climatology Bin Duration parameter (which defaults
787  to 1). The number of bins is calculated by dividing 12 by the bin
788  duration. If there is no remainder, then that number of bins will be
789  created. For example, if the bin duration is 3, there will be four
790  bins: January-March, April-June, July-September, and
791  October-December. If there is a remainder, then one additional bin
792  will be created. For example, if the bin duration is 5, 3 bins will
793  be created: January-May, June-October, November-December.
794
795* Cumulative - one bin. A single climatology raster will be calculated
796  from the entire dataset. The Bin Duration parameter is ignored.
797
798For Daily and Monthly, to adjust when the bins start (e.g. to center a
7994-bin seasonal climatology on solstices and equinoxes), use the Start
800Climatology At This Day Of The Year parameter."""),
801    arcGISDisplayName=_(u'Climatology bin type'))
802
803CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'outputWorkspace', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'outputWorkspace')
804
805AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'mode',
806    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Add', u'Replace'], makeLowercase=True),
807    description=_(
808u"""Overwrite mode, one of:
809
810* Add - create rasters that do not exist and skip those that already
811  exist. This is the default.
812
813* Replace - create rasters that do not exist and overwrite those that
814  already exist. Choose this option when you want to regenerate the
815  climatologies using the latest OSCAR data.
816
817The ArcGIS Overwrite Outputs geoprocessing setting has no effect on
818this tool. If 'Replace' is selected the rasters will be overwritten,
819regardless of the ArcGIS Overwrite Outputs setting."""),
820    arcGISDisplayName=_(u'Overwrite mode'))
821
822AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'rasterNameExpressions',
823    typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(), minLength=1),
824    description=_(
825u"""List of expressions specifying how the output rasters should be
826named.
827
828The default expression assumes you are storing rasters in a file
829system directory and creates them in a tree structure with levels for
830the geophysical parameter and climatology type. When storing rasters
831in a directory, the final expression specifies the file name of the
832raster and any preceding expressions specify subdirectories. The
833extension of the final expression determines the output raster format:
834.asc for ArcInfo ASCII Grid, .bmp for BMP, .gif for GIF, .img for an
835ERDAS IMAGINE file, .jpg for JPEG, .jp2 for JPEG 2000, .png for PNG,
836.tif for GeoTIFF, or no extension for ArcInfo Binary Grid. The default
837expression uses .img.
838
839When storing rasters in a geodatabase, you should provide only one
840expression. That expression specifies the raster's name.
841
842Each expression may contain any sequence of characters permitted by
843the output workspace. Each expression may optionally contain one or
844more of the following case-sensitive codes. The tool replaces the
845codes with appropriate values when creating each raster:
846
847* %(Parameter)s - Geophysical parameter represented by the the output
848  raster, either "dir", "dir_anom", "eke", "mag", "mag_anom", "u",
849  "v", "u_anom", or "v_anom".
850
851* %(ClimatologyBinType)s - type of the climatology bin, either "Daily"
852  if 1-day bins, "Xday" if multi-day bins (X is replaced by the
853  duration), "Monthly" if 1-month bins, "Xmonth" if multi-month bins,
854  or "Cumulative".
855
856* %(ClimatologyBinName)s - name of the climatology bin corresponding
857  represented by the output raster, either "dayXXX" for 1-day bins
858  (XXX is replaced by the day of the year), "daysXXXtoYYY" for
859  multi-day bins (XXX is replaced by the first day of the bin, YYY is
860  replaced by the last day), "monthXX" for 1-month bins (XX is
861  replaced by the month), "monthXXtoYY" (XX is replaced by the first
862  month of the bin, YY by the last month), or "cumulative".
863
864* %(Statistic)s - statistic that was calculated, in lowercase and with
865  spaces replaced by underscores; one of: "count", "maximum", "mean",
866  "minimum", "range", "standard_deviation", "sum".
867
868If the Bin Type is "Daily", the following additional codes are
869available:
870
871* %(FirstDay)i - first day of the year of the climatology bin
872  represented by the output raster.
873
874* %(LastDay)i - last day of the year of the climatology bin
875  represented by the output raster. For 1-day climatologies, this will
876  be the same as %(FirstDay)i.
877
878If the Bin Type is "Monthly", the following additional codes are
879available:
880
881* %(FirstMonth)i - first month of the climatology bin represented by
882  the output raster.
883
884* %(DayOfFirstMonth)i - first day of the first month of the
885  climatology bin represented by the output raster.
886
887* %(LastMonth)i - last month of the climatology bin represented by
888  the output raster.
889
890* %(DayOfLastMonth)i - last day of the last month of the climatology
891  bin represented by the output raster.
892
893Note that the additional codes are integers and may be formatted using
894"printf"-style formatting codes. For example, to format the FirstDay
895as a three-digit number with leading zeros::
896
897    %(FirstDay)03i
898"""),
899    arcGISDisplayName=_(u'Raster name expressions'))
900
901AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'binDuration',
902    typeMetadata=IntegerTypeMetadata(minValue=1),
903    description=_(
904u"""Duration of each bin, in days or months, when the Bin Type is
905Daily or Monthly, respectively. The default is 1. See the Bin Type
906parameter for more information."""),
907    arcGISDisplayName=_(u'Climatology bin duration'),
908    arcGISCategory=_(u'Climatology options'))
909
910AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'startDayOfYear',
911    typeMetadata=IntegerTypeMetadata(minValue=1, maxValue=365),
912    description=_(
913u"""Use this parameter to create bin defintions that deviate from the
914traditional calendar. The interpretation of this parameter depends on
915the Bin Type:
916
917* Daily - this parameter defines the day of the year of the first
918  climatology bin. For example, if this parameter is 100 and the Bin
919  Duration is 10, the first bin will be numbered 100-109. The bin
920  spanning the end of the year will be numbered 360-004. The last bin
921  will be numbered 095-099. To define a four-bin climatology with bins
922  that are centered approximately on the equinoxes and solstices
923  (i.e., a seasonal climatology), set the Bin Duration to 91 and the
924  start day to 36 (February 5). This will produce bins with dates
925  036-126, 127-217, 218-308, and 309-035.
926
927* Monthly - this parameter defines the day of the year of the first
928  climatology bin, and the day of the month of that bin will be used
929  as the first day of the month of all of the bins. For example, if
930  this parameter is 46, which is February 15, and the Bin Duration is
931  1, then the bins will be February 15 - March 14, March 15 - April
932  14, April 15 - May 14, and so on. Calculations involving this
933  parameter always assume a 365 day year (a non-leap year). To define
934  a four-bin climatology using the months traditionally associated
935  with spring, summer, fall, and winter in many northern hemisphere
936  cultures, set the Bin Duration to 3 and the start day to 60 (March
937  1). This will produce bins with months 03-05, 06-08, 09-11, and
938  12-02.
939
940* Cumulative - this parameter is ignored.
941"""),
942    arcGISDisplayName=_(u'Start climatology at this day of the year'),
943    arcGISCategory=_(u'Climatology options'))
944
945CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'rotationOffset', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'rotationOffset')
946CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'spatialExtent', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'spatialExtent')
947CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'startDate', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'startDate')
948CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'endDate', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'endDate')
949CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'timeout', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'timeout')
950CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'maxRetryTime', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'maxRetryTime')
951CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cacheDirectory', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'cacheDirectory')
952CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'calculateStatistics', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'calculateStatistics')
953CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'buildPyramids', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'buildPyramids')
954
955CopyResultMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'updatedOutputWorkspace', OSCAR5DayThirdDegreeCurrents.CreateClimatologicalArcGISRasters, u'updatedOutputWorkspace')
956
957# Public method: OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses
958
959AddMethodMetadata(OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses,
960    shortDescription=_(u'Creates line feature classes representing the vectors of NOAA OSCAR 5-day unfiltered 1/3 degree ocean surface currents.'),
961    longDescription=_(
962u"""The lines output by this tool are similar to those in a "quiver
963plot". When displayed on a map, they can help visualize the direction
964and speed of ocean currents. In ArcMap, select the "Arrow at End"
965symbology. You may also want to reduce the line decoration (the arrow)
966to a small size, such as 2.0.
967
968""") + _OSCAR_LongDescription % {u'name': 'tool'},
969    isExposedToPythonCallers=True,
970    isExposedByCOM=True,
971    isExposedAsArcGISTool=True,
972    arcGISDisplayName=_(u'Create Vectors for OSCAR Currents'),
973    arcGISToolCategory=_(u'Data Products\\NOAA OSCAR'),
974    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
975
976CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cls', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'cls')
977
978AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'outputWorkspace',
979    typeMetadata=ArcGISWorkspaceTypeMetadata(createParentDirectories=True),
980    description=_(
981u"""Directory or geodatabase to receive the feature classes.
982
983Unless you have a specific reason to store the feature classes in a
984geodatabase, we recommend you store them in a directory because it
985will be faster and allows them to be organized as a tree (of
986shapefiles). If you do store the feature classes in a geodatabase, you
987must change the Feature Class Name Expressions parameter; see below
988for more information."""),
989    arcGISDisplayName=_(u'Output workspace'))
990
991AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'mode',
992    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Add', u'Replace'], makeLowercase=True),
993    description=_(
994u"""Overwrite mode, one of:
995
996* Add - create feature classes that do not exist and skip those that
997  already exist. This is the default.
998
999* Replace - create feature classes that do not exist and overwrite
1000  those that already exist.
1001
1002The ArcGIS Overwrite Outputs geoprocessing setting has no effect on
1003this tool. If 'Replace' is selected the feature classes will be
1004overwritten, regardless of the ArcGIS Overwrite Outputs setting."""),
1005    arcGISDisplayName=_(u'Overwrite mode'))
1006
1007AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'featureClassNameExpressions',
1008    typeMetadata=ListTypeMetadata(elementType=UnicodeStringTypeMetadata(), minLength=1),
1009    description=_(
1010u"""List of expressions specifying how the output feature classes
1011should be named.
1012
1013The default expression assumes the output workspace is a directory and
1014creates shapefiles in a "uv_vectors" subdirectory with a subdirectory
1015level below that for each year.
1016
1017If the output workspace is a geodatabase, you should provide only one
1018or two expressions. If you provide one expression, it specifies the
1019feature class name. If you provide two, the first one specifies the
1020feature dataset name and the second specifies the feature class name.
1021
1022Each expression may contain any sequence of characters permitted by
1023the output workspace. Each expression may optionally contain one or
1024more of the following case-sensitive codes. The tool replaces the
1025codes with appropriate values when creating each feature class:
1026
1027* %%Y - four-digit year of the output feature class.
1028
1029* %%m - two-digit month of the output feature class.
1030
1031* %%d - two-digit day of the month of the output feature class.
1032
1033* %%j - three-digit day of the year of the output feature class.
1034"""),
1035    arcGISDisplayName=_(u'Feature class name expressions'))
1036
1037AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'scaleFactor',
1038    typeMetadata=FloatTypeMetadata(mustBeGreaterThan=0.0),
1039    description=_(
1040u"""Factor for scaling lines lengths.
1041
1042Use this parameter to scale the lines output by this tool to lengths
1043that are visually appealing. If the lines are too short, they will
1044resemble a grid of dots and you will not be able to discern the flow
1045of the vector field. If the lines are too long, they will overlap each
1046other and resemble a plate of spaghetti.
1047
1048If the vectors all have about the same magnitude, then a good approach
1049is to scale the lines so that the longest one is about as long as the
1050raster cell size. But if there are a few very long vectors, then you
1051may prefer to scale the lines so that the average-length vector is as
1052long as the raster cell size.
1053
1054For OSCAR geostrophic currents, the raster cell size is 1/3 degree and
1055currents are given in m/s. So, if the maximum (or mean) velocity in
1056your region of interest is about 0.75 m/s:
1057
1058    scale factor = 0.333 / 0.75 = 0.444
1059"""),
1060    arcGISDisplayName=_(u'Scale factor'),
1061    arcGISCategory=_(u'Vector options'))
1062
1063AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'uniformLength',
1064    typeMetadata=BooleanTypeMetadata(),
1065    description=_(
1066u"""If False (the default) then the lengths of the lines are
1067determined by multiplying the magnitude of the vector by the Scale
1068Factor parameter.
1069
1070If True, all lines will have the same length, which will be determined
1071by multiplying the cell size of the OSCAR grids (i.e. 1/3 degree) by
1072the the Scale Factor. Use this option when you want to the lines'
1073colors to indicate the magnitude of the vector, rather than the lines'
1074lengths. Start with a Scale Factor of 1 and increase it or decrease it
1075slightly to achieve the desired visual effect."""),
1076    arcGISDisplayName=_(u'Create all lines with the same length'),
1077    arcGISCategory=_(u'Vector options'))
1078
1079CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'rotationOffset', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'rotationOffset')
1080CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'spatialExtent', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'spatialExtent')
1081CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'startDate', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'startDate')
1082CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'endDate', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'endDate')
1083CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'timeout', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'timeout')
1084CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'maxRetryTime', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'maxRetryTime')
1085CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cacheDirectory', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'cacheDirectory')
1086
1087CopyResultMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'updatedOutputWorkspace', OSCAR5DayThirdDegreeCurrents.CreateVectorsAsArcGISFeatureClasses, u'updatedOutputWorkspace')
1088
1089# Public method: OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints
1090
1091AddMethodMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints,
1092    shortDescription=_(u'Interpolates the values of NOAA OSCAR 5-day unfiltered 1/3 degree ocean surface currents at points.'),
1093    longDescription=_(
1094u"""This tool performs the same basic operation as the ArcGIS Spatial
1095Analyst's Extract Values to Points tool, but it reads data directly
1096from OSCAR's server using the `OPeNDAP <http://opendap.org/>`_
1097protocol, rather than reading rasters stored on your machine.
1098
1099""") + _OSCAR_LongDescription % {u'name': 'tool'},
1100    isExposedToPythonCallers=True,
1101    isExposedByCOM=True,
1102    isExposedAsArcGISTool=True,
1103    arcGISDisplayName=_(u'Interpolate OSCAR Currents at Points'),
1104    arcGISToolCategory=_(u'Data Products\\NOAA OSCAR'),
1105    dependencies=[ArcGISDependency(9, 1), PythonAggregatedModuleDependency('numpy')])
1106
1107CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cls', OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'cls')
1108CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'parameter', OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'parameter')
1109
1110AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'points',
1111    typeMetadata=ArcGISFeatureLayerTypeMetadata(mustExist=True, allowedShapeTypes=[u'Point']),
1112    description=_(u'Points at which values should be interpolated.'),
1113    arcGISDisplayName=_(u'Point features'))
1114
1115AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'valueField',
1116    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'short', u'long', u'float', u'double']),
1117    description=_(
1118u"""Field of the points to receive the interpolated values.
1119
1120The field must have a floating-point or integer data type. If the
1121field cannot represent the interpolated value at full precision, the
1122closest approximation will be stored and a warning will be issued.
1123This will happen, for example, when you interpolate values into an
1124integer field."""),
1125    arcGISDisplayName=_(u'Field to receive the interpolated values'),
1126    arcGISParameterDependencies=[u'points'])
1127
1128AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'tField',
1129    typeMetadata=ArcGISFieldTypeMetadata(mustExist=True, allowedFieldTypes=[u'date']),
1130    description=_(
1131u"""Field of the points that specifies the date and time of the point.
1132
1133The field must have a date or datetime data type. If the field can
1134only represent dates with no time component, the time will assumed to
1135be 00:00:00.
1136
1137The OSCAR products use the UTC time zone, and it is assumed that the
1138points do as well."""),
1139    arcGISDisplayName=_(u'Date field'),
1140    arcGISParameterDependencies=[u'points'])
1141
1142AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'method',
1143    typeMetadata=UnicodeStringTypeMetadata(allowedValues=[u'Nearest', u'Linear'], makeLowercase=True),
1144    description=_(
1145u"""Interpolation method to use, one of:
1146
1147* Nearest - nearest neighbor interpolation. The interpolated value
1148  will simply be the value of the cell that contains the point. This
1149  is the default.
1150
1151* Linear - linear interpolation (also known as trilinear
1152  interpolation). This method averages the values of the eight nearest
1153  cells in the x, y, and time dimensions, weighting the contribution
1154  of each cell by the area of it that would be covered by a
1155  hypothetical cell centered on the point being interpolated. If the
1156  cell containing the point contains NoData, the result is NoData. If
1157  any of the other seven cells contain NoData, they are omitted from
1158  the average, and the result is based on the weighted average of the
1159  cells that do contain data. This is the same algorithm implemented
1160  by the ArcGIS Spatial Analyst's Extract Values to Points tool.
1161"""),
1162    arcGISDisplayName=_(u'Interpolation method'))
1163
1164AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'where',
1165    typeMetadata=SQLWhereClauseTypeMetadata(canBeNone=True),
1166    description=_(
1167u"""SQL WHERE clause expression that specifies the subset of points to
1168use. If this parameter is not provided, all of the points will be
1169used.
1170
1171The exact syntax of this expression depends on the type of feature
1172class you're using. ESRI recommends you reference fields using the
1173following syntax:
1174
1175* For shapefiles, ArcInfo coverages, or feature classes stored in file
1176  geodatabases, ArcSDE geodatabases, or ArcIMS, enclose field names in
1177  double quotes: "MY_FIELD"
1178
1179* For feature classes stored in personal geodatabases, enclose field
1180  names in square brackets: [MY_FIELD].
1181"""),
1182    arcGISDisplayName=_(u'Where clause'),
1183    arcGISCategory=_(u'Interpolation options'),
1184    arcGISParameterDependencies=[u'points'])
1185
1186AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'noDataValue',
1187    typeMetadata=FloatTypeMetadata(canBeNone=True),
1188    description=_(
1189u"""Value to use when the interpolated value is NoData.
1190
1191If a value is not provided for this parameter, a database NULL value
1192will be stored in the field when the interpolated value is NoData. If
1193the field cannot store NULL values, as is the case with shapefiles,
1194the value -9999 will be used."""),
1195    arcGISDisplayName=_(u'Value to use when the interpolated value is NoData'),
1196    arcGISCategory=_(u'Interpolation options'))
1197
1198CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'timeout', OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'timeout')
1199CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'maxRetryTime', OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'maxRetryTime')
1200CopyArgumentMetadata(OSCAR5DayThirdDegreeCurrents.CreateArcGISRasters, u'cacheDirectory', OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'cacheDirectory')
1201
1202AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'orderByFields',
1203    typeMetadata=ListTypeMetadata(elementType=ArcGISFieldTypeMetadata(mustExist=True), minLength=1, canBeNone=True),
1204    description=_(
1205u"""Fields for defining the order in which the points are processed.
1206
1207The points may be processed faster if they are ordered
1208spatiotemporally, such that points that are close in space and time
1209are processed sequentially. Ordering the points this way increases the
1210probability that the value of a given point can be interpolated from
1211data that is cached in memory, rather than from data that must be read
1212from the disk or network, which is much slower. Choose fields that
1213faciliate this. For example, if your points represent the locations of
1214animals tracked by satellite telemetry, order the processing first by
1215the animal ID and then by the transmission date or number.
1216
1217If you omit this parameter, the Date Field will be used automatically.
1218
1219This parameter requires ArcGIS 9.2 or later."""),
1220    arcGISDisplayName=_(u'Order by fields'),
1221    arcGISCategory=_(u'Performance tuning options'),
1222    arcGISParameterDependencies=[u'points'],
1223    dependencies=[ArcGISDependency(9, 2)])
1224
1225AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'numBlocksToCacheInMemory',
1226    typeMetadata=IntegerTypeMetadata(minValue=0, canBeNone=True),
1227    description=_(
1228u"""Maximum number of blocks of OSCAR data to cache in memory.
1229
1230To minimize the number of times that the disk or network must be
1231accessed, this tool employs a simple caching strategy, in addition to
1232disk caching described by the Cache Directory parameter. When it
1233processes the first point, it reads a square block of cells centered
1234on that point and caches it in memory. When it processes the second
1235and subsequent points, it first checks whether the cells needed for
1236that point are contained by the block cached in memory. If so, it
1237processes that point using the in-memory block, rather than reading
1238from disk or the network again. If not, it reads another square block
1239centered on that point and adds it to the cache.
1240
1241The tool processes the remaining points, adding additional blocks to
1242the cache, as needed. To prevent the cache from exhausing all memory,
1243it is only permitted to grow to the size specified by this parameter.
1244When the cache is full but a new block is needed, the oldest block is
1245discarded to make room for the newest block.
1246
1247The maximum size of the cache in bytes may be calculated by
1248multiplying 4 by the number of blocks and by the block sizes. For
1249example, if there are 128 blocks with size x=32 by y=32 by t=2, the
1250maximum size of the cache is 1048576 bytes (1 MB).
1251
1252If this parameter is 0, no blocks will be cached in memory."""),
1253    arcGISDisplayName=_(u'Number of blocks of data to cache in memory'),
1254    arcGISCategory=_(u'Performance tuning options'))
1255
1256AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'xBlockSize',
1257    typeMetadata=IntegerTypeMetadata(minValue=0, canBeNone=True),
1258    description=_(
1259u"""Size of the blocks of OSCAR data to cache in memory, in the x
1260direction (longitude). The size is given as the number of cells.
1261
1262If this parameter is 0, no blocks will be cached in memory."""),
1263    arcGISDisplayName=_(u'In-memory cache block size, in X direction'),
1264    arcGISCategory=_(u'Performance tuning options'))
1265
1266AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'yBlockSize',
1267    typeMetadata=IntegerTypeMetadata(minValue=0, canBeNone=True),
1268    description=_(
1269u"""Size of the blocks of OSCAR data to cache in memory, in the y
1270direction (latitude). The size is given as the number of cells.
1271
1272If this parameter is 0, no blocks will be cached in memory."""),
1273    arcGISDisplayName=_(u'In-memory cache block size, in Y direction'),
1274    arcGISCategory=_(u'Performance tuning options'))
1275
1276AddArgumentMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'tBlockSize',
1277    typeMetadata=IntegerTypeMetadata(minValue=0, canBeNone=True),
1278    description=_(
1279u"""Size of the blocks of OSCAR data to cache in memory, in the t
1280direction (time). The size is given as the number of cells.
1281
1282If this parameter is 0, no blocks will be cached in memory."""),
1283    arcGISDisplayName=_(u'In-memory cache block size, in T direction'),
1284    arcGISCategory=_(u'Performance tuning options'))
1285
1286AddResultMetadata(OSCAR5DayThirdDegreeCurrents.InterpolateAtArcGISPoints, u'updatedPoints',
1287    typeMetadata=ArcGISFeatureLayerTypeMetadata(),
1288    description=_(u'Updated points.'),
1289    arcGISDisplayName=_(u'Updated points'),
1290    arcGISParameterDependencies=[u'points'])
1291
1292###############################################################################
1293# Names exported by this module
1294###############################################################################
1295
1296__all__ = ['OSCAR5DayThirdDegreeCurrents']
Note: See TracBrowser for help on using the browser.