Exemple #1
0
    def __init__(self, config):
        self.config = config

        self.in_frame = Frame(
            topology_file=self.config.topology,
            trajectory_file=self.config.trajectory,  # May be None
            frame_start=self.config.begin,
            frame_end=self.config.end,
        )

        self.mapping = None
        self.out_frame = self.in_frame
        if self.config.mapping:
            self.mapping, self.out_frame = self.apply_mapping(self.in_frame)

        if self.out_frame.natoms == 0:
            # The following steps won't work with frames containing no atoms
            logger.warning(
                "Mapped trajectory contains no atoms - check your mapping file is correct!"
            )
            return

        self.bondset = None
        if self.config.bondset:
            self.bondset = BondSet(self.config.bondset, self.config)
            self.measure_bonds()

        if self.config.output_xtc:
            self.out_frame.save(self.get_output_filepath("xtc"))
Exemple #2
0
    def test_bondset_boltzmann_invert(self):
        measure = BondSet("test/data/sugar.bnd", DummyOptions)
        frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc")
        mapping = Mapping("test/data/sugar.map", DummyOptions)

        cgframe = mapping.apply(frame)
        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()
        self.support_check_mean_fc(measure["ALLA"], 1)
Exemple #3
0
 def test_bondset_polymer(self):
     bondset = BondSet("test/data/polyethene.bnd", DummyOptions)
     frame = Frame("test/data/polyethene.gro")
     bondset.apply(frame)
     self.assertEqual(5, len(bondset["ETH"][0].values))
     self.assertEqual(4, len(bondset["ETH"][1].values))
     self.assertEqual(4, len(bondset["ETH"][2].values))
     self.assertEqual(4, len(bondset["ETH"][3].values))
     bondset.boltzmann_invert()
     self.assertAlmostEqual(0.107, bondset["ETH"][0].eqm,
                            delta=0.107 / 500)
     self.assertAlmostEqual(0.107, bondset["ETH"][1].eqm,
                            delta=0.107 / 500)
Exemple #4
0
    def test_full_itp_vsites(self):
        """Test full operation to output of .itp file for molecule with vsites."""
        options = DummyOptions()
        options.generate_angles = False

        measure = BondSet(self.data_dir.joinpath("martini3/naphthalene.bnd"),
                          options)
        frame = Frame(self.data_dir.joinpath("martini3/naphthalene.gro"))
        mapping = Mapping(self.data_dir.joinpath("martini3/naphthalene.map"),
                          options)

        cg_frame = mapping.apply(frame)

        measure.apply(cg_frame)
        measure.boltzmann_invert()

        with tempfile.TemporaryDirectory() as tmpdir:
            tmp_path = pathlib.Path(tmpdir)
            measure.write_itp(tmp_path.joinpath("naphthalene_out.itp"),
                              mapping)

            self.assertTrue(
                cmp_file_whitespace_float(
                    tmp_path.joinpath("naphthalene_out.itp"),
                    self.data_dir.joinpath("martini3/naphthalene_out.itp"),
                    rtol=0.005,
                    verbose=True,
                ))
Exemple #5
0
    def test_bondset_boltzmann_invert_mdtraj(self):
        logging.disable(logging.WARNING)
        frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc",
                      xtc_reader="mdtraj")
        logging.disable(logging.NOTSET)

        measure = BondSet("test/data/sugar.bnd", DummyOptions)
        mapping = Mapping("test/data/sugar.map", DummyOptions)

        cgframe = mapping.apply(frame)
        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()
        self.support_check_mean_fc(measure["ALLA"], 1)
Exemple #6
0
 def test_bondset_apply(self):
     measure = BondSet("test/data/sugar.bnd", DummyOptions)
     frame = Frame("test/data/sugar-cg.gro")
     measure.apply(frame)
     # First six are bond lengths
     self.assertEqual(1, len(measure["ALLA"][0].values))
     self.assertAlmostEqual(0.2225376, measure["ALLA"][0].values[0],
                            delta=0.2225376 / 500)
     # Second six are angles
     self.assertEqual(1, len(measure["ALLA"][6].values))
     self.assertAlmostEqual(77.22779289, measure["ALLA"][6].values[0],
                            delta=77.22779289 / 500)
     # Final six are dihedrals
     self.assertEqual(1, len(measure["ALLA"][12].values))
     self.assertAlmostEqual(-89.5552903, measure["ALLA"][12].values[0],
                            delta=89.552903 / 500)
