Source code for pymatgen.analysis.chemenv.utils.chemenv_config
# coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.
"""
This module contains the classes for configuration of the chemenv package.
"""
import json
from os import makedirs
from os.path import exists, expanduser
from pymatgen.core import SETTINGS
from pymatgen.analysis.chemenv.utils.scripts_utils import strategies_class_lookup
__author__ = "David Waroquiers"
__copyright__ = "Copyright 2012, The Materials Project"
__credits__ = "Geoffroy Hautier"
__version__ = "2.0"
__maintainer__ = "David Waroquiers"
__email__ = "david.waroquiers@gmail.com"
__date__ = "Feb 20, 2016"
[docs]class ChemEnvConfig:
"""
Class used to store the configuration of the chemenv package :
- Materials project access
- ICSD database access
- Default options (strategies, ...)
"""
DEFAULT_PACKAGE_OPTIONS = {
"default_strategy": {
"strategy": "SimplestChemenvStrategy",
"strategy_options": {
"distance_cutoff": strategies_class_lookup["SimplestChemenvStrategy"].DEFAULT_DISTANCE_CUTOFF,
"angle_cutoff": strategies_class_lookup["SimplestChemenvStrategy"].DEFAULT_ANGLE_CUTOFF,
"additional_condition": strategies_class_lookup["SimplestChemenvStrategy"].DEFAULT_ADDITIONAL_CONDITION,
"continuous_symmetry_measure_cutoff": strategies_class_lookup[
"SimplestChemenvStrategy"
].DEFAULT_CONTINUOUS_SYMMETRY_MEASURE_CUTOFF,
},
},
"default_max_distance_factor": 1.5,
}
def __init__(self, package_options=None):
"""
:param package_options:
"""
if SETTINGS.get("PMG_MAPI_KEY", "") != "":
self.materials_project_configuration = SETTINGS.get("PMG_MAPI_KEY", "")
else:
self.materials_project_configuration = None
if package_options is None:
self.package_options = self.DEFAULT_PACKAGE_OPTIONS
else:
self.package_options = package_options
[docs] def setup(self):
"""
Setup the class.
"""
while True:
print("\n=> Configuration of the ChemEnv package <=")
print("Current configuration :")
if self.has_materials_project_access:
print(" - Access to materials project is configured (add test ?)")
else:
print(" - No access to materials project")
print(" - Package options :")
for key, val in self.package_options.items():
print(" {} : {}".format(str(key), str(val)))
print("\nChoose in the following :")
print(" <1> + <ENTER> : configuration of the package options (strategy, ...)")
print(" <q> + <ENTER> : quit without saving configuration")
test = input(" <S> + <ENTER> : save configuration and quit\n ... ")
if test == "1":
self.setup_package_options()
elif test == "q":
break
elif test == "S":
config_file = self.save()
break
else:
print(" ... wrong key, try again ...")
print("")
if test == "S":
print('Configuration has been saved to file "{}"'.format(config_file))
@property
def has_materials_project_access(self):
"""
Whether MP access is enabled.
:return:
"""
return self.materials_project_configuration is not None
[docs] def setup_package_options(self):
"""
Setup the package options.
"""
self.package_options = self.DEFAULT_PACKAGE_OPTIONS
print("Choose between the following strategies : ")
strategies = list(strategies_class_lookup.keys())
for istrategy, strategy in enumerate(strategies):
print(" <{}> : {}".format(str(istrategy + 1), strategy))
test = input(" ... ")
self.package_options["default_strategy"] = {
"strategy": strategies[int(test) - 1],
"strategy_options": {},
}
strategy_class = strategies_class_lookup[strategies[int(test) - 1]]
if len(strategy_class.STRATEGY_OPTIONS) > 0:
for option, option_dict in strategy_class.STRATEGY_OPTIONS.items():
while True:
print(
' => Enter value for option "{}" '
"(<ENTER> for default = {})\n".format(option, str(option_dict["default"]))
)
print(" Valid options are :\n")
print(" {}".format(option_dict["type"].allowed_values))
test = input(" Your choice : ")
if test == "":
self.package_options["default_strategy"]["strategy_options"][option] = option_dict["type"](
strategy_class.STRATEGY_OPTIONS[option]["default"]
)
break
try:
self.package_options["default_strategy"]["strategy_options"][option] = option_dict["type"](test)
break
except ValueError:
print("Wrong input for option {}".format(option))
[docs] def package_options_description(self):
"""
Describe package options.
"""
out = "Package options :\n"
out += " - Maximum distance factor : {:.4f}\n".format(self.package_options["default_max_distance_factor"])
out += ' - Default strategy is "{}" :\n'.format(self.package_options["default_strategy"]["strategy"])
strategy_class = strategies_class_lookup[self.package_options["default_strategy"]["strategy"]]
out += "{}\n".format(strategy_class.STRATEGY_DESCRIPTION)
out += " with options :\n"
for option, option_dict in strategy_class.STRATEGY_OPTIONS.items():
out += " - {} : {}\n".format(
option,
self.package_options["default_strategy"]["strategy_options"][option],
)
return out
[docs] def save(self, root_dir=None):
"""
Save the options.
:param root_dir:
"""
if root_dir is None:
home = expanduser("~")
root_dir = "{}/.chemenv".format(home)
if not exists(root_dir):
makedirs(root_dir)
config_dict = {"package_options": self.package_options}
config_file = "{}/config.json".format(root_dir)
if exists(config_file):
test = input("Overwrite existing configuration ? (<Y> + <ENTER> to confirm)")
if test != "Y":
print("Configuration not saved")
return config_file
f = open(config_file, "w")
json.dump(config_dict, f)
f.close()
print("Configuration saved")
return config_file
[docs] @classmethod
def auto_load(cls, root_dir=None):
"""
Autoload options.
:param root_dir:
"""
if root_dir is None:
home = expanduser("~")
root_dir = "{}/.chemenv".format(home)
config_file = "{}/config.json".format(root_dir)
try:
f = open(config_file, "r")
config_dict = json.load(f)
f.close()
return ChemEnvConfig(package_options=config_dict["package_options"])
except IOError:
print('Unable to load configuration from file "{}" ...'.format(config_file))
print(" ... loading default configuration")
return ChemEnvConfig()