Module bioiain.aleph
Sub-modules
bioiain.aleph.corebioiain.aleph.fragmentsbioiain.aleph.vectors
Classes
class ALEPH2 (params={})-
Expand source code
class ALEPH2(object): def __init__(self, params={}): self.params = dict( min_ah=4, min_bs=3, strictness_ah=0.45, strictness_bs=0.20, weight = "distance_avg", ) self.params |= params def annotate(self, entity_or_path): if not isinstance(entity_or_path, BIEntity): entity = BIEntity.from_file(entity_or_path) else: entity = entity_or_path log(1, "Annotating with ALEPH2:", entity) entity.cvectors() pass def _generate_matrix_and_graph(self, entity): passMethods
def annotate(self, entity_or_path)-
Expand source code
def annotate(self, entity_or_path): if not isinstance(entity_or_path, BIEntity): entity = BIEntity.from_file(entity_or_path) else: entity = entity_or_path log(1, "Annotating with ALEPH2:", entity) entity.cvectors() pass
class CVMatrix (cvector_list, vc_mode=None, complete=False, max_distance=30, **kwargs)-
Expand source code
class CVMatrix(object): def __init__(self, cvector_list, vc_mode=None, complete=False, max_distance=30, **kwargs): self.vectors = cvector_list self.matrix = None self.length = len(self.vectors) self.vc_mode = vc_mode self.max_distance = max_distance self.entity = kwargs.get("entity", None) self.reset_matrix() self.calculate_neighbours(max_distance=max_distance) def __repr__(self): return f"<{self.__class__.__name__} of {self.entity} N={self.length}>" def reset_matrix(self): self.matrix = [[None] * self.length] * self.length def calculate_full(self): self.matrix = [] log(2, f"Calculating matrix ({self.vc_mode})...") for n, v1 in enumerate(self.vectors): self.matrix.append([]) print(f"{n:5d}/{len(self.vectors):5d}", end="\r") for v2 in self.vectors: if v1 == v2: pair = None else: pair = v1 % v2 self.matrix[n].append(pair) for n, r in enumerate(self.matrix): extension = self.length - len(r) -1 zeros = [None] * extension self.matrix[n] = zeros + self.matrix[n] log(3, "n vectors", len(self.vectors)) log(3 , "m length", len(self.matrix)) return self def map(self, attribute): log(2, f"Mapping CVMatrix (attr={attribute})") #print(self.matrix) return (lambda m: np.array([np.array([getattr(x, attribute) if x is not None and getattr(x, attribute) is not None else 0 for x in l]) for l in m ]))(self.matrix) def square(self, attribute): t = self.map(attribute) sq = square_matrix(t) return sq def triangle(self, attribute="d"): t = self.map(attribute) return t def save_fig(self, attribute="d", save_folder=None, prefix="cvmatrix"): from ..visualisation.plots import plot_heatmap if save_folder is None: save_folder = os.path.join(SUBDIR_NAME, "cvmaps") os.makedirs(save_folder, exist_ok=True) if self.vc_mode is not None: prefix = f"{prefix}_{self.vc_mode}" filename = os.path.join(save_folder, f"{prefix}_{attribute}.png") plot_heatmap(self.square(attribute), filename=filename) return filename def show(self, attribute="d"): from ..visualisation.plots import plot_heatmap plot_heatmap(self.square(attribute), show=True) def map_ligands(self, entity): log(2, "Mapping ligands...") ligands = entity.ligands() if len(ligands) == 0: log("warning", f"No ligands found in {entity.name()}") for cv in self.vectors: cv.dist_to_lig = 99 cv.closest_lig = None return self for cv in self.vectors: distances = [length(vector(cv.start, l.com())) for l in ligands] #print(distances) cv.dist_to_lig = min(distances) cv.closest_lig = ligands[distances.index(cv.dist_to_lig)] #log(1, f"Closest lig ({cv}): {cv.closest_lig} at {cv.dist_to_lig:4.2f}A") for row in self.matrix: for vp in row: if vp is None: continue vp.map_lig() return self def calculate_neighbours(self, use_fragments=True, max_distance=30, n_neighbours=1): log(2, "Calculating neighbours for:", self) from ..tools.SASA import KDT data = {k: {"vc":cv.vc, "cv":cv} for k, cv in enumerate(self.vectors)} for k, v in data.items(): v["vc"]._nnk = k if self.entity is not None: tree = KDT([v["vc"] for v in data.values()], params=self.entity.params(), symops=self.entity.symops(), centre=self.entity.com()) else: tree = KDT([v["vc"] for v in data.values()]) for k1, v in data.items(): print(f"{k1:5d}/{len(data.keys()):5d}", end="\r") cv = v["cv"] vc = v["vc"] radius = 10 neighs_found=False while radius <= max_distance: neighbors, distances = tree.of(vc, radius=radius, distances=True) #print(neighbors) #print(distances) if len(neighbors) == 0: log("error", f"No neighbours found radius={radius}, even itself") raise Exception() potential = [(tree.atom_of(neigh)._nnk, tree.atom_of(neigh), tree.op_of(neigh), tree.pos_of(neigh), d) for neigh, d in zip(neighbors, distances)] targets = [] for p in potential: #print("POTENTIAL:", p) k = p[0] pvc = p[1] if pvc == vc: #print("Same vc") continue pfrag = data[k]["cv"].fragment pop = p[2] ppos = p[3] if (pfrag == cv.fragment) and (pop ==1): #print("Same fragment") continue targets.append(p) #print("TARGETS:") #[print(t) for t in targets] if len(targets) < n_neighbours: radius += 5 #log("warning", "Expanding search to:", radius) continue neighs_found = True targets = sorted(targets, key=lambda x: x[-1]) #print("sorted targets:") #print(targets) for t in targets[:n_neighbours]: k2 = t[0] cv.closest = data[k2]["cv"] cv.closest_vp = cv.pair(cv.closest, d= t[-1], op_of_v2=t[2], pos_of_v2=t[3]) cv.closest_opn = cv.closest_vp.opn_of_v2 cv.closest_pos = cv.closest_vp.pos_of_v2 if n_neighbours != 1: log("Warning", "More than one neighbour requested but not implemented") self.matrix[k1][k2] = cv.closest_vp break # Only programmed for n_neighbours == 1, must be adapted if more needed break if not neighs_found: log("ERROR", f"No neighbours found for cv: {cv}\nMight be due to small structure") raise NoNeighboursFound() return self # for n2, vp in enumerate(self.matrix[n1]): # # if vp is None: # vp = self.matrix[n2][n1] # # if n2 == n1 or (vp.chain1 == vp.chain2 and vp.opn_of_v2 is not None and vp.pos_of_v2 is not None and abs(vp.resnum1-vp.resnum2) <=2) : # continue # print(f"{n1+1} / {n2+1} / {len(self.vectors)}", end="\r") # # # #if vp is None: # # continue # #print(vp, vp.d) # #print(vp.chain1, vp.chain2) # # if use_fragments: # #print(vp.fragment1, vp.fragment2) # if vp.fragment1 == vp.fragment2: # continue # else: # if vp.chain1 == vp.chain2: # continue # # # #print(str(cv), str(vp.v1), str(vp.v2)) # # if str(cv) == str(vp.v1): # t = vp.v2 # elif str(cv) == str(vp.v2): # t = vp.v1 # else: # continue # # #print(cv, t) # if vp.d < target[0]: # target = (vp.d, t, vp, vp.opn_of_v2, vp.pos_of_v2) # continue # # #print(target) # cv.closest = target[1] # cv.closest_vp = target[2] # cv.closest_opn = target[3] # cv.closest_pos = target[4] # #print("closest to", cv, "is", cv.closest) # if target[1] is None: # log("ERROR", f"No neighbours found for cv: {cv}\nMight be due to small structure") # raise NoNeighboursFound() # # return selfMethods
def calculate_full(self)-
Expand source code
def calculate_full(self): self.matrix = [] log(2, f"Calculating matrix ({self.vc_mode})...") for n, v1 in enumerate(self.vectors): self.matrix.append([]) print(f"{n:5d}/{len(self.vectors):5d}", end="\r") for v2 in self.vectors: if v1 == v2: pair = None else: pair = v1 % v2 self.matrix[n].append(pair) for n, r in enumerate(self.matrix): extension = self.length - len(r) -1 zeros = [None] * extension self.matrix[n] = zeros + self.matrix[n] log(3, "n vectors", len(self.vectors)) log(3 , "m length", len(self.matrix)) return self def calculate_neighbours(self, use_fragments=True, max_distance=30, n_neighbours=1)-
Expand source code
def calculate_neighbours(self, use_fragments=True, max_distance=30, n_neighbours=1): log(2, "Calculating neighbours for:", self) from ..tools.SASA import KDT data = {k: {"vc":cv.vc, "cv":cv} for k, cv in enumerate(self.vectors)} for k, v in data.items(): v["vc"]._nnk = k if self.entity is not None: tree = KDT([v["vc"] for v in data.values()], params=self.entity.params(), symops=self.entity.symops(), centre=self.entity.com()) else: tree = KDT([v["vc"] for v in data.values()]) for k1, v in data.items(): print(f"{k1:5d}/{len(data.keys()):5d}", end="\r") cv = v["cv"] vc = v["vc"] radius = 10 neighs_found=False while radius <= max_distance: neighbors, distances = tree.of(vc, radius=radius, distances=True) #print(neighbors) #print(distances) if len(neighbors) == 0: log("error", f"No neighbours found radius={radius}, even itself") raise Exception() potential = [(tree.atom_of(neigh)._nnk, tree.atom_of(neigh), tree.op_of(neigh), tree.pos_of(neigh), d) for neigh, d in zip(neighbors, distances)] targets = [] for p in potential: #print("POTENTIAL:", p) k = p[0] pvc = p[1] if pvc == vc: #print("Same vc") continue pfrag = data[k]["cv"].fragment pop = p[2] ppos = p[3] if (pfrag == cv.fragment) and (pop ==1): #print("Same fragment") continue targets.append(p) #print("TARGETS:") #[print(t) for t in targets] if len(targets) < n_neighbours: radius += 5 #log("warning", "Expanding search to:", radius) continue neighs_found = True targets = sorted(targets, key=lambda x: x[-1]) #print("sorted targets:") #print(targets) for t in targets[:n_neighbours]: k2 = t[0] cv.closest = data[k2]["cv"] cv.closest_vp = cv.pair(cv.closest, d= t[-1], op_of_v2=t[2], pos_of_v2=t[3]) cv.closest_opn = cv.closest_vp.opn_of_v2 cv.closest_pos = cv.closest_vp.pos_of_v2 if n_neighbours != 1: log("Warning", "More than one neighbour requested but not implemented") self.matrix[k1][k2] = cv.closest_vp break # Only programmed for n_neighbours == 1, must be adapted if more needed break if not neighs_found: log("ERROR", f"No neighbours found for cv: {cv}\nMight be due to small structure") raise NoNeighboursFound() return self # for n2, vp in enumerate(self.matrix[n1]): # # if vp is None: # vp = self.matrix[n2][n1] # # if n2 == n1 or (vp.chain1 == vp.chain2 and vp.opn_of_v2 is not None and vp.pos_of_v2 is not None and abs(vp.resnum1-vp.resnum2) <=2) : # continue # print(f"{n1+1} / {n2+1} / {len(self.vectors)}", end="\r") # # # #if vp is None: # # continue # #print(vp, vp.d) # #print(vp.chain1, vp.chain2) # # if use_fragments: # #print(vp.fragment1, vp.fragment2) # if vp.fragment1 == vp.fragment2: # continue # else: # if vp.chain1 == vp.chain2: # continue # # # #print(str(cv), str(vp.v1), str(vp.v2)) # # if str(cv) == str(vp.v1): # t = vp.v2 # elif str(cv) == str(vp.v2): # t = vp.v1 # else: # continue # # #print(cv, t) # if vp.d < target[0]: # target = (vp.d, t, vp, vp.opn_of_v2, vp.pos_of_v2) # continue # # #print(target) # cv.closest = target[1] # cv.closest_vp = target[2] # cv.closest_opn = target[3] # cv.closest_pos = target[4] # #print("closest to", cv, "is", cv.closest) # if target[1] is None: # log("ERROR", f"No neighbours found for cv: {cv}\nMight be due to small structure") # raise NoNeighboursFound() # # return self def map(self, attribute)-
Expand source code
def map(self, attribute): log(2, f"Mapping CVMatrix (attr={attribute})") #print(self.matrix) return (lambda m: np.array([np.array([getattr(x, attribute) if x is not None and getattr(x, attribute) is not None else 0 for x in l]) for l in m ]))(self.matrix) def map_ligands(self, entity)-
Expand source code
def map_ligands(self, entity): log(2, "Mapping ligands...") ligands = entity.ligands() if len(ligands) == 0: log("warning", f"No ligands found in {entity.name()}") for cv in self.vectors: cv.dist_to_lig = 99 cv.closest_lig = None return self for cv in self.vectors: distances = [length(vector(cv.start, l.com())) for l in ligands] #print(distances) cv.dist_to_lig = min(distances) cv.closest_lig = ligands[distances.index(cv.dist_to_lig)] #log(1, f"Closest lig ({cv}): {cv.closest_lig} at {cv.dist_to_lig:4.2f}A") for row in self.matrix: for vp in row: if vp is None: continue vp.map_lig() return self def reset_matrix(self)-
Expand source code
def reset_matrix(self): self.matrix = [[None] * self.length] * self.length def save_fig(self, attribute='d', save_folder=None, prefix='cvmatrix')-
Expand source code
def save_fig(self, attribute="d", save_folder=None, prefix="cvmatrix"): from ..visualisation.plots import plot_heatmap if save_folder is None: save_folder = os.path.join(SUBDIR_NAME, "cvmaps") os.makedirs(save_folder, exist_ok=True) if self.vc_mode is not None: prefix = f"{prefix}_{self.vc_mode}" filename = os.path.join(save_folder, f"{prefix}_{attribute}.png") plot_heatmap(self.square(attribute), filename=filename) return filename def show(self, attribute='d')-
Expand source code
def show(self, attribute="d"): from ..visualisation.plots import plot_heatmap plot_heatmap(self.square(attribute), show=True) def square(self, attribute)-
Expand source code
def square(self, attribute): t = self.map(attribute) sq = square_matrix(t) return sq def triangle(self, attribute='d')-
Expand source code
def triangle(self, attribute="d"): t = self.map(attribute) return t
class CVPair (cvec1, cvec2, recalculate=False, **kwargs)-
Expand source code
class CVPair(object): def __init__(self, cvec1, cvec2, recalculate=False, **kwargs): self.v1 = cvec1 self.v2 = cvec2 self.opn_of_v2 = kwargs.get("opn_of_v2", None) self.pos_of_v2 = kwargs.get("pos_of_v2", None) self.chain1 = self.v1.chain self.chain2 = self.v2.chain self.resnum1 = self.v1.resnum self.resnum2 = self.v2.resnum self.fragment1 = self.v1.fragment self.fragment2 = self.v2.fragment self.dlig = kwargs.get("dlig", None) self.v = kwargs.get("v", None) self.d = kwargs.get("d", None) self.a = kwargs.get("a", None) self.t1 = kwargs.get("t1", None) self.t2 = kwargs.get("t2", None) self.da = kwargs.get("da", None) self.calculate() def __repr__(self): if self.fragment1 is not None and self.fragment2 is not None: return f"<bi.{self.__class__.__name__} {self.v1.resnum}(F{self.v1.fragment}) - {self.v2.resnum}(F{self.v2.fragment})>" else: return f"<bi.{self.__class__.__name__} {self.v1.resnum}({self.v1.chain}) - {self.v2.resnum}({self.v2.chain})>" def calculate(self): if self.v2.params is not None and self.v2.symops is not None: if any([v is None for v in [self.d, self.v, self.opn_of_v2, self.pos_of_v2]]): self.v1.vc.to_frac(self.v2.params) self.v2.vc.to_frac(self.v2.params) coord, d, opn, pos = self.v2.vc.closest(self.v1.vc.coord, symops=self.v2.symops, params=self.v2.params, centre=self.v2.entity_centre) self.d = d self.opn_of_v2 = opn self.pos_of_v2 = pos self.v1.vc.to_orth(self.v2.params) self.v2.vc.to_orth(self.v2.params) self.v = vector(self.v1.vc.coord, coord) else: if self.v is None: self.v = vector(self.v1.vc.coord, self.v2.vc.coord) if self.d is None: self.d = flength(self.v) #print(self.v, self.d) if self.a is None: self.a = angle_between_vectors(self.v1.v, self.v2.v)+ 180 if self.t1 is None: self.t1 = angle_between_vectors(self.v1.v, self.v)+ 180 if self.t2 is None: self.t2 = angle_between_vectors(self.v2.v, self.v)+ 180 if self.da is None: self.da = dihedral_angle(self.v1.end, self.v1.start, self.v2.start, self.v2.end) + 180 return self def map_lig(self): try: dlig = min([d for d in (self.v1.dist_to_lig, self.v2.dist_to_lig) if d is not None], default=None) self.dlig = dlig except: raise def _mmcif_dict(self): data = { "cv1_id": f"{self.v1.full_id():18s}", "cv2_id": f"{self.v2.full_id():18s}", "resnum_1": f"{self.v1.resnum:3d}" if self.v1.resnum is not None else " . ", "chain1": self.v1.chain if self.v1.chain is not None else ".", "fragment1": f"{self.v1.fragment:2d}" if self.v1.fragment is not None else " .", "resnum_2": f"{self.v2.resnum:3d}" if self.v2.resnum is not None else " . ", "chain2": self.v2.chain if self.v2.chain is not None else ".", "fragment2": f"{self.v2.fragment:2d}" if self.v2.fragment is not None else " .", "opn_of_v2": self.opn_of_v2 if self.opn_of_v2 is not None else ".", "v_x": f"{self.v[0]:8.3f}" if self.v is not None else ".", "v_y": f"{self.v[1]:8.3f}" if self.v is not None else ".", "v_z": f"{self.v[2]:8.3f}" if self.v is not None else ".", "d": f"{self.d:8.3f}" if self.d is not None else " .", "a": f"{self.a:8.3f}" if self.a is not None else " .", "t1": f"{self.t1:8.3f}" if self.t1 is not None else " .", "t2": f"{self.t2:8.3f}" if self.t2 is not None else " .", "da": f"{self.da:8.3f}" if self.da is not None else " .", "dlig": f"{self.dlig:8.3f}" if self.dlig is not None else " .", "pos_of_v2": "_".join([str(p) for p in self.pos_of_v2]) if self.pos_of_v2 is not None else " .", } return dataMethods
def calculate(self)-
Expand source code
def calculate(self): if self.v2.params is not None and self.v2.symops is not None: if any([v is None for v in [self.d, self.v, self.opn_of_v2, self.pos_of_v2]]): self.v1.vc.to_frac(self.v2.params) self.v2.vc.to_frac(self.v2.params) coord, d, opn, pos = self.v2.vc.closest(self.v1.vc.coord, symops=self.v2.symops, params=self.v2.params, centre=self.v2.entity_centre) self.d = d self.opn_of_v2 = opn self.pos_of_v2 = pos self.v1.vc.to_orth(self.v2.params) self.v2.vc.to_orth(self.v2.params) self.v = vector(self.v1.vc.coord, coord) else: if self.v is None: self.v = vector(self.v1.vc.coord, self.v2.vc.coord) if self.d is None: self.d = flength(self.v) #print(self.v, self.d) if self.a is None: self.a = angle_between_vectors(self.v1.v, self.v2.v)+ 180 if self.t1 is None: self.t1 = angle_between_vectors(self.v1.v, self.v)+ 180 if self.t2 is None: self.t2 = angle_between_vectors(self.v2.v, self.v)+ 180 if self.da is None: self.da = dihedral_angle(self.v1.end, self.v1.start, self.v2.start, self.v2.end) + 180 return self def map_lig(self)-
Expand source code
def map_lig(self): try: dlig = min([d for d in (self.v1.dist_to_lig, self.v2.dist_to_lig) if d is not None], default=None) self.dlig = dlig except: raise
class CVector (res1, res2, res3, params=None, symops=None, entity_centre=None, vc_mode=None)-
Expand source code
class CVector(object): def __init__(self, res1, res2, res3, params=None, symops=None, entity_centre=None, vc_mode=None): self.res1 = res1 self.res2 = res2 self.res3 = res3 self.residues = (res1, res2, res3) self.chain = res2.chain self.resnum = res2.resnum self.resname = res2.resname self.resseq = res2.resseq self.fragment = res2.fragment self.id = (self.resnum, self.chain) self.across_chains = False self.is_gap = False self.trash = False self.vc_mode = vc_mode self.vc = None self.ss = None self.d = None self.v = None self.start = None self.end = None self.closest = None self.closest_vp = None self.closest_opn = None self.closest_pos = None self.closest_lig = None self.dist_to_lig = None self.params = params self.symops = symops self.entity_centre = entity_centre self.calculate() def full_id(self): return f"{self.chain}_{self.fragment}_{self.resseq}_{self.resname}_{self.resnum}" def _mmcif_dict(self): d = dict( id=f"{self.full_id():18s}", chain=self.chain, fragment=f"{self.fragment:2d}" if self.fragment else ". ", resseq=f"{self.resseq:3d}", resname=f"{self.resname:3s}", resnum=f"{self.resnum:3d}", ss=f"{self.ss:2s}" if self.ss is not None else ". ", d=f"{self.d:8.3f}", start_x=f"{self.start.coord[0]:8.3f}", start_y=f"{self.start.coord[1]:8.3f}", start_z=f"{self.start.coord[2]:8.3f}", end_x=f"{self.end.coord[0]:8.3f}", end_y=f"{self.end.coord[1]:8.3f}", end_z=f"{self.end.coord[2]:8.3f}", vc_x=f"{self.vc.coord[0]:8.3f}", vc_y=f"{self.vc.coord[1]:8.3f}", vc_z=f"{self.vc.coord[2]:8.3f}", closest_resseq=f"{self.closest.resseq:3d}" if self.closest is not None else " . ", closest_resnum=f"{self.closest.resnum:3d}" if self.closest is not None else " . ", closest_chain=self.closest.chain if self.closest is not None else None, closest_fragment=self.closest.fragment if self.closest is not None else None, closest_opn=f"{self.closest_opn:2d}", closest_lig_name=f"{self.closest_lig.name:3s}" if self.closest_lig is not None else " . ", closest_lig_chain=f"{self.closest_lig.chain}" if self.closest_lig is not None else " . ", dist_to_lig=f"{self.dist_to_lig:8.3f}" if self.dist_to_lig is not None else " .", closest_pos="_".join([str(p) for p in self.closest_pos]) if self.closest_pos is not None else " .", ) for k, v in d.items(): if v is None: d[k] = "." d[k] = str(d[k]) return d def __repr__(self): return f"<bi.{self.__class__.__name__} c.{self.chain} ({self.res1.resnum}>{self.res2.resnum}>{self.res3.resnum})>" def _centroid(self, *coords): coords = np.array(coords) coords = coords.sum(axis=0) coords = coords/len(coords) return coords def calculate(self): from ..base.atom import PseudoAtom self.start = PseudoAtom(find_com([r.ca for r in self.residues])) self.end = PseudoAtom(find_com([r.o for r in self.residues])) self.v = vector(self.start.coord, self.end.coord) self.d = length(self.v) if self.vc_mode is None: self.vc = self.start.copy() elif self.vc_mode == "ca_projection": ca = self.res2.ca.coord start_ca = vector(self.start.coord, ca) self.vc = PseudoAtom((start_ca[0] + ca[0], start_ca[1] + ca[1], start_ca[2] + ca[2])) else: log("error", "VC Mode Not Implemented:", self.vc_mode) raise NotImplementedError("VC Mode Not Implemented:", self.vc_mode) if len({self.res1.chain, self.res2.chain, self.res3.chain}) > 1: self.across_chains = True self.trash = True if abs(self.res1.resnum - self.res2.resnum) != 1 or abs(self.res2.resnum - self.res3.resnum) != 1: self.is_gap = True self.trash = True self.ss = self._calculate_ss() return self def _calculate_ss(self, delta_cvla = 0.2, delta_cvlb = 0.05): if 1.4 - delta_cvlb <= self.d <= 1.4 + delta_cvlb: ss = "bs" elif 2.2 - delta_cvla <= self.d <= 2.2 + delta_cvla: ss = "ah" else: ss = "co" return ss def pair(self, target, **kwargs): return CVPair(self, target, **kwargs) def __mod__(self, target): return self.pair(target)Methods
def calculate(self)-
Expand source code
def calculate(self): from ..base.atom import PseudoAtom self.start = PseudoAtom(find_com([r.ca for r in self.residues])) self.end = PseudoAtom(find_com([r.o for r in self.residues])) self.v = vector(self.start.coord, self.end.coord) self.d = length(self.v) if self.vc_mode is None: self.vc = self.start.copy() elif self.vc_mode == "ca_projection": ca = self.res2.ca.coord start_ca = vector(self.start.coord, ca) self.vc = PseudoAtom((start_ca[0] + ca[0], start_ca[1] + ca[1], start_ca[2] + ca[2])) else: log("error", "VC Mode Not Implemented:", self.vc_mode) raise NotImplementedError("VC Mode Not Implemented:", self.vc_mode) if len({self.res1.chain, self.res2.chain, self.res3.chain}) > 1: self.across_chains = True self.trash = True if abs(self.res1.resnum - self.res2.resnum) != 1 or abs(self.res2.resnum - self.res3.resnum) != 1: self.is_gap = True self.trash = True self.ss = self._calculate_ss() return self def full_id(self)-
Expand source code
def full_id(self): return f"{self.chain}_{self.fragment}_{self.resseq}_{self.resname}_{self.resnum}" def pair(self, target, **kwargs)-
Expand source code
def pair(self, target, **kwargs): return CVPair(self, target, **kwargs)
class FragmentedStructure (*args, **kwargs)-
Expand source code
class FragmentedStructure(BIStructure): child_class = Fragment extension = "fstructure" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.paths["sub_folder"] = "fragmented" self.data["fragments"] = {} self._cvmatrix = None self._fragments = None @classmethod def from_file(cls, *args, **kwargs): self = super().from_file(*args, **kwargs) # if not self.has_flag("fragmented", True): # self.fragment(in_place=True) if self is not None: self.recover_cvmatrix() return self def recover_cvmatrix(self): pass def _fragment_with_aleph(self, force=False, export=False, **kwargs): log(2, "Fragmenting structure with ALEPH...") if self.has_flag("fragmented", True) and not force: log(2, "Fragments already generated!") return self._fragments if (self.path() is not None) and self.has_flag("fragmented") and not force: if os.path.exists(self.path()): log(2, "Recovering previously fragmented file...") return self.from_file(self.path(), export_folder=self.paths["export_folder"]) from .core.ALEPH import annotate_pdb_model_with_aleph target_path = self.export(minimal=True, target_folder=os.path.join(TEMP_FOLDER, "trash")) if target_path is None: raise ALEPHError("Minimal cif could not be generated") self.data["fragments"]["weight"] = "distance_avg" self.data["fragments"]["threshold_ah"] = 0.50 self.data["fragments"]["threshold_bs"] = 0.30 self.data["fragments"]["peptide_length"] = 3 try: print("### ALEPH start ###") graph, _, _, _, _ = annotate_pdb_model_with_aleph( target_path, weight=self.data["fragments"]["weight"], strictness_ah=self.data["fragments"]["threshold_ah"], strictness_bs=self.data["fragments"]["threshold_bs"], peptide_length=self.data["fragments"]["peptide_length"], write_pdb=False, ) print("### ALEPH end ###") except Exception as e: print("### ALEPH failed ###") log("warning", e) raise ALEPHError(e) log(1, "Fragmented:", target_path) fragments = [] fragmented_ids = graph.vs atoms = [] for n, fraglist in enumerate(fragmented_ids): single_atom_ratio = [0, 0] cvs = fraglist["reslist"] reslist = self.residues() target_res= [] for fres in cvs: try: _, model, chain, full_id, resname = fres except: #log("warning", fres) _, model, chain, full_id = fres resname = None for res in reslist.copy(): if res.complex == chain and res.resnum == full_id[1]: if full_id[2].strip() != "": continue # Not implemented print(full_id, res.ca.ins_code) if full_id[2].strip() != res.ca.ins_code: continue if res.resname != resname: if resname is not None: print(res.resseq, res.resnum, res.complex, chain, full_id, res.entity) raise Exception(f"res.resname({res.resname}) != resname({resname})\nfres:{fres}\nres: {res}") else: #log("warning", f"res.resname({res.resname}) != resname({resname})\nfres:{fres}\nres: {res}") pass if len(res.atoms) == 1: single_atom_ratio[0] += 1 single_atom_ratio[1] += 1 target_res.append(res) reslist.remove(res) continue del res del fres if len(target_res) == 0: log("warning", f"fragment {n}: no residues") break fatoms = [] for res in target_res: fatoms.extend(res.atoms) atoms.extend(res.atoms) chain = list(set([r.chain for r in fatoms])) if len(chain) > 0: chain = chain[0] fragment = Fragment.from_atoms(fatoms, code=self.code(), chain_id=chain, fragment_id=n, parent=self) if export: fragment.export() log(2, f"fragment {n}: {fragment}", end="\r") if single_atom_ratio[0] / single_atom_ratio[1] > 0.5: log("Warning", f"Detected fragment with too many missing side chains ({single_atom_ratio[0] / single_atom_ratio[1]:3.1f}%)") fragment.set_flag("missing_side_chains", True) self.set_flag("missing_side_chains", True) fragments.append(fragment) else: log("warning", f"fragment {n}: no residues") #self._atoms = atoms self._fragments = fragments for a in self.all_atoms(): if a.get_misc("fragment", None) is None: a.set_misc("fragment", None) pass self.data["fragments"]["n_fragments"] = len(self._fragments) self.set_flag("fragmented", True) self.export() #print(self.all_atoms()) return self._fragments def fragments(self, force=False): log(1, "Fragmenting structure...") if self._fragments is None and not force: if self.has_flag("fragmented", True): log(2, f"Recovering fragments from cif...") atoms_by_fragment = {} for a in self.all_atoms(): f = a.get_misc("fragment", None) if f is None or f == ".": continue if int(f) not in atoms_by_fragment: atoms_by_fragment[int(f)] = [] atoms_by_fragment[int(f)].append(a) fragments = [] for n, fatoms in atoms_by_fragment.items(): chain = list(set([r.chain for r in fatoms]))[0] fragment = Fragment.from_atoms(fatoms, code=self.code(), chain_id=chain, fragment_id=n, parent=self) log(2, f"fragment {n}: {fragment}", end="\r") fragments.append(fragment) if len(fragments) > 0: self._fragments = fragments if self._fragments is None or force: log(2, "Recalculating fragments...") self._fragment_with_aleph() return self._fragments def _map_cvectors(self, with_ligands=True, vc_mode=None): log(1, "Generating CVMatrix for:", self.name(), f"({vc_mode})") from . import CVMatrix matrix = CVMatrix(self.cvectors(vc_mode=vc_mode), vc_mode=vc_mode, entity=self) try: matrix.calculate_neighbours() except NoNeighboursFound as e: log("warning", e) self.set_flag("cvmatrix_error", True) self._cvmatrix = None return None matrix.save_fig(attribute="d", save_folder=os.path.join(self.folder(), "cvmaps")) if with_ligands: matrix.map_ligands(self) matrix.save_fig(attribute="dlig", save_folder=os.path.join(self.folder(), "cvmaps")) self._cvmatrix = matrix self._matrix_vc_mode = vc_mode return self._cvmatrix def cvmatrix(self, vc_mode=None, **kwargs): if self._cvmatrix is None or vc_mode != getattr(self, "_matrix_vc_mode", None): self._map_cvectors(vc_mode=vc_mode, **kwargs) else: log(1, f"Using previously saved CVMatrix ({vc_mode})...") return self._cvmatrix def show(self): for a in self.all_atoms(): a.set_bfactor(a.get_misc("fragment")) super().show() def show_fragments(self, execute=True, script=None): if script is None: from ..visualisation.pymol import PymolScript script = PymolScript(self.name()) for fragment in self.fragments(): for a in fragment.all_atoms(): a.set_bfactor(a.get_misc("fragment")) script.load(fragment.export(), "frag_"+fragment.name()) script.group("frag_", "fragments") script.spectrum("(all)") script.orient() script.write_script() if execute: script.execute() return script def show_cvectors(self, execute=True, script=None, vc_mode=None): script = self.show_fragments(execute=False, script=script) m = self.cvmatrix(vc_mode=vc_mode) if m is None: log("error", f"No CVMatrix for {self.name()}") return None for cv in self.cvectors(vc_mode=vc_mode): if cv.is_gap: script.line("gap_cvectors", coord1=cv.start.coord, coord2=cv.end.coord) else: script.line("cvectors", coord1=cv.start.coord, coord2=cv.end.coord) if m.vc_mode is not None: script.line("ca_vc", coord1=cv.res2.ca.coord, coord2=cv.vc.coord) script.line("ca_cv", coord1=cv.res2.ca.coord, coord2=cv.start.coord) #if cv.fragment is None: # continue if cv.closest_opn == 1 or cv.closest_opn is None: script.line("neighbours", coord1=cv.vc.coord, coord2=cv.closest.vc.coord) else: symstart = cv.closest.start.copy().to_frac(self.params()).symop(self.symops(cv.closest_opn), self.params(), position=cv.closest_pos).to_orth(self.params()) symend = cv.closest.end.copy().to_frac(self.params()).symop(self.symops(cv.closest_opn), self.params(), position=cv.closest_pos).to_orth(self.params()) script.line("neighbours", coord1=cv.vc.coord, coord2=symstart) script.line("cvectors_sym", coord1=symstart, coord2=symend) script.color("neighbours", "orange") script.color("cvectors", "cyan") script.color("gap_cvectors", "purple") script.color("cvectors_sym", "green") script.color("ca_vc", "yellow") script.color("ca_cv", "red") print(self.export()) script.load(self.path(), self.name()) script.color(self.name(), "white") script.hide(self.name()) script.show(self.name(), "ribbon") script.write_script() if execute: script.execute() return scriptAncestors
Static methods
def from_file(*args, **kwargs)
Methods
def cvmatrix(self, vc_mode=None, **kwargs)-
Expand source code
def cvmatrix(self, vc_mode=None, **kwargs): if self._cvmatrix is None or vc_mode != getattr(self, "_matrix_vc_mode", None): self._map_cvectors(vc_mode=vc_mode, **kwargs) else: log(1, f"Using previously saved CVMatrix ({vc_mode})...") return self._cvmatrix def fragments(self, force=False)-
Expand source code
def fragments(self, force=False): log(1, "Fragmenting structure...") if self._fragments is None and not force: if self.has_flag("fragmented", True): log(2, f"Recovering fragments from cif...") atoms_by_fragment = {} for a in self.all_atoms(): f = a.get_misc("fragment", None) if f is None or f == ".": continue if int(f) not in atoms_by_fragment: atoms_by_fragment[int(f)] = [] atoms_by_fragment[int(f)].append(a) fragments = [] for n, fatoms in atoms_by_fragment.items(): chain = list(set([r.chain for r in fatoms]))[0] fragment = Fragment.from_atoms(fatoms, code=self.code(), chain_id=chain, fragment_id=n, parent=self) log(2, f"fragment {n}: {fragment}", end="\r") fragments.append(fragment) if len(fragments) > 0: self._fragments = fragments if self._fragments is None or force: log(2, "Recalculating fragments...") self._fragment_with_aleph() return self._fragments def recover_cvmatrix(self)-
Expand source code
def recover_cvmatrix(self): pass def show(self)-
Expand source code
def show(self): for a in self.all_atoms(): a.set_bfactor(a.get_misc("fragment")) super().show() def show_cvectors(self, execute=True, script=None, vc_mode=None)-
Expand source code
def show_cvectors(self, execute=True, script=None, vc_mode=None): script = self.show_fragments(execute=False, script=script) m = self.cvmatrix(vc_mode=vc_mode) if m is None: log("error", f"No CVMatrix for {self.name()}") return None for cv in self.cvectors(vc_mode=vc_mode): if cv.is_gap: script.line("gap_cvectors", coord1=cv.start.coord, coord2=cv.end.coord) else: script.line("cvectors", coord1=cv.start.coord, coord2=cv.end.coord) if m.vc_mode is not None: script.line("ca_vc", coord1=cv.res2.ca.coord, coord2=cv.vc.coord) script.line("ca_cv", coord1=cv.res2.ca.coord, coord2=cv.start.coord) #if cv.fragment is None: # continue if cv.closest_opn == 1 or cv.closest_opn is None: script.line("neighbours", coord1=cv.vc.coord, coord2=cv.closest.vc.coord) else: symstart = cv.closest.start.copy().to_frac(self.params()).symop(self.symops(cv.closest_opn), self.params(), position=cv.closest_pos).to_orth(self.params()) symend = cv.closest.end.copy().to_frac(self.params()).symop(self.symops(cv.closest_opn), self.params(), position=cv.closest_pos).to_orth(self.params()) script.line("neighbours", coord1=cv.vc.coord, coord2=symstart) script.line("cvectors_sym", coord1=symstart, coord2=symend) script.color("neighbours", "orange") script.color("cvectors", "cyan") script.color("gap_cvectors", "purple") script.color("cvectors_sym", "green") script.color("ca_vc", "yellow") script.color("ca_cv", "red") print(self.export()) script.load(self.path(), self.name()) script.color(self.name(), "white") script.hide(self.name()) script.show(self.name(), "ribbon") script.write_script() if execute: script.execute() return script def show_fragments(self, execute=True, script=None)-
Expand source code
def show_fragments(self, execute=True, script=None): if script is None: from ..visualisation.pymol import PymolScript script = PymolScript(self.name()) for fragment in self.fragments(): for a in fragment.all_atoms(): a.set_bfactor(a.get_misc("fragment")) script.load(fragment.export(), "frag_"+fragment.name()) script.group("frag_", "fragments") script.spectrum("(all)") script.orient() script.write_script() if execute: script.execute() return script
Inherited members