def transformBases(self, start, end, x, y, z, is_5to3): """ assumes start < end start (int): the start index to transform end (int): the end_idx to transform (use -1 for the end) (non-inclusive) x (int): unit in bases from 0 y, z (float): units in multiple of RADIUS from 0,0 is_5to3 (bool): if the bases will be 5' to 3' in the x direction or 3' to 5' """ old_coords = self.atom_group._getCoords() # points to source array start_idxs = self.start_idxs twist_per_segment = 2.*math.pi/self.bases_per_turn theta0 = self.theta_offset try: start_idx = start_idxs[start] except: print("start idx problem:", len(start_idxs), start) raise if end == -1 or end > len(self.seq) - 1: # print("doop", end) end_idx = len(old_coords) else: # print("goop", end) end_idx = start_idxs[end] if not is_5to3: # 1. Flip 180 degrees about Z to change direction m_rev = matrix.makeRotationZ(math.pi) self.reverse_queue.append((m_rev, start_idx, end_idx)) # 2. Translate as required # print("translating", x + end - start ) m = matrix.makeTranslation((x + end - start)*DELTA_X + DELTA_X_REV_OFFSET, y*RADIUS, z*RADIUS) if x + end - start - 1 < 1: print("tb", len(self.twists), x, end, start, x + end - start - 1) raise ValueError("transformBases: issue with start and end") self.twists[start:end] = [(q*twist_per_segment + theta0 + THETA_REV_OFFSET)\ for q in range(x + end - start - 1, x - 1, -1)] else: m = matrix.makeTranslation(x*DELTA_X, y*RADIUS, z*RADIUS) self.twists[start:end] = \ [(q*twist_per_segment + theta0) \ for q in range(x, x + end - start)] self.base_idxs[start:end] = list(range(0, end - start)) self.transform_queue.append((m, start_idx, end_idx))
def linearize(self): """ Using self.base_idxs, separate out bases relative to one another """ new_coords = self.atom_group._getCoords() bidxs = self.base_idxs sidxs = self.start_idxs start = 0 lim = len(sidxs) - 1 for i in range(lim+1): if i < lim: next = sidxs[i+1] else: next = len(new_coords) base_idx = bidxs[i] m = matrix.makeTranslation(base_idx*DELTA_X, 0, 0) new_coords[start:next] = matrix.applyTransform(new_coords[start:next], m) start = next # end for self.atom_group.setCoords(new_coords)