Ejemplo n.º 1
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,
                ))
Ejemplo n.º 2
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))
Ejemplo n.º 3
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))
Ejemplo n.º 4
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,
                ))
Ejemplo n.º 5
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"))