From 95a43ab243d0451381072e9ea12c5a859782c94c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20L=C3=B6hel?= Date: Mon, 10 Jan 2022 07:16:52 +0100 Subject: [PATCH] Reorganizes the project MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Renames package into tidymol * Replaces docopt by click * Moves molden parser into the parsers module * Introduces exceptions * Introduces loguru Signed-off-by: Jürgen Löhel --- README.rst | 17 +- requirements.txt | 4 +- setup.py | 8 +- src/molden_modifier/cli.py | 179 ---------------- src/molden_modifier/commands.py | 95 --------- src/molden_modifier/common.py | 96 --------- src/molden_modifier/exceptions.py | 3 - src/molden_modifier/log.py | 33 --- src/{molden_modifier => tidymol}/__init__.py | 0 src/{molden_modifier => tidymol}/__main__.py | 2 +- .../change_label.py | 0 src/tidymol/cli.py | 196 ++++++++++++++++++ src/tidymol/constants.py | 1 + src/tidymol/exceptions.py | 11 + src/tidymol/parsers/__init__.py | 0 .../parsers/molden/__init__.py} | 0 .../parsers/molden/lexer.py} | 0 .../parsers/molden/parser.py} | 0 18 files changed, 224 insertions(+), 421 deletions(-) delete mode 100644 src/molden_modifier/cli.py delete mode 100644 src/molden_modifier/commands.py delete mode 100644 src/molden_modifier/common.py delete mode 100644 src/molden_modifier/exceptions.py delete mode 100644 src/molden_modifier/log.py rename src/{molden_modifier => tidymol}/__init__.py (100%) rename src/{molden_modifier => tidymol}/__main__.py (90%) rename src/{molden_modifier => tidymol}/change_label.py (100%) create mode 100644 src/tidymol/cli.py create mode 100644 src/tidymol/constants.py create mode 100644 src/tidymol/exceptions.py create mode 100644 src/tidymol/parsers/__init__.py rename src/{molden_modifier/molden.py => tidymol/parsers/molden/__init__.py} (100%) rename src/{molden_modifier/molden_lexer.py => tidymol/parsers/molden/lexer.py} (100%) rename src/{molden_modifier/molden_parser.py => tidymol/parsers/molden/parser.py} (100%) diff --git a/README.rst b/README.rst index 90a3c3e..617489a 100644 --- a/README.rst +++ b/README.rst @@ -1,12 +1,12 @@ ===================== -molden_modifier 0.1.0 +tidymol 0.1.0 ===================== Some tools to modify molden files. * Free software: MIT license -Installation +Development ============ Use your package manager or use the following instructions to install it @@ -14,19 +14,18 @@ in a virtual environment:: $ python3 -m venv .env $ source .env/bin/activate - $ pip install --upgrade pip - $ pip install --upgrade + $ pip install --upgrade pip setuptools wheel $ pip install -r devel-requirements.txt - $ python setup.py develop + $ pip install -e . Citation ======== :: - @Misc{Loehel2020, + @Misc{Loehel2022, author = {Juergen Loehel and Alba Vargas-Caamal}, - title = {Molden-modifier 1.0}, - year = {2020}, - url = {https://github.com/jloehel/molden_modifier}, + title = {tidymol 1.0}, + year = {2022}, + url = {https://github.com/jloehel/tidymol}, } diff --git a/requirements.txt b/requirements.txt index 8af33fc..6353fc3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ ply numpy -docopt +Cython molmod pandas +loguru +click diff --git a/setup.py b/setup.py index 1571ac7..890941f 100644 --- a/setup.py +++ b/setup.py @@ -38,17 +38,17 @@ def requires(filename): # ------------------------------------------------------ setup( - name='molden_modifier', + name='tidymol', version='0.1.0', license='MIT', - description='Helps to modify molden files', + description='Little Chem Helper', long_description='%s\n%s' % ( re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')), re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')) ), author='Jürgen Löhel', author_email='juergen@loehel.de', - url='https://bitbucket.com/jloehel/molden_modifier', + url='https://github.com/jloehel/tidymol', packages=find_packages('src'), package_dir={'': 'src'}, py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')], @@ -85,7 +85,7 @@ def requires(filename): entry_points={ 'console_scripts': [ - 'molden_modifier = molden_modifier.cli:main', + 'tidymol = tidymol.cli:main', ] }, ) diff --git a/src/molden_modifier/cli.py b/src/molden_modifier/cli.py deleted file mode 100644 index bd3c6d7..0000000 --- a/src/molden_modifier/cli.py +++ /dev/null @@ -1,179 +0,0 @@ -"""Helps to modify molden files - -Usage: - molden_modifier [options] info - molden_modifier [options] filter -f FILTER - molden_modifier [options] mirror [--compare] - molden_modifier [options] sort - molden_modifier [options] shortest_distance -s SYMBOL - molden_modifier -h | --help | --version - -Required Arguments: - Path to Molden file (file extension .molden) - -Options: - -h, --help Shows this help - --version Prints the version - -v Raise verbosity level - --output=, -o - Optional file where results are written to - -Subcommands: - info Prints some basic information about the molden file. - filter Applies a specific filter on a molden file. - sort Sorts the the moleculs of the molden file by energy. - Options: - -f The molden file which is used for filtering. - - mirror Mirrors the moleculs of the molden file. - Options: - --compare The mirrored and the original molecule will be added - both to the output file. This helps to compare it. - - shortest_distance Finds the shortest distance of every Hydrogen Bonding - Options: - -s The Symbol ... -""" - -# Standard Library -import logging -import os -import re -import sys -from logging.config import dictConfig - -# Third Party Libraries -from docopt import DocoptExit, docopt, printable_usage - -# Local imports -from . import __version__ -from .commands import info, filter, mirror, sort, shortest_distance -from .common import DEFAULT_LOGGING_DICT, LOGLEVELS, errorcode -from .molden import parse - -#: Use __package__, not __name__ here to set overall LOGging level: -LOG = logging.getLogger(__package__) - - -def parsecli(cliargs=None): - """Parse CLI arguments with docopt - - :param cliargs: List of commandline arguments - :type cliargs: list(str) - :return: dictionary from :class:`docopt.docopt` - :rtype: dict - """ - version = "%s %s" % (__package__, __version__) - args = docopt(__doc__, - argv=cliargs, version=version) - dictConfig(DEFAULT_LOGGING_DICT) - LOG.setLevel(LOGLEVELS.get(args['-v'], logging.DEBUG)) - - return args - - -def checkargs(args): - """Check arguments for validity - - :param args: parsed arguments from :class:`docopt.docopt` - :type args: dict - :raises: :class:`docopt.DocoptExit`, :class:`FileNotFoundError` - :return: - """ - molden_file = args[''] - if molden_file is None: - raise DocoptExit() - if not os.path.exists(molden_file): - raise FileNotFoundError(molden_file) - - -def output(results, file_path, cvs): - """Write the result to a file if the --output argument is set otherwise - the result will be printed on stdout. - - :param result: The results of the modification - :type result: List of molecules - :param file_path: The file path to the output file - :type file_path: str - :return: None - """ - if results is None: - return None - path, filename = os.path.split(file_path) - if path != "": - os.makedirs(path, exist_ok=True) - if file_path: - if cvs: - results.to_csv(file_path) - else: - with open(file_path, "w") as outfile: - for molecule in results: - outfile.write(str(molecule)) - else: - for molecule in results: - print(molecule) - - -def main(cliargs=None): - """Entry point for the application script - - :param list(str) cliargs: Arguments to parse or None (=use ``sys.argv``) - :return: return codes from :func:`molden_modifier.common.errorcode` - :rtype: int - """ - try: - args = parsecli(cliargs) - LOG.info('%s version: %s', __package__, __version__) - LOG.debug('Python version: %s', sys.version.split()[0]) - LOG.debug("CLI result: %s", args) - checkargs(args) - data = "" - with open(args[''], 'r') as infile: - for line in infile.readlines(): - data += re.sub(r" *$", "", line) - if data is None: - Log.error("Empty file") - sys.exit(1) - molecules = parse(data) - if molecules is None: - LOG.info("No molecules found!") - sys.exit(1) - LOG.info("Found %s molecules in %s", len(molecules), args['']) - results = None - cvs = False - if args["mirror"]: - results = mirror(molecules, args["--compare"]) - elif args["filter"]: - with open(args["-f"], 'r') as filter_file: - filter_data = filter_file.read() - molecules_filter = parse(filter_data) - results = filter(molecules_filter, molecules) - elif args["info"]: - info(molecules) - elif args["sort"]: - results = sort(molecules) - elif args["shortest_distance"]: - results = shortest_distance(molecules, args["-s"]) - cvs = True - else: - raise RuntimeError("Unknown command") - output(results, args["--output"], cvs) - - LOG.info("Done.") - return 0 - - except DocoptExit as error: - LOG.fatal("Need a molden file.") - printable_usage(__doc__) - return errorcode(error) - - except FileNotFoundError as error: - LOG.fatal("File not found '%s'", error) - return errorcode(error) - - except RuntimeError as error: - LOG.fatal("Something failed '%s'", error) - return 1 - - except KeyboardInterrupt as error: - return errorcode(error) diff --git a/src/molden_modifier/commands.py b/src/molden_modifier/commands.py deleted file mode 100644 index 0c555e8..0000000 --- a/src/molden_modifier/commands.py +++ /dev/null @@ -1,95 +0,0 @@ -"""Cli commands""" - -# Standard Library -import copy -import logging -import pandas as pd - -from molmod.molecules import Molecule - -LOG = logging.getLogger(__name__) - - -def mirror(molecules, compare): - copy_of_molecules = list() - for molecule in molecules: - if compare: - copy_of_molecules.append(copy.deepcopy(molecule)) - molecule.mirror() - copy_of_molecules.append(molecule) - copy_of_molecules = sort(copy_of_molecules) - return copy_of_molecules - - -def sort(molecules): - return sorted(molecules, key=lambda molecule: molecule.energy) - - -def info(molecules): - pass - - -def filter(molecules_filter, molecules): - filtered_list = list() - for molecule in molecules: - for molecule_filter in molecules_filter: - if molecule.label == molecule_filter.label: - filtered_list.append(molecule) - continue - return filtered_list - - -def convert_molecule_to_molmod(molecule): - molModMolecule = Molecule(molecule.numbers, - molecule.coordinates, molecule.label, - symbols=molecule.symbols) - molModMolecule.set_default_graph() - return molModMolecule - - -def shortest_distance(molecules, symbol, max_distance=100): - distances = { - "molecules": [], - "indxs_a": [], - "indxs_H": [], - "indxs_b": [], - "q1s": [], - "q2s": [], - "types": [], - } - for indx, molecule in enumerate(molecules): - indexes = molecule.get_indexes_by_symbol(symbol) - molModMolecule = convert_molecule_to_molmod(molecule) - for i in indexes: - neighbors_r1 = molModMolecule.graph.neighbors[i] - H_neighbors = [(neighbor, molModMolecule.distance_matrix[i][neighbor]) for neighbor - in neighbors_r1 - if molModMolecule.symbols[neighbor] == "H"] - shortest_H = sorted(H_neighbors, key=lambda neighbor: neighbor[1])[0] - r1_index = shortest_H[0] - r1_distance = shortest_H[1] - - neighbors_r2 = molModMolecule.graph.neighbors[r1_index] - neighbors_r2 = list(filter(lambda neighbor: neighbor != i, neighbors_r2)) - X_neighbors = [(neighbor, molModMolecule.distance_matrix[r1_index][neighbor]) for neighbor - in neighbors_r2 - if molModMolecule.symbols[neighbor] == "O" - or molModMolecule.symbols[neighbor] == symbol] - shortest_X = sorted(X_neighbors, key=lambda neighbor: neighbor[1])[0] - r2_index = shortest_X[0] - r2_distance = shortest_X[1] - - q1 = (r1_distance-r2_distance)/2.0 - q2 = r1_distance+r2_distance - - distances["molecules"].append(indx) - distances["indxs_a"].append(i+1) - distances["indxs_H"].append(r1_index+1) - distances["indxs_b"].append(r2_index+1) - distances["q1s"].append(q1) - distances["q2s"].append(q2) - distances["types"].append("{}-H-{}".format(symbol, - molModMolecule.symbols[r2_index])) - - results = pd.DataFrame(distances) - return results diff --git a/src/molden_modifier/common.py b/src/molden_modifier/common.py deleted file mode 100644 index aa11004..0000000 --- a/src/molden_modifier/common.py +++ /dev/null @@ -1,96 +0,0 @@ -"""Constants for all the other modules -""" - -# Third Party Libraries -from docopt import DocoptExit - -from logging import (CRITICAL, # isort:skip - DEBUG, - ERROR, - FATAL, - INFO, - NOTSET, - WARN, - WARNING, - ) - - -# Error codes -# Make an error dictionary that contains both the class and its -# string representation -ERROR_CODES = dict() -for _error, _rc in [ # exception class, return value: - (FileNotFoundError, 40), - (OSError, 40), - (DocoptExit, 50), - (KeyboardInterrupt, 200), - ]: - ERROR_CODES[_error] = _rc - ERROR_CODES[repr(_error)] = _rc - - -def errorcode(error): - """Get the error exit code from an exception ``error`` - - :param error: exception instance like :class:`OSError` - :return: exit code - :rtype: int - """ - return ERROR_CODES.get(repr(type(error)), 255) - - -#: Map verbosity to log levels -LOGLEVELS = {None: WARNING, # 0 - 0: WARNING, - 1: INFO, - 2: DEBUG, - } - -#: Map log numbers to log names -LOGNAMES = {NOTSET: 'NOTSET', # 0 - None: 'NOTSET', - DEBUG: 'DEBUG', # 10 - INFO: 'INFO', # 20 - WARN: 'WARNING', # 30 - WARNING: 'WARNING', # 30 - ERROR: 'ERROR', # 40 - CRITICAL: 'CRITICAL', # 50 - FATAL: 'CRITICAL', # 50 - } - -#: Default logging dict for :class:`logging.config.dictConfig`: -DEFAULT_LOGGING_DICT = { - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'standard': { - # See https://docs.python.org/3.5/library/logging.html#logrecord-attributes - 'format': '[%(levelname)s] %(name)s::%(funcName)s: %(message)s' - }, - 'myformatter': { - '()': 'molden_modifier.log.CustomConsoleFormatter', - 'format': '[%(levelname)s] %(message)s', - }, - }, - 'handlers': { - 'default': { - 'level': 'NOTSET', - 'formatter': 'standard', - 'class': 'logging.StreamHandler', - # 'stream': 'ext://sys.stderr', - }, - 'myhandler': { - 'level': 'NOTSET', - 'formatter': 'myformatter', - 'class': 'logging.StreamHandler', - # 'stream': 'ext://sys.stderr', - }, - }, - 'loggers': { - __package__: { - 'handlers': ['myhandler', ], # 'default' - 'level': 'INFO', - 'propagate': True - } - } -} diff --git a/src/molden_modifier/exceptions.py b/src/molden_modifier/exceptions.py deleted file mode 100644 index 666d979..0000000 --- a/src/molden_modifier/exceptions.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -Module for all exceptions -""" diff --git a/src/molden_modifier/log.py b/src/molden_modifier/log.py deleted file mode 100644 index c754fc0..0000000 --- a/src/molden_modifier/log.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Logging module - -""" - -# Standard Library -import logging - -# Local imports -from .common import DEFAULT_LOGGING_DICT - -#: the default logging format -DEFAULT_FORMAT = DEFAULT_LOGGING_DICT['formatters']['standard']['format'] - -#: a very simple format -SIMPLE_FORMAT = DEFAULT_LOGGING_DICT['formatters']['myformatter']['format'] - - -class CustomConsoleFormatter(logging.Formatter): - """ - Modify the way DEBUG messages are displayed. - """ - # Lists all different formats - FORMATS = {logging.INFO: logging.Formatter(SIMPLE_FORMAT), - logging.WARNING: logging.Formatter(SIMPLE_FORMAT), - logging.ERROR: logging.Formatter(SIMPLE_FORMAT), - logging.FATAL: logging.Formatter(SIMPLE_FORMAT), - 'DEFAULT': logging.Formatter(DEFAULT_FORMAT), - } - - def format(self, record): - "Format the specified record as text." - fmt = self.FORMATS.get(record.levelno, self.FORMATS['DEFAULT']) - return fmt.format(record) diff --git a/src/molden_modifier/__init__.py b/src/tidymol/__init__.py similarity index 100% rename from src/molden_modifier/__init__.py rename to src/tidymol/__init__.py diff --git a/src/molden_modifier/__main__.py b/src/tidymol/__main__.py similarity index 90% rename from src/molden_modifier/__main__.py rename to src/tidymol/__main__.py index 4dc5fe7..deaa3eb 100644 --- a/src/molden_modifier/__main__.py +++ b/src/tidymol/__main__.py @@ -11,6 +11,6 @@ if __name__ == "__main__": import sys - from molden_modifier.cli import main + from tidymol.cli import main sys.exit(main()) # pragma: no cover diff --git a/src/molden_modifier/change_label.py b/src/tidymol/change_label.py similarity index 100% rename from src/molden_modifier/change_label.py rename to src/tidymol/change_label.py diff --git a/src/tidymol/cli.py b/src/tidymol/cli.py new file mode 100644 index 0000000..a5e16aa --- /dev/null +++ b/src/tidymol/cli.py @@ -0,0 +1,196 @@ +"""Helps to modify molden files +""" +# Local imports +from . import __version__ +from .constants import SYMBOLS +from .exceptions import EmptyFile, NoMolecules +from .parsers.molden import parse + +# Standard Library +import copy +import re +import sys +from logging import DEBUG, INFO, WARNING + +# Third Party Libraries +import click +import pandas as pd +from loguru import logger +from molmod.molecules import Molecule + +LOGLEVELS = { + 0: WARNING, + 1: INFO, + 2: DEBUG, +} + + +def convert_molecule_to_molmod(molecule): + molModMolecule = Molecule( + molecule.numbers, + molecule.coordinates, molecule.label, + symbols=molecule.symbols + ) + molModMolecule.set_default_graph() + return molModMolecule + + +def output(results): + """Prints results + + :param result: The results of the modification + :type result: List of molecules + :return: None + """ + for molecule in results: + print(molecule) + + +def read_file(filename): + data = "" + with open(filename, 'r') as infile: + for line in infile.readlines(): + data += re.sub(r" *$", "", line) + if data is None: + raise EmptyFile() + molecules = parse(data) + if molecules is None: + raise NoMolecules() + logger.info("Found %s molecules in %s", len(molecules), filename) + return molecules + + +@click.group() +@click.version_option(__version__, prog_name="tidymol") +@click.option("-v", "--verbose", count=True, default=0) +@click.pass_context +def main(ctx, verbose): + ctx.ensure_object(dict) + ctx.obj["LOGLEVEL"] = LOGLEVELS.get(min(len(LOGLEVELS) - 1, verbose)) + logger.remove() + logger.add(sys.stderr, level=ctx.obj["LOGLEVEL"]) + logger.info(f"tidymol version: {__version__}") + logger.debug("Python version: {}".format(sys.version.split()[0])) + + +@main.command() +@click.argument("filename", type=click.Path(exists=True)) +def info(filename): + """Prints some basic information about the molden file.""" + molecules = read_file(filename) + click.echo(f"Filename: {filename}") + click.echo("=" * len(f"Filename: {filename}")) + click.echo("Fileformat: .molden") + click.echo(f"Number of Molecules: {len(molecules)}") + + +@main.command() +@click.option( + "-f", + "--filter-file", + type=click.Path(exists=True), + help="The molden file which is used for filtering.", +) +@click.argument("filename", type=click.Path(exists=True)) +def filter(filter_file, filename): + """Applies a specific filter on a molden file.""" + molecules = read_file(filename) + molecules_filter = read_file(filter_file) + filtered_list = list() + for molecule in molecules: + for molecule_filter in molecules_filter: + if molecule.label == molecule_filter.label: + filtered_list.append(molecule) + continue + output(filtered_list) + + +@main.command() +@click.option( + "--compare", + is_flag=True, + help="The mirrored and the original molecule will be added both to the output file. This helps to compare it.", # noqa +) +@click.argument("filename", type=click.Path(exists=True)) +def mirror(compare, filename): + """Mirrors the moleculs of the molden file.""" + molecules = read_file(filename) + _molecules = list() + for molecule in molecules: + if compare: + _molecules.append(copy.deepcopy(molecule)) + molecule.mirror() + _molecules.append(molecule) + _molecules = sorted(_molecules, key=lambda molecule: molecule.energy) + output(_molecules) + + +@main.command() +@click.argument("filename", type=click.Path(exists=True)) +def sort(filename): + """Sorts the the moleculs of the molden file by energy.""" + molecules = read_file(filename) + output(sorted(molecules, key=lambda molecule: molecule.energy)) + + +@main.command() +@click.argument("filename", type=click.Path(exists=True)) +@click.option( + "-s", + "--symbol", + type=click.Tuple([str, click.Choice(SYMBOLS)]), + help="The symbol", +) +def shortest_distance(symbol, filename): + """Finds the shortest distance of every Hydrogen Bonding""" + molecules = read_file(filename) + distances = { + "molecules": [], + "indxs_a": [], + "indxs_H": [], + "indxs_b": [], + "q1s": [], + "q2s": [], + "types": [], + } + for indx, molecule in enumerate(molecules): + indexes = molecule.get_indexes_by_symbol(symbol) + molModMolecule = convert_molecule_to_molmod(molecule) + for i in indexes: + neighbors_r1 = molModMolecule.graph.neighbors[i] + H_neighbors = [ + (neighbor, molModMolecule.distance_matrix[i][neighbor]) + for neighbor in neighbors_r1 + if molModMolecule.symbols[neighbor] == "H" + ] + shortest_H = sorted(H_neighbors, key=lambda neighbor: neighbor[1])[0] + r1_index = shortest_H[0] + r1_distance = shortest_H[1] + + neighbors_r2 = molModMolecule.graph.neighbors[r1_index] + neighbors_r2 = list(filter(lambda neighbor: neighbor != i, neighbors_r2)) + X_neighbors = [ + (neighbor, molModMolecule.distance_matrix[r1_index][neighbor]) + for neighbor in neighbors_r2 + if molModMolecule.symbols[neighbor] == "O" + or molModMolecule.symbols[neighbor] == symbol + ] + shortest_X = sorted(X_neighbors, key=lambda neighbor: neighbor[1])[0] + r2_index = shortest_X[0] + r2_distance = shortest_X[1] + + q1 = (r1_distance-r2_distance)/2.0 + q2 = r1_distance+r2_distance + + distances["molecules"].append(indx) + distances["indxs_a"].append(i+1) + distances["indxs_H"].append(r1_index+1) + distances["indxs_b"].append(r2_index+1) + distances["q1s"].append(q1) + distances["q2s"].append(q2) + distances["types"].append( + "{}-H-{}".format(symbol, molModMolecule.symbols[r2_index]) + ) + + results = pd.DataFrame(distances) + print(results) diff --git a/src/tidymol/constants.py b/src/tidymol/constants.py new file mode 100644 index 0000000..e5940b2 --- /dev/null +++ b/src/tidymol/constants.py @@ -0,0 +1 @@ +SYMBOLS = ["X", "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr"] diff --git a/src/tidymol/exceptions.py b/src/tidymol/exceptions.py new file mode 100644 index 0000000..8c74719 --- /dev/null +++ b/src/tidymol/exceptions.py @@ -0,0 +1,11 @@ +""" +Module for all exceptions +""" + + +class EmptyFile(ValueError): + pass + + +class NoMolecules(ValueError): + pass diff --git a/src/tidymol/parsers/__init__.py b/src/tidymol/parsers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/molden_modifier/molden.py b/src/tidymol/parsers/molden/__init__.py similarity index 100% rename from src/molden_modifier/molden.py rename to src/tidymol/parsers/molden/__init__.py diff --git a/src/molden_modifier/molden_lexer.py b/src/tidymol/parsers/molden/lexer.py similarity index 100% rename from src/molden_modifier/molden_lexer.py rename to src/tidymol/parsers/molden/lexer.py diff --git a/src/molden_modifier/molden_parser.py b/src/tidymol/parsers/molden/parser.py similarity index 100% rename from src/molden_modifier/molden_parser.py rename to src/tidymol/parsers/molden/parser.py