From cb41a3b0d75ac62e683ec86abf93d6d2b175c689 Mon Sep 17 00:00:00 2001 From: Rodrigo Vargas Honorato Date: Thu, 21 Nov 2024 16:59:56 +0100 Subject: [PATCH] add `unambig-ti` subcommand (#32) * add unambig_ti stub * add `unambig-ti` subcommand * add test data * cleaning * update docs * cleaning * bump version * update `README.md` --- Cargo.lock | 213 ++++++++++++++++++----------------------- Cargo.toml | 2 +- README.md | 20 ++-- docs/src/unambig-ti.md | 19 ++++ docs/src/usage.md | 5 +- src/main.rs | 90 ++++++++++++++++- src/structure.rs | 116 ++++++++++++++++++++++ tests/data/two_res.pdb | 18 ++++ 8 files changed, 349 insertions(+), 134 deletions(-) create mode 100644 docs/src/unambig-ti.md create mode 100644 tests/data/two_res.pdb diff --git a/Cargo.lock b/Cargo.lock index 5cf9419..916ff87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -34,36 +34,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" @@ -98,9 +98,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bytemuck" -version = "1.17.1" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -116,9 +116,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.16" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -138,27 +138,27 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", - "proc-macro2 1.0.86", + "proc-macro2 1.0.91", "quote 1.0.37", "syn", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "crc32fast" @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "critical-section" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" @@ -234,15 +234,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -261,12 +261,12 @@ dependencies = [ [[package]] name = "haddock-restraints" -version = "0.6.1" +version = "0.7.0" dependencies = [ "clap", "itertools", "kd-tree", - "nalgebra 0.33.0", + "nalgebra", "pdb-handler", "pdbtbx", "rand", @@ -296,9 +296,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "heapless" @@ -331,9 +331,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", @@ -356,9 +356,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "kd-tree" @@ -380,15 +380,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "linux-raw-sys" @@ -433,9 +433,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.6" +version = "0.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" dependencies = [ "approx", "matrixmultiply", @@ -443,23 +443,7 @@ dependencies = [ "num-complex", "num-rational", "num-traits", - "simba 0.8.1", - "typenum", -] - -[[package]] -name = "nalgebra" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4b5f057b303842cf3262c27e465f4c303572e7f6b0648f60e16248ac3397f4" -dependencies = [ - "approx", - "matrixmultiply", - "nalgebra-macros", - "num-complex", - "num-rational", - "num-traits", - "simba 0.9.0", + "simba", "typenum", ] @@ -469,7 +453,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.91", "quote 1.0.37", "syn", ] @@ -525,15 +509,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "ordered-float" -version = "4.2.2" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a91171844676f8c7990ce64959210cd2eaef32c2612c50f9fae9f8aaa6065a6" +checksum = "c65ee1f9701bf938026630b455d5315f490640234259037edb259798b3bcf85e" dependencies = [ "num-traits", ] @@ -589,9 +573,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3" dependencies = [ "unicode-ident", ] @@ -611,7 +595,7 @@ version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.91", ] [[package]] @@ -672,9 +656,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -684,9 +668,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -695,9 +679,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rstar" @@ -712,9 +696,9 @@ dependencies = [ [[package]] name = "rstar" -version = "0.12.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133315eb94c7b1e8d0cb097e5a710d850263372fd028fff18969de708afc7008" +checksum = "421400d13ccfd26dfa5858199c30a5d76f9c54e0dba7575273025b43c5175dbb" dependencies = [ "heapless 0.8.0", "num-traits", @@ -723,15 +707,15 @@ dependencies = [ [[package]] name = "rust-sasa" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e104b492a7a23bd4a60708820c010cd1d12e465070b593ac1e99a0e9898495b" +checksum = "e558f2e471a933b98a3218e604c6761ff1ebe7434b1a326d39c0338054651d5e" dependencies = [ "lazy_static", - "nalgebra 0.32.6", + "nalgebra", "pdbtbx", "rayon", - "rstar 0.12.0", + "rstar 0.12.2", "snafu", ] @@ -746,9 +730,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.35" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags", "errno", @@ -786,29 +770,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.91", "quote 1.0.37", "syn", ] [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -816,19 +800,6 @@ dependencies = [ "serde", ] -[[package]] -name = "simba" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" -dependencies = [ - "approx", - "num-complex", - "num-traits", - "paste", - "wide", -] - [[package]] name = "simba" version = "0.9.0" @@ -850,21 +821,21 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snafu" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b835cb902660db3415a672d862905e791e54d306c6e8189168c7f3d9ae1c79d" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" dependencies = [ "snafu-derive", ] [[package]] name = "snafu-derive" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d1e02fca405f6280643174a50c942219f0bbf4dbf7d480f1dd864d6f211ae5" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" dependencies = [ "heck", - "proc-macro2 1.0.86", + "proc-macro2 1.0.91", "quote 1.0.37", "syn", ] @@ -892,20 +863,20 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.76" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.91", "quote 1.0.37", "unicode-ident", ] [[package]] name = "tempfile" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -922,9 +893,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-xid" @@ -946,9 +917,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wide" -version = "0.7.28" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b828f995bf1e9622031f8009f8481a85406ce1f4d4588ff746d872043e855690" +checksum = "58e6db2670d2be78525979e9a5f9c69d296fd7d670549fe9ebf70f8708cb5019" dependencies = [ "bytemuck", "safe_arch", @@ -1052,7 +1023,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.91", "quote 1.0.37", "syn", ] diff --git a/Cargo.toml b/Cargo.toml index e20fbf8..d40a14a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "haddock-restraints" -version = "0.6.2" +version = "0.7.0" edition = "2021" description = "Generate restraints to be used in HADDOCK" license = "MIT" diff --git a/README.md b/README.md index 8de731c..715e3f0 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ A standalone command-line application to generate restraints to be used in HADDO - [`restraint`: Generate Unambiguous restraints to keep molecules together during docking](https://www.bonvinlab.org/haddock-restraints/restraint.html) - [`interface`: List residues in the interface](https://www.bonvinlab.org/haddock-restraints/interface.html) - [`z`: Generate Z-restraints for a protein](https://www.bonvinlab.org/haddock-restraints/z.html) +- [`unambig-ti`: Generate unambiguous true-interface restraints from a PDB file](https://www.bonvinlab.org/haddock-restraints/unambig-ti.html) ## Usage @@ -31,9 +32,9 @@ OR - Install it with [`cargo`](https://www.rust-lang.org/tools/install) - ```bash - cargo install haddock-restraints - ``` + ```bash + cargo install haddock-restraints + ``` ## Execute @@ -44,12 +45,13 @@ Generate restraints to be used in HADDOCK Usage: haddock-restraints Commands: - tbl Generate TBL file from input file - ti Generate true-interface restraints from a PDB file - restraint Generate Unambiguous restraints to keep molecules together during docking - interface List residues in the interface - z Generate Z-restraints for a protein - help Print this message or the help of the given subcommand(s) + tbl Generate TBL file from input file + ti Generate true-interface restraints from a PDB file + unambig-ti Generate unambiguous true-interface restraints from a PDB file + restraint Generate unambiguous restraints to keep molecules together during docking + interface List residues in the interface + z Generate Z-restraints for a protein + help Print this message or the help of the given subcommand(s) Options: -h, --help Print help diff --git a/docs/src/unambig-ti.md b/docs/src/unambig-ti.md new file mode 100644 index 0000000..c256344 --- /dev/null +++ b/docs/src/unambig-ti.md @@ -0,0 +1,19 @@ +# Generate _unambiguous true-interface_ restraints from a PDB file + +This is a more strict version of the true-interface restraints that assigns +specific pairs to each residue in the interface. + +For each atom in each of the chains, the algorithm defines the pairs based on +atomic interactions between any atom of a given residue in the interface and +any other atom in an interacting chain. The restraints are later defined +considering the CA-CA distances of such pairs; thus allowing for +side-chain flexibility. + +## Usage + +To run the `unambig-ti` subcommand, you just need to provide the path to the +PDB file and the cutoff distance. For example: + +```bash +haddock-restraints unambig-ti path/to/complex.pdb 5.0 > unambig.tbl +``` diff --git a/docs/src/usage.md b/docs/src/usage.md index 74e5910..5e1d199 100644 --- a/docs/src/usage.md +++ b/docs/src/usage.md @@ -1,6 +1,7 @@ # Usage -`haddock-restraints` is a command-line tool that is organized with subcommands. Each subcommand has its own set of options and arguments. The main subcommands are: +`haddock-restraints` is a command-line tool that is organized with subcommands. +Each subcommand has its own set of options and arguments. The main subcommands are: - [`tbl`: Generate .tbl file from a configuration file](./tbl.md) @@ -11,3 +12,5 @@ - [`interface`: List residues in the interface](./interface.md) - [`z`: Generate restraints to keep the molecule aligned to the Z-axis](./z.md) + +- [`unambig-ti`: Generate unambiguous true-interface restraints](./unambig-ti.md) diff --git a/src/main.rs b/src/main.rs index 5479208..0f58106 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,7 +33,14 @@ enum Commands { #[arg(help = "Cutoff distance for interface residues")] cutoff: f64, }, - #[command(about = "Generate Unambiguous restraints to keep molecules together during docking")] + #[command(about = "Generate unambiguous true-interface restraints from a PDB file")] + UnambigTi { + #[arg(help = "PDB file")] + input: String, + #[arg(help = "Cutoff distance for interface residues")] + cutoff: f64, + }, + #[command(about = "Generate unambiguous restraints to keep molecules together during docking")] Restraint { #[arg(help = "PDB file")] input: String, @@ -45,7 +52,6 @@ enum Commands { #[arg(help = "Cutoff distance for interface residues")] cutoff: f64, }, - #[command(about = "Generate Z-restraints for a protein")] Z { #[arg(required = true, help = "Input file")] @@ -89,6 +95,9 @@ fn main() -> Result<(), Box> { Commands::Ti { input, cutoff } => { let _ = true_interface(input, cutoff); } + Commands::UnambigTi { input, cutoff } => { + let _ = unambig_ti(input, cutoff); + } Commands::Restraint { input } => { let _ = restraint_bodies(input); } @@ -172,6 +181,74 @@ fn gen_tbl(input_file: &str) { println!("{}", tbl); } +/// Generates Unambiguous Topological Interactions (TIs) from a protein structure. +/// +/// This function reads a PDB file, identifies the closest residue pairs based on a specified distance cutoff, +/// and creates unambiguous interactors for each residue pair. +/// +/// # Arguments +/// +/// * input_file - A string slice that holds the path to the input PDB file. +/// * cutoff - A reference to a f64 value specifying the distance cutoff (in Angstroms) for determining interactions. +/// +/// # Returns +/// +/// A Result> containing the generated TBL (Topological Restraints List) if successful. +/// +/// # Functionality +/// +/// 1. Loads the PDB file using the structure::load_pdb function. +/// 2. Finds the closest residue pairs within the specified distance cutoff. +/// 3. Creates Interactor instances for each residue pair. +/// 4. Assigns chains, active/passive residues, and atoms to the interactors. +/// 5. Generates the Topological Restraints List (TBL) using the created interactors. +/// 6. Prints the generated TBL to stdout. +/// +/// # Panics +/// +/// This function will panic if: +/// - The PDB file cannot be opened or parsed. +fn unambig_ti(input_file: &str, cutoff: &f64) -> Result> { + let pdb = match structure::load_pdb(input_file) { + Ok(pdb) => pdb, + Err(e) => { + panic!("Error opening PDB file: {:?}", e); + } + }; + let pairs = structure::get_closest_residue_pairs(&pdb, *cutoff); + + let mut interactors: Vec = Vec::new(); + let mut counter = 0; + pairs.iter().for_each(|g| { + let mut interactor_i = Interactor::new(counter); + counter += 1; + let mut interactor_j = Interactor::new(counter); + interactor_j.add_target(counter - 1); + interactor_i.add_target(counter); + counter += 1; + + interactor_i.set_chain(g.chain_i.as_str()); + interactor_i.set_active(vec![g.res_i as i16]); + interactor_i.set_active_atoms(vec![g.atom_i.clone()]); + interactor_i.set_target_distance(g.distance); + + interactor_j.set_chain(g.chain_j.as_str()); + interactor_j.set_passive(vec![g.res_j as i16]); + interactor_j.set_passive_atoms(vec![g.atom_j.clone()]); + + interactors.push(interactor_i); + interactors.push(interactor_j); + }); + + // Make the restraints + let air = Air::new(interactors); + let tbl = air.gen_tbl().unwrap(); + + println!("{}", tbl); + + Ok(tbl) +} + /// Analyzes the true interface of a protein structure and generates Ambiguous Interaction Restraints (AIRs). /// /// This function reads a PDB file, identifies the true interface between chains based on a distance cutoff, @@ -645,4 +722,13 @@ assign ( resid 2 and segid A and name CA ) ( resid 8 and segid A and name CA ) 1 Err(_e) => (), } } + #[test] + fn test_unambigti() { + let expected_tbl = "assign ( resid 2 and segid A and name CA ) ( resid 10 and segid B and name CA ) 9.1 2.0 0.0\n\n"; + + match unambig_ti("tests/data/two_res.pdb", &5.0) { + Ok(tbl) => assert_eq!(tbl, expected_tbl), + Err(_e) => (), + } + } } diff --git a/src/structure.rs b/src/structure.rs index ce15aed..dde46c6 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -18,6 +18,17 @@ pub struct Bead { pub position: Vector3, } +#[derive(Debug, Clone)] +pub struct Pair { + pub chain_i: String, + pub res_i: isize, + pub atom_i: String, + pub chain_j: String, + pub res_j: isize, + pub atom_j: String, + pub distance: f64, +} + /// Performs a neighbor search for residues within a specified radius of target residues. /// /// This function uses a K-d tree to efficiently find residues that are within a given radius @@ -623,6 +634,88 @@ pub fn process_pdb(input_pdb: &str) -> BufReader>> { pdb_handler::pad_lines(temp_path) } +/// Finds the closest residue pairs between different protein chains within a specified distance cutoff. +/// +/// This function analyzes inter-chain interactions by identifying the closest atom pairs between residues +/// from different chains, using the alpha carbon (CA) atoms for distance calculation. +/// +/// # Arguments +/// +/// * pdb - A reference to a parsed PDB structure. +/// * cutoff - A floating-point value specifying the maximum distance (in Angstroms) for considering residue pairs. +/// +/// # Returns +/// +/// A Vec containing the closest residue pairs within the specified cutoff, sorted by distance. +/// +/// # Functionality +/// +/// 1. Iterates through all unique chain pairs in the PDB structure. +/// 2. For each chain pair, finds the closest atoms between residues. +/// 3. Selects pairs where the inter-residue distance is less than the specified cutoff. +/// 4. Uses alpha carbon (CA) atoms for distance calculation and pair representation. +/// 5. Sorts the resulting pairs by their inter-alpha carbon distance. +/// +/// # Notes +/// +/// - Only inter-chain interactions are considered. +/// - The distance is calculated based on the closest atom pairs between residues. +/// - The resulting pairs are sorted from shortest to longest distance. +pub fn get_closest_residue_pairs(pdb: &pdbtbx::PDB, cutoff: f64) -> Vec { + let mut closest_pairs = Vec::new(); + + let chains: Vec<_> = pdb.chains().collect(); + + for i in 0..chains.len() { + for j in (i + 1)..chains.len() { + let chain_i = &chains[i]; + let chain_j = &chains[j]; + + for res_i in chain_i.residues() { + let mut min_distance = f64::MAX; + let mut closest_pair = None; + + for res_j in chain_j.residues() { + let mut atom_dist = f64::MAX; + for atom_i in res_i.atoms() { + for atom_j in res_j.atoms() { + let distance = atom_i.distance(atom_j); + if distance < atom_dist { + atom_dist = distance; + } + } + } + if atom_dist < min_distance { + min_distance = atom_dist; + closest_pair = Some((res_j, res_i)); + } + } + + if min_distance < cutoff { + if let Some((res_j, res_i)) = closest_pair { + let ca_i = res_i.atoms().find(|atom| atom.name() == "CA").unwrap(); + let ca_j = res_j.atoms().find(|atom| atom.name() == "CA").unwrap(); + let ca_ca_dist = ca_i.distance(ca_j); + closest_pairs.push(Pair { + chain_i: chain_i.id().to_string(), + res_i: res_i.serial_number(), + atom_i: ca_i.name().to_string(), + chain_j: chain_j.id().to_string(), + res_j: res_j.serial_number(), + atom_j: ca_j.name().to_string(), + distance: ca_ca_dist, + }); + } + } + } + } + } + + closest_pairs.sort_by(|a, b| a.distance.partial_cmp(&b.distance).unwrap()); + + closest_pairs +} + #[cfg(test)] mod tests { @@ -686,4 +779,27 @@ mod tests { .filter(|line| line.starts_with("ATOM")) .all(|line| line.len() == 80)); } + #[test] + fn test_get_closest_residue_pairs() { + let pdb = load_pdb("tests/data/two_res.pdb").unwrap(); + let observed_pairs = get_closest_residue_pairs(&pdb, 5.0); + let expected_pairs = vec![Pair { + chain_i: "A".to_string(), + chain_j: "B".to_string(), + atom_i: "CA".to_string(), + atom_j: "CA".to_string(), + res_i: 2, + res_j: 10, + distance: 9.1, + }]; + assert_eq!(observed_pairs.len(), expected_pairs.len()); + let pair = &observed_pairs[0]; + assert_eq!(pair.chain_i, expected_pairs[0].chain_i); + assert_eq!(pair.chain_j, expected_pairs[0].chain_j); + assert_eq!(pair.atom_i, expected_pairs[0].atom_i); + assert_eq!(pair.atom_j, expected_pairs[0].atom_j); + assert_eq!(pair.res_i, expected_pairs[0].res_i); + assert_eq!(pair.res_j, expected_pairs[0].res_j); + assert!((pair.distance - 9.1).abs() < 0.1); + } } diff --git a/tests/data/two_res.pdb b/tests/data/two_res.pdb new file mode 100644 index 0000000..b884885 --- /dev/null +++ b/tests/data/two_res.pdb @@ -0,0 +1,18 @@ +ATOM 8 N THR A 2 15.115 11.555 5.265 1.00 7.81 N +ATOM 9 CA THR A 2 13.856 11.469 6.066 1.00 8.31 C +ATOM 10 C THR A 2 14.164 10.785 7.379 1.00 5.80 C +ATOM 11 O THR A 2 14.993 9.862 7.443 1.00 6.94 O +ATOM 12 CB THR A 2 12.732 10.711 5.261 1.00 10.32 C +ATOM 13 CG2 THR A 2 12.484 11.442 3.895 1.00 11.90 C +ATOM 14 OG1 THR A 2 13.308 9.439 4.926 1.00 12.81 O +ATOM 47 N ARG B 10 7.647 4.909 10.005 1.00 3.73 N +ATOM 48 CA ARG B 10 8.496 4.609 8.837 1.00 3.38 C +ATOM 49 C ARG B 10 7.798 3.609 7.876 1.00 3.47 C +ATOM 50 O ARG B 10 7.878 3.778 6.651 1.00 4.67 O +ATOM 51 CB ARG B 10 9.847 4.020 9.305 1.00 3.95 C +ATOM 52 CG ARG B 10 10.752 3.607 8.149 1.00 4.55 C +ATOM 53 CD ARG B 10 11.226 4.699 7.244 1.00 5.89 C +ATOM 54 NE ARG B 10 12.143 5.571 8.035 1.00 6.20 N +ATOM 55 CZ ARG B 10 12.758 6.609 7.443 1.00 7.52 C +ATOM 56 NH1 ARG B 10 12.539 6.932 6.158 1.00 10.68 N1+ +ATOM 57 NH2 ARG B 10 13.601 7.322 8.202 1.00 9.48 N