From b58792fe0be916875e379023a18530dbb41f480c Mon Sep 17 00:00:00 2001 From: Rodrigo Vargas Honorato Date: Mon, 11 Nov 2024 16:35:09 +0100 Subject: [PATCH] Specify atom in second selection of `restraints` subcommand (#30) * order body_ids this is important to ensure reproducibility * specify atom for second selection in restraint_bodies * add test data --- src/main.rs | 20 +++++++++++++--- src/structure.rs | 3 ++- tests/data/gaps.pdb | 57 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 tests/data/gaps.pdb diff --git a/src/main.rs b/src/main.rs index 01c5b9a..5479208 100644 --- a/src/main.rs +++ b/src/main.rs @@ -315,7 +315,7 @@ fn true_interface(input_file: &str, cutoff: &f64) -> Result Result<(), Box> { +fn restraint_bodies(input_file: &str) -> Result> { // Read PDB file let pdb = match structure::load_pdb(input_file) { Ok(pdb) => pdb, @@ -343,13 +343,13 @@ fn restraint_bodies(input_file: &str) -> Result<(), Box> { interactor_i.set_chain(g.chain.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_passive_atoms(vec![g.atom_j.clone()]); interactor_i.set_target_distance(g.distance); interactor_i.set_lower_margin(0.0); interactor_i.set_upper_margin(0.0); interactor_j.set_chain(g.chain.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); @@ -360,7 +360,7 @@ fn restraint_bodies(input_file: &str) -> Result<(), Box> { println!("{}", tbl); - Ok(()) + Ok(tbl) } /// Lists the interface residues for each chain in a protein structure. @@ -631,4 +631,18 @@ assign ( resid 47 and segid B ) Err(_e) => (), }; } + + #[test] + fn test_restraint_bodies() { + let expected_tbl = r"assign ( resid 1 and segid A and name CA ) ( resid 4 and segid A and name CA ) 10.2 0.0 0.0 + +assign ( resid 2 and segid A and name CA ) ( resid 8 and segid A and name CA ) 14.2 0.0 0.0 + +"; + + match restraint_bodies("tests/data/gaps.pdb") { + Ok(tbl) => assert_eq!(tbl, expected_tbl), + Err(_e) => (), + } + } } diff --git a/src/structure.rs b/src/structure.rs index 1f3004f..ce15aed 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -408,7 +408,8 @@ pub fn create_iter_body_gaps( ) -> Vec { let mut rng = StdRng::seed_from_u64(42); let mut pairs: Vec = Vec::new(); - let body_ids: Vec = bodies.keys().cloned().collect(); + let mut body_ids: Vec = bodies.keys().cloned().collect(); + body_ids.sort(); for (i, &body_id1) in body_ids.iter().enumerate() { for &body_id2 in body_ids[i + 1..].iter() { if let (Some(atoms1), Some(atoms2)) = (bodies.get(&body_id1), bodies.get(&body_id2)) { diff --git a/tests/data/gaps.pdb b/tests/data/gaps.pdb new file mode 100644 index 0000000..5573a67 --- /dev/null +++ b/tests/data/gaps.pdb @@ -0,0 +1,57 @@ +ATOM 1 N THR A 1 17.047 14.099 3.625 1.00 13.79 N +ATOM 2 CA THR A 1 16.967 12.784 4.338 1.00 10.80 C +ATOM 3 C THR A 1 15.685 12.755 5.133 1.00 9.19 C +ATOM 4 O THR A 1 15.268 13.825 5.594 1.00 9.85 O +ATOM 5 CB THR A 1 18.170 12.703 5.337 1.00 13.02 C +ATOM 6 CG2 THR A 1 18.150 11.546 6.304 1.00 14.23 C +ATOM 7 OG1 THR A 1 19.334 12.829 4.463 1.00 15.06 O +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 15 N CYS A 3 13.488 11.241 8.417 1.00 5.24 N +ATOM 16 CA CYS A 3 13.660 10.707 9.787 1.00 5.39 C +ATOM 17 C CYS A 3 12.269 10.431 10.323 1.00 4.45 C +ATOM 18 O CYS A 3 11.393 11.308 10.185 1.00 6.54 O +ATOM 19 CB CYS A 3 14.368 11.748 10.691 1.00 5.99 C +ATOM 20 SG CYS A 3 15.885 12.426 10.016 1.00 7.01 S +ATOM 21 N CYS A 4 12.019 9.272 10.928 1.00 3.90 N +ATOM 22 CA CYS A 4 10.646 8.991 11.408 1.00 4.24 C +ATOM 23 C CYS A 4 10.654 8.793 12.919 1.00 3.72 C +ATOM 24 O CYS A 4 11.659 8.296 13.491 1.00 5.30 O +ATOM 25 CB CYS A 4 10.057 7.752 10.682 1.00 4.41 C +ATOM 26 SG CYS A 4 9.837 8.018 8.904 1.00 4.72 S +ATOM 27 N ILE A 7 8.881 3.075 14.358 1.00 4.94 N +ATOM 28 CA ILE A 7 8.912 2.083 13.258 1.00 6.33 C +ATOM 29 C ILE A 7 7.581 2.090 12.506 1.00 5.32 C +ATOM 30 O ILE A 7 7.670 2.031 11.245 1.00 6.85 O +ATOM 31 CB ILE A 7 9.207 0.677 13.924 1.00 8.43 C +ATOM 32 CG1 ILE A 7 10.714 0.702 14.312 1.00 9.78 C +ATOM 33 CG2 ILE A 7 8.811 -0.477 12.969 1.00 11.70 C +ATOM 34 CD1 ILE A 7 11.185 -0.516 15.142 1.00 9.92 C +ATOM 35 N VAL A 8 6.458 2.162 13.159 1.00 5.02 N +ATOM 36 CA VAL A 8 5.145 2.209 12.453 1.00 6.93 C +ATOM 37 C VAL A 8 5.115 3.379 11.461 1.00 5.39 C +ATOM 38 O VAL A 8 4.664 3.268 10.343 1.00 6.30 O +ATOM 39 CB VAL A 8 3.995 2.354 13.478 1.00 9.64 C +ATOM 40 CG1 VAL A 8 2.716 2.891 12.869 1.00 13.85 C +ATOM 41 CG2 VAL A 8 3.758 1.032 14.208 1.00 11.97 C +ATOM 42 N ALA A 9 5.606 4.546 11.941 1.00 3.73 N +ATOM 43 CA ALA A 9 5.598 5.767 11.082 1.00 3.56 C +ATOM 44 C ALA A 9 6.441 5.527 9.850 1.00 4.13 C +ATOM 45 O ALA A 9 6.052 5.933 8.744 1.00 4.36 O +ATOM 46 CB ALA A 9 6.022 6.977 11.891 1.00 4.80 C +ATOM 47 N ARG A 10 7.647 4.909 10.005 1.00 3.73 N +ATOM 48 CA ARG A 10 8.496 4.609 8.837 1.00 3.38 C +ATOM 49 C ARG A 10 7.798 3.609 7.876 1.00 3.47 C +ATOM 50 O ARG A 10 7.878 3.778 6.651 1.00 4.67 O +ATOM 51 CB ARG A 10 9.847 4.020 9.305 1.00 3.95 C +ATOM 52 CG ARG A 10 10.752 3.607 8.149 1.00 4.55 C +ATOM 53 CD ARG A 10 11.226 4.699 7.244 1.00 5.89 C +ATOM 54 NE ARG A 10 12.143 5.571 8.035 1.00 6.20 N +ATOM 55 CZ ARG A 10 12.758 6.609 7.443 1.00 7.52 C +ATOM 56 NH1 ARG A 10 12.539 6.932 6.158 1.00 10.68 N1+ +ATOM 57 NH2 ARG A 10 13.601 7.322 8.202 1.00 9.48 N