Skip to content

Commit cf62ebc

Browse files
authored
Merge pull request #1 from ReactionMechanismGenerator/hwpang-patch-1
Add settings to __init__.py
2 parents 120dff9 + ba860d0 commit cf62ebc

1 file changed

Lines changed: 164 additions & 0 deletions

File tree

molecule/__init__.py

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
#!/usr/bin/env python3
2+
3+
###############################################################################
4+
# #
5+
# RMG - Reaction Mechanism Generator #
6+
# #
7+
# Copyright (c) 2002-2021 Prof. William H. Green (whgreen@mit.edu), #
8+
# Prof. Richard H. West (r.west@neu.edu) and the RMG Team (rmg_dev@mit.edu) #
9+
# #
10+
# Permission is hereby granted, free of charge, to any person obtaining a #
11+
# copy of this software and associated documentation files (the 'Software'), #
12+
# to deal in the Software without restriction, including without limitation #
13+
# the rights to use, copy, modify, merge, publish, distribute, sublicense, #
14+
# and/or sell copies of the Software, and to permit persons to whom the #
15+
# Software is furnished to do so, subject to the following conditions: #
16+
# #
17+
# The above copyright notice and this permission notice shall be included in #
18+
# all copies or substantial portions of the Software. #
19+
# #
20+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
21+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
22+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
23+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
24+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
25+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
26+
# DEALINGS IN THE SOFTWARE. #
27+
# #
28+
###############################################################################
29+
30+
"""
31+
This is the rmg module.
32+
"""
33+
34+
import os
35+
import os.path
36+
37+
from rmgpy.version import __version__
38+
from rmgpy.exceptions import SettingsError
39+
40+
41+
################################################################################
42+
43+
class Settings(dict):
44+
"""
45+
A dictionary-like object containing global settings for RMG jobs. These
46+
settings are generally loaded from a file named ``rmgrc`` located at one
47+
of several possible places on disk. The ``rmgrc`` file used is stored in
48+
the `filename` attribute. This class inherits from the built-in dict class
49+
and adds methods for loading and resetting the settings, as well as a
50+
custom :meth:`__setitem__` method for processing the setting values before
51+
adding them to the dictionary.
52+
53+
In general you should be working with the module-level variable
54+
``settings`` in this module, which is an instance of this class.
55+
"""
56+
57+
def __init__(self, path=None):
58+
super(Settings, self).__init__()
59+
self.filename = None
60+
self.sources = dict()
61+
self.load(path)
62+
63+
def __setitem__(self, key, value):
64+
if key == 'database.directory':
65+
value = os.path.abspath(os.path.expandvars(value))
66+
elif key == 'test_data.directory':
67+
value = os.path.abspath(os.path.expandvars(value))
68+
else:
69+
raise SettingsError('Unexpecting setting "{0}" encountered.'.format(key))
70+
self.sources[key] = '-'
71+
super(Settings, self).__setitem__(key, value)
72+
73+
def report(self):
74+
"""
75+
Returns a string saying what is set and where things came from, suitable for logging
76+
"""
77+
lines = ['Global RMG Settings:']
78+
for key in self.keys():
79+
lines.append(" {0:20s} = {1:20s} ({2})".format(key, self[key], self.sources[key]))
80+
return '\n'.join(lines)
81+
82+
def load(self, path=None):
83+
"""
84+
Load settings from a file on disk. If an explicit file is not specified,
85+
the following locations will be searched for a settings file, and the
86+
first one found will be loaded:
87+
88+
* An rmgrc file in the current working directory
89+
90+
* An rmgrc file in the user's $HOME/.rmg directory
91+
92+
* An rmgrc file in the same directory as this package
93+
94+
If none of these can be found, a SettingsError is raised.
95+
"""
96+
# First set all settings to their default values
97+
self.reset()
98+
99+
if path:
100+
# The user specified an explicit file to use for the settings
101+
# Make sure that it exists, fail if it does not
102+
if not os.path.exists(path):
103+
raise SettingsError('Specified RMG settings file "{0}" does not exist.'.format(path))
104+
else:
105+
self.filename = path
106+
else:
107+
# The user did not specify an explicit file to use for the settings
108+
# Load one of the default settings files instead
109+
working_dir = os.path.abspath(os.path.dirname(__file__))
110+
if os.path.exists('rmgrc'):
111+
self.filename = 'rmgrc'
112+
elif os.path.exists(os.path.expanduser('~/.rmg/rmgrc')):
113+
self.filename = os.path.expanduser('~/.rmg/rmgrc')
114+
elif os.path.exists(os.path.join(working_dir, 'rmgrc')):
115+
self.filename = os.path.join(working_dir, 'rmgrc')
116+
else:
117+
return # fail silently, instead of raising an error
118+
119+
# From here on we assume that we have identified the appropriate
120+
# settings file to load
121+
122+
with open(self.filename, 'r') as f:
123+
for line in f:
124+
# Remove any comments from the line
125+
index = line.find('#')
126+
if index != -1:
127+
line = line[:index]
128+
# Is there a key-value pair remaining?
129+
if line.find('database.directory') != -1:
130+
value = line.split()[-1] # Get the last token from this line
131+
value = value.strip()
132+
self['database.directory'] = value
133+
self.sources['database.directory'] = "from {0}".format(self.filename)
134+
135+
elif line.find('test_data.directory') != -1:
136+
value = line.split()[-1] # Get the last token from this line
137+
value = value.strip()
138+
self['test_data.directory'] = value
139+
self.sources['test_data.directory'] = "from {0}".format(self.filename)
140+
141+
def reset(self):
142+
"""
143+
Reset all settings to their default values.
144+
"""
145+
self.filename = None
146+
rmgpy_module_dir = os.path.abspath(os.path.dirname(__file__))
147+
self['database.directory'] = os.path.realpath(
148+
os.path.join(rmgpy_module_dir, '..', '..', 'RMG-database', 'input'))
149+
self.sources['database.directory'] = 'Default, relative to RMG-Py source code'
150+
self['test_data.directory'] = os.path.realpath(os.path.join(rmgpy_module_dir, 'test_data'))
151+
self.sources['test_data.directory'] = 'Default, relative to RMG-Py source code'
152+
153+
154+
# The global settings object
155+
settings = Settings(path=None)
156+
157+
158+
################################################################################
159+
160+
def get_path():
161+
"""
162+
Return the directory that this file is found in on disk.
163+
"""
164+
return os.path.abspath(os.path.dirname(__file__))

0 commit comments

Comments
 (0)