Exemple #7
0
    def test_bondset_boltzmann_invert_func_forms(self):
        class FuncFormOptions(DummyOptions):
            length_form = "CosHarmonic"
            angle_form = "Harmonic"
            dihedral_form = "MartiniDefaultLength"

        measure = BondSet("test/data/sugar.bnd", FuncFormOptions)
        frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc")
        mapping = Mapping("test/data/sugar.map", DummyOptions)

        cgframe = mapping.apply(frame)
        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()
        self.support_check_mean_fc(measure["ALLA"], 3)
Exemple #8
0
 def test_bondset_pbc(self):
     bondset = BondSet("test/data/polyethene.bnd", DummyOptions)
     frame = Frame("test/data/pbcpolyethene.gro")
     bondset.apply(frame)
     bondset.boltzmann_invert()
     for bond in bondset.get_bond_lengths("ETH", True):
         self.assertAlmostEqual(1., bond.eqm)
         self.assertEqual(float("inf"), bond.fconst)
Exemple #9
0
 def test_bondset_apply(self):
     measure = BondSet("test/data/sugar.bnd", DummyOptions)
     frame = Frame("test/data/sugar-cg.gro")
     measure.apply(frame)
     # First six are bond lengths
     self.assertEqual(1, len(measure["ALLA"][0].values))
     self.assertAlmostEqual(0.2225376,
                            measure["ALLA"][0].values[0],
                            delta=0.2225376 / 500)
     # Second six are angles
     self.assertEqual(1, len(measure["ALLA"][6].values))
     expected = math.radians(77.22779289)
     self.assertAlmostEqual(expected,
                            measure["ALLA"][6].values[0],
                            delta=expected / 500)
     # Final six are dihedrals
     self.assertEqual(1, len(measure["ALLA"][12].values))
     expected = math.radians(-89.5552903)
     self.assertAlmostEqual(expected,
                            measure["ALLA"][12].values[0],
                            delta=abs(expected) / 500)
Exemple #10
0
    def test_bondset_pbc(self):
        bondset = BondSet(self.data_dir.joinpath("polyethene.bnd"),
                          DummyOptions)
        frame = Frame(self.data_dir.joinpath("pbcpolyethene.gro"))

        bondset.apply(frame)
        bondset.boltzmann_invert()

        for bond in bondset.get_bond_lengths("ETH", True):
            self.assertAlmostEqual(1.0, bond.eqm)
            self.assertEqual(math.inf, bond.fconst)
Exemple #11
0
 def test_bondset_pbc(self):
     bondset = BondSet("test/data/polyethene.bnd", DummyOptions)
     frame = Frame("test/data/pbcpolyethene.gro")
     bondset.apply(frame)
     bondset.boltzmann_invert()
     for bond in bondset.get_bond_lengths("ETH", True):
         self.assertAlmostEqual(1., bond.eqm)
         self.assertEqual(float("inf"), bond.fconst)
Exemple #12
0
 def test_bondset_polymer(self):
     bondset = BondSet("test/data/polyethene.bnd", DummyOptions)
     frame = Frame("test/data/polyethene.gro")
     bondset.apply(frame)
     self.assertEqual(5, len(bondset["ETH"][0].values))
     self.assertEqual(4, len(bondset["ETH"][1].values))
     self.assertEqual(4, len(bondset["ETH"][2].values))
     self.assertEqual(4, len(bondset["ETH"][3].values))
     bondset.boltzmann_invert()
     self.assertAlmostEqual(0.107, bondset["ETH"][0].eqm, delta=0.107 / 500)
     self.assertAlmostEqual(0.107, bondset["ETH"][1].eqm, delta=0.107 / 500)
Exemple #13
0
    def test_get_lines_for_bond_dump(self):
        expected = [
            "     0.00000     1.00000     2.00000",
            "     1.00000     2.00000     3.00000",
            "     2.00000     3.00000     4.00000",
            "     3.00000     4.00000     5.00000",
        ]

        bonds = [
            DummyBond(None, None, None, values=[0, 1, 2, 3]),
            DummyBond(None, None, None, values=[1, 2, 3, 4]),
            DummyBond(None, None, None, values=[2, 3, 4, 5]),
        ]

        output = BondSet._get_lines_for_bond_dump(bonds)

        self.assertListEqual(expected, output)
