Exemplo n.º 1
0
    def __getitem__(self, indices):
        if self.variable.getDataType() in [DataType.STRUCTURE, DataType.SEQUENCE]:
            if isinstance(indices, str):    #metadata
                return self.member_array(indices)
            else:
                a = self.dataset.read(self.name)
                return StructureArray(a.getArrayObject())

        if indices is None:
            inds = []
            for i in range(self.ndim):
                inds.append(slice(None))
            indices = tuple(inds)
        
        if not isinstance(indices, tuple):
            inds = []
            inds.append(indices)
            indices = inds
            
        if len(indices) < self.ndim:
            indices = list(indices)
            for i in range(self.ndim - len(indices)):
                indices.append(slice(None))
            indices = tuple(indices)
        
        if len(indices) != self.ndim:
            print 'indices must be ' + str(self.ndim) + ' dimensions!'
            return None
            
        if not self.proj is None and not self.proj.isLonLat():
            xlim = None
            ylim = None
            xidx = -1
            yidx = -1
            for i in range(0, self.ndim):
                dim = self.dims[i]
                if dim.getDimType() == DimensionType.X:                    
                    k = indices[i]
                    if isinstance(k, basestring):
                        xlims = k.split(':')
                        if len(xlims) == 1:
                            xlim = [float(xlims[0])]
                        else:
                            xlim = [float(xlims[0]), float(xlims[1])]
                        xidx = i
                elif dim.getDimType() == DimensionType.Y:
                    k = indices[i]
                    if isinstance(k, basestring):
                        ylims = k.split(':')
                        if len(ylims) == 1:
                            ylim = [float(ylims[0])]
                        else:
                            ylim = [float(ylims[0]), float(ylims[1])]
                        yidx = i
            if not xlim is None and not ylim is None:                
                fromproj=KnownCoordinateSystems.geographic.world.WGS1984
                inpt = PointD(xlim[0], ylim[0])
                outpt1 = Reproject.reprojectPoint(inpt, fromproj, self.proj)
                if len(xlim) == 1:
                    xlim = [outpt1.X]
                    ylim = [outpt1.Y]
                else:
                    inpt = PointD(xlim[1], ylim[1])
                    outpt2 = Reproject.reprojectPoint(inpt, fromproj, self.proj)
                    xlim = [outpt1.X, outpt2.X]
                    ylim = [outpt1.Y, outpt2.Y]
                indices1 = []
                for i in range(0, self.ndim):
                    if i == xidx:
                        if len(xlim) == 1:
                            indices1.append(str(xlim[0]))
                        else:
                            indices1.append(str(xlim[0]) + ':' + str(xlim[1]))
                    elif i == yidx:
                        if len(ylim) == 1:
                            indices1.append(str(ylim[0]))
                        else:
                            indices1.append(str(ylim[0]) + ':' + str(ylim[1]))
                    else:
                        indices1.append(indices[i])
                indices = indices1
        
        origin = []
        size = []
        stride = []
        ranges = []
        dims = []
        flips = []
        onlyrange = True
        for i in range(0, self.ndim):  
            isrange = True
            dimlen = self.dimlen(i)
            k = indices[i]
            if isinstance(k, int):
                if k < 0:
                    k = self.dims[i].getLength() + k
                sidx = k
                eidx = k
                step = 1
            elif isinstance(k, slice):
                if isinstance(k.start, basestring):
                    sv = float(k.start)
                    sidx = self.dims[i].getValueIndex(sv)
                elif isinstance(k.start, datetime.datetime):
                    sv = miutil.date2num(k.start)
                    sidx = self.dims[i].getValueIndex(sv)
                else:
                    sidx = 0 if k.start is None else k.start
                if sidx < 0:
                    sidx = self.dimlen(i) + sidx
                    
                if isinstance(k.stop, basestring):
                    ev = float(k.stop)
                    eidx = self.dims[i].getValueIndex(ev)
                elif isinstance(k.stop, datetime.datetime):
                    ev = miutil.date2num(k.stop)
                    eidx = self.dims[i].getValueIndex(ev)
                else:
                    eidx = self.dimlen(i) if k.stop is None else k.stop
                    if eidx < 0:
                        eidx = self.dimlen(i) + eidx
                    eidx -= 1
                    
                if isinstance(k.step, basestring):
                    nv = float(k.step) + self.dims[i].getDimValue()[0]
                    nidx = self.dims[i].getValueIndex(nv)
                    step = nidx - sidx
                elif isinstance(k.step, datetime.timedelta):
                    nv = miutil.date2num(k.start + k.step)
                    nidx = self.dims[i].getValueIndex(nv)
                    step = nidx - sidx
                else:
                    step = 1 if k.step is None else k.step
                if sidx > eidx:
                    iidx = eidx
                    eidx = sidx
                    sidx = iidx
            elif isinstance(k, list):
                onlyrange = False
                isrange = False
                if not isinstance(k[0], datetime.datetime):
                    ranges.append(k)
                else:
                    tlist = []
                    for tt in k:
                        sv = miutil.date2num(tt)
                        idx = self.dims[i].getValueIndex(sv)
                        tlist.append(idx)
                    ranges.append(tlist)
                    k = tlist
            elif isinstance(k, basestring):
                dim = self.variable.getDimension(i)
                kvalues = k.split(':')
                sv = float(kvalues[0])
                sidx = dim.getValueIndex(sv)
                if len(kvalues) == 1:
                    eidx = sidx
                    step = 1
                else:                    
                    ev = float(kvalues[1])
                    eidx = dim.getValueIndex(ev)
                    if len(kvalues) == 2:
                        step = 1
                    else:
                        step = int(float(kvalues[2]) / dim.getDeltaValue())
                    if sidx > eidx:
                        iidx = eidx
                        eidx = sidx
                        sidx = iidx
            else:
                print k
                return None
            if isrange:
                if eidx >= dimlen:
                    print 'Index out of range!'
                    return None
                origin.append(sidx)
                n = eidx - sidx + 1
                size.append(n)                   
                if n > 1:
                    dim = self.variable.getDimension(i)
                    if dim.isReverse():
                        step = -step      
                    dim = dim.extract(sidx, eidx, step)
                    dim.setReverse(False)
                    dims.append(dim)
                stride.append(step) 
                if step < 0:
                    step = abs(step)
                    flips.append(i)
                rr = Range(sidx, eidx, step)
                ranges.append(rr)
            else:
                if len(k) > 1:
                    dim = self.variable.getDimension(i)
                    dim = dim.extract(k)
                    dim.setReverse(False)
                    dims.append(dim)
        #rr = self.dataset.read(self.name, origin, size, stride).reduce()
        if onlyrange:
            rr = self.dataset.dataset.read(self.name, ranges)
        else:
            rr = self.dataset.dataset.take(self.name, ranges)
        if rr.getSize() == 1:
            iter = rr.getIndexIterator()
            return iter.getObjectNext()
        else:
            for i in flips:
                rr = rr.flip(i)
            rr = rr.reduce()
            ArrayMath.missingToNaN(rr, self.fill_value)
            if len(flips) > 0:
                rrr = Array.factory(rr.getDataType(), rr.getShape())
                MAMath.copy(rrr, rr)
                array = np.array(rrr)
            else:
                array = np.array(rr)
            data = np.DimArray(array, dims, self.fill_value, self.dataset.proj)
            return data
