Skip to content

Commit 18e8933

Browse files
authored
Merge branch 'master' into graph_for_paper
2 parents 97677ea + f4e4d8c commit 18e8933

File tree

5 files changed

+66
-21
lines changed

5 files changed

+66
-21
lines changed

propnet/core/tests/test_fitting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def test_get_sse(self):
3636
self.assertAlmostEqual(err, test_val)
3737
# Big dataset
3838
err = get_sse(self.evaluated, self.benchmarks)
39-
self.assertAlmostEqual(err, 173.5710251)
39+
self.assertAlmostEqual(err, 190.002519386222)
4040

4141
def test_get_weight(self):
4242
q1 = QuantityFactory.create_quantity("band_gap", 3.2)

propnet/dbtools/correlation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,9 @@ def _make_data_combinations(self, prop_x, prop_y, data):
293293
prop_combos = ((prop_x, prop_y), (prop_y, prop_x))
294294
for x, y in prop_combos:
295295
for name, func in self._funcs.items():
296-
data_dict = {'x_data': data[x],
296+
data_dict = {'x_data': data.get(x, []),
297297
'x_name': x,
298-
'y_data': data[y],
298+
'y_data': data.get(y, []),
299299
'y_name': y,
300300
'func': (name, func)}
301301
yield data_dict

propnet/dbtools/mp_builder.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ class PropnetBuilder(MapBuilder):
2828
"""
2929

3030
def __init__(self, materials, propstore, materials_symbol_map=None,
31-
criteria=None, source_name="", graph_parallel=False,
31+
criteria=None, source_name="", include_deprecated=False,
32+
graph_parallel=False,
3233
max_graph_workers=None, graph_timeout=None,
3334
allow_child_process=False, **kwargs):
3435
"""
@@ -40,6 +41,11 @@ def __init__(self, materials, propstore, materials_symbol_map=None,
4041
criteria (dict): criteria for Mongodb find() query specifying
4142
criteria for records to process
4243
source_name (str): identifier for record source
44+
include_deprecated (bool): True processes materials marked as
45+
deprecated via the "deprecated" field. False skips those materials.
46+
If an entry does not have the "deprecated" field, it will be processed.
47+
Note that False will create a logical "and" with any criteria specified
48+
in "criteria". Default: False
4349
graph_parallel (bool): True runs the graph algorithm in parallel with
4450
the number of workers specified by max_workers. Default: False (serial)
4551
Note: there will be no substantial speed-up from using a parallel
@@ -64,6 +70,17 @@ def __init__(self, materials, propstore, materials_symbol_map=None,
6470
self.materials = materials
6571
self.propstore = propstore
6672
self.criteria = criteria
73+
self.include_deprecated = include_deprecated
74+
if not include_deprecated:
75+
deprecated_filter = {
76+
"$or": [{"deprecated": {"$exists": False}},
77+
{"deprecated": False}]
78+
}
79+
if criteria:
80+
self.criteria = {'$and': [criteria, deprecated_filter]}
81+
else:
82+
self.criteria = deprecated_filter
83+
6784
self.materials_symbol_map = materials_symbol_map \
6885
or MPRester.mapping
6986
if source_name == "":
@@ -84,11 +101,12 @@ def __init__(self, materials, propstore, materials_symbol_map=None,
84101
props = list(self.materials_symbol_map.keys())
85102
props += ["task_id", "pretty_formula", "run_type", "is_hubbard",
86103
"pseudo_potential", "hubbards", "potcar_symbols", "oxide_type",
87-
"final_energy", "unit_cell_formula", "created_at"]
104+
"final_energy", "unit_cell_formula", "created_at", "deprecated"]
88105
props = list(set(props))
89106

90107
super(PropnetBuilder, self).__init__(source=materials,
91108
target=propstore,
109+
query=self.criteria,
92110
ufn=self.process,
93111
projection=props,
94112
**kwargs)
@@ -180,6 +198,9 @@ def process(self, item):
180198
aggregated_quantities = new_material.get_aggregated_quantities()
181199

182200
for symbol, quantity in aggregated_quantities.items():
201+
if symbol.name not in doc:
202+
# No new quantities were derived
203+
continue
183204
# Store mean and std dev for aggregated quantities
184205
sub_doc = {"mean": unumpy.nominal_values(quantity.value).tolist(),
185206
"std_dev": unumpy.std_devs(quantity.value).tolist(),
@@ -189,7 +210,8 @@ def process(self, item):
189210
doc[symbol.name].update(sub_doc)
190211

191212
doc.update({"task_id": item["task_id"],
192-
"pretty_formula": item.get("pretty_formula")})
213+
"pretty_formula": item.get("pretty_formula"),
214+
"deprecated": item.get("deprecated", False)})
193215
return jsanitize(doc, strict=True)
194216

195217

propnet/web/layouts_interactive.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,23 @@ def clear_data(n_clicks):
217217
)
218218
def evaluate(input_rows, data, aggregate):
219219

220-
quantities = [QuantityFactory.create_quantity(symbol_type=ROW_IDX_TO_SYMBOL_NAME[idx],
221-
value=ureg.parse_expression(row['Editable Value']),
222-
units=Registry("units").get(ROW_IDX_TO_SYMBOL_NAME[idx]))
223-
for idx, row in enumerate(input_rows) if row['Editable Value']]
220+
quantities = []
221+
222+
for idx, row in enumerate(input_rows):
223+
if row['Editable Value']:
224+
try:
225+
value = ureg.parse_expression(row['Editable Value'])
226+
units = Registry("units").get(ROW_IDX_TO_SYMBOL_NAME[idx])
227+
value.ito(units)
228+
except Exception:
229+
# Someone put an invalid value in the table
230+
# TODO: Make error known to the user
231+
raise PreventUpdate
232+
q = QuantityFactory.create_quantity(
233+
symbol_type=ROW_IDX_TO_SYMBOL_NAME[idx],
234+
value=value
235+
)
236+
quantities.append(q)
224237

225238
if data and len(data) > 0:
226239
quantities += json.loads(data, cls=MontyDecoder).values()

propnet/web/layouts_plot.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424

2525
from pymongo.errors import ServerSelectionTimeoutError
2626

27+
import logging
28+
29+
logger = logging.getLogger(__name__)
30+
2731
mpr = MPRester()
2832

2933
try:
@@ -213,9 +217,14 @@ def update_info_box(clickData, x_prop, y_prop, z_prop, color_prop):
213217
mpid = point['text']
214218
x = point['x']
215219
y = point['y']
216-
print(point)
217-
218-
s = mpr.get_structure_by_material_id(mpid)
220+
logger.debug(f"User clicked: {point}")
221+
222+
try:
223+
s = mpr.get_structure_by_material_id(mpid)
224+
except IndexError:
225+
logger.error(f"{mpid} cannot be found on MP. Database refresh needed?")
226+
return f"{mpid} cannot be found on Materials Project. " \
227+
f"It may have been deprecated. This error has been logged."
219228
formula = unicodeify(s.composition.reduced_formula)
220229

221230
info = f"""
@@ -333,26 +342,27 @@ def get_graph_data(x_prop, y_prop, z_prop, color_prop):
333342
props_to_get = [prop for prop in (x_prop, y_prop, z_prop, color_prop)
334343
if prop is not None]
335344

336-
data = CorrelationBuilder.get_data_from_quantity_db(store, *props_to_get,
337-
include_id=True)
345+
query_data = CorrelationBuilder.get_data_from_quantity_db(store, *props_to_get,
346+
include_id=True)
338347

339-
if len(data[x_prop]) == 0:
348+
if any(prop not in query_data for prop in props_to_get) or \
349+
any(len(query_data[prop]) == 0 for prop in props_to_get):
340350
return {'query_success': False}
341351

342352
data = {
343353
'query_success': True,
344-
'x': data[x_prop],
354+
'x': query_data[x_prop],
345355
'x_name': x_prop,
346-
'y': data[y_prop],
356+
'y': query_data[y_prop],
347357
'y_name': y_prop,
348-
'mpids': data['_id'],
358+
'mpids': query_data['_id'],
349359
'zoom': None,
350360
'color_range': None
351361
}
352362
if z_prop:
353-
data.update({'z': data[z_prop], 'z_name': z_prop, 'z_enabled': True})
363+
data.update({'z': query_data[z_prop], 'z_name': z_prop, 'z_enabled': True})
354364
if color_prop:
355-
data.update({'color': data[color_prop], 'color_name': color_prop, 'color_enabled': True})
365+
data.update({'color': query_data[color_prop], 'color_name': color_prop, 'color_enabled': True})
356366

357367
return data
358368

0 commit comments

Comments
 (0)