Exemple #14
0
    def test_bondset_boltzmann_invert(self):
        measure = BondSet(self.data_dir.joinpath("sugar.bnd"), DummyOptions)
        frame = Frame(self.data_dir.joinpath("sugar.gro"),
                      self.data_dir.joinpath("sugar.xtc"))
        mapping = Mapping(self.data_dir.joinpath("sugar.map"), DummyOptions)

        cg_frame = mapping.apply(frame)

        measure.apply(cg_frame)
        measure.boltzmann_invert()

        self.support_check_mean_fc(measure["ALLA"], 1)
Exemple #15
0
    def test_bondset_boltzmann_invert(self):
        measure = BondSet("test/data/sugar.bnd", DummyOptions)
        frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc")
        mapping = Mapping("test/data/sugar.map", DummyOptions)

        cgframe = mapping.apply(frame)
        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()
        self.support_check_mean_fc(measure["ALLA"], 1)
Exemple #16
0
    def test_full_itp_sugar(self):
        measure = BondSet("test/data/sugar.bnd", DummyOptions)
        frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc")
        mapping = Mapping("test/data/sugar.map", DummyOptions)
        cgframe = mapping.apply(frame)

        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()

        logging.disable(logging.WARNING)
        measure.write_itp("sugar_out.itp", mapping)
        logging.disable(logging.NOTSET)

        self.assertTrue(
            cmp_whitespace_float("sugar_out.itp",
                                 "test/data/sugar_out.itp",
                                 float_rel_error=0.001))
Exemple #17
0
    def test_dump_bonds(self):
        measure = BondSet(self.data_dir.joinpath("sugar.bnd"), DummyOptions)
        frame = Frame(self.data_dir.joinpath("sugar.gro"),
                      self.data_dir.joinpath("sugar.xtc"))
        mapping = Mapping(self.data_dir.joinpath("sugar.map"), DummyOptions)

        cg_frame = mapping.apply(frame)

        measure.apply(cg_frame)
        measure.boltzmann_invert()
        measure.dump_values()

        filenames = ("ALLA_length.dat", "ALLA_angle.dat", "ALLA_dihedral.dat")
        for filename in filenames:
            self.assertTrue(
                cmp_file_whitespace_float(self.data_dir.joinpath(filename),
                                          filename,
                                          rtol=0.008,
                                          verbose=True))
            os.remove(filename)
Exemple #18
0
    def test_full_itp_sugar(self):
        measure = BondSet("test/data/sugar.bnd", DummyOptions)
        frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc")
        mapping = Mapping("test/data/sugar.map", DummyOptions)
        cgframe = mapping.apply(frame)

        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()

        logging.disable(logging.WARNING)
        measure.write_itp("sugar_out.itp", mapping)
        logging.disable(logging.NOTSET)

        self.assertTrue(cmp_whitespace_float("sugar_out.itp", "test/data/sugar_out.itp", float_rel_error=0.001))
Exemple #19
0
    def test_full_itp_sugar(self):
        measure = BondSet(self.data_dir.joinpath("sugar.bnd"), DummyOptions)
        frame = Frame(self.data_dir.joinpath("sugar.gro"),
                      self.data_dir.joinpath("sugar.xtc"))
        mapping = Mapping(self.data_dir.joinpath("sugar.map"), DummyOptions)

        cg_frame = mapping.apply(frame)

        measure.apply(cg_frame)
        measure.boltzmann_invert()

        with tempfile.TemporaryDirectory() as tmpdir:
            tmp_path = pathlib.Path(tmpdir)

            measure.write_itp(tmp_path.joinpath("sugar_out.itp"), mapping)

            self.assertTrue(
                cmp_file_whitespace_float(
                    tmp_path.joinpath("sugar_out.itp"),
                    self.data_dir.joinpath("sugar_out.itp"),
                    rtol=0.005,
                    verbose=True,
                ))
