|
26 | 26 | #include <rdkit/GraphMol/FileParsers/FileParsers.h> |
27 | 27 | #include <rdkit/GraphMol/FileParsers/MolSupplier.h> |
28 | 28 | #include <rdkit/GraphMol/MolTransforms/MolTransforms.h> |
| 29 | +#include <rdkit/GraphMol/MonomerInfo.h> |
29 | 30 | #include <rdkit/GraphMol/QueryAtom.h> |
30 | 31 | #include <rdkit/GraphMol/QueryBond.h> |
31 | 32 | #include <rdkit/GraphMol/ROMol.h> |
@@ -4800,6 +4801,130 @@ BOOST_AUTO_TEST_CASE(test_addBoundMonomer_RNA) |
4800 | 4801 | BOOST_TEST(helm == "RNA1{R(C)P.R(A)P.R(G)P}$$$$V2.0"); |
4801 | 4802 | } |
4802 | 4803 |
|
| 4804 | +/** |
| 4805 | + * Test get_residue_number_for_new_monomer() for a peptide |
| 4806 | + */ |
| 4807 | +BOOST_AUTO_TEST_CASE(test_get_residue_number_for_new_monomer_peptide) |
| 4808 | +{ |
| 4809 | + QUndoStack undo_stack; |
| 4810 | + TestMolModel model(&undo_stack); |
| 4811 | + |
| 4812 | + // create an amino acid with a residue number of 10 |
| 4813 | + auto mol = rdkit_extensions::to_rdkit("PEPTIDE1{A}$$$$V2.0", Format::HELM); |
| 4814 | + auto* res_info = static_cast<RDKit::AtomPDBResidueInfo*>( |
| 4815 | + mol->getAtomWithIdx(0)->getMonomerInfo()); |
| 4816 | + res_info->setResidueNumber(10); |
| 4817 | + model.addMol(*mol); |
| 4818 | + auto peptide = model.getMol()->getAtomWithIdx(0); |
| 4819 | + BOOST_REQUIRE(rdkit_extensions::get_residue_number(peptide) == 10u); |
| 4820 | + |
| 4821 | + // check residue numbers for the previous and next peptide |
| 4822 | + auto prev_peptide_num = get_residue_number_for_new_monomer( |
| 4823 | + "C", ChainType::PEPTIDE, ap_model_name_for(PeptideAP::C), peptide); |
| 4824 | + auto next_peptide_num = get_residue_number_for_new_monomer( |
| 4825 | + "C", ChainType::PEPTIDE, ap_model_name_for(PeptideAP::N), peptide); |
| 4826 | + BOOST_TEST(prev_peptide_num == 9u); |
| 4827 | + BOOST_TEST(next_peptide_num == 11u); |
| 4828 | + |
| 4829 | + // add a new amino acid so we can check what happens when the ideal residue |
| 4830 | + // numbers is already assigned to an existing monomer |
| 4831 | + model.addBoundMonomer("C", ChainType::PEPTIDE, {1.0, 0.0, 0.0}, |
| 4832 | + ap_model_name_for(PeptideAP::N), peptide, |
| 4833 | + ap_model_name_for(PeptideAP::C)); |
| 4834 | + peptide = model.getMol()->getAtomWithIdx(0); |
| 4835 | + next_peptide_num = get_residue_number_for_new_monomer( |
| 4836 | + "C", ChainType::PEPTIDE, ap_model_name_for(PeptideAP::N), peptide); |
| 4837 | + BOOST_TEST(next_peptide_num == 12u); |
| 4838 | +} |
| 4839 | + |
| 4840 | +/** |
| 4841 | + * Test get_residue_number_for_new_monomer() for a nucleic acid sugar |
| 4842 | + */ |
| 4843 | +BOOST_AUTO_TEST_CASE(test_get_residue_number_for_new_monomer_na_sugar) |
| 4844 | +{ |
| 4845 | + QUndoStack undo_stack; |
| 4846 | + TestMolModel model(&undo_stack); |
| 4847 | + |
| 4848 | + // create a sugar with a residue number of 10 |
| 4849 | + auto mol = rdkit_extensions::to_rdkit("RNA1{R}$$$$V2.0", Format::HELM); |
| 4850 | + auto* res_info = static_cast<RDKit::AtomPDBResidueInfo*>( |
| 4851 | + mol->getAtomWithIdx(0)->getMonomerInfo()); |
| 4852 | + res_info->setResidueNumber(10); |
| 4853 | + model.addMol(*mol); |
| 4854 | + auto sugar = model.getMol()->getAtomWithIdx(0); |
| 4855 | + BOOST_REQUIRE(rdkit_extensions::get_residue_number(sugar) == 10u); |
| 4856 | + |
| 4857 | + // check residue numbers for a base and phosphates bound to the sugar |
| 4858 | + auto base_num = get_residue_number_for_new_monomer( |
| 4859 | + "A", ChainType::RNA, ap_model_name_for(NA_BASE_AP_N1_9), sugar); |
| 4860 | + auto next_phos_num = get_residue_number_for_new_monomer( |
| 4861 | + "P", ChainType::RNA, ap_model_name_for(NAPhosphateAP::TO_PREV_SUGAR), |
| 4862 | + sugar); |
| 4863 | + auto prev_phos_num = get_residue_number_for_new_monomer( |
| 4864 | + "P", ChainType::RNA, ap_model_name_for(NAPhosphateAP::TO_NEXT_SUGAR), |
| 4865 | + sugar); |
| 4866 | + BOOST_TEST(base_num == 11u); |
| 4867 | + BOOST_TEST(next_phos_num == 12u); |
| 4868 | + BOOST_TEST(prev_phos_num == 9u); |
| 4869 | +} |
| 4870 | + |
| 4871 | +/** |
| 4872 | + * Test get_residue_number_for_new_monomer() for a nucleic acid phosphate |
| 4873 | + */ |
| 4874 | +BOOST_AUTO_TEST_CASE(test_get_residue_number_for_new_monomer_na_phosphate) |
| 4875 | +{ |
| 4876 | + QUndoStack undo_stack; |
| 4877 | + TestMolModel model(&undo_stack); |
| 4878 | + |
| 4879 | + // create a phosphate with a residue number of 10 |
| 4880 | + auto mol = rdkit_extensions::to_rdkit("RNA1{P}$$$$V2.0", Format::HELM); |
| 4881 | + auto* res_info = static_cast<RDKit::AtomPDBResidueInfo*>( |
| 4882 | + mol->getAtomWithIdx(0)->getMonomerInfo()); |
| 4883 | + res_info->setResidueNumber(10); |
| 4884 | + model.addMol(*mol); |
| 4885 | + auto phosphate = model.getMol()->getAtomWithIdx(0); |
| 4886 | + BOOST_REQUIRE(rdkit_extensions::get_residue_number(phosphate) == 10u); |
| 4887 | + |
| 4888 | + // check residue numbers for sugars bound to the phosphate |
| 4889 | + auto prev_sugar_num = get_residue_number_for_new_monomer( |
| 4890 | + "R", ChainType::RNA, ap_model_name_for(NASugarAP::THREE_PRIME), |
| 4891 | + phosphate); |
| 4892 | + auto next_sugar_num = get_residue_number_for_new_monomer( |
| 4893 | + "R", ChainType::RNA, ap_model_name_for(NASugarAP::FIVE_PRIME), |
| 4894 | + phosphate); |
| 4895 | + // the base is expected to be numbered in between the previous sugar and |
| 4896 | + // this phosphate, so we skip 9 and instead assign 8 to the previous sugar |
| 4897 | + BOOST_TEST(prev_sugar_num == 8u); |
| 4898 | + // the next base should get 12 (i.e. be numbered after the next sugar), so |
| 4899 | + // we don't need to skip a number between this phosphate and the next sugar |
| 4900 | + BOOST_TEST(next_sugar_num == 11u); |
| 4901 | +} |
| 4902 | + |
| 4903 | +/** |
| 4904 | + * Test get_residue_number_for_new_monomer() for a nucleic acid base |
| 4905 | + */ |
| 4906 | +BOOST_AUTO_TEST_CASE(test_get_residue_number_for_new_monomer_na_base) |
| 4907 | +{ |
| 4908 | + QUndoStack undo_stack; |
| 4909 | + TestMolModel model(&undo_stack); |
| 4910 | + |
| 4911 | + // create a base with a residue number of 10 |
| 4912 | + auto mol = rdkit_extensions::to_rdkit("RNA1{A}$$$$V2.0", Format::HELM); |
| 4913 | + auto* res_info = static_cast<RDKit::AtomPDBResidueInfo*>( |
| 4914 | + mol->getAtomWithIdx(0)->getMonomerInfo()); |
| 4915 | + res_info->setResidueNumber(10); |
| 4916 | + model.addMol(*mol); |
| 4917 | + auto base = model.getMol()->getAtomWithIdx(0); |
| 4918 | + BOOST_REQUIRE(rdkit_extensions::get_residue_number(base) == 10u); |
| 4919 | + |
| 4920 | + // check residue number for a sugar bound to the base |
| 4921 | + auto sugar_num = get_residue_number_for_new_monomer( |
| 4922 | + "R", ChainType::RNA, ap_model_name_for(NASugarAP::ONE_PRIME), base); |
| 4923 | + // the base should be numbered after the sugar, so the sugar should get 9 |
| 4924 | + // (instead of 11) |
| 4925 | + BOOST_TEST(sugar_num == 9); |
| 4926 | +} |
| 4927 | + |
4803 | 4928 | /** |
4804 | 4929 | * Confirm that combining two peptide chains via a standard backbone connection |
4805 | 4930 | * produces HELM output with only a single chain |
|
0 commit comments