~/bend-docscommunity

tpl.bend source

tpl.bend on the hub · documented module

import Baseimport ./geom.bend as Gimport ./protein.bend as Pimport ./pdb.bend as Pdbimport ./templates.bend as Templates# --- Residue templates: CCD-derived bonds applied by name. ---# TplAtom carries parse-time identity (chain/seq/residue/atom names) that# P.Atom drops. A template bond fires for same-residue atom pairs whose# names are linked in the residue's template; unknown residues yield no# template bonds (inference + CONECT cover them). The union is used# downstream; duplicates across sources are harmless for boolean# exclusions and negligible in energies (documented).type TplAtom is Data:  TA{serial: U32, chain: U32, seq: Nat, res: String, name: String}def tpl_bond_match(+n1: String, +n2: String, +x: String, +y: String) -> Bool:  Bool.or(Bool.and(String.eq(n1, x), String.eq(n2, y)), Bool.and(String.eq(n1, y), String.eq(n2, x)))def tpl_has_scan(bs: List<&2, String>, +n1: String, +n2: String) -> Bool:  match bs:    case Nil{}:      False{}    case x <> Nil{}:      False{}    case x <> y <> t:      Bool.or(tpl_bond_match(n1, n2, x, y), tpl_has_scan(t, n1, n2))def tpl_has_bond(+res: String, +n1: String, +n2: String) -> Bool:  tpl_has_scan(Templates.tpl_bonds_for(res), n1, n2)def tpl_bonded(+ra: String, +na: String, +ca: U32, +qa: Nat, rb: String, nb: String, cb: U32, qb: Nat) -> Bool:  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)))def tpl_one(a: TplAtom, h: TplAtom) -> List<&1, U32 & U32>:  match a h:    case TA{sa, ca, qa, ra, na} TA{sb, cb, qb, rb, nb}:      Bool.pick(List<&1, U32 & U32>, tpl_bonded(ra, na, ca, qa, rb, nb, cb, qb), [(sa, sb)], Nil{})def append_tpl(a: List<&1, U32 & U32>, b: List<&1, U32 & U32>) -> List<&1, U32 & U32>:  match a:    case Nil{}:      b    case h <> t:      h <> append_tpl(t, b)def tpl_row(+a: TplAtom, ys: List<&2, TplAtom>) -> List<&1, U32 & U32>:  match ys:    case Nil{}:      Nil{}    case h <> t:      append_tpl(tpl_one(a, h), tpl_row(a, t))def tpl_total(+xs: List<&2, TplAtom>) -> List<&1, U32 & U32>:  match xs:    case Nil{}:      Nil{}    case h <> +t:      append_tpl(tpl_row(h, t), tpl_total(t))def parse_tpl_seq(serial: U32, ch: U32, ms: Maybe<&2, Nat>, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:  match ms:    case None{}:      None{}    case Some{seq}:      Some{TA{serial, ch, seq, String.trim(res_s), String.trim(name_s)}}def parse_tpl_chain(serial: U32, chain_s: String, seq_s: String, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:  parse_tpl_seq(serial, Pdb.chain_u32(chain_s), Nat.read(String.trim(seq_s)), res_s, name_s)def parse_tpl_serial(ms: Maybe<&2, U32>, chain_s: String, seq_s: String, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:  match ms:    case None{}:      None{}    case Some{serial}:      parse_tpl_chain(serial, chain_s, seq_s, res_s, name_s)def parse_tpl_fields(serial_s: String, chain_s: String, seq_s: String, res_s: String, name_s: String) -> Maybe<&2, TplAtom>:  parse_tpl_serial(U32.read(String.trim(serial_s)), chain_s, seq_s, res_s, name_s)def parse_tpl_line(+line: String) -> Maybe<&2, TplAtom>:  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))def collect_tpl_head(m: Maybe<&2, TplAtom>, rest: List<&2, TplAtom> & Nat) -> List<&2, TplAtom> & Nat:  match m:    case None{}:      match rest:        case (as, n):          (as, 1n+n)    case Some{x}:      match rest:        case (as, n):          (x <> as, n)def collect_tpl(lines: List<&2, String>) -> List<&2, TplAtom> & Nat:  match lines:    case Nil{}:      (Nil{}, 0n)    case h <> t:      collect_tpl_head(parse_tpl_line(h), collect_tpl(t))def tpl_atoms_only(p: List<&2, TplAtom> & Nat) -> List<&2, TplAtom>:  match p:    case (xs, n):      xs