Exemple #20
0
    def test_bondset_boltzmann_invert_manual_default_fc(self):
        class FuncFormOptions(DummyOptions):
            length_form = "MartiniDefaultLength"
            angle_form = "MartiniDefaultAngle"
            dihedral_form = "MartiniDefaultDihedral"

        measure = BondSet(self.data_dir.joinpath("sugar.bnd"), FuncFormOptions)
        frame = Frame(self.data_dir.joinpath("sugar.gro"),
                      self.data_dir.joinpath("sugar.xtc"))
        mapping = Mapping(self.data_dir.joinpath("sugar.map"), DummyOptions)

        cg_frame = mapping.apply(frame)

        measure.apply(cg_frame)
        measure.boltzmann_invert()

        self.support_check_mean_fc(measure["ALLA"], 2)
Exemple #21
0
    def test_bondset_boltzmann_invert_mdtraj(self):
        logging.disable(logging.WARNING)
        frame = Frame("test/data/sugar.gro",
                      xtc="test/data/sugar.xtc",
                      xtc_reader="mdtraj")
        logging.disable(logging.NOTSET)

        measure = BondSet("test/data/sugar.bnd", DummyOptions)
        mapping = Mapping("test/data/sugar.map", DummyOptions)

        cgframe = mapping.apply(frame)
        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()
        self.support_check_mean_fc(measure["ALLA"], 1)
Exemple #22
0
    def test_bondset_boltzmann_invert_manual_default_fc(self):
        class FuncFormOptions(DummyOptions):
            length_form = "MartiniDefaultLength"
            angle_form = "MartiniDefaultAngle"
            dihedral_form = "MartiniDefaultDihedral"

        measure = BondSet("test/data/sugar.bnd", FuncFormOptions)
        frame = Frame("test/data/sugar.gro", xtc="test/data/sugar.xtc")
        mapping = Mapping("test/data/sugar.map", DummyOptions)

        cgframe = mapping.apply(frame)
        while frame.next_frame():
            cgframe = mapping.apply(frame, cgframe=cgframe)
            measure.apply(cgframe)

        measure.boltzmann_invert()
        self.support_check_mean_fc(measure["ALLA"], 2)
Exemple #23
0
    def test_get_lines_for_bond_dump_sample(self):
        expected = [
            "     0.00000     1.00000     2.00000",
            "     1.00000     2.00000     3.00000",
            "     2.00000     3.00000     4.00000",
            "     3.00000     4.00000     5.00000",
        ]

        bonds = [
            DummyBond(None, None, None, values=[0, 1, 2, 3]),
            DummyBond(None, None, None, values=[1, 2, 3, 4]),
            DummyBond(None, None, None, values=[2, 3, 4, 5]),
        ]

        nlines = 2
        output = BondSet._get_lines_for_bond_dump(bonds, target_number=nlines)

        self.assertEqual(nlines, len(output))

        seen = set()
        for line in output:
            self.assertIn(line, expected)
            self.assertNotIn(line, seen)
            seen.add(line)
Exemple #24
0
 def test_duplicate_atoms_in_bond(self):
     with self.assertRaises(ValueError):
         bondset = BondSet("test/data/duplicate_atoms.bnd", DummyOptions)
Exemple #25
0
 def test_bondset_create(self):
     measure = BondSet("test/data/sugar.bnd", DummyOptions)
     self.assertEqual(1, len(measure))
     self.assertTrue("ALLA" in measure)
     self.assertEqual(18, len(measure["ALLA"]))
Exemple #26
0
 def test_duplicate_atoms_in_bond(self):
     with self.assertRaises(ValueError):
         _ = BondSet(self.data_dir.joinpath("duplicate_atoms.bnd"),
                     DummyOptions)
Exemple #27
0
 def test_bondset_create(self):
     measure = BondSet(self.data_dir.joinpath("sugar.bnd"), DummyOptions)
     self.assertEqual(1, len(measure))
     self.assertTrue("ALLA" in measure)
     self.assertEqual(18, len(measure["ALLA"]))
