1#!/usr/bin/env python
2#  coding: utf-8
3# Copyright (c) Pymatgen Development Team.
4# Distributed under the terms of the MIT License.
5
6"""
7A convenience script engine to read Gaussian output in a directory tree.
8"""
9
10
11import argparse
12import logging
13import multiprocessing
14import os
15import re
16
17from tabulate import tabulate
18
19from pymatgen.apps.borg.hive import GaussianToComputedEntryDrone
20from pymatgen.apps.borg.queen import BorgQueen
21
22save_file = "gau_data.gz"
23
24
25def get_energies(rootdir, reanalyze, verbose):
26    """
27    :param rootdir:
28    :param reanalyze:
29    :param verbose:
30    :return:
31    """
32    if verbose:
33        FORMAT = "%(relativeCreated)d msecs : %(message)s"
34        logging.basicConfig(level=logging.INFO, format=FORMAT)
35    drone = GaussianToComputedEntryDrone(inc_structure=True, parameters=["filename"])
36    ncpus = multiprocessing.cpu_count()
37    logging.info("Detected {} cpus".format(ncpus))
38    queen = BorgQueen(drone, number_of_drones=ncpus)
39    if os.path.exists(save_file) and not reanalyze:
40        msg = "Using previously assimilated data from {}.".format(save_file) + " Use -f to force re-analysis."
41        queen.load_data(save_file)
42    else:
43        queen.parallel_assimilate(rootdir)
44        msg = "Results saved to {} for faster reloading.".format(save_file)
45        queen.save_data(save_file)
46
47    entries = queen.get_data()
48    entries = sorted(entries, key=lambda x: x.parameters["filename"])
49    all_data = [
50        (
51            e.parameters["filename"].replace("./", ""),
52            re.sub(r"\s+", "", e.composition.formula),
53            "{}".format(e.parameters["charge"]),
54            "{}".format(e.parameters["spin_mult"]),
55            "{:.5f}".format(e.energy),
56            "{:.5f}".format(e.energy_per_atom),
57        )
58        for e in entries
59    ]
60    headers = ("Directory", "Formula", "Charge", "Spin Mult.", "Energy", "E/Atom")
61    print(tabulate(all_data, headers=headers))
62    print("")
63    print(msg)
64
65
66def main():
67    """
68    Main function
69    """
70    desc = """
71    Convenient Gaussian run analyzer which can recursively go into a directory
72    to search results.
73    Author: Shyue Ping Ong
74    Version: 1.0
75    Last updated: Jul 6 2012"""
76
77    parser = argparse.ArgumentParser(description=desc)
78    parser.add_argument(
79        "directories",
80        metavar="dir",
81        default=".",
82        type=str,
83        nargs="*",
84        help="directory to process",
85    )
86    parser.add_argument(
87        "-v",
88        "--verbose",
89        dest="verbose",
90        action="store_const",
91        const=True,
92        help="Verbose mode. Provides detailed output on progress.",
93    )
94    parser.add_argument(
95        "-f",
96        "--force",
97        dest="reanalyze",
98        action="store_const",
99        const=True,
100        help="Force reanalysis, instead of reusing gaussian_analyzer_data.gz.",
101    )
102
103    args = parser.parse_args()
104    for d in args.directories:
105        get_energies(d, args.reanalyze, args.verbose)
106
107
108if __name__ == "__main__":
109    main()
110