# coding: utf-8
# Distributed under the terms of the MIT License.
""" This file implements the diffing of phase diagrams as new structures
are added.
Intended usage:
- Compare current hull with 5 days ago
matador hulldiff -c KSnP -int --compare 5
- Compare hull a month ago to 2 days ago
matador hulldiff -c KSnP -int --compare 30 2
"""
from matador.utils.cursor_utils import display_results
[docs]class HullDiff:
"""Takes two QueryConvexHull objects and 'diffs' them, printing a
+/- line for each new/deleted structure within the specified hull
cutoff (i.e. compares hull.hull_cursor only).
"""
def __init__(self, hull_old, hull_new, **args):
"""Initialise difference from two hulls.
Parameters:
hull_old (QueryConvexHull): older hull object.
hull_new (QueryConvexHull): newer hull object.
Keyword arguments:
args: dict, command-line arguments to print results.
"""
self.id_new = [doc["text_id"] for doc in hull_new.hull_cursor]
self.id_old = [doc["text_id"] for doc in hull_old.hull_cursor]
self.additions = []
self.deletions = []
self.cursor = []
# self.cursor = [doc for doc in hull_new.hull_cursor]
for doc in hull_new.hull_cursor:
if doc["text_id"] not in self.id_old:
self.cursor.append(doc)
self.additions.append(doc["text_id"])
for doc in hull_old.hull_cursor:
if doc["text_id"] not in self.id_new:
self.cursor.append(doc)
self.deletions.append(doc["text_id"])
self.cursor = sorted(
self.cursor, key=lambda x: (x["enthalpy_per_atom"], x["concentration"])
)
self.print_diff(**args)
[docs] def print_diff(self, **args):
"""Use the display_results function to print the diff."""
display_results(
self.cursor, hull=True, additions=self.additions, deletions=self.deletions
)
if self.additions is not None:
if args.get("summary"):
print(
"{} additions and {} replacements as best at stoichiometry.".format(
len(self.additions), len(self.deletions)
)
)
else:
print(
"{} additions and {} deletions.".format(
len(self.additions), len(self.deletions)
)
)
[docs] def plot_diff(self):
"""Plot the hull with additions ONLY highlighted in green."""
raise NotImplementedError
[docs]def diff_hulls(client, collections, **args):
"""Helper function to diff hulls from cmd-line args.
Parameters:
client (MongoClient): connection to database
collections (dict of Collection): dict of collections to query
Keyword arguments:
args: dict, command-line arguments to select hulls.
"""
from matador.query import DBQuery
from matador.hull import QueryConvexHull
diff_args = args["compare"]
del args["compare"]
args["no_plot"] = True
if args.get("verbosity") in [0, None] and not args.get("debug"):
args["quiet"] = True
diff_args = sorted(diff_args)
args["time"] = diff_args[0]
print("Calculating hull {} days ago...".format(args["time"]))
query_old = DBQuery(client, collections, **args)
hull_old = QueryConvexHull(query_old, **args)
if len(diff_args) == 1 or isinstance(diff_args, str):
args["time"] = "0"
else:
args["time"] = diff_args[1]
if args["time"] == "0":
print("... to compare with up-to-date hull.")
else:
print("... to compare with hull {} days ago.".format(args["time"]))
query_new = DBQuery(client, collections, **args)
hull_new = QueryConvexHull(query_new, **args)
HullDiff(hull_old, hull_new, **args)