def __getitem__(self, index): """ Read PhysArray from file """ with Dataset(self._filepath, 'r') as ncfile: # Get a reference to the variable ncvar = ncfile.variables[self._variable] # Get the attributes into a dictionary, for convenience attrs = {a: ncvar.getncattr(a) for a in ncvar.ncattrs()} # Read the variable units units_attr = attrs.get('units', 1) calendar_attr = attrs.get('calendar', None) try: units = Unit(units_attr, calendar=calendar_attr) except ValueError: msg = 'Units {!r} unrecognized in UDUNITS. Assuming unitless.'.format( units_attr) warn(msg, UnitsWarning) units = Unit(1) except: raise # Read the original variable dimensions dimensions0 = ncvar.dimensions # Read the original variable shape shape0 = ncvar.shape # Align the read-indices on dimensions index1 = align_index(self._index, dimensions0) # Get the dimensions after application of the first index dimensions1 = tuple(d for d, i in zip( dimensions0, index1) if isinstance(i, slice)) # Align the second index on the intermediate dimensions index2 = align_index(index, dimensions1) # Get the dimensions after application of the second index dimensions2 = tuple(d for d, i in zip( dimensions1, index2) if isinstance(i, slice)) # Compute the joined index object index12 = join(shape0, index1, index2) data = ncvar[index12] # Upconvert, if possible if issubclass(ncvar.dtype.type, numpy.float) and ncvar.dtype.itemsize < 8: data = data.astype(numpy.float64) # Read the positive attribute, if available pos = attrs.get('positive', None) return PhysArray(data, name=self.label, units=units, dimensions=dimensions2, positive=pos)
def test_dict(self): indata = ({'a': slice(1, 5, 2), 'b': 6}, ('a', 'b', 'c')) testname = 'align_index({}, {})'.format(*indata) actual = align_index(*indata) expected = (indata[0]['a'], indata[0]['b'], slice(None)) print_test_message(testname, indata=indata, actual=actual, expected=expected) self.assertEqual(actual, expected, '{} failed'.format(testname))
def test_tuple(self): indata = ((4, slice(1, 5, 2)), ('a', 'b', 'c')) testname = 'align_index({}, {})'.format(*indata) actual = align_index(*indata) expected = indata[0] + (slice(None), ) print_test_message(testname, indata=indata, actual=actual, expected=expected) self.assertEqual(actual, expected, '{} failed'.format(testname))
def __getitem__(self, index): idx = align_index(index, self.dimensions) if len(idx) == 0: return self else: dimensions = tuple(d for i, d in zip(idx, self.dimensions) if isinstance(i, slice)) if dimensions != self.dimensions: return PhysArray(super(PhysArray, self).__getitem__(idx), dimensions=dimensions) else: return super(PhysArray, self).__getitem__(idx)
def test_dict(self): indata = ({"a": slice(1, 5, 2), "b": 6}, ("a", "b", "c")) testname = "align_index({}, {})".format(*indata) actual = align_index(*indata) expected = (indata[0]["a"], indata[0]["b"], slice(None)) print_test_message(testname, indata=indata, actual=actual, expected=expected) self.assertEqual(actual, expected, "{} failed".format(testname))
def test_tuple(self): indata = ((4, slice(1, 5, 2)), ("a", "b", "c")) testname = "align_index({}, {})".format(*indata) actual = align_index(*indata) expected = indata[0] + (slice(None), ) print_test_message(testname, indata=indata, actual=actual, expected=expected) self.assertEqual(actual, expected, "{} failed".format(testname))
def __setitem__(self, index, values): idx = align_index(index, self.dimensions) if isinstance(values, PhysArray): values = values.convert(self.units).transpose(self.dimensions) super(PhysArray, self).__setitem__(idx, values)