Exemple #1
0
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        # Any BaseException is logged; KeyboardInterrupt and SystemExit must still be raised (see below)
        except BaseException as exc:

            home = getattr(args[0].molecule, "home", None)
            state = getattr(args[0].molecule, "state", None)

            if home is None or state is None:
                raise

            mol = unpickle()[state]
            if getattr(args[0].molecule, "verbose"):
                pretty_print(mol, to_file=True, finished=False)

            log_file = os.path.join(home, "QUBEKit_log.txt")
            logger = logger_format(log_file)

            logger.exception(f"\nAn exception occurred with: {func.__qualname__}\n")
            print(
                f"{COLOURS.red}\n\nAn exception occurred with: {func.__qualname__}{COLOURS.end}\n"
                f"Exception: {exc}\nView the log file for details."
            )

            if isinstance(exc, SystemExit) or isinstance(exc, KeyboardInterrupt):
                raise

            # Re-raises the exception if it's not a bulk run.
            # Even if the exception is not raised, it is still logged.
            if len(args) >= 1 and hasattr(args[0], "molecule"):
                if getattr(args[0].molecule, "bulk_run", None) in [False, None]:
                    raise
Exemple #2
0
    def __call__(self, *args, **kwargs):

        try:
            return self.func(*args, **kwargs)
        # Any BaseException is logged; KeyboardInterrupt and SystemExit must still be raised (see below)
        except Exception as exc:

            home = getattr(args[0].molecule, 'home', None)
            state = getattr(args[0].molecule, 'state', None)

            if home is None or state is None:
                raise

            mol = unpickle()[state]
            pretty_print(mol, to_file=True, finished=False)

            self.log_file = os.path.join(home, 'QUBEKit_log.txt')
            logger = self.logger_format()

            logger.exception(
                f'\nAn exception occurred with: {self.func.__qualname__}\n')
            print(f'\n\nAn exception occurred with: {self.func.__qualname__}\n'
                  f'Exception: {exc}\nView the log file for details.'.upper())

            # Re-raises the exception if it's not a bulk run.
            # Even if the exception is not raised, it is still logged.
            if len(args) >= 1 and hasattr(args[0], 'molecule'):
                if not hasattr(args[0].molecule, 'bulk_run'):
                    raise
                if args[0].molecule.bulk_run is None:
                    raise
Exemple #3
0
def display_molecule_objects(*names):
    """
    prints the requested molecule objects in a nicely formatted way, easy to copy elsewhere.
    To be used via the -display command
    :param names: list of strings where each item is the name of a molecule object such as 'basis' or 'coords'
    """
    try:
        molecule = unpickle()["finalise"]
    except KeyError:
        print(
            "QUBEKit encountered an error during execution; returning the initial molecule objects."
        )
        molecule = unpickle()["parametrise"]

    for name in names:
        result = getattr(molecule, name, None)
        if result is not None:
            print(f"{name}:  {repr(result)}")
        else:
            print(
                f"Invalid molecule object: {name}. Please check the log file for the data you require."
            )
Exemple #4
0
    def stage_wrapper(self, start_key, begin_log_msg='', fin_log_msg='', torsion_options=None):
        """
        Firstly, check if the stage start_key is in self.order; this tells you if the stage should be called or not.
        If it isn't in self.order:
            - Do nothing
        If it is:
            - Unpickle the ligand object at the start_key stage
            - Write to the log that something's about to be done (if specified)
            - Make (if not restarting) and / or move into the working directory for that stage
            - Do the thing
            - Move back out of the working directory for that stage
            - Write to the log that something's been done (if specified)
            - Pickle the ligand object again with the next_key marker as its stage
        """

        mol = unpickle()[start_key]

        # Set the state for logging any exceptions should they arise
        mol.state = start_key

        # if we have a torsion options dictionary pass it to the molecule
        if torsion_options is not None:
            mol = self.store_torsions(mol, torsion_options)

        skipping = False
        if self.order[start_key] == self.skip:
            printf(f'{COLOURS.blue}Skipping stage: {start_key}{COLOURS.end}')
            append_to_log(f'skipping stage: {start_key}')
            skipping = True
        else:
            if begin_log_msg:
                printf(f'{begin_log_msg}...', end=' ')

        home = os.getcwd()

        folder_name = f'{str(self.immutable_order.index(start_key) + 1).zfill(2)}_{start_key}'

        make_and_change_into(folder_name)

        self.order[start_key](mol)
        self.order.pop(start_key, None)
        os.chdir(home)

        # Begin looping through self.order, but return after the first iteration.
        for key in self.order:
            next_key = key
            if fin_log_msg and not skipping:
                printf(f'{COLOURS.green}{fin_log_msg}{COLOURS.end}')

            mol.pickle(state=next_key)
            return next_key
Exemple #5
0
def test_double_pickle(tmpdir, acetone):
    """
    Make sure we can add multiple pickled objects to the same file.
    """
    with tmpdir.as_cwd():
        acetone.pickle(state="input")
        # remove all coords
        acetone.coordinates = None
        acetone.pickle(state="after")

        # now check we have both states
        mols = unpickle()
        assert "after" in mols
        assert "input" in mols
