def alignment(self, segpos, debug=0, **kw): cen1 = segpos[self.from_seg][..., :, 3] cen2 = segpos[self.to_seg][..., :, 3] ax1 = segpos[self.from_seg][..., :, 2] ax2 = segpos[self.to_seg][..., :, 2] if not self.distinct_axes and hm.angle(ax1, ax2) > np.pi / 2: ax2 = -ax2 p, q = hm.line_line_closest_points_pa(cen1, ax1, cen2, ax2) cen = (p + q) / 2 # ax1 = hm.hnormalized(cen1 - cen) # ax2 = hm.hnormalized(cen2 - cen) x = hm.align_vectors(ax1, ax2, self.tgtaxis1[1], self.tgtaxis2[1]) x[..., :, 3] = -x @ cen if debug: print('angs', hm.angle_degrees(ax1, ax2), hm.angle_degrees(self.tgtaxis1[1], self.tgtaxis2[1])) print('ax1', ax1) print('ax2', ax2) print('xax1', x @ ax1) print('tax1', self.tgtaxis1[1]) print('xax2', x @ ax2) print('tax2', self.tgtaxis2[1]) raise AssertionError # if not (np.allclose(x @ ax1, self.tgtaxis1[1], atol=1e-2) and # np.allclose(x @ ax2, self.tgtaxis2[1], atol=1e-2)): # print(hm.angle(self.tgtaxis1[1], self.tgtaxis2[1])) # print(hm.angle(ax1, ax2)) # print(x @ ax1) # print(self.tgtaxis1[1]) # print(x @ ax2) # print(self.tgtaxis2[1]) # raise AssertionError('hm.align_vectors sucks') return x
def alignment(self, segpos, out_cell_spacing=False, **kw): ax = segpos[self.to_seg, :3, 2] cn = segpos[self.to_seg, :3, 3] origin = np.array([0, 0, 0]) if self.d_nfold > 2 and self.c_nfold > 2: mn, mni = 9e9, None for i, _ in enumerate(self.c_tgt_axis_isect): c_axis_isects, c_tgt_axis = _ d = hm.numba_line_line_distance_pa(cn, ax, origin, c_axis_isects) a = np.arccos(abs(np.sum(c_tgt_axis * ax))) err = np.sqrt(d**2 + (a * self.lever)**2) if err < mn: mn = err mni = i c_axis_isects, c_tgt_axis = self.c_tgt_axis_isect[mni] p, q = hm.line_line_closest_points_pa(cn, ax, origin, c_axis_isects) cell_spacing = np.linalg.norm(p + q) / np.sqrt(2) # 2x from p+q xalign = np.eye(4) if np.sum(c_axis_isects * q) > 0: xalign = hm.hrot(hm.hcross(c_axis_isects, c_tgt_axis), 180) @ xalign xalign = self.aligners[mni] @ xalign xalign[:3, 3] = self.to_origin * cell_spacing d = np.linalg.norm(p - q) a = np.arccos(abs(np.sum(c_tgt_axis * ax))) carterr2 = d**2 angerr2 = (a * self.lever)**2 if np.sum(c_axis_isects * q) > 0: print() print("alignment", d, a * self.lever, self.lever) print("ax", ax, xalign[:3, :3] @ ax) print("cn", cn, xalign @ [cn[0], cn[1], cn[2], 1]) print("isect", p) print("isect", q) print("cell_spacing", cell_spacing) print("xalign", hm.axis_angle_of(xalign)) print(xalign) else: raise NotImplementedError if out_cell_spacing: return xalign, cell_spacing else: return xalign
def score(self, segpos, verbosity=False, **kw): cen1 = segpos[self.from_seg][..., :, 3] cen2 = segpos[self.to_seg][..., :, 3] ax1 = segpos[self.from_seg][..., :, 2] ax2 = segpos[self.to_seg][..., :, 2] if self.nondistinct_axes: p, q = hm.line_line_closest_points_pa(cen1, ax1, cen2, ax2) dist = hm.hnorm(p - q) cen = (p + q) / 2 ax1c = hm.hnormalized(cen1 - cen) ax2c = hm.hnormalized(cen2 - cen) ax1 = np.where(hm.hdot(ax1, ax1c)[..., None] > 0, ax1, -ax1) ax2 = np.where(hm.hdot(ax2, ax2c)[..., None] > 0, ax2, -ax2) ang = np.arccos(hm.hdot(ax1, ax2)) else: dist = hm.line_line_distance_pa(cen1, ax1, cen2, ax2) ang = np.arccos(np.abs(hm.hdot(ax1, ax2))) roterr2 = (ang - self.tgtangle)**2 return np.sqrt(roterr2 / self.rot_tol**2 + (dist / self.tolerance)**2)
def alignment(self, segpos, out_cell_spacing=False, **kw): ax = segpos[self.to_seg, :3, 2] cn = segpos[self.to_seg, :3, 3] if self.d_nfold > 2 and self.c_nfold > 2: mn, mni = 9e9, -1 for i, tf in enumerate(self.d_2folds): d = hm.line_line_distance_pa(cn, ax, [0, 0, 0], tf) if d < mn: mn, mni = d, i p, q = hm.line_line_closest_points_pa(cn, ax, [0, 0, 0], self.d_2folds[mni]) spacing = np.linalg.norm(p + q) / 2 xalign = hm.align_vectors([0, 0, 1], q, [0, 0, 1], [1, 0, 0]) elif self.d_nfold > 2 and self.c_nfold == 2: if abs(ax[2]) > 0.5: # case: c2 on z pick d2 isects axis mn, mni = 9e9, -1 for i, tf in enumerate(self.d_2folds): d = hm.line_line_distance_pa(cn, ax, [0, 0, 0], tf) if d < mn: mn, mni = d, i p, q = hm.line_line_closest_points_pa(cn, ax, [0, 0, 0], self.d_2folds[mni]) spacing = np.linalg.norm(p + q) / 2 xalign = hm.align_vectors([0, 0, 1], q, [0, 0, 1], [1, 0, 0]) else: # case: c2 prep to z, pick D2 perp to axis mn, mni = 9e9, -1 for i, tf in enumerate(self.d_2folds): d = abs(np.sum(tf * ax)) if d < mn: mn, mni = d, i p, q = hm.line_line_closest_points_pa(cn, ax, [0, 0, 0], self.d_2folds[mni]) spacing = np.linalg.norm(p + q) / 2 xalign = hm.align_vectors([0, 0, 1], q, [0, 0, 1], [1, 0, 0]) elif self.d_nfold == 2 and self.c_nfold > 2: mn, mni = 9e9, -1 mxdot, mxdoti = 0, -1 for i, tf in enumerate(self.d_2folds): d = hm.line_line_distance_pa(cn, ax, [0, 0, 0], tf) if d < mn: mn, mni = d, i dot = abs(np.sum(tf * ax)) if dot > mxdot: mxdot, mxdoti = dot, i assert mni != mxdoti p, q = hm.line_line_closest_points_pa(cn, ax, [0, 0, 0], self.d_2folds[mni]) spacing = np.linalg.norm(p + q) / 2 # assumes d_folds are X Y Z ax[argmin] selects correct one xalign = hm.align_vectors(self.d_2folds[mni], self.d_2folds[mxdoti], [1, 0, 0], [0, 0, 1]) # print("cn", cn) # print("ax", ax) # print("isect", self.d_2folds[mni]) # print("align", self.d_2folds[mxdoti]) # print("align xform", xalign) # print("aligned ax", xalign[:3, :3] @ ax) # assert 0 elif self.d_nfold == 2 and self.c_nfold == 2: mn, mni = 9e9, -1 for i, tf in enumerate(self.d_2folds): d = hm.line_line_distance_pa(cn, ax, [0, 0, 0], self.d_2diag[i]) dot = abs(np.sum(tf * ax)) angerr2 = (np.arccos(dot) * self.lever)**2 err = np.sqrt(d**2 + angerr2) if err < mn: mn = err mni = i p, q = hm.line_line_closest_points_pa(cn, ax, [0, 0, 0], self.d_2diag[mni]) spacing = np.linalg.norm(p + q) / 2 / np.sqrt(2) # assumes d_folds are X Y Z ax[argmin] selects correct one xalign = hm.align_vectors(self.d_2diag[mni], self.d_2folds[mni], [1, 1, 0], [0, 0, 1]) else: raise NotImplementedError if out_cell_spacing: return xalign, spacing else: return xalign