Exemplo n.º 2
0
    def __getitem__(self, indices):
        if not isinstance(indices, tuple):
            inds = []
            inds.append(indices)
            indices = inds

        if len(indices) < self.ndim:
            indices = list(indices)
            for i in range(self.ndim - len(indices)):
                indices.append(slice(None))
            indices = tuple(indices)

        if len(indices) != self.ndim:
            print 'indices must be ' + str(self.ndim) + ' dimensions!'
            return None
        
        k = indices[0]
        if isinstance(k, int):
            sidx = k
            eidx = k
            step = 1
        elif isinstance(k, slice):
            sidx = 0 if k.start is None else k.start
            if sidx < 0:
                sidx = self.tnum + sidx
            eidx = self.tnum if k.stop is None else k.stop
            if eidx < 0:
                eidx = self.tnum + eidx
            eidx -= 1
            step = 1 if k.step is None else k.step
        elif isinstance(k, list):
            sidx = self.dataset.timeindex(k[0])
            if len(k) == 1:
                eidx = sidx
                step = 1
            else:
                eidx = self.dataset.timeindex(k[1])
                if len(k) == 3:
                    tt = self.dataset.timeindex(k[0] + k[3])
                    step = tt - sidx
                else:
                    step = 1
        
        sfidx = self.dataset.datafileindex(sidx)
        si = sidx
        isfirst = True
        times = []
        fidx = sfidx
        aa = None
        var = None
        for i in range(sidx, eidx + 1, step):
            times.append(miutil.date2num(self.dataset.gettime(i)))
            fidx = self.dataset.datafileindex(i) 
            if fidx > sfidx:
                ei = i - step
                ddf = self.dataset[sfidx]
                var = ddf[self.name]
                ii, ssi = self.dataset.dftindex(si)
                ii, eei = self.dataset.dftindex(ei)
                eei += 1
                nindices = list(indices)                
                nindices[0] = slice(ssi, eei, step)
                nindices = tuple(nindices)
                aa = var.__getitem__(nindices)
                if si == ei:
                    if isinstance(aa, np.DimArray):
                        aa.addtdim(self.dataset.gettime(si))
                    else:
                        aa = np.array([aa])
                        aa = np.DimArray(aa)
                        aa.addtdim(self.dataset.gettime(si))
                if isfirst:
                    data = aa
                    isfirst = False
                else:
                    data = np.concatenate([data, aa])
                si = i
                sfidx = fidx
                
        if si < eidx + 1:            
            ei = eidx + 1 - step
            ddf = self.dataset[sfidx]
            var = ddf[self.name]
            ii, ssi = self.dataset.dftindex(si)
            ii, eei = self.dataset.dftindex(ei)
            eei += 1
            nindices = list(indices)
            nindices[0] = slice(ssi, eei, step)
            nindices = tuple(nindices)
            aa = var.__getitem__(nindices)
            if si == ei and eidx != sidx:
                if isinstance(aa, np.DimArray):
                    aa.addtdim(self.dataset.gettime(si))
                else:
                    aa = np.array([aa])
                    aa = np.DimArray(aa)
                    aa.addtdim(self.dataset.gettime(si))
            if isfirst:
                data = aa
                isfirst = False
            else:
                data = np.concatenate([data, aa])
        
        if aa is None:
            sfidx = self.dataset.datafileindex(sidx)
            ddf = self.dataset[sfidx]
            var = ddf[self.name]
            ii, ssi = self.dataset.dftindex(sidx)
            nindices = list(indices)
            nindices[0] = slice(ssi, ssi, step)
            nindices = tuple(nindices)
            aa = var.__getitem__(nindices)            
            return aa
                
        if isinstance(data, np.DimArray):
            return data
        else:
            dims = aa.dims
            dims[0].setDimValues(times)
            r = np.DimArray(data, dims, aa.fill_value, aa.proj)
            return r