def paddingFourier(arr, shape, value=0, interpolate=True): """ arr: assuming origin at 0, rfft product (half x size), up to 3D shape: target shape value: the value to fill in empty part interpolate: shift by interpolation if necessary return array with target shape """ # prepare buffer dtype = arr.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calc and shift shapeS = N.array(arr.shape) shapeL = N.asarray(shape) halfS = shapeS / 2. subpx_shift = halfS % 1 if interpolate and N.sometrue(subpx_shift): arr = U.nd.shift(arr, subpx_shift) halfS = [int(s) for s in halfS] # create empty list for slices nds = arr.ndim - 1 choices = ['slice(halfS[%i])', 'slice(-halfS[%i], None)'] nchoices = len(choices) nds2 = nds**2 slcs = [] for ns in range(nds2): slcs.append([]) for n in range(nchoices * nds): slcs[ns].append( [Ellipsis]) # Ellipsis help to make arbitray number of list # fill the empty list by slice (here I don't know how to use 4D..) for i in range(nds2): for d in range(nds): for x in range(nds): for c, choice in enumerate(choices): if d == 0 and x == 0: idx = x * (nchoices) + c else: # how can I use 4D?? idx = x * (nchoices) + (nchoices - 1) - c exec('content=' + choice % d) slcs[i][idx] += [content] # cutout and paste for slc in slcs: for s in slc: s.append(slice(int(shapeS[-1]))) #print s canvas[s] = arr[s] return canvas
def paddingFourier(arr, shape, value=0, interpolate=True): """ arr: assuming origin at 0, rfft product (half x size), up to 3D shape: target shape value: the value to fill in empty part interpolate: shift by interpolation if necessary return array with target shape """ # prepare buffer dtype = arr.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calc and shift shapeS = N.array(arr.shape) shapeL = N.asarray(shape) halfS = shapeS / 2. subpx_shift = halfS % 1 if interpolate and N.sometrue(subpx_shift): arr = U.nd.shift(arr, subpx_shift) halfS = [int(s) for s in halfS] # create empty list for slices nds = arr.ndim - 1 choices = ['slice(halfS[%i])', 'slice(-halfS[%i], None)'] nchoices = len(choices) nds2 = nds**2 slcs = [] for ns in range(nds2): slcs.append([]) for n in range(nchoices*nds): slcs[ns].append([Ellipsis]) # Ellipsis help to make arbitray number of list # fill the empty list by slice (here I don't know how to use 4D..) for i in range(nds2): for d in range(nds): for x in range(nds): for c, choice in enumerate(choices): if d == 0 and x == 0: idx = x*(nchoices) + c else: # how can I use 4D?? idx = x*(nchoices) + (nchoices-1) - c exec('content=' + choice % d) slcs[i][idx] += [content] # cutout and paste for slc in slcs: for s in slc: s.append(slice(int(shapeS[-1]))) #print s canvas[s] = arr[s] return canvas
def evenShapeArr(a): """ return even shaped array """ shapeA = N.asarray(a.shape) shapeM = shapeA.copy() for i,s in enumerate(shapeM): if not i and s == 1: continue elif s % 2: shapeM[i] -= 1 #sy,sx = shapeA #if sx % 2:# or sy %2: # sx += 1 #if sy % 2: # sy += 1 #shapeM = N.array([sy, sx]) if N.sometrue(shapeA < shapeM): a = paddingMed(a, shapeM) elif N.sometrue(shapeA > shapeM): a = cutOutCenter(a, shapeM, interpolate=False) return a
def evenShapeArr(a): """ return even shaped array """ shapeA = N.asarray(a.shape) shapeM = shapeA.copy() for i, s in enumerate(shapeM): if not i and s == 1: continue elif s % 2: shapeM[i] -= 1 #sy,sx = shapeA #if sx % 2:# or sy %2: # sx += 1 #if sy % 2: # sy += 1 #shapeM = N.array([sy, sx]) if N.sometrue(shapeA < shapeM): a = paddingMed(a, shapeM) elif N.sometrue(shapeA > shapeM): a = cutOutCenter(a, shapeM, interpolate=False) return a
def paddingValue(img, shape, value=0, shift=None, smooth=0, interpolate=True): """ shape: in the same dimension as img value: value in padded region, can be scaler or array with the shape shift: scaler or in the same dimension as img and shape (default 0) smooth: scaler value to smoothen border (here value must be scaler) interpolate: shift array by subpixel interpolation to adjust center return: padded array with shape """ # create buffer dtype = img.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calculate position shape = N.array(shape) shapeS = img.shape center = N.divide(shape, 2) if shift is None: shift = 0#[0] * len(shapeS) shapeL = shape#N.add(shapeS, center+shift) #start, stop = (shapeL - shapeS)/2., (shapeL + shapeS)/2. start = N.round_((shapeL - shapeS)/2.).astype(N.int) stop = shapeS + start slc = [slice(start[d], stop[d], None) for d in range(img.ndim)] #slc = [slice(int(round(start[d])), int(round(stop[d])), None) for d in range(img.ndim)] #print slc, shapeS, shapeL # shift if necessary if interpolate: subpx_shift = start % 1 # should be 0.5 or 0 if N.sometrue(subpx_shift): img = U.nd.shift(img, subpx_shift) # padding canvas[slc] = img if smooth: canvas = _smoothBorder(canvas, start, stop, smooth, value) canvas = N.ascontiguousarray(canvas) #print shapeS, shapeL, slc return canvas
def paddingValue(img, shape, value=0, shift=None, smooth=0, interpolate=True): """ shape: in the same dimension as img value: value in padded region, can be scaler or array with the shape shift: scaler or in the same dimension as img and shape (default 0) smooth: scaler value to smoothen border (here value must be scaler) interpolate: shift array by subpixel interpolation to adjust center return: padded array with shape """ # create buffer dtype = img.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calculate position shape = N.array(shape) shapeS = img.shape center = N.divide(shape, 2) if shift is None: shift = 0 #[0] * len(shapeS) shapeL = shape #N.add(shapeS, center+shift) #start, stop = (shapeL - shapeS)/2., (shapeL + shapeS)/2. start = N.round_((shapeL - shapeS) / 2.).astype(N.int) stop = shapeS + start slc = [slice(start[d], stop[d], None) for d in range(img.ndim)] #slc = [slice(int(round(start[d])), int(round(stop[d])), None) for d in range(img.ndim)] #print slc, shapeS, shapeL # shift if necessary if interpolate: subpx_shift = start % 1 # should be 0.5 or 0 if N.sometrue(subpx_shift): img = U.nd.shift(img, subpx_shift) # padding canvas[slc] = img if smooth: canvas = _smoothBorder(canvas, start, stop, smooth, value) canvas = N.ascontiguousarray(canvas) #print shapeS, shapeL, slc return canvas
def rotateIndicesND(slicelist, dtype=N.float64, rot=0, mode=2): """ slicelist: even shape works much better than odd shape rot: counter-clockwise, xy-plane mode: testing different ways of doing, (1 or 2 and the same result) return inds, LD """ global INDS_DIC shape = [] LD = [] for sl in slicelist: if isinstance(sl, slice): shape.append(sl.stop - sl.start) LD.append(sl.start) shapeTuple = tuple(shape + [rot]) if shapeTuple in INDS_DIC: inds = INDS_DIC[shapeTuple] else: shape = N.array(shape) ndim = len(shape) odd_even = shape % 2 s2 = N.ceil(shape * (2**0.5)) if mode == 1: # everything is even s2 = N.where(s2 % 2, s2 + 1, s2) elif mode == 2: # even & even or odd & odd for d, s in enumerate(shape): if (s % 2 and not s2[d] % 2) or (not s % 2 and s2[d] % 2): s2[d] += 1 cent = s2 / 2. dif = (s2 - shape) / 2. dm = dif % 1 # print s2, cent, dif, dm slc = [Ellipsis] + [ slice(int(d), int(d) + shape[i]) for i, d in enumerate(dif) ] # This slice is float which shift array when cutting out!! s2 = tuple([int(ss) for ss in s2]) # numpy array cannot use used for slice inds = N.indices(s2, N.float32) ind_shape = inds.shape nz = N.product(ind_shape[:-2]) nsec = nz / float(ndim) if ndim > 2: inds = N.reshape(inds, (nz, ) + ind_shape[-2:]) irs = N.empty_like(inds) for d, ind in enumerate(inds): idx = int(d // nsec) c = cent[idx] if rot and inds.ndim > 2: U.trans2d(ind - c, irs[d], (0, 0, rot, 1, 0, 1)) irs[d] += c - dif[idx] else: irs[d] = ind - dif[idx] if len(ind_shape) > 2: irs = N.reshape(irs, ind_shape) irs = irs[slc] if mode == 1 and N.sometrue(dm): inds = N.empty_like(irs) # print 'translate', dm for d, ind in enumerate(irs): U.trans2d(ind, inds[d], (-dm[1], -dm[0], 0, 1, 0, 1)) else: inds = irs INDS_DIC[shapeTuple] = inds r_inds = N.empty_like(inds) for d, ld in enumerate(LD): r_inds[d] = inds[d] + ld return r_inds, LD
def Xcorr(a, b, highpassSigma=2.5, wiener=0.2, cutoffFreq=3, forceSecondPeak=None, acceptOrigin=True, maskSigmaFact=1., removeY=None, removeX=None, ret=None, normalize=True, gFit=True, lap=None, win=11): """ returns (y,x), image if ret is True, returns [v, yx, image] to get yx cordinate of the image, yx += N.divide(picture.shape, 2) a, b: 2D array highpassSigma: sigma value used for highpass pre-filter wiener: wiener value used for highpass pre-filter cutoffFreq: kill lowest frequency component from 0 to this level forceSecondPeak: If input is n>0 (True is 1), pick up n-th peak acceptOrigin: If None, result at origin is rejected, look for the next peak maskSigmaFact: Modifier to remove previous peak to look for another peak removeYX: Rremove given number of pixel high intensity lines of the Xcorr Y: Vertical, X: Horizontal normalize: intensity normalized gFit: peak is fitted to 2D gaussian array, if None use center of mass win: window for gFit if b is a + (y,x) then, answer is (-y,-x) """ shapeA = N.asarray(a.shape) shapeB = N.asarray(b.shape) shapeM = N.max([shapeA, shapeB], axis=0) shapeM = N.where(shapeM % 2, shapeM+1, shapeM) center = shapeM / 2. arrs = [a,b] arrsS = ['a','b'] arrsF = [] for i, arr in enumerate(arrs): if arr.dtype not in [N.float32, N.float64]: arr = N.asarray(arr, N.float32) # this convolution has to be done beforehand to remove 2 pixels at the edge if lap == 'nothing': pass elif lap: arr = arr_Laplace(arr, mask=2) else: arr = arr_sorbel(arr, mask=1) if N.sometrue(shapeA < shapeM): arr = paddingMed(arr, shapeM) if normalize: mi, ma, me, sd = U.mmms(arr) arr = (arr - me) / sd if i ==1: arr = F.shift(arr) af = F.rfft(arr) af = highPassF(af, highpassSigma, wiener, cutoffFreq) arrsF.append(af) # start cross correlation af, bf = arrsF bf = bf.conjugate() cf = af * bf # go back to space domain c = F.irfft(cf) # c = _changeOrigin(cr) # removing lines if removeX: yi, xi = N.indices((removeX, shapeM[-1]))#sx)) yi += center[-2] - removeX/2.#sy/2 - removeX/2 c[yi, xi] = 0 if removeY: yi, xi = N.indices((shapeM[-2], removeY))#sy, removeY)) xi += center[-1] - removeY/2.#sx/2 - removeY/2 c[yi, xi] = 0 # find the first peak if gFit: v, yx, s = findMaxWithGFit(c, win=win)#, window=win, gFit=gFit) if v == 0: v, yx, s = findMaxWithGFit(c, win=win+2)#, window=win+2, gFit=gFit) if v == 0: v = U.findMax(c)[0] yx = N.add(yx, 0.5) #yx += 0.5 else: vzyx = U.findMax(c) v = vzyx[0] yx = vzyx[-2:] s = 2.5 yx -= center if N.alltrue(N.abs(yx) < 1.0) and not acceptOrigin: forceSecondPeak = True # forceSecondPeak: if not forceSecondPeak: forceSecondPeak = 0 for i in range(int(forceSecondPeak)): print('%i peak was removed' % (i+1)) #, sigma: %.2f' % (i+1, s) yx += center g = gaussianArr2D(c.shape, sigma=s/maskSigmaFact, peakVal=v, orig=yx) c = c - g #c = mask_gaussian(c, yx[0], yx[1], v, s) if gFit: v, yx, s = findMaxWithGFit(c, win=win)#, window=win, gFit=gFit) if v == 0: v, yx, s = findMaxWithGFit(c, win=win+2)#, window=win+2, gFit=gFit) if v == 0: v = U.findMax(c)[0] yx -= (center - 0.5) else: vzyx = U.findMax(c) v = vzyx[0] if not gFit: yx = centerOfMass(c, vzyx[-2:]) - center if lap is not 'nothing': c = paddingValue(c, shapeM+2) if ret == 2: return yx, af, bf.conjugate() elif ret: return v, yx, c else: return yx, c
def pointsCutOutND(arr, posList, windowSize=100, sectWise=None, interpolate=True): """ array: nd array posList: ([(z,)y,x]...) windowSize: scalar (in pixel or as percent < 1.) or ((z,)y,x) if arr.ndim > 2, and len(windowSize) == 2, then cut out section-wise (higher dimensions stay the same) sectWise: conern only XY of windowSize (higher dimensions stay the same) interpolate: shift array by subpixel interpolation to adjust center return: list of array centered at each pos in posList """ shape = N.array(arr.shape) center = shape / 2. # prepare N-dimensional window size try: len(windowSize) # seq if sectWise: windowSize = windowSize[-2:] if len(windowSize) != arr.ndim: dim = len(windowSize) windowSize = tuple(shape[:-dim]) + tuple(windowSize) except TypeError: # scaler if windowSize < 1 and windowSize > 0: # percentage w = shape * windowSize if sectWise: w[:-2] = shape[:-2] windowSize = w.astype(N.uint16) else: windowSize = N.where(shape >= windowSize, windowSize, shape) if sectWise: windowSize = arr.shape[:-2] + tuple(windowSize[-2:]) windowSize = N.asarray(windowSize) # cutout individual position arrList=[] for pos in posList: # prepare N-dimensional coordinate n = len(pos) if n != len(windowSize): temp = center.copy() center[-n:] = pos pos = center # calculate idx ori = pos - (windowSize / 2.) # float value oidx = N.ceil(ori) # idx subpxl = oidx - ori # subpixel mod if interpolate and N.sometrue(subpxl): # comit to make shift SHIFT = 1 else: SHIFT = 0 # prepare slice # when comitted to make shift, first cut out window+1, # then make subpixle shift, and then cutout 1 edge slc = [Ellipsis] # Ellipsis is unnecessary, just in case... slc_edge = [slice(1,-1,None)] * arr.ndim for d in range(arr.ndim): start = oidx[d] - SHIFT if start < 0: start = 0 slc_edge[d] = slice(0, slc_edge[d].stop, None) stop = oidx[d] + windowSize[d] + SHIFT if stop > shape[d]: stop = shape[d] slc_edge[d] = slice(slc_edge[d].start, shape[d], None) slc += [slice(int(start), int(stop), None)] # cutout, shift and cutout #print(slc, slc_edge) try: canvas = arr[slc] if SHIFT: # 20180214 subpixel shift +0.5 was fixed #raise RuntimeError('check') if sectWise: subpxl[-2:] = N.where(windowSize[-2:] > 1, subpxl[-2:]-0.5, subpxl[-2:]) else: subpxl[-n:] = N.where(windowSize[-n:] > 1, subpxl[-n:]-0.5, subpxl[-n:]) canvas = U.nd.shift(canvas, subpxl) canvas = canvas[slc_edge] check = 1 except IndexError: print('position ', pos, ' was skipped') check = 0 raise if check: arrList += [N.ascontiguousarray(canvas)] return arrList
def Xcorr(a, b, highpassSigma=2.5, wiener=0.2, cutoffFreq=3, forceSecondPeak=None, acceptOrigin=True, maskSigmaFact=1., removeY=None, removeX=None, ret=None, normalize=True, gFit=True, lap=None, win=11): """ returns (y,x), image if ret is True, returns [v, yx, image] to get yx cordinate of the image, yx += N.divide(picture.shape, 2) a, b: 2D array highpassSigma: sigma value used for highpass pre-filter wiener: wiener value used for highpass pre-filter cutoffFreq: kill lowest frequency component from 0 to this level forceSecondPeak: If input is n>0 (True is 1), pick up n-th peak acceptOrigin: If None, result at origin is rejected, look for the next peak maskSigmaFact: Modifier to remove previous peak to look for another peak removeYX: Rremove given number of pixel high intensity lines of the Xcorr Y: Vertical, X: Horizontal normalize: intensity normalized gFit: peak is fitted to 2D gaussian array, if None use center of mass win: window for gFit if b is a + (y,x) then, answer is (-y,-x) """ shapeA = N.asarray(a.shape) shapeB = N.asarray(b.shape) shapeM = N.max([shapeA, shapeB], axis=0) shapeM = N.where(shapeM % 2, shapeM + 1, shapeM) center = shapeM / 2. arrs = [a, b] arrsS = ['a', 'b'] arrsF = [] for i, arr in enumerate(arrs): if arr.dtype not in [N.float32, N.float64]: arr = N.asarray(arr, N.float32) # this convolution has to be done beforehand to remove 2 pixels at the edge if lap == 'nothing': pass elif lap: arr = arr_Laplace(arr, mask=2) else: arr = arr_sorbel(arr, mask=1) if N.sometrue(shapeA < shapeM): arr = paddingMed(arr, shapeM) if normalize: mi, ma, me, sd = U.mmms(arr) arr = (arr - me) / sd if i == 1: arr = F.shift(arr) af = F.rfft(arr) af = highPassF(af, highpassSigma, wiener, cutoffFreq) arrsF.append(af) # start cross correlation af, bf = arrsF bf = bf.conjugate() cf = af * bf # go back to space domain c = F.irfft(cf) # c = _changeOrigin(cr) # removing lines if removeX: yi, xi = N.indices((removeX, shapeM[-1])) #sx)) yi += center[-2] - removeX / 2. #sy/2 - removeX/2 c[yi, xi] = 0 if removeY: yi, xi = N.indices((shapeM[-2], removeY)) #sy, removeY)) xi += center[-1] - removeY / 2. #sx/2 - removeY/2 c[yi, xi] = 0 # find the first peak if gFit: v, yx, s = findMaxWithGFit(c, win=win) #, window=win, gFit=gFit) if v == 0: v, yx, s = findMaxWithGFit(c, win=win + 2) #, window=win+2, gFit=gFit) if v == 0: v = U.findMax(c)[0] yx = N.add(yx, 0.5) #yx += 0.5 else: vzyx = U.findMax(c) v = vzyx[0] yx = vzyx[-2:] s = 2.5 yx -= center if N.alltrue(N.abs(yx) < 1.0) and not acceptOrigin: forceSecondPeak = True # forceSecondPeak: if not forceSecondPeak: forceSecondPeak = 0 for i in range(int(forceSecondPeak)): print('%i peak was removed' % (i + 1)) #, sigma: %.2f' % (i+1, s) yx += center g = gaussianArr2D(c.shape, sigma=s / maskSigmaFact, peakVal=v, orig=yx) c = c - g #c = mask_gaussian(c, yx[0], yx[1], v, s) if gFit: v, yx, s = findMaxWithGFit(c, win=win) #, window=win, gFit=gFit) if v == 0: v, yx, s = findMaxWithGFit(c, win=win + 2) #, window=win+2, gFit=gFit) if v == 0: v = U.findMax(c)[0] yx -= (center - 0.5) else: vzyx = U.findMax(c) v = vzyx[0] if not gFit: yx = centerOfMass(c, vzyx[-2:]) - center if lap is not 'nothing': c = paddingValue(c, shapeM + 2) if ret == 2: return yx, af, bf.conjugate() elif ret: return v, yx, c else: return yx, c
def pointsCutOutND(arr, posList, windowSize=100, sectWise=None, interpolate=True): """ array: nd array posList: ([(z,)y,x]...) windowSize: scalar (in pixel or as percent < 1.) or ((z,)y,x) if arr.ndim > 2, and len(windowSize) == 2, then cut out section-wise (higher dimensions stay the same) sectWise: conern only XY of windowSize (higher dimensions stay the same) interpolate: shift array by subpixel interpolation to adjust center return: list of array centered at each pos in posList """ shape = N.array(arr.shape) center = shape / 2. # prepare N-dimensional window size try: len(windowSize) # seq if sectWise: windowSize = windowSize[-2:] if len(windowSize) != arr.ndim: dim = len(windowSize) windowSize = tuple(shape[:-dim]) + tuple(windowSize) except TypeError: # scaler if windowSize < 1 and windowSize > 0: # percentage w = shape * windowSize if sectWise: w[:-2] = shape[:-2] windowSize = w.astype(N.uint16) else: windowSize = N.where(shape >= windowSize, windowSize, shape) if sectWise: windowSize = arr.shape[:-2] + windowSize[-2:] windowSize = N.asarray(windowSize) # cutout individual position arrList = [] for pos in posList: # prepare N-dimensional coordinate n = len(pos) if n != len(windowSize): temp = center.copy() center[-n:] = pos pos = center # calculate idx ori = pos - (windowSize / 2.) # float value oidx = N.ceil(ori) # idx subpxl = oidx - ori # subpixel mod if interpolate and N.sometrue(subpxl): # comit to make shift SHIFT = 1 else: SHIFT = 0 # prepare slice # when comitted to make shift, first cut out window+1, # then make subpixle shift, and then cutout 1 edge slc = [Ellipsis] # Ellipsis is unnecessary, just in case... slc_edge = [slice(1, -1, None)] * arr.ndim for d in range(arr.ndim): start = oidx[d] - SHIFT if start < 0: start = 0 slc_edge[d] = slice(0, slc_edge[d].stop, None) stop = oidx[d] + windowSize[d] + SHIFT if stop > shape[d]: stop = shape[d] slc_edge[d] = slice(slc_edge[d].start, shape[d], None) slc += [slice(int(start), int(stop), None)] # cutout, shift and cutout try: canvas = arr[slc] if SHIFT: canvas = U.nd.shift(canvas, subpxl) canvas = canvas[slc_edge] check = 1 except IndexError: print('position ', pos, ' was skipped') check = 0 raise if check: arrList += [N.ascontiguousarray(canvas)] return arrList
def rotateIndicesND(slicelist, dtype=N.float64, rot=0, mode=2): """ slicelist: even shape works much better than odd shape rot: counter-clockwise, xy-plane mode: testing different ways of doing, (1 or 2 and the same result) return inds, LD """ global INDS_DIC shape = [] LD = [] for sl in slicelist: if isinstance(sl, slice): shape.append(sl.stop - sl.start) LD.append(sl.start) shapeTuple = tuple(shape+[rot]) if shapeTuple in INDS_DIC: inds = INDS_DIC[shapeTuple] else: shape = N.array(shape) ndim = len(shape) odd_even = shape % 2 s2 = N.ceil(shape * (2**0.5)) if mode == 1: # everything is even s2 = N.where(s2 % 2, s2 + 1, s2) elif mode == 2: # even & even or odd & odd for d, s in enumerate(shape): if (s % 2 and not s2[d] % 2) or (not s % 2 and s2[d] % 2): s2[d] += 1 cent = s2 / 2. dif = (s2 - shape) / 2. dm = dif % 1 # print s2, cent, dif, dm slc = [Ellipsis] + [slice(int(d), int(d)+shape[i]) for i, d in enumerate(dif)] # This slice is float which shift array when cutting out!! s2 = tuple([int(ss) for ss in s2]) # numpy array cannot use used for slice inds = N.indices(s2, N.float32) ind_shape = inds.shape nz = N.product(ind_shape[:-2]) nsec = nz / float(ndim) if ndim > 2: inds = N.reshape(inds, (nz,)+ind_shape[-2:]) irs = N.empty_like(inds) for d, ind in enumerate(inds): idx = int(d//nsec) c = cent[idx] if rot and inds.ndim > 2: U.trans2d(ind - c, irs[d], (0,0,rot,1,0,1)) irs[d] += c - dif[idx] else: irs[d] = ind - dif[idx] if len(ind_shape) > 2: irs = N.reshape(irs, ind_shape) irs = irs[slc] if mode == 1 and N.sometrue(dm): inds = N.empty_like(irs) # print 'translate', dm for d, ind in enumerate(irs): U.trans2d(ind, inds[d], (-dm[1], -dm[0], 0, 1, 0, 1)) else: inds = irs INDS_DIC[shapeTuple] = inds r_inds = N.empty_like(inds) for d, ld in enumerate(LD): r_inds[d] = inds[d] + ld return r_inds, LD