tpl.bend

bend-prot@0.1.0.0 · 106 lines · 17 definitions

1import Base
2import bend-prot@0.1.0.0/geom.bend as G
3import bend-prot@0.1.0.0/protein.bend as P
4import bend-prot@0.1.0.0/pdb.bend as Pdb
5import bend-prot@0.1.0.0/templates.bend as Templates
6
7# --- Residue templates: CCD-derived bonds applied by name. ---
8# TplAtom carries parse-time identity (chain/seq/residue/atom names) that
9# P.Atom drops. A template bond fires for same-residue atom pairs whose
10# names are linked in the residue's template; unknown residues yield no
11# template bonds (inference + CONECT cover them). The union is used
12# downstream; duplicates across sources are harmless for boolean
13# exclusions and negligible in energies (documented).
14
15type TplAtom is Data:
16  TA{serial: U32, chain: U32, seq: Nat, res: String, name: String}
17
18def tpl_bond_match(+n1: String, +n2: String, +x: String, +y: String) -> Bool:
19  Bool.or(Bool.and(String.eq(n1, x), String.eq(n2, y)), Bool.and(String.eq(n1, y), String.eq(n2, x)))
20
21def tpl_has_scan(bs: List<&2, String>, +n1: String, +n2: String) -> Bool:
22  match bs:
23    case Nil{}:
24      False{}
25    case x <> Nil{}:
26      False{}
27    case x <> y <> t:
28      Bool.or(tpl_bond_match(n1, n2, x, y), tpl_has_scan(t, n1, n2))
29
30def tpl_has_bond(+res: String, +n1: String, +n2: String) -> Bool:
31  tpl_has_scan(Templates.tpl_bonds_for(res), n1, n2)
32
33def tpl_bonded(+ra: String, +na: String, +ca: U32, +qa: Nat, rb: String, nb: String, cb: U32, qb: Nat) -> Bool:
34  Bool.and(Bool.and(U32.is_eq(ca, cb), Nat.is_eq(qa, qb)), Bool.and(String.eq(ra, rb), tpl_has_bond(ra, na, nb)))
35
36def tpl_one(a: TplAtom, h: TplAtom) -> List<&1, U32 & U32>:
37  match a h:
38    case TA{sa, ca, qa, ra, na} TA{sb, cb, qb, rb, nb}:
39      Bool.pick(List<&1, U32 & U32>, tpl_bonded(ra, na, ca, qa, rb, nb, cb, qb), [(sa, sb)], Nil{})
40
41def append_tpl(a: List<&1, U32 & U32>, b: List<&1, U32 & U32>) -> List<&1, U32 & U32>:
42  match a:
43    case Nil{}:
44      b
45    case h <> t:
46      h <> append_tpl(t, b)
47
48def tpl_row(+a: TplAtom, ys: List<&2, TplAtom>) -> List<&1, U32 & U32>:
49  match ys:
50    case Nil{}:
51      Nil{}
52    case h <> t:
53      append_tpl(tpl_one(a, h), tpl_row(a, t))
54
55def tpl_total(+xs: List<&2, TplAtom>) -> List<&1, U32 & U32>:
56  match xs:
57    case Nil{}:
58      Nil{}
59    case h <> +t:
60      append_tpl(tpl_row(h, t), tpl_total(t))
61
62def parse_tpl_seq(serial: U32, ch: U32, ms: Maybe<&2, Nat>, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:
63  match ms:
64    case None{}:
65      None{}
66    case Some{seq}:
67      Some{TA{serial, ch, seq, String.trim(res_s), String.trim(name_s)}}
68
69def parse_tpl_chain(serial: U32, chain_s: String, seq_s: String, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:
70  parse_tpl_seq(serial, Pdb.chain_u32(chain_s), Nat.read(String.trim(seq_s)), res_s, name_s)
71
72def parse_tpl_serial(ms: Maybe<&2, U32>, chain_s: String, seq_s: String, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:
73  match ms:
74    case None{}:
75      None{}
76    case Some{serial}:
77      parse_tpl_chain(serial, chain_s, seq_s, res_s, name_s)
78
79def parse_tpl_fields(serial_s: String, chain_s: String, seq_s: String, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:
80  parse_tpl_serial(U32.read(String.trim(serial_s)), chain_s, seq_s, res_s, name_s)
81
82def parse_tpl_line(+line: String) -> Maybe<&2, TplAtom>:
83  parse_tpl_fields(Pdb.pdb_slice(line, 6n, 5n), Pdb.pdb_slice(line, 21n, 1n), Pdb.pdb_slice(line, 22n, 4n), Pdb.pdb_slice(line, 17n, 3n), Pdb.pdb_slice(line, 12n, 4n))
84
85def collect_tpl_head(m: Maybe<&2, TplAtom>, rest: List<&2, TplAtom> & Nat) -> List<&2, TplAtom> & Nat:
86  match m:
87    case None{}:
88      match rest:
89        case (as, n):
90          (as, 1n+n)
91    case Some{x}:
92      match rest:
93        case (as, n):
94          (x <> as, n)
95
96def collect_tpl(lines: List<&2, String>) -> List<&2, TplAtom> & Nat:
97  match lines:
98    case Nil{}:
99      (Nil{}, 0n)
100    case h <> t:
101      collect_tpl_head(parse_tpl_line(h), collect_tpl(t))
102
103def tpl_atoms_only(p: List<&2, TplAtom> & Nat) -> List<&2, TplAtom>:
104  match p:
105    case (xs, n):
106      xs