Exemple #6
0
def test_pickle_round_trip(tmpdir, acetone):
    """
    test dumping a molecule to pickle and loading it back in.
    """
    with tmpdir.as_cwd():
        acetone.pickle(state="test")
        mols = unpickle()
        pickle_mol = mols["test"]
        for atom in acetone.atoms:
            pickle_atom = pickle_mol.get_atom_with_name(atom.atom_name)
            assert pickle_atom.__dict__ == atom.__dict__
        assert acetone.bonds == pickle_mol.bonds
        assert acetone.angles == pickle_mol.angles
        assert acetone.dihedrals == pickle_mol.dihedrals
Exemple #7
0
    def setUp(self):
        """
        Set up the seminario test case by loading a pickled ligand that contains the hessian already
        """

        self.home = os.getcwd()
        self.test_folder = os.path.join(os.path.dirname(__file__), 'files')

        # Make temp folder and move the pickle file in
        with tempfile.TemporaryDirectory() as temp:
            os.chdir(temp)
            copy(os.path.join(self.test_folder, '.QUBEKit_states'),
                 '.QUBEKit_states')
            self.molecules = unpickle()
            self.benzene_hessian, self.benzene_mod_sem = self.molecules[
                'hessian'], self.molecules['mod_sem']
            self.benzene_mod_sem_vib_1 = self.molecules['mod_sem_vib_1']
            self.benzonitrile_hessian, self.benzonitrile_mod_sem = self.molecules[
                'benzonitrile_hessian'], self.molecules['benzonitrile_mod_sem']
Exemple #8
0
    def setUp(self):
        """Set up the Seminario test by loading a pickled ligand that already contains the hessian."""

        self.home = os.getcwd()
        self.test_folder = os.path.join(os.path.dirname(__file__), "files")

        # Make temp folder and move the pickle file in
        with tempfile.TemporaryDirectory() as temp:
            os.chdir(temp)
            copy(os.path.join(self.test_folder, ".QUBEKit_states"), ".QUBEKit_states")

            self.molecules = unpickle()

            self.benzene_hessian, self.benzene_mod_sem = (
                self.molecules["hessian"],
                self.molecules["mod_sem"],
            )
            self.benzene_hessian.testing = True
            self.benzene_mod_sem_vib_1 = self.molecules["mod_sem_vib_1"]
            self.benzene_mod_sem_vib_1.testing = True
            self.benzonitrile_hessian = self.molecules["benzonitrile_hessian"]
            self.benzonitrile_hessian.testing = True
            self.benzonitrile_mod_sem = self.molecules["benzonitrile_mod_sem"]
            self.benzonitrile_mod_sem.testing = True
Exemple #9
0
    def __init__(self):
        # First make sure the config folder has been made missing for conda and pip
        home = os.path.expanduser('~')
        config_folder = os.path.join(home, 'QUBEKit_configs')
        if not os.path.exists(config_folder):
            os.makedirs(config_folder)
            printf(f'Making config folder at: {home}')

        self.args = self.parse_commands()

        # If we are doing the torsion test add the attribute to the molecule so we can catch it in execute
        if self.args.torsion_test:
            self.args.restart = 'finalise'

        # If it's a bulk run, handle it separately
        # TODO Add .sdf as possible bulk_run, not just .csv
        if self.args.bulk_run is not None:
            self.handle_bulk()

        elif self.args.restart is not None:
            # Find the pickled checkpoint file and load it as the molecule
            try:
                self.molecule = unpickle()[self.args.restart]
            except KeyError:
                raise KeyError('This stage was not found in the log file; was the previous stage completed?')
        else:
            # Initialise molecule
            if self.args.smiles:
                self.molecule = Ligand(*self.args.smiles)
                # Now we should create the initial molecule and
            else:
                self.molecule = Ligand(self.args.input)

        # Find which config file is being used
        self.molecule.config_file = self.args.config_file

        # Handle configs which are in a file
        file_configs = Configure().load_config(self.molecule.config_file)
        for name, val in file_configs.items():
            setattr(self.molecule, name, val)

        # Although these may be None always, they need to be explicitly set anyway.
        self.molecule.restart = None
        self.molecule.end = None
        self.molecule.skip = None

        # Handle configs which are changed by terminal commands
        for name, val in vars(self.args).items():
            if val is not None:
                setattr(self.molecule, name, val)

        # Now we need to remove torsion_test as it is passed from the command line
        if self.args.torsion_test is False:
            delattr(self.molecule, 'torsion_test')

        # Now check if we have been supplied a dihedral file and a constraints file
        if self.args.dihedral_file:
            self.molecule.read_scan_order(self.args.dihedral_file)
        if self.args.constraints_file:
            self.molecule.constraints_file = self.args.constaints_file

        # If restarting put the molecule back into the checkpoint file with the new configs
        if self.args.restart is not None:
            self.molecule.pickle(state=self.args.restart)

        # Now that all configs are stored correctly: execute.
        Execute(self.molecule)