def analyze(data): """ Do all the analysis that's needed to create the interface """ prepared, centre = preparedata(data) xx, yy, dx, dy, angle = fastfit.d4s(prepared) xx += centre[0] yy += centre[1] xr, yr = fastfit.getellipse(xx, yy, dx, dy, angle) # fix axes calculation so no more -1 is needed angle *= -1 adeg = "%.1f deg" %(angle / np.pi * 180) xxx = [xx - dx/2*np.cos(angle), xx + dx/2*np.cos(angle)] xxy = [yy + dx/2*np.sin(angle), yy - dx/2*np.sin(angle)] yyx = [xx + dy/2*np.sin(angle), xx - dy/2*np.sin(angle)] yyy = [yy + dy/2*np.cos(angle), yy - dy/2*np.cos(angle)] xwidth = (dx*np.cos(angle)**2 + dy*np.sin(angle)**2)/4.0 ywidth = (dx*np.sin(angle)**2 + dy*np.cos(angle)**2)/4.0 try: xc = int(np.round(xx)) yc = int(np.round(yy)) except ValueError: xc = 320 yc = 240 sy, sx = data.shape xcut = data[yc, :] ycut = data[:, xc] xline = range(0, sx) yline = range(0, sy) xcutg = gauss(xline, xx, xwidth, max(xcut)) ycutg = gauss(yline, yy, ywidth, max(ycut)) return (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg)
def fitgaussian(data): """Returns (height, x, y, width_x, width_y) the gaussian parameters of a 2D distribution found by a fit""" xx, yy, dx, dy, angle = fastfit.d4s(data) # For some reason x and y are exchanged params = [np.max(data), yy, xx, dy/4, dx/4, -angle, np.min(data)] errorfunction = lambda p: np.ravel(gaussian(*p)(*np.indices(data.shape)) - data) try: p, success = optimize.leastsq(errorfunction, params, maxfev=90) except: # This should be triggered normally by KeyboardInterrupt but optimize throws different error that's hard to catch p = None # to propagate stop signal upstream return p
def preparedata(data): """ Prepare data for processing by cutting down on the area for D4s Input: ------ data: original reading values in numpy array from Output: ------ prepared: data in the cropped area (xbottom, ybottom): value of the starting corner in two dimension """ dh, dw = data.shape border = np.array([]) border = np.append(border, np.ravel(data[:-1, 0])) border = np.append(border, np.ravel(data[0, 1:])) border = np.append(border, np.ravel(data[1:, -1])) border = np.append(border, np.ravel(data[-1, :-1])) borderavg, bordervar = np.mean(border), np.var(border) slimdata = np.copy(data) - borderavg maxy, maxx = np.unravel_index(np.argmax(slimdata), slimdata.shape) # Find the number of points in the x/y direction that are above the background noise xl = slimdata[:, maxx] xdim = sum(sum([xl > 10*bordervar])) yl = slimdata[maxy, :] ydim = sum(sum([yl > 10*bordervar])) dim = 2 * max(xdim, ydim) if dim < 5: # In this case, most likely we don't have a peak, just noise, since # very few points are over the noiselevel return data, (0, 0) xbottom, xtop = limits(maxx, dim, (0, dw)) ybottom, ytop = limits(maxy, dim, (0, dh)) testdata = slimdata[ybottom:ytop, xbottom:xtop] xx, yy, dx, dy, angle = fastfit.d4s(testdata) xc = int(xbottom+xx) yc = int(ybottom+yy) limr = 0.69 limx = int(dx * limr) limy = int(dy * limr) xbottom, xtop = limits(xc, limx, (0, dw)) ybottom, ytop = limits(yc, limy, (0, dh)) prepared = slimdata[ybottom:ytop, xbottom:xtop] return prepared, (xbottom, ybottom)
def analyze(data): """ Do all the analysis that's needed to create the interface """ prepared, centre = interface.preparedata(data) xx, yy, dx, dy, angle = fastfit.d4s(prepared) xx += centre[0] yy += centre[1] try: outparams = gaussfit.fitgaussian(prepared) # Order somehow changed between x and y if outparams is None: return None (a, y, x, ddy, ddx, angle, b) = outparams dx = 4*ddx dy = 4*ddy print "Gaussian fit" except (ValueError): print "D4s fit" pass xr, yr = fastfit.getellipse(xx, yy, dx, dy, angle) # fix axes calculation so no more -1 is needed angle *= -1 adeg = "%.1f deg" %(angle / np.pi * 180) xxx = [xx - dx/2*np.cos(angle), xx + dx/2*np.cos(angle)] xxy = [yy + dx/2*np.sin(angle), yy - dx/2*np.sin(angle)] yyx = [xx + dy/2*np.sin(angle), xx - dy/2*np.sin(angle)] yyy = [yy + dy/2*np.cos(angle), yy - dy/2*np.cos(angle)] xwidth = (dx*np.cos(angle)**2 + dy*np.sin(angle)**2)/4.0 ywidth = (dx*np.sin(angle)**2 + dy*np.cos(angle)**2)/4.0 try: xc = int(np.round(xx)) yc = int(np.round(yy)) except ValueError: xc = 320 yc = 240 xcut = data[yc, :] ycut = data[:, xc] xline = range(0, sx) yline = range(0, sy) xcutg = gauss(xline, xx, xwidth, max(xcut)) ycutg = gauss(yline, yy, ywidth, max(ycut)) return (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg)