1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
from numpy import array as numpy_array
from numpy import reshape as numpy_reshape
from numpy.ma import masked as numpy_ma_masked
from numpy.ma import resize as numpy_ma_resize
from numpy.ma import where as numpy_ma_where
from operator import mul
from .functions import _open_netcdf_file, _close_netcdf_file
from ..data.filearray import FileArray
# ====================================================================
#
# NetCDFFileArray object
#
# ====================================================================
class NetCDFFileArray(FileArray):
'''
A sub-array stored in a netCDF file.
**Initialization**
:Parameters:
file : str
The netCDF file name in normalized, absolute form.
dtype : numpy.dtype
The numpy data type of the data array.
ndim : int
Number of dimensions in the data array.
shape : tuple
The data array's dimension sizes.
size : int
Number of elements in the data array.
ncvar : str, optional
The netCDF variable name containing the data array. Must be
set if *varid* is not set.
varid : int, optional
The netCDF ID of the variable containing the data array. Must
be set if *ncvar* is not set. Ignored if *ncvar* is set.
:Examples:
>>> import netCDF4
>>> import os
>>> nc = netCDF4.Dataset('file.nc', 'r')
>>> v = nc.variable['tas']
>>> a = NetCDFFileArray(file=os.path.abspath('file.nc'), ncvar='tas',
dtype=v.dtype, ndim=v.ndim, shape=v.shape, size=v.size)
'''
def __getitem__(self, indices):
'''
x.__getitem__(indices) <==> x[indices]
Returns a numpy array.
'''
nc = self.open()
ncvar = getattr(self, 'ncvar', None)
if ncvar is not None:
# Get the variable by name
array = nc.variables[ncvar][indices]
else:
# Get the variable by netCDF ID
varid = self.varid
for value in nc.variables.itervalues():
if value._varid == varid:
array = value[indices]
break
#--- End: if
if not self.ndim:
# Hmm netCDF4 has a thing for making scalar size 1 , 1d
array = array.squeeze()
# ------------------------------------------------------------
# If approriate, collapse (by concatenation) the outermost
# (fastest varying) dimension of string valued array into
# memory. E.g. [['a','b','c']] becomes ['abc']
# ------------------------------------------------------------
if array.dtype.kind == 'S' and array.ndim > self.ndim:
strlen = array.shape[-1]
new_shape = array.shape[0:-1]
new_size = long(reduce(mul, new_shape, 1))
array = numpy_ma_resize(array, (new_size, strlen))
array = array.filled(fill_value='')
array = numpy_array([''.join(x).rstrip() for x in array],
dtype='S%d' % strlen)
array = array.reshape(new_shape)
array = numpy_ma_where(array=='', numpy_ma_masked, array)
#--- End: if
return array
#--- End: def
def __str__(self):
'''
x.__str__() <==> str(x)
'''
name = getattr(self, 'ncvar', None)
if name is None:
name = self.varid
return "%s%s in %s" % (name, self.shape, self.file)
#--- End: def
def close(self):
'''
Close the file containing the data array.
If the file is not open then no action is taken.
:Returns:
None
:Examples:
>>> f.close()
'''
_close_netcdf_file(self.file)
#--- End: def
@property
def file_pointer(self):
'''
'''
offset = getattr(self, 'ncvar', None)
if offset is None:
offset = self.varid
return (self.file, offset)
#--- End: def
def open(self):
'''
Return a `netCDF4.Dataset` object for the file containing the data
array.
:Returns:
out : netCDF4.Dataset
:Examples:
>>> f.open()
<netCDF4.Dataset at 0x115a4d0>
'''
return _open_netcdf_file(self.file, 'r')
#--- End: def
#--- End: class
|