def subtract_cone(pp, odr, sampleName='', outfile=None, vmin=None, vmax=None): #not used in v1 """ odr: 6-vector (origin_y,origin_y,origin_z,direction_x,direction_y,direction_z), note that this is redundant, since only two components are enough for direction (magnitude is irrelevant). pp: complete set of points Npx3 """ fom, deltaR, coeff = cone_error(odr, pp, extra=True) xymin = np.nanmin(pp, axis=0)[0:2] xymax = np.nanmax(pp, axis=0)[0:2] rp = plot_points( np.hstack([pp[:, 0:2], deltaR[:, None] * 1000]), shape=(281, 3001)) #this is done to easily replot and change scale #surface map and data plt.clf() plt.imshow(rp, aspect='equal', interpolation='none', vmin=vmin, vmax=vmax, extent=[xymin[1], xymax[1], xymin[0], xymax[0]]) plt.colorbar() plt.title(((sampleName + ' - ') if sampleName else ('')) + 'best-fit-cone removed.') plt.xlabel('Y(mm)') plt.ylabel('X(mm)') if outfile: plt.savefig(fn_add_subfix(outfile, '_cone', 'png')) save_points(np.hstack([pp[:, 0:2], deltaR[:, None] * 1000]), fn_add_subfix(outfile, '_cone')) #cone output m = coeff[0] print('Cone angle:%s+/-%s rad(%s+/-%s deg) ' % (np.arctan(m), 0, np.arctan(m) * 180 / np.pi, 0)) print('Axis intercept at x=0: %smm ' % (coeff[1])) misal = np.arccos(1 / np.sqrt(1 + ((odr[2:]**2).sum()))) print('Misalignment of optical axis: %s rad (%s deg)' % (misal, misal * 180. / pi)) #rms output print('rms entire surface %s' % (np.nanstd)) plt.figure() plt.plot(np.nanstd(rp)) plt.plot(np.nanstd(rp, axis=0)) plt.plot(np.nanstd(rp, axis=1)) #mask outliers on a copy rp2 = rp[:] np.where(np.isnan(rp2)) return fom, deltaR, coeff
def subtract_cylinder(pp, odr, sampleName=''): #not used in v1 """ odr: 6-vector (origin_y,origin_y,origin_z,direction_x,direction_y,direction_z), note that this is redundant, since only two components are enough for direction (magnitude is irrelevant). pp: complete set of points Npx3 """ fom, deltaR, radius = cylinder_error(odr, pp, extra=True) xymin = np.nanmin(pp, axis=0)[0:2] xymax = np.nanmax(pp, axis=0)[0:2] rp = plot_points( np.hstack([pp[:, 0:2], deltaR[:, None] * 1000]), shape=(281, 3001)) #this is done to easily replot and change scale #surface map and data plt.clf() plt.imshow(rp, aspect='equal', interpolation='none', vmin=-5, vmax=10, extent=[xymin[1], xymax[1], xymin[0], xymax[0]]) plt.colorbar() plt.title(sampleName + (sampleName if sampleName else '') + 'best-fit-cylinder removed.') plt.xlabel('Y(mm)') plt.ylabel('X(mm)') plt.savefig(fn_add_subfix(datafile, '_cylinder', 'png')) save_points(np.hstack([pp[:, 0:2], deltaR[:, None] * 1000]), fn_add_subfix(datafile, '_cylinder')) #cylinder output print('Best fit radius %s' % radius) misal = np.arccos(1 / np.sqrt(1 + ((odr[2:]**2).sum()))) print('Misalignment of optical axis: %s rad (%s deg)' % (misal, misal * np.pi / 180)) #rms output print('rms entire surface %s' % (np.nanstd(rp))) plt.figure() plt.plot(np.nanstd(rp)) plt.plot(np.nanstd(rp, axis=0)) plt.plot(np.nanstd(rp, axis=1)) #mask outliers on a copy rp2 = rp[:] np.where(np.isnan(rp2))
#create points to be fit from a subset of points. pts = get_points(datafile, delimiter=' ') #pts=rotate_points(pts,-np.pi/2) pts = crop_points(pts, (-28, 33), (-75, 65)) pts[:, 2] = pts[:, 2] / 1000. c = crop_points(pts, (-28, 33), (-50, 50)) #[0:-1:1000,:] odr2 = (33, 220., 0, 0, 220) result = minimize(fit_func, x0=(odr2[0:-1], ), args=(c, ), options={'maxiter': 1000}, callback=p, method='Nelder-Mead') print('-----------------------------------') print('Results of fit on subset of points:') print(result) #create output results applying the value from fit to all points odr = result.x fom, deltaR, coeff = fit_func(odr, pts, extra=True) origin = (odr[0], 0, odr[1]) direction = (odr[2], 1., odr[3]) deltaR[:, 2] = deltaR[:, 2] * 1000 print('-----------------------------------') print('Results of fit applied to complete set of points:') print('F.O.M.=%s' % (fom)) plot_points(deltaR, vmin=-5, vmax=10, scatter=1, aspect='equal') save_points(deltaR, filename=fn_add_subfix(datafile, outSubfix)) plt.savefig(fn_add_subfix(datafile, outSubfix, '.png'))