def make_mask(self, isl, subn, subm, nsrc, src_id, g_list, delc): import functions as func # define stuff for calculating gaussian boxx, boxy = isl.bbox subn = boxx.stop - boxx.start subm = boxy.stop - boxy.start x, y = N.indices((subn, subm)) # construct image of each source in the island src_image = N.zeros((subn, subm, nsrc), dtype=N.float32) nn = 1 for isrc in range(nsrc): if nsrc == 1: g_sublist = g_list else: posn = N.where(src_id == isrc)[0] g_sublist = [] for i in posn: g_sublist.append(g_list[i]) for g in g_sublist: params = func.g2param(g) params[1] -= delc[0] params[2] -= delc[1] gau = func.gaus_2d(params, x, y) src_image[:, :, isrc] = src_image[:, :, isrc] + gau # mark each pixel as belonging to one source # just compare value, should compare with sigma later mask = N.argmax(src_image, axis=2) + src_id orig_mask = isl.mask_active mask[N.where(orig_mask)] = -1 return mask
def make_mask(self, isl, subn, subm, nsrc, src_id, g_list, delc): import functions as func # define stuff for calculating gaussian boxx, boxy = isl.bbox subn = boxx.stop-boxx.start; subm = boxy.stop-boxy.start x, y = N.indices((subn, subm)) # construct image of each source in the island src_image = N.zeros((subn, subm, nsrc), dtype=N.float32) nn = 1 for isrc in range(nsrc): if nsrc == 1: g_sublist = g_list else: posn = N.where(src_id == isrc)[0] g_sublist=[] for i in posn: g_sublist.append(g_list[i]) for g in g_sublist: params = func.g2param(g) params[1] -= delc[0]; params[2] -= delc[1] gau = func.gaus_2d(params, x, y) src_image[:,:,isrc] = src_image[:,:,isrc] + gau # mark each pixel as belonging to one source # just compare value, should compare with sigma later mask = N.argmax(src_image, axis=2) + src_id orig_mask = isl.mask_active mask[N.where(orig_mask)] = -1 return mask
def make_subim(self, subn, subm, g_list, delc, mc=False): import functions as func subim = N.zeros((subn, subm), dtype=N.float32) x, y = N.indices((subn, subm)) for g in g_list: params = func.g2param(g) params[1] -= delc[0]; params[2] -= delc[1] if mc: # draw random variables from distributions given by errors params_err = func.g2param_err(g) for i in range(len(params)): mc_param = N.random.normal(loc=params[i], scale=params_err[i]) params[i] = mc_param gau = func.gaus_2d(params, x, y) subim = subim + gau return subim
def inigaus_nobeam(self, isl, thr, beam, img): """ To get initial guesses when the source sizes are very different from the beam, and can also be elongated. Mainly in the context of a-trous transform images. Need to arrive at a good guess of the sizes and hence need to partition the image around the maxima first. Tried the IFT watershed algo but with markers, it segments the island only around the minima and not the whole island. Cant find a good weighting scheme for tesselation either. Hence will try this : Calculate number of maxima. If one, then take moment as initial guess. If more than one, then moment of whole island is one of the guesses if mom1 is within n pixels of one of the maxima. Else dont take whole island moment. Instead, find minima on lines connecting all maxima and use geometric mean of all minima of a peak as the size of that peak. """ from math import sqrt from const import fwsig import scipy.ndimage as nd import functions as func im = isl.image-isl.islmean if img.opts.ini_method == 'curvature': im_pos = -1.0 * func.make_curvature_map(isl.image-isl.islmean) thr_pos = 0.0 else: im_pos = im thr_pos = -1e9 mask = isl.mask_active av = img.clipped_mean inipeak, iniposn, im1 = func.get_maxima(im, mask, thr_pos, isl.shape, beam, im_pos=im_pos) npeak = len(iniposn) gaul = [] av, stdnew, maxv, maxp, minv, minp = func.arrstatmask(im, mask) mom = func.momanalmask_gaus(isl.image-isl.islmean, isl.mask_active, 0, 1.0, True) if npeak <= 1: g = (float(maxv), int(round(mom[1])), int(round(mom[2])), mom[3]/fwsig, \ mom[4]/fwsig, mom[5]) gaul.append(g) if npeak > 1: # markers start from 1=background, watershed starts from 1=background watershed, markers = func.watershed(im, mask=isl.mask_active) nshed = N.max(markers)-1 # excluding background xm, ym = N.transpose([N.where(markers==i) for i in range(1,nshed+2)])[0] coords = [c for c in N.transpose([xm,ym])[1:]] alldists = [func.dist_2pt(c1, c2) for c1 in coords for c2 in coords if N.any(c1!=c2)] # has double meandist = N.mean(alldists) # mean dist between all pairs of markers compact = []; invmask = [] for ished in range(nshed): shedmask = N.where(watershed==ished+2, False, True) + isl.mask_active # good unmasked pixels = 0 imm = nd.binary_dilation(~shedmask, N.ones((3,3), int)) xbad, ybad = N.where((imm==1)*(im>im[xm[ished+1], ym[ished+1]])) imm[xbad, ybad] = 0 invmask.append(imm); x, y = N.where(imm); xcen, ycen = N.mean(x), N.mean(y) # good pixels are now = 1 dist = func.dist_2pt([xcen, ycen], [xm[ished+1], ym[ished+1]]) if dist < max(3.0, meandist/4.0): compact.append(True) # if not compact, break source + diffuse else: compact.append(False) if not N.all(compact): avsize = [] ind = N.where(compact)[0] for i in ind: avsize.append(N.sum(invmask[i])) avsize = sqrt(N.mean(N.array(avsize))) for i in range(len(compact)): if not compact[i]: # make them all compact newmask = N.zeros(imm.shape, bool) newmask[max(0,xm[i+1]-avsize/2):min(im.shape[0],xm[i+1]+avsize/2), \ max(0,ym[i+1]-avsize/2):min(im.shape[1],ym[i+1]+avsize/2)] = True invmask[i] = invmask[i]*newmask resid = N.zeros(im.shape, dtype=N.float32) # approx fit all compact ones for i in range(nshed): mask1 = ~invmask[i] size = sqrt(N.sum(invmask))/fwsig xf, yf = coords[i][0], coords[i][1] p_ini = [im[xf, yf], xf, yf, size, size, 0.0] x, y = N.indices(im.shape) p, success = func.fit_gaus2d(im*invmask[i], p_ini, x, y) resid = resid + func.gaus_2d(p, x, y) gaul.append(p) resid = im - resid if not N.all(compact): # just add one gaussian to fit whole unmasked island maxv = N.max(resid) # assuming resid has only diffuse emission. can be false x, y = N.where(~isl.mask_active); xcen = N.mean(x); ycen = N.mean(y) invm = ~isl.mask_active #bound = invm - nd.grey_erosion(invm, footprint = N.ones((3,3), int)) # better to use bound for ellipse fitting mom = func.momanalmask_gaus(invm, N.zeros(invm.shape, dtype=N.int16), 0, 1.0, True) g = (maxv, xcen, ycen, mom[3]/fwsig, mom[4]/fwsig, mom[5]-90.) gaul.append(g) coords.append([xcen, ycen]) return gaul