Exemple #28
0
class PyCGTOOL:
    def __init__(self, config):
        self.config = config

        self.in_frame = Frame(
            topology_file=self.config.topology,
            trajectory_file=self.config.trajectory,  # May be None
            frame_start=self.config.begin,
            frame_end=self.config.end,
        )

        self.mapping = None
        self.out_frame = self.in_frame
        if self.config.mapping:
            self.mapping, self.out_frame = self.apply_mapping(self.in_frame)

        if self.out_frame.natoms == 0:
            # The following steps won't work with frames containing no atoms
            logger.warning(
                "Mapped trajectory contains no atoms - check your mapping file is correct!"
            )
            return

        self.bondset = None
        if self.config.bondset:
            self.bondset = BondSet(self.config.bondset, self.config)
            self.measure_bonds()

        if self.config.output_xtc:
            self.out_frame.save(self.get_output_filepath("xtc"))

    def get_output_filepath(self, ext: PathLike) -> pathlib.Path:
        """Get file path for an output file by extension.

        Creates the output directory if missing.
        """
        out_dir = pathlib.Path(self.config.out_dir)
        out_dir.mkdir(parents=True, exist_ok=True)
        return out_dir.joinpath(self.config.output_name + "." + ext)

    def apply_mapping(self, in_frame: Frame) -> typing.Tuple[Mapping, Frame]:
        """Map input frame to output using requested mapping file."""
        mapping = Mapping(self.config.mapping,
                          self.config,
                          itp_filename=self.config.itp)
        out_frame = mapping.apply(in_frame)
        out_frame.save(self.get_output_filepath("gro"), frame_number=0)

        if self.config.backmapper_resname and self.out_frame.n_frames > 1:
            try:
                self.train_backmapper(self.config.resname)

            except ImportError:
                logger.error("MDPlus must be installed to perform backmapping")

        return mapping, out_frame

    def measure_bonds(self) -> None:
        """Measure bonds at the end of a run."""
        self.bondset.apply(self.out_frame)

        if self.mapping is not None and self.out_frame.n_frames > 1:
            # Only perform Boltzmann Inversion if we have a mapping and a trajectory.
            # Otherwise we get infinite force constants.
            logger.info("Starting Boltzmann Inversion")
            self.bondset.boltzmann_invert()
            logger.info("Finished Boltzmann Inversion")

            if self.config.output_forcefield:
                logger.info("Writing GROMACS forcefield directory")
                out_dir = pathlib.Path(self.config.out_dir)
                forcefield = ForceField(self.config.output_name,
                                        dir_path=out_dir)
                forcefield.write(self.config.output_name, self.mapping,
                                 self.bondset)
                logger.info("Finished writing GROMACS forcefield directory")

            else:
                self.bondset.write_itp(self.get_output_filepath("itp"),
                                       mapping=self.mapping)

        if self.config.dump_measurements:
            logger.info("Writing bond measurements to file")
            self.bondset.dump_values(self.config.dump_n_values,
                                     self.config.out_dir)
            logger.info("Finished writing bond measurements to file")

    def train_backmapper(self, resname: str):
        from mdplus.multiscale import GLIMPS

        sel = f"resname {resname}"

        aa_subset_traj = self.in_frame._trajectory.atom_slice(
            self.in_frame._trajectory.topology.select(sel))
        cg_subset_traj = self.out_frame._trajectory.atom_slice(
            self.out_frame._trajectory.topology.select(sel))

        logger.info("Training backmapper")
        # Param x_valence is approximate number of bonds per CG bead
        # Values greater than 2 fail for small molecules e.g. sugar test case
        backmapper = GLIMPS(x_valence=2)
        backmapper.fit(cg_subset_traj.xyz, aa_subset_traj.xyz)
        logger.info("Finished training backmapper")

        backmapper.save(self.get_output_filepath("backmapper.pkl"))
Exemple #29
0
 def test_bondset_remove_triangles(self):
     bondset = BondSet(self.data_dir.joinpath("triangle.bnd"), DummyOptions)
     angles = bondset.get_bond_angles("TRI", exclude_triangle=False)
     self.assertEqual(3, len(angles))
     angles = bondset.get_bond_angles("TRI", exclude_triangle=True)
     self.assertEqual(0, len(angles))
Exemple #30
0
 def test_bondset_remove_triangles(self):
     bondset = BondSet("test/data/triangle.bnd", DummyOptions)
     angles = bondset.get_bond_angles("TRI", exclude_triangle=False)
     self.assertEqual(3, len(angles))
     angles = bondset.get_bond_angles("TRI", exclude_triangle=True)
     self.assertEqual(0, len(angles))