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): """ Alignment to move stuff to be in line with symdef file Args: segpos (lst): List of segment positions / coordinates. **kw I'll accept any "non-positional" argument as name = value, and store in a dictionary """ cen1 = segpos[self.from_seg][..., :, 3] ## 4th column is x,y,z translation cen2 = segpos[self.to_seg][..., :, 3] ax1 = segpos[self.from_seg][..., :, 2] ## 3rd column is axis ax2 = segpos[self.to_seg][..., :, 2] if hm.angle( ax1, ax2 ) > np.pi / 2: ## make sure to align with smaller axis choice ax2 = -ax2 if abs(hm.angle(self.tgtaxis1, self.tgtaxis2)) < 0.1: d = hm.proj_perp(ax1, cen2 - cen1) #vector delta between cen2 and cen1 Xalign = hm.align_vectors(ax1, d, self.tgtaxis1, [0, 1, 0, 0]) #align d to Y axis Xalign[..., :, 3] = -Xalign @ cen1 cell_dist = (Xalign @ cen2)[..., 1] else: Xalign = hm.align_vectors( ax1, ax2, self.tgtaxis1, self.tgtaxis2 ) ## utility function that tries to align ax1 and ax2 to the target axes Xalign[..., :, 3] = -Xalign @ cen1 ## move from_seg cen1 to origin cen2_0 = Xalign @ cen2 #moving cen2 by Xalign D = np.stack([ self.tgtaxis1[:3], [0, 1, 0], self.tgtaxis2[:3] ]).T #matrix where the columns are the things in the list #CHANGE Uy to an ARGUMENT SOON!!!! #print("D: ", D) A1offset, cell_dist, _ = np.linalg.inv( D ) @ cen2_0[: 3] #transform of A1 offest, cell distance (offset along other axis), and A2 offset (<-- we are ignoring this) Xalign[..., :, 3] = Xalign[..., :, 3] - (A1offset * self.tgtaxis1) #Xalign[..., :, 3] = Xalign[..., :, 3] + [0,cell_dist,0,0] if out_cell_spacing: #print(2*cell_dist) return Xalign, cell_dist else: return Xalign
def alignment(self, segpos, out_cell_spacing=False, **kw): """ Alignment to move stuff to be in line with symdef file Args: segpos (lst): List of segment positions / coordinates. **kw I'll accept any "non-positional" argument as name = value, and store in a dictionary """ cen1 = segpos[self.from_seg][..., :, 3] cen2 = segpos[self.to_seg][..., :, 3] ax1 = segpos[self.from_seg][..., :, 2] ## 3rd column is axis ax2 = segpos[self.to_seg][..., :, 2] ## make sure to align with smaller axis choice if hm.angle(ax1, ax2) > np.pi / 2: ax2 = -ax2 if abs(hm.angle(self.tgtaxis1, self.tgtaxis2)) < 0.1: # vector delta between cen2 and cen1 d = hm.proj_perp(ax1, cen2 - cen1) Xalign = hm.align_vectors(ax1, d, self.tgtaxis1, self.tgtaxis2_isects + [0]) # align d to Y axis Xalign[..., :, 3] = -Xalign @ cen1 cell_dist = (Xalign @ cen2)[..., 1] else: try: Xalign = hm.align_vectors(ax1, ax2, self.tgtaxis1, self.tgtaxis2) except AssertionError as e: print("align_vectors error") print(" ", ax1) print(" ", ax2) print(" ", self.tgtaxis1) print(" ", self.tgtaxis2) raise e Xalign[..., :, 3] = -Xalign @ cen1 ## move from_seg cen1 to origin cen2_0 = Xalign @ cen2 # moving cen2 by Xalign D = np.stack( [self.tgtaxis1[:3], self.tgtaxis2_isects, self.tgtaxis2[:3]]).T A1offset, cell_dist, _ = np.linalg.inv(D) @ cen2_0[:3] # transform of A1 offest, cell distance (offset along other axis), and A2 offset (<-- we are ignoring this) Xalign[..., :, 3] = Xalign[..., :, 3] - (A1offset * self.tgtaxis1) # Xalign[..., :, 3] = Xalign[..., :, 3] + [0,cell_dist,0,0] if out_cell_spacing: return Xalign, cell_dist else: return Xalign
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