diff --git a/README.rst b/README.rst
index 3e8f3cbc..e224ceb3 100644
Binary files a/README.rst and b/README.rst differ
diff --git a/mpworks/check_snl/builders/base.py b/mpworks/check_snl/builders/base.py
index 5d8bd641..2ff34f48 100644
--- a/mpworks/check_snl/builders/base.py
+++ b/mpworks/check_snl/builders/base.py
@@ -1,10 +1,15 @@
-import sys, multiprocessing, time
-from mpworks.snl_utils.mpsnl import SNLGroup
+import multiprocessing
+import sys
+import time
+
+from init_plotly import py, stream_ids, categories
from matgendb.builders.core import Builder
from matgendb.builders.util import get_builder_log
-from mpworks.check_snl.utils import div_plus_mod
from pymatgen.analysis.structure_matcher import StructureMatcher, ElementComparator
-from init_plotly import py, stream_ids, categories
+
+from mpworks.check_snl.utils import div_plus_mod
+from mpworks.snl_utils.mpsnl import SNLGroup
+
if py is not None:
from plotly.graph_objs import *
@@ -66,7 +71,7 @@ def get_items(self, snls=None, snlgroups=None, ncols=None):
return self._snls.query(distinct_key='snl_id')
def process_item(self, item, index):
- nrow, ncol = index/self._ncols, index%self._ncols
+ nrow, ncol = index//self._ncols, index%self._ncols
snlgroups = {} # keep {snlgroup_id: SNLGroup} to avoid dupe queries
if isinstance(item, dict) and 'snlgroup_ids' in item:
for gid in item['snlgroup_ids']:
@@ -83,19 +88,19 @@ def _push_to_plotly(self):
heatmap_z = self._counter._getvalue() if not self._seq else self._counter
bar_x = self._mismatch_counter._getvalue() if not self._seq else self._mismatch_counter
md = self._mismatch_dict._getvalue() if not self._seq else self._mismatch_dict
- try:
- self._streams[0].write(Heatmap(z=heatmap_z))
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- _log.info('%r %r', exc_type, exc_value)
- _log.info('_push_to_plotly ERROR: heatmap=%r', heatmap_z)
- try:
- self._streams[1].write(Bar(x=bar_x))
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- _log.info('%r %r', exc_type, exc_value)
- _log.info('_push_to_plotly ERROR: bar=%r', bar_x)
- for k,v in md.iteritems():
+ try:
+ self._streams[0].write(Heatmap(z=heatmap_z))
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ _log.info('%r %r', exc_type, exc_value)
+ _log.info('_push_to_plotly ERROR: heatmap=%r', heatmap_z)
+ try:
+ self._streams[1].write(Bar(x=bar_x))
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ _log.info('%r %r', exc_type, exc_value)
+ _log.info('_push_to_plotly ERROR: bar=%r', bar_x)
+ for k, v in md.items():
if len(v) < 1: continue
try:
self._streams[2].write(Scatter(
@@ -103,7 +108,7 @@ def _push_to_plotly(self):
y=k, text='
'.join(v)
))
_log.info('_push_to_plotly: mismatch_dict[%r]=%r', k, v)
- self._mismatch_dict.update({k:[]}) # clean
+ self._mismatch_dict.update({k: []}) # clean
time.sleep(0.052)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
@@ -122,7 +127,7 @@ def _increase_counter(self, nrow, ncol, mismatch_dict):
for k in categories[self.checker_name]:
mc[categories[self.checker_name].index(k)] += len(mismatch_dict[k])
self._mismatch_counter = mc
- for k,v in mismatch_dict.iteritems():
+ for k,v in mismatch_dict.items():
self._mismatch_dict[k] += v
currow = self._counter[nrow]
currow[ncol] += 1
@@ -136,7 +141,7 @@ def _increase_counter(self, nrow, ncol, mismatch_dict):
if self._lock is not None: self._lock.release()
def finalize(self, errors):
- if py is not None: self._push_to_plotly()
+ if py is not None: self._push_to_plotly()
_log.info("%d items processed.", self._counter_total.value)
return True
diff --git a/mpworks/check_snl/builders/init_plotly.py b/mpworks/check_snl/builders/init_plotly.py
index 263d1bed..da8a6fa7 100644
--- a/mpworks/check_snl/builders/init_plotly.py
+++ b/mpworks/check_snl/builders/init_plotly.py
@@ -90,4 +90,4 @@
fig['layout'] = layout
py.plot(fig, filename='builder_stream', auto_open=False)
else:
- print 'plotly ImportError'
+ print('plotly ImportError')
diff --git a/mpworks/check_snl/check_snl.py b/mpworks/check_snl/check_snl.py
index 989df0d3..703ba187 100644
--- a/mpworks/check_snl/check_snl.py
+++ b/mpworks/check_snl/check_snl.py
@@ -36,16 +36,16 @@
)
num_ids_per_stream = 20000
-num_ids_per_stream_k = num_ids_per_stream/1000
+num_ids_per_stream_k = num_ids_per_stream//1000
num_snls = sma.snl.count()
num_snlgroups = sma.snlgroups.count()
num_pairs_per_job = 1000 * num_ids_per_stream
-num_pairs_max = num_snlgroups*(num_snlgroups-1)/2
+num_pairs_max = num_snlgroups*(num_snlgroups-1)//2
num_snl_streams = div_plus_mod(num_snls, num_ids_per_stream)
num_snlgroup_streams = div_plus_mod(num_snlgroups, num_ids_per_stream)
num_jobs = div_plus_mod(num_pairs_max, num_pairs_per_job)
-print num_snl_streams, num_snlgroup_streams, num_jobs
+print(num_snl_streams, num_snlgroup_streams, num_jobs)
checks = ['spacegroups', 'groupmembers', 'canonicals']
categories = [ 'SG Change', 'SG Default', 'PybTeX', 'Others' ]
@@ -113,7 +113,7 @@ def __iter__(self):
def _get_initial_pair(self, job_id):
N, J, M = num_snlgroups, job_id, num_pairs_per_job
i = int(N+.5-sqrt(N*(N-1)+.25-2*J*M))
- j = J*M-(i-1)*(2*N-i)/2+i+1
+ j = J*M-(i-1)*(2*N-i)//2+i+1
return Pair(i,j)
def next(self):
if self.num_pairs > num_pairs_per_job:
@@ -202,7 +202,7 @@ def init_plotly(args):
def check_snl_spacegroups(args):
"""check spacegroups of all available SNLs"""
- range_index = args.start / num_ids_per_stream
+ range_index = args.start // num_ids_per_stream
idxs = [range_index*2]
idxs += [idxs[0]+1]
s = [py.Stream(stream_ids[i]) for i in idxs]
@@ -242,7 +242,7 @@ def check_snl_spacegroups(args):
def check_snls_in_snlgroups(args):
"""check whether SNLs in each SNLGroup still match resp. canonical SNL"""
- range_index = args.start / num_ids_per_stream
+ range_index = args.start // num_ids_per_stream
idxs = [2*(num_snl_streams+range_index)]
idxs += [idxs[0]+1]
s = [py.Stream(stream_ids[i]) for i in idxs]
@@ -314,7 +314,7 @@ def analyze(args):
if args.t:
if args.fig_id == 42:
label_entries = filter(None, '
'.join(fig['data'][2]['text']).split('
'))
- pairs = map(make_tuple, label_entries)
+ pairs = list(map(make_tuple, label_entries))
grps = set(chain.from_iterable(pairs))
snlgrp_cursor = sma.snlgroups.aggregate([
{ '$match': {
@@ -326,7 +326,7 @@ def analyze(args):
snlgroup_keys = {}
for d in snlgrp_cursor:
snlgroup_keys[d['snlgroup_id']] = d['canonical_snl']['snlgroup_key']
- print snlgroup_keys[40890]
+ print(snlgroup_keys[40890])
sma2 = SNLMongoAdapter.from_file(
os.path.join(os.environ['DB_LOC'], 'materials_db.yaml')
)
@@ -353,7 +353,7 @@ def analyze(args):
'band_gap': band_gap, 'task_id': material['task_id'],
'volume_per_atom': volume_per_atom
}
- print snlgroup_data[40890]
+ print(snlgroup_data[40890])
filestem = 'mpworks/check_snl/results/bad_snlgroups_2_'
with open(filestem+'in_matdb.csv', 'wb') as f, \
open(filestem+'notin_matdb.csv', 'wb') as g:
@@ -402,7 +402,7 @@ def analyze(args):
rms_dist = matcher.get_rms_dist(primary_structure, secondary_structure)
if rms_dist is not None:
rms_dist_str = "({0:.3g},{1:.3g})".format(*rms_dist)
- print rms_dist_str
+ print(rms_dist_str)
row = [
category, composition,
primary_id, primary_sg_num,
@@ -420,13 +420,13 @@ def analyze(args):
out_fig = Figure()
badsnls_trace = Scatter(x=[], y=[], text=[], mode='markers', name='SG Changes')
bisectrix = Scatter(x=[0,230], y=[0,230], mode='lines', name='bisectrix')
- print 'pulling bad snls from plotly ...'
+ print('pulling bad snls from plotly ...')
bad_snls = OrderedDict()
for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']):
for snl_id in map(int, text.split('
')):
bad_snls[snl_id] = category
with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f:
- print 'pulling bad snls from database ...'
+ print('pulling bad snls from database ...')
mpsnl_cursor = sma.snl.find({
'snl_id': { '$in': bad_snls.keys() },
'about.projects': {'$ne': 'CederDahn Challenge'}
@@ -435,7 +435,7 @@ def analyze(args):
writer.writerow([
'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks', 'projects', 'authors'
])
- print 'writing bad snls to file ...'
+ print('writing bad snls to file ...')
for mpsnl_dict in mpsnl_cursor:
mpsnl = MPStructureNL.from_dict(mpsnl_dict)
row = [ mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key ]
@@ -450,8 +450,8 @@ def analyze(args):
badsnls_trace['y'].append(sf.get_spacegroup_number())
badsnls_trace['text'].append(mpsnl.snl_id)
if bad_snls[mpsnl.snl_id] == 'SG default':
- print sg_num, sf.get_spacegroup_number()
- print 'plotting out-fig ...'
+ print(sg_num, sf.get_spacegroup_number())
+ print('plotting out-fig ...')
out_fig['data'] = Data([bisectrix, badsnls_trace])
out_fig['layout'] = Layout(
showlegend=False, hovermode='closest',
@@ -467,7 +467,7 @@ def analyze(args):
ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True,
attempt_supercell=True, comparator=ElementComparator()
)
- print 'pulling data from plotly ...'
+ print('pulling data from plotly ...')
trace = Scatter(x=[], y=[], text=[], mode='markers', name='mismatches')
bad_snls = OrderedDict() # snlgroup_id : [ mismatching snl_ids ]
for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']):
@@ -475,7 +475,7 @@ def analyze(args):
for entry in text.split('
'):
fields = entry.split(':')
snlgroup_id = int(fields[0].split(',')[0])
- print snlgroup_id
+ print(snlgroup_id)
snlgrp_dict = sma.snlgroups.find_one({ 'snlgroup_id': snlgroup_id })
snlgrp = SNLGroup.from_dict(snlgrp_dict)
s1 = snlgrp.canonical_structure.get_primitive_structure()
@@ -483,7 +483,7 @@ def analyze(args):
for i, snl_id in enumerate(fields[1].split(',')):
mpsnl_dict = sma.snl.find_one({ 'snl_id': int(snl_id) })
if 'CederDahn Challenge' in mpsnl_dict['about']['projects']:
- print 'skip CederDahn: %s' % snl_id
+ print('skip CederDahn: %s' % snl_id)
continue
mpsnl = MPStructureNL.from_dict(mpsnl_dict)
s2 = mpsnl.structure.get_primitive_structure()
@@ -496,13 +496,13 @@ def analyze(args):
if len(bad_snls[snlgroup_id]) < 1:
bad_snls.pop(snlgroup_id, None)
with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f:
- print 'pulling bad snlgroups from database ...'
+ print('pulling bad snlgroups from database ...')
snlgroup_cursor = sma.snlgroups.find({
'snlgroup_id': { '$in': bad_snls.keys() },
})
writer = csv.writer(f)
writer.writerow(['snlgroup_id', 'snlgroup_key', 'mismatching snl_ids'])
- print 'writing bad snlgroups to file ...'
+ print('writing bad snlgroups to file ...')
for snlgroup_dict in snlgroup_cursor:
snlgroup = SNLGroup.from_dict(snlgroup_dict)
row = [
@@ -510,7 +510,7 @@ def analyze(args):
' '.join(bad_snls[snlgroup.snlgroup_id])
]
writer.writerow(row)
- print 'plotting out-fig ...'
+ print('plotting out-fig ...')
out_fig = Figure()
out_fig['data'] = Data([trace])
out_fig['layout'] = Layout(
@@ -544,11 +544,11 @@ def analyze(args):
snlgroup_id = start_id + d['x'][idx]
mismatch_snl_id, canonical_snl_id = d['text'][idx].split(' != ')
bad_snlgroups[snlgroup_id] = int(mismatch_snl_id)
- print errors
+ print(errors)
fig_data = fig['data'][-1]
fig_data['x'] = [ errors[color] for color in fig_data['marker']['color'] ]
filename = _get_filename()
- print filename
+ print(filename)
#py.plot(fig, filename=filename)
with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f:
mpsnl_cursor = sma.snl.find({ 'snl_id': { '$in': bad_snls.keys() } })
diff --git a/mpworks/check_snl/icsd.py b/mpworks/check_snl/icsd.py
index 4dadd5f8..9ecf76ea 100644
--- a/mpworks/check_snl/icsd.py
+++ b/mpworks/check_snl/icsd.py
@@ -10,8 +10,8 @@
for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']):
for line in text.split('
'):
before_colon, after_colon = line.split(':')
- snlgroup1, snlgroup2 = map(int, before_colon[1:-1].split(','))
+ snlgroup1, snlgroup2 = list(map(int, before_colon[1:-1].split(',')))
snls, icsd_matches = after_colon.split('->')
- snl1, snl2 = map(int, snls[2:-2].split(','))
+ snl1, snl2 = list(map(int, snls[2:-2].split(',')))
icsd, matches = icsd_matches.strip().split(' ')
writer.writerow([snlgroup1, snlgroup2, snl1, snl2, int(icsd), matches[1:-1]])
diff --git a/mpworks/check_snl/scripts/sg_changes_examples.py b/mpworks/check_snl/scripts/sg_changes_examples.py
index 466c2626..e3dad567 100644
--- a/mpworks/check_snl/scripts/sg_changes_examples.py
+++ b/mpworks/check_snl/scripts/sg_changes_examples.py
@@ -34,8 +34,8 @@ def _get_mp_link(mp_id):
fig = py.get_figure('tschaume',11)
df = DataFrame.from_dict(fig['data'][1]).filter(['x','y','text'])
grouped_x = df.groupby('x')
-print '|==============================='
-print '| old SG | close to bisectrix | far from bisectrix'
+print('|===============================')
+print('| old SG | close to bisectrix | far from bisectrix')
for n,g in grouped_x:
if g.shape[0] < 2: continue # at least two entries at same old SG
grouped_y = g.groupby('y')
@@ -50,9 +50,9 @@ def _get_mp_link(mp_id):
if ratios[0] > 0.2 or ratios[1] < 0.8: continue
snlgroup_ids = _get_snlgroup_id(first['text']), _get_snlgroup_id(last['text'])
mp_ids = _get_mp_id(snlgroup_ids[0]), _get_mp_id(snlgroup_ids[1])
- print '| %d | %d (%d) -> %d -> %s | %d (%d) -> %d -> %s' % (
+ print('| %d | %d (%d) -> %d -> %s | %d (%d) -> %d -> %s' % (
first['x'],
first['text'], first['y'], snlgroup_ids[0], _get_mp_link(mp_ids[0]),
last['text'], last['y'], snlgroup_ids[1], _get_mp_link(mp_ids[1])
- )
-print '|==============================='
+ ))
+print('|===============================')
diff --git a/mpworks/check_snl/scripts/sg_default_bad_snls_check.py b/mpworks/check_snl/scripts/sg_default_bad_snls_check.py
index 24345e9a..034fd592 100644
--- a/mpworks/check_snl/scripts/sg_default_bad_snls_check.py
+++ b/mpworks/check_snl/scripts/sg_default_bad_snls_check.py
@@ -119,4 +119,4 @@
nonvalid_snlids.append(snl['snl_id'])
else:
valid_snlids.append(snl['snl_id'])
-print len(valid_snlids), len(nonvalid_snlids)
+print(len(valid_snlids), len(nonvalid_snlids))
diff --git a/mpworks/drones/mp_vaspdrone.py b/mpworks/drones/mp_vaspdrone.py
index 3df970e5..5e4146ba 100644
--- a/mpworks/drones/mp_vaspdrone.py
+++ b/mpworks/drones/mp_vaspdrone.py
@@ -5,6 +5,8 @@
import pprint
import re
import traceback
+import warnings
+
from monty.io import zopen
from monty.os.path import zpath
from pymongo import MongoClient
@@ -66,16 +68,16 @@ def assimilate(self, path, launches_coll=None):
d["dir_name"] = get_block_part(d["dir_name_full"])
d["stored_data"] = {}
except:
- print 'COULD NOT GET DIR NAME'
+ print('COULD NOT GET DIR NAME')
pprint.pprint(d)
- print traceback.format_exc()
+ print(traceback.format_exc())
raise ValueError('IMPROPER PARSING OF {}'.format(path))
if not self.simulate:
# Perform actual insertion into db. Because db connections cannot
# be pickled, every insertion needs to create a new connection
# to the db.
- conn = MongoClient(self.host, self.port)
+ conn = MongoClient(self.host, self.port, connect=False)
db = conn[self.database]
if self.user:
db.authenticate(self.user, self.password)
@@ -101,8 +103,8 @@ def assimilate(self, path, launches_coll=None):
if ("task_id" not in d) or (not d["task_id"]):
d["task_id"] = "mp-{}".format(
db.counter.find_one_and_update(
- {"_id": "taskid"}, {"$inc": {"c": 1}}
- )["c"])
+ {"_id": "taskid"}, {"$inc": {"c": 1}})
+ ["c"])
logger.info("Inserting {} with taskid = {}"
.format(d["dir_name"], d["task_id"]))
elif self.update_duplicates:
@@ -166,7 +168,7 @@ def assimilate(self, path, launches_coll=None):
d['is_compatible'] = bool(mpc.process_entry(entry))
except:
traceback.print_exc()
- print 'ERROR in getting compatibility'
+ print('ERROR in getting compatibility')
d['is_compatible'] = None
@@ -215,7 +217,7 @@ def string_to_numlist(stringlist):
d['analysis'].update(update_doc)
d['calculations'][0]['output'].update(update_doc)
- coll.update_one({"dir_name": d["dir_name"]}, {'$set': d}, upsert=True)
+ coll.update_one({"dir_name": d["dir_name"]}, {'$set': d}, upsert=True)
return d["task_id"], d
else:
@@ -238,7 +240,7 @@ def process_fw(self, dir_name, d):
break
# custom Materials Project post-processing for FireWorks
- with zopen(zpath(os.path.join(dir_name, 'FW.json'))) as f:
+ with zopen(zpath(os.path.join(dir_name, 'FW.json')), 'rt') as f:
fw_dict = json.load(f)
d['fw_id'] = fw_dict['fw_id']
d['snl'] = fw_dict['spec']['mpsnl']
@@ -250,7 +252,9 @@ def process_fw(self, dir_name, d):
d['deformation_matrix'] = fw_dict['spec']['deformation_matrix']
d['original_task_id'] = fw_dict['spec']['original_task_id']
if not self.update_duplicates:
- if 'optimize structure' in d['task_type'] and 'output' in d:
+ if ('optimize structure' in d['task_type'] or
+ 'Triple Jump Relax' in d['task_type']) \
+ and 'output' in d:
# create a new SNL based on optimized structure
new_s = Structure.from_dict(d['output']['crystal'])
old_snl = StructureNL.from_dict(d['snl'])
@@ -275,6 +279,14 @@ def process_fw(self, dir_name, d):
d['snlgroup_id_final'] = snlgroup_id
d['snlgroup_changed'] = (d['snlgroup_id'] !=
d['snlgroup_id_final'])
+ if len(d["calculations"][-1]["output"]["ionic_steps"]) >= 3 and not d['snlgroup_changed']:
+ message = "The structure has been relaxed for >=3 step, however, final structure" \
+ "ends in the snlgroup with the initial group, please change either structure" \
+ "relax criteria or StructureMatcher tolerance"
+ if "NMR" not in mpsnl.projects:
+ warnings.warn(message)
+ else:
+ raise ValueError(message)
else:
d['snl_final'] = d['snl']
d['snlgroup_id_final'] = d['snlgroup_id']
@@ -309,7 +321,7 @@ def process_fw(self, dir_name, d):
vasp_signals['last_relax_dir'] = last_relax_dir
## see what error signals are present
- print "getting signals for dir :{}".format(last_relax_dir)
+ print("getting signals for dir :{}".format(last_relax_dir))
sl = SignalDetectorList()
sl.append(VASPInputsExistSignal())
diff --git a/mpworks/drones/signals.py b/mpworks/drones/signals.py
index 28ce3c65..ccc39c38 100644
--- a/mpworks/drones/signals.py
+++ b/mpworks/drones/signals.py
@@ -30,7 +30,7 @@ def string_list_in_file(s_list, filename, ignore_case=True):
"""
matches = set()
- with zopen(filename, 'r') as f:
+ with zopen(filename, 'rt') as f:
for line in f:
for s in s_list:
if (ignore_case and s.lower() in line.lower()) or s in line:
@@ -184,7 +184,7 @@ def detect(self, dir_name):
file_names = glob.glob("%s/*.error" % dir_name)
rx = re.compile(r'segmentation', re.IGNORECASE)
for file_name in file_names:
- with zopen(file_name, 'r') as f:
+ with zopen(file_name, 'rt') as f:
lines = f.readlines()
for line in lines:
if rx.search(line) is not None:
diff --git a/mpworks/dupefinders/dupefinder_vasp.py b/mpworks/dupefinders/dupefinder_vasp.py
index c27ed7a7..66ff2335 100644
--- a/mpworks/dupefinders/dupefinder_vasp.py
+++ b/mpworks/dupefinders/dupefinder_vasp.py
@@ -15,13 +15,10 @@ class DupeFinderVasp(DupeFinderBase):
_fw_name = 'Dupe Finder Vasp'
- def verify(self, spec1, spec2):
- # assert: task_type and snlgroup_id have already been checked through query
- return set(spec1.get('run_tags', [])) == set(spec2.get('run_tags', []))
-
def query(self, spec):
return {'spec.task_type': spec['task_type'],
- 'spec.snlgroup_id': spec['snlgroup_id']}
+ 'spec.snlgroup_id': spec['snlgroup_id'],
+ 'spec.run_tags': spec['run_tags']}
class DupeFinderDB(DupeFinderBase):
diff --git a/mpworks/examples/firetasks_ex.py b/mpworks/examples/firetasks_ex.py
index 39d6068a..d1f1fcbf 100644
--- a/mpworks/examples/firetasks_ex.py
+++ b/mpworks/examples/firetasks_ex.py
@@ -89,7 +89,7 @@ def run_task(self, fw_spec):
t_id = drone.assimilate(prev_dir)
if t_id:
- print 'ENTERED task id:', t_id
+ print('ENTERED task id:', t_id)
stored_data = {'task_id': t_id}
update_spec = {'prev_vasp_dir': prev_dir, 'prev_task_type': fw_spec['prev_task_type']}
return FWAction(stored_data=stored_data, update_spec=update_spec)
diff --git a/mpworks/firetasks/boltztrap_tasks.py b/mpworks/firetasks/boltztrap_tasks.py
index 9538fdad..46f3c642 100644
--- a/mpworks/firetasks/boltztrap_tasks.py
+++ b/mpworks/firetasks/boltztrap_tasks.py
@@ -162,13 +162,13 @@ def run_task(self, fw_spec):
nelect = m_task['calculations'][0]['input']['parameters']['NELECT']
bs_id = m_task['calculations'][0]['band_structure_fs_id']
- print bs_id, type(bs_id)
+ print(bs_id, type(bs_id))
fs = gridfs.GridFS(tdb, 'band_structure_fs')
bs_dict = json.loads(fs.get(bs_id).read())
bs_dict['structure'] = m_task['calculations'][0]['output']['crystal']
bs = BandStructure.from_dict(bs_dict)
- print 'Band Structure found:', bool(bs)
- print nelect
+ print('Band Structure found:', bool(bs))
+ print(nelect)
# run Boltztrap
runner = BoltztrapRunner(bs, nelect)
@@ -233,7 +233,7 @@ def run_task(self, fw_spec):
ted['kappa_best_dope19'] = self.get_extreme(ted, 'kappa_eigs', maximize=False, max_didx=4)
try:
- from mpcollab.thermoelectrics.boltztrap_TE import BoltzSPB
+ from mpcollab.thermoelectrics.boltztrap_TE import BoltzSPB
bzspb = BoltzSPB(ted)
maxpf_p = bzspb.get_maximum_power_factor('p', temperature=0, tau=1E-14, ZT=False, kappal=0.5,\
otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \
@@ -254,7 +254,7 @@ def run_task(self, fw_spec):
except:
import traceback
traceback.print_exc()
- print 'COULD NOT GET FINE MESH DATA'
+ print('COULD NOT GET FINE MESH DATA')
# add is_compatible
mpc = MaterialsProjectCompatibility("Advanced")
@@ -273,7 +273,7 @@ def run_task(self, fw_spec):
ted["is_compatible"] = bool(mpc.process_entry(entry))
except:
traceback.print_exc()
- print 'ERROR in getting compatibility, task_id: {}'.format(m_task["task_id"])
+ print('ERROR in getting compatibility, task_id: {}'.format(m_task["task_id"]))
ted["is_compatible"] = None
tdb.boltztrap.insert(jsanitize(ted))
diff --git a/mpworks/firetasks/controller_tasks.py b/mpworks/firetasks/controller_tasks.py
index 55425211..77072563 100644
--- a/mpworks/firetasks/controller_tasks.py
+++ b/mpworks/firetasks/controller_tasks.py
@@ -33,10 +33,10 @@ def __init__(self, parameters=None):
self.metal_cutoff = parameters.get('metal_cutoff', 0.05)
def run_task(self, fw_spec):
- print 'sleeping 10s for Mongo'
+ print('sleeping 10s for Mongo')
time.sleep(10)
- print 'done sleeping'
- print 'the gap is {}, the cutoff is {}'.format(fw_spec['analysis']['bandgap'], self.gap_cutoff)
+ print('done sleeping')
+ print('the gap is {}, the cutoff is {}'.format(fw_spec['analysis']['bandgap'], self.gap_cutoff))
if fw_spec['analysis']['bandgap'] >= self.gap_cutoff:
static_dens = 90
uniform_dens = 1000
@@ -51,7 +51,7 @@ def run_task(self, fw_spec):
else:
user_incar_settings = {}
- print 'Adding more runs...'
+ print('Adding more runs...')
type_name = 'GGA+U' if 'GGA+U' in fw_spec['prev_task_type'] else 'GGA'
@@ -123,7 +123,7 @@ def run_task(self, fw_spec):
wf = Workflow(fws, connections)
- print 'Done adding more runs...'
+ print('Done adding more runs...')
return FWAction(additions=wf)
@@ -145,13 +145,13 @@ def __init__(self, parameters=None):
self.gap_cutoff = parameters.get('gap_cutoff', 0.5) # see e-mail from Geoffroy, 5/1/2013
def run_task(self, fw_spec):
- print 'sleeping 10s for Mongo'
+ print('sleeping 10s for Mongo')
time.sleep(10)
- print 'done sleeping'
- print 'the gap is {}, the cutoff is {}'.format(fw_spec['analysis']['bandgap'], self.gap_cutoff)
+ print('done sleeping')
+ print('the gap is {}, the cutoff is {}'.format(fw_spec['analysis']['bandgap'], self.gap_cutoff))
if fw_spec['analysis']['bandgap'] >= self.gap_cutoff:
- print 'Adding more runs...'
+ print('Adding more runs...')
type_name = 'GGA+U' if 'GGA+U' in fw_spec['prev_task_type'] else 'GGA'
snl = fw_spec['mpsnl']
@@ -211,7 +211,7 @@ def run_task(self, fw_spec):
wf = Workflow(fws, connections)
- print 'Done adding more runs...'
+ print('Done adding more runs...')
return FWAction(additions=wf)
return FWAction()
diff --git a/mpworks/firetasks/custodian_task.py b/mpworks/firetasks/custodian_task.py
index c48f11da..fe156fd2 100644
--- a/mpworks/firetasks/custodian_task.py
+++ b/mpworks/firetasks/custodian_task.py
@@ -1,18 +1,22 @@
+import tarfile
+from glob import glob
from gzip import GzipFile
import logging
import socket
+import shutil
from fireworks.fw_config import FWData
from monty.os.path import which
from custodian.vasp.handlers import VaspErrorHandler, NonConvergingErrorHandler, \
- FrozenJobErrorHandler, MeshSymmetryErrorHandler, PositiveEnergyErrorHandler
+ FrozenJobErrorHandler, MeshSymmetryErrorHandler, PositiveEnergyErrorHandler, StdErrHandler
from custodian.vasp.validators import VasprunXMLValidator
from fireworks.core.firework import FireTaskBase, FWAction
from fireworks.utilities.fw_serializers import FWSerializable
-from custodian.custodian import Custodian
+from custodian.custodian import Custodian, CustodianError
from custodian.vasp.jobs import VaspJob
import shlex
import os
+import copy
from fireworks.utilities.fw_utilities import get_slug
from mpworks.workflows.wf_utils import j_decorate, ScancelJobStepTerminator
from pymatgen.io.vasp.inputs import Incar
@@ -29,7 +33,7 @@
def check_incar(task_type):
errors = []
incar = Incar.from_file("INCAR")
-
+
if 'deformed' in task_type:
if incar['ISIF'] != 2:
errors.append("Deformed optimization requires ISIF = 2")
@@ -45,10 +49,10 @@ def check_incar(task_type):
errors.append("LCHARG must be True for static runs")
if 'Uniform' in task_type and incar["ICHARG"] != 11:
- errors.append("ICHARG must be 11 for Uniform runs")
+ errors.append("ICHARG must be 11 for Uniform runs")
if 'band structure' in task_type and incar["ICHARG"] != 11:
- errors.append("ICHARG must be 11 for band structure runs")
+ errors.append("ICHARG must be 11 for band structure runs")
if 'GGA+U' in task_type:
# check LDAU
@@ -70,8 +74,6 @@ class VaspCustodianTask(FireTaskBase, FWSerializable):
def __init__(self, parameters):
self.update(parameters)
self.jobs = self['jobs']
- dec = MontyDecoder()
- self.handlers = map(dec.process_decoded, self['handlers'])
self.max_errors = self.get('max_errors', 1)
self.gzip_output = self.get('gzip_output', True)
@@ -130,10 +132,35 @@ def run_task(self, fw_spec):
logging.basicConfig(level=logging.DEBUG)
- c = Custodian(self.handlers, self.jobs, max_errors=self.max_errors, gzipped_output=False,
- validators=[VasprunXMLValidator()],
- terminate_func=terminate_func) # manual gzip
- custodian_out = c.run()
+ error_list = []
+ cus_ex = None
+
+ if "alt_cmds" in fw_env and fw_spec['task_type'] in fw_env["alt_cmds"]:
+ try:
+ logging.info("Initiate VASP calculations using alternate binaries")
+ all_errors = self._run_alt_vasp_cmd(terminate_func, v_exe, gv_exe,
+ fw_env.get("vasp_cmd", "vasp"),
+ fw_env.get("gvasp_cmd", "gvasp"),
+ fw_env["alt_cmds"][fw_spec['task_type']],
+ fw_env.get("input_rewind", True),
+ fw_spec['mpsnl'].structure)
+ error_list.extend(all_errors)
+ except Exception as ex:
+ cus_ex = ex
+ try:
+ all_errors = self._run_custodian(terminate_func)
+ error_list.extend(all_errors)
+ except Exception as ex:
+ cus_ex = ex
+
+ dynamic_wf = None
+ if cus_ex is not None:
+ if os.path.exists("std_err.txt") and \
+ self._is_kpts_parallel_chemical_shift_eligible(fw_spec):
+ from mpworks.firetasks.nmr_tasks import chemical_shift_spec_to_dynamic_kpt_average_wfs
+ dynamic_wf = chemical_shift_spec_to_dynamic_kpt_average_wfs(fw_spec)
+ else:
+ raise cus_ex
if self.gzip_output:
for f in os.listdir(os.getcwd()):
@@ -143,20 +170,116 @@ def run_task(self, fw_spec):
f_out.writelines(f_in)
os.remove(f)
- all_errors = set()
- for run in custodian_out:
- for correction in run['corrections']:
- all_errors.update(correction['errors'])
-
- stored_data = {'error_list': list(all_errors)}
+ stored_data = {'error_list': error_list}
update_spec = {'prev_vasp_dir': os.getcwd(),
'prev_task_type': fw_spec['task_type'],
'mpsnl': fw_spec['mpsnl'],
'snlgroup_id': fw_spec['snlgroup_id'],
'run_tags': fw_spec['run_tags'],
'parameters': fw_spec.get('parameters')}
+ for k in ['kpoint_tag', 'scf_vasp_dir', 'functional', 'total_kpts']:
+ if k in fw_spec:
+ update_spec[k] = fw_spec[k]
- return FWAction(stored_data=stored_data, update_spec=update_spec)
+ if dynamic_wf is None:
+ return FWAction(stored_data=stored_data, update_spec=update_spec)
+ else:
+ return FWAction(stored_data=stored_data, update_spec=update_spec,
+ detours=dynamic_wf)
+
+ def _is_kpts_parallel_chemical_shift_eligible(self, fw_spec):
+ if fw_spec['task_type'] == "NMR CS":
+ eh = StdErrHandler(output_filename="std_err.txt")
+ eh.check()
+ if set(eh.errors) & {'out_of_memory', 'seg_fault'}:
+ return True
+ return False
+
+
+ def _run_alt_vasp_cmd(self, terminate_func, v_exe, gv_exe, vasp_cmd,
+ gvasp_cmd, alt_cmds, input_rewind, structure):
+ error_list = []
+ cus_ex = None
+ for new_vasp_path in alt_cmds:
+ new_vasp_cmd = new_vasp_path["vasp_cmd"]
+ new_gvasp_cmd = new_vasp_path["gvasp_cmd"]
+ new_v_exe = shlex.split(" ".join(v_exe).replace(vasp_cmd, new_vasp_cmd))
+ new_gv_exe = shlex.split(" ".join(gv_exe).replace(gvasp_cmd, new_gvasp_cmd))
+ logging.info("Run VASP with binary from {}".format(os.path.dirname(new_vasp_cmd)))
+ for job in self.jobs:
+ # set the vasp command to the alternative binaries
+ job.vasp_cmd = new_v_exe
+ job.gamma_vasp_cmd = new_gv_exe
+
+ # backup the files for the last VASP binary run
+ error_file_prefix = "error"
+ error_num = max([0] + [int(f.split(".")[1])
+ for f in glob("{}.*.tar.gz".format(error_file_prefix))])
+ error_filename = "{}.{}.tar.gz".format(error_file_prefix, error_num)
+ binary_file_prefix = "binary"
+ binary_num = max([0] + [int(f.split(".")[1])
+ for f in glob("{}.*.tar.gz".format(binary_file_prefix))])
+ binary_filename = "{}.{}.tar.gz".format(binary_file_prefix, binary_num + 1)
+
+ with tarfile.open(binary_filename, "w:gz") as tar:
+ for fname in ["custodian.json", error_filename, "CONTCAR", "OUTCAR",
+ "vasp.out", "std_err.txt", "INCAR", "POSCAR", "KPOINTS"]:
+ for f in glob(fname):
+ tar.add(f)
+
+ for fname in ["OSZICAR", "vasp.out", "std_err.txt", "custodian.json",
+ "OUTCAR"]:
+ # remove old file before starting new calculations to
+ # avoid confuse custodian
+ if os.path.exists(fname):
+ os.remove(fname)
+
+ if input_rewind:
+ # rewind the input to every beginning
+ if os.path.exists("error.1.tar.gz") and os.path.isfile("error.1.tar.gz"):
+ # restore to initial input set
+ with tarfile.open("error.1.tar.gz", "r") as tf:
+ for filename in ["INCAR", "KPOINTS", "POSCAR"]:
+ tf.extract(filename)
+
+ if os.path.exists("CONTCAR"):
+ natoms = len(structure)
+ with open("CONTCAR") as f:
+ contcar_lines = f.readlines()
+ n_contcar_lines = len(contcar_lines)
+ if n_contcar_lines > natoms + 5:
+ # valid CONTCAR file
+ if os.path.exists("POSCAR"):
+ os.remove("POSCAR")
+ shutil.move("CONTCAR", "POSCAR")
+
+ # run the calculation
+ cus_ex = None
+ try:
+ all_errors = self._run_custodian(terminate_func)
+ error_list.extend(all_errors)
+ except Exception as ex:
+ cus_ex = ex
+ if cus_ex is None:
+ break
+ if cus_ex is not None:
+ raise cus_ex
+
+ return error_list
+
+ def _run_custodian(self, terminate_func):
+ dec = MontyDecoder()
+ h_dict = copy.deepcopy(self['handlers'])
+ handlers = list(map(dec.process_decoded, h_dict))
+ c = Custodian(handlers, self.jobs, max_errors=self.max_errors, gzipped_output=False,
+ validators=[VasprunXMLValidator()],
+ terminate_func=terminate_func) # manual gzip
+ custodian_out = c.run()
+ all_errors = set()
+ for run in custodian_out:
+ for correction in run['corrections']:
+ all_errors.update(correction['errors'])
+ return all_errors
@staticmethod
def _get_vasp_cmd_in_job_packing(fw_data, fw_env, mpi_cmd):
@@ -172,24 +295,22 @@ def _get_vasp_cmd_in_job_packing(fw_data, fw_env, mpi_cmd):
nodes_spec = {"srun": "--nodes {}".format(len(fw_data.NODE_LIST)),
"mpirun": "",
"aprun": ""}
- verbose_flag = {"srun": "-v",
- "mpirun": "",
- "aprun": ""}
mpirun = mpi_cmd.split()[0]
+ if "srun" in mpi_cmd:
+ mpi_cmd += " -v"
fw_data = FWData()
# Don't honor the SLURM_NTASKS in case of job packing, Because SLURM_NTASKS is referring
# to total number of processes of the parent job
sub_nproc = fw_data.SUB_NPROCS
vasp_cmds = [fw_env.get("vasp_cmd", "vasp"), fw_env.get("gvasp_cmd", "gvasp")]
- vasp_exes = [shlex.split('{mpi_cmd} {verbose_flag} {nodes_spec} {ranks_flag} {nproc} {tpn_flag} {tpn} '
+ vasp_exes = [shlex.split('{mpi_cmd} {nodes_spec} {ranks_flag} {nproc} {tpn_flag} {tpn} '
'{nl_flag} {nl} {vasp_cmd}'.
format(mpi_cmd=mpi_cmd,
- verbose_flag=verbose_flag,
nodes_spec=nodes_spec[mpirun],
ranks_flag=ranks_num_flag[mpirun],
nproc=sub_nproc,
tpn_flag=tasks_per_node_flag[mpirun],
- tpn=int(fw_data.SUB_NPROCS) / len(fw_data.NODE_LIST),
+ tpn=int(fw_data.SUB_NPROCS)//len(fw_data.NODE_LIST),
nl_flag=nodelist_flag[mpirun],
nl=','.join(fw_data.NODE_LIST),
vasp_cmd=vasp_cmd))
@@ -209,12 +330,21 @@ def _write_formula_file(fw_spec):
def get_custodian_task(spec):
task_type = spec['task_type']
v_exe = 'VASP_EXE' # will be transformed to vasp executable on the node
- handlers = [VaspErrorHandler(), FrozenJobErrorHandler(),
- MeshSymmetryErrorHandler(), NonConvergingErrorHandler(), PositiveEnergyErrorHandler()]
+ if {'NMR EFG', 'NMR CS', 'Triple Jump Relax S1',
+ 'Triple Jump Relax S2', 'Triple Jump Relax S3',
+ 'Pre Kpt CS SCF', 'Single Kpt CS'} & {task_type}:
+ handlers = [VaspErrorHandler(natoms_large_cell=50),
+ StdErrHandler(output_filename="std_err.txt")]
+ else:
+ handlers = [VaspErrorHandler()]
+ handlers += [FrozenJobErrorHandler(),
+ MeshSymmetryErrorHandler(), NonConvergingErrorHandler(), PositiveEnergyErrorHandler()]
if 'optimize structure (2x)' in task_type:
jobs = VaspJob.double_relaxation_run(v_exe)
- elif 'static' in task_type or 'deformed' in task_type:
+ elif {'static', 'deformed', 'NMR EFG', 'NMR CS', 'Triple Jump Relax S1',
+ 'Triple Jump Relax S2', 'Triple Jump Relax S3', 'Pre Kpt CS SCF',
+ 'Single Kpt CS'} & {task_type}:
jobs = [VaspJob(v_exe)]
else:
# non-SCF runs
diff --git a/mpworks/firetasks/elastic_tasks.py b/mpworks/firetasks/elastic_tasks.py
index 33bd1a4f..12372eae 100644
--- a/mpworks/firetasks/elastic_tasks.py
+++ b/mpworks/firetasks/elastic_tasks.py
@@ -148,9 +148,9 @@ def run_task(self, fw_spec):
"state":"successful"}).count()
existing_doc = elasticity.find_one({"relaxation_task_id" : i})
if existing_doc:
- print "Updating: " + i
+ print("Updating: " + i)
else:
- print "New material: " + i
+ print("New material: " + i)
d = {"analysis": {}, "error": [], "warning": []}
d["ndocs"] = ndocs
o = tasks.find_one({"task_id" : i},
@@ -178,8 +178,8 @@ def run_task(self, fw_spec):
"{:.0e}".format(delta)])
sm = IndependentStrain(defo)
if dtype in d["deformation_tasks"].keys():
- print "old_task: {}".format(d["deformation_tasks"][dtype]["task_id"])
- print "new_task: {}".format(k["task_id"])
+ print("old_task: {}".format(d["deformation_tasks"][dtype]["task_id"]))
+ print("new_task: {}".format(k["task_id"]))
raise ValueError("Duplicate deformation task in database.")
d["deformation_tasks"][dtype] = {"state" : k["state"],
"deformation_matrix" : defo,
diff --git a/mpworks/firetasks/nmr_tasks.py b/mpworks/firetasks/nmr_tasks.py
new file mode 100644
index 00000000..9ab34e39
--- /dev/null
+++ b/mpworks/firetasks/nmr_tasks.py
@@ -0,0 +1,670 @@
+import copy
+import hashlib
+import json
+import os
+
+import shutil
+import yaml
+from fireworks import FireTaskBase
+from fireworks.core.firework import FWAction, Firework, Workflow
+from fireworks.utilities.fw_serializers import FWSerializable
+from fireworks.utilities.fw_utilities import get_slug
+from monty.os.path import zpath
+from pymatgen.analysis.bond_valence import BVAnalyzer
+from pymatgen.io.vasp import Outcar, Kpoints
+from monty.io import zopen
+import re
+import math
+from pymatgen.analysis.nmr import NMRChemicalShiftNotation
+from pymatgen.io.vasp.sets import DictSet
+
+from mpworks.dupefinders.dupefinder_vasp import DupeFinderVasp
+from mpworks.firetasks.vasp_io_tasks import VaspToDBTask, VaspCopyTask
+from mpworks.firetasks.vasp_setup_tasks import SetupUnconvergedHandlerTask
+from mpworks.workflows.wf_settings import WFSettings
+from mpworks.workflows.wf_utils import get_loc
+
+__author__ = 'Xiaohui Qu'
+__copyright__ = 'Copyright 2016, The Materials Project'
+__version__ = '0.1'
+__maintainer__ = 'Xiaohui Qu'
+__email__ = 'xhqu1981@gmail.com'
+__date__ = 'May 31, 2016'
+
+
+"""
+This is modified from Wei Chen & Joseph Montoya's elastic_tasks.
+"""
+
+tri_val_elements = {"Ce", "Dy", "Er", "Eu", "Gd", "Ho", "Lu", "Nd", "Pm", "Pr", "Sm", "Tb", "Tm"}
+di_val_elements = {"Er", "Eu", "Yb"}
+
+def _get_nuclear_quadrupole_moment(element, nqm_dict, parameters):
+ if element not in nqm_dict:
+ return 0.0
+ d = nqm_dict[element]
+ if len(d) > 1:
+ prefered_isotopes = set(parameters.get("isotopes", []))
+ pi = prefered_isotopes & set(list(d.keys()))
+ if len(pi) == 1:
+ return d[list(pi)[0]]
+ if len(pi) >= 1:
+ raise ValueError("Multiple isotope is requested \"{}\", "
+ "please request only one for each elements".format(list(pi)))
+ isotopes = list(d.keys())
+ isotopes.sort(key=lambda x: int(x.split("-")[1]), reverse=False)
+ return d[isotopes[0]]
+ else:
+ return list(d.values())[0]
+
+
+def _config_dict_to_input_set(config_dict, structure, incar_enforce, parameters):
+ functional = parameters.get("functional", "PBE")
+ pot_map = {"PBE": "PBE", "SCAN": "PBE_52"}
+ potcar_functional = pot_map[functional]
+ trial_set = DictSet(structure, config_dict=config_dict,
+ user_incar_settings=incar_enforce,
+ potcar_functional=potcar_functional)
+ trial_potcar = trial_set.potcar
+ all_enmax = [sp.enmax for sp in trial_potcar]
+ all_eaug = [sp.eaug for sp in trial_potcar]
+ all_elements = [sp.element for sp in trial_potcar]
+ num_species = len(all_enmax)
+ processed_config_dict = copy.deepcopy(config_dict)
+ for k1, pot_values in [("ENCUT", all_enmax), ("ENAUG", all_eaug)]:
+ k2 = "{}_ENHANCE_RATIO".format(k1)
+ if k2 in config_dict["INCAR"]:
+ ratio = 1.0 + config_dict["INCAR"][k2]
+ processed_config_dict["INCAR"].pop(k2)
+ processed_config_dict["INCAR"][k1] = round(ratio * max(pot_values), 0)
+ if "ROPT_PER_ATOM" in config_dict["INCAR"]:
+ processed_config_dict["INCAR"].pop("ROPT_PER_ATOM")
+ processed_config_dict["INCAR"]["ROPT"] = \
+ [config_dict["INCAR"]["ROPT_PER_ATOM"]] * num_species
+ if "QUAD_EFG_MAP" in config_dict["INCAR"]:
+ nqm_map = processed_config_dict["INCAR"].pop("QUAD_EFG_MAP")
+ quad_efg = [_get_nuclear_quadrupole_moment(el, nqm_map, parameters) for el in all_elements]
+ processed_config_dict["INCAR"]["QUAD_EFG"] = quad_efg
+ vis = DictSet(structure, config_dict=processed_config_dict,
+ user_incar_settings=incar_enforce,
+ potcar_functional=potcar_functional)
+ return vis
+
+
+def _change_garden_setting():
+ db_dir = os.environ['DB_LOC']
+ db_path = os.path.join(db_dir, 'tasks_db.json')
+ with open(db_path) as f:
+ db_creds = json.load(f)
+ if 'prod' in db_creds['database']:
+ WFSettings().MOVE_TO_GARDEN_PROD = True
+ elif 'test' in db_creds['database']:
+ WFSettings().MOVE_TO_GARDEN_DEV = True
+ if 'nmr' not in WFSettings().GARDEN:
+ WFSettings().GARDEN = os.path.join(WFSettings().GARDEN, 'nmr')
+
+
+def _assign_potcar_valence(structure, potcar_dict):
+ st_elements = set([specie.symbol for specie in structure.species])
+ bva = BVAnalyzer()
+ valences = bva.get_valences(structure)
+ for val, val_elements in [[3, tri_val_elements],
+ [2, di_val_elements]]:
+ for el in sorted(val_elements & st_elements):
+ if "_" in potcar_dict[el]:
+ continue
+ el_indices = structure.indices_from_symbol(el)
+ cur_el_valences = {valences[i] for i in el_indices}
+ if len(cur_el_valences) == 1 and val in cur_el_valences:
+ potcar_dict[el] = "{el}_{val:d}".format(el=el, val=val)
+
+
+def snl_to_nmr_spec(structure, istep_triple_jump, parameters=None, additional_run_tags=()):
+ parameters = copy.deepcopy(parameters) if parameters else {}
+ spec = {'parameters': parameters}
+
+ module_dir = os.path.abspath(os.path.dirname(__file__))
+ if 1 <= istep_triple_jump <= 3:
+ config_file = os.path.join(module_dir, "triple_jump_relax_set.yaml")
+ config_key = "STEP{}".format(istep_triple_jump)
+ config_name = "Triple Jump Relax S{}".format(istep_triple_jump)
+ elif istep_triple_jump == -1:
+ # NMR Chemical Shit calculations
+ config_file = os.path.join(module_dir, "nmr_tensor_set.yaml")
+ config_key = "CS"
+ config_name = "NMR CS"
+ elif istep_triple_jump == -2:
+ # NMR Chemical Shit calculations
+ config_file = os.path.join(module_dir, "nmr_tensor_set.yaml")
+ config_key = "EFG"
+ config_name = "NMR EFG"
+ else:
+ raise ValueError("Unknow Step Index \"{}\"".format(istep_triple_jump))
+ with open(config_file) as f:
+ parent_config_dict = yaml.load(stream=f)
+ config_dict = parent_config_dict[config_key]
+ if len(structure) < 64:
+ par_num = 4
+ else:
+ par_num = 8
+ if config_name == "NMR CS":
+ incar_enforce = {'KPAR': par_num}
+ else:
+ incar_enforce = {'NPAR': par_num}
+ spec['run_tags'] = spec.get('run_tags', [])
+ spec['run_tags'].extend(additional_run_tags)
+ elements_in_structure = set([sp.symbol for sp in structure.species])
+ if elements_in_structure & \
+ (tri_val_elements | di_val_elements):
+ _assign_potcar_valence(structure, config_dict["POTCAR"])
+ if not elements_in_structure <= set(config_dict["POTCAR"].keys()):
+ missing_elements = elements_in_structure - set(config_dict["POTCAR"].keys())
+ raise ValueError("Element {} is not available in config dict".format(missing_elements))
+
+ mpvis = _config_dict_to_input_set(config_dict, structure,
+ incar_enforce, parameters=parameters)
+ incar = mpvis.incar
+ poscar = mpvis.poscar
+ potcar = mpvis.potcar
+
+ spec["input_set_config_dict"] = mpvis.config_dict
+ spec["input_set_incar_enforce"] = incar_enforce
+ spec["custodian_default_input_set"] = mpvis
+
+ # Add run tags of pseudopotential
+ spec['run_tags'] = spec.get('run_tags', [potcar.functional])
+ spec['run_tags'].extend(potcar.symbols)
+
+ # Add run tags of +U
+ u_tags = ['%s=%s' % t for t in
+ zip(poscar.site_symbols, incar.get('LDAUU', [0] * len(poscar.site_symbols)))]
+ spec['run_tags'].extend(u_tags)
+
+ # add user run tags
+ if 'run_tags' in parameters:
+ spec['run_tags'].extend(parameters['run_tags'])
+ del spec['parameters']['run_tags']
+
+ spec['_dupefinder'] = DupeFinderVasp().to_dict()
+ spec['task_type'] = config_name
+ spec['vaspinputset_name'] = config_name + ' DictSet'
+
+ return spec
+
+def chemical_shift_spec_to_dynamic_kpt_average_wfs(fw_spec):
+ no_jobs_spec = copy.deepcopy(fw_spec)
+ no_jobs_spec.pop('jobs', None)
+ no_jobs_spec.pop('handlers', None)
+ no_jobs_spec.pop('max_errors', None)
+ no_jobs_spec.pop('_tasks', None)
+ no_jobs_spec.pop('custodian_default_input_set', None)
+ no_jobs_spec.pop('prev_task_type', None)
+ no_jobs_spec.pop('prev_vasp_dir', None)
+ no_jobs_spec.pop('task_type', None)
+ no_jobs_spec.pop('vaspinputset_name', None)
+ nick_name = no_jobs_spec['parameters']['nick_name']
+ priority = no_jobs_spec['_priority']
+
+ cur_fwid = -1
+ fws = []
+
+ # Pre Single Kpt CS SCF Task
+ scf_spec = copy.deepcopy(no_jobs_spec)
+ for k in ["DQ", "ICHIBARE", "LCHIMAG", "LNMR_SYM_RED", "NSLPLINE"]:
+ scf_spec['input_set_config_dict']['INCAR'].pop(k, None)
+ scf_spec['input_set_config_dict']['INCAR']['ISMEAR'] = 0
+ scf_spec['input_set_config_dict']['INCAR']['LCHARG'] = True
+ scf_spec['input_set_incar_enforce'] = {"NPAR": fw_spec['input_set_incar_enforce']["KPAR"]}
+ scf_spec['task_type'] = 'Pre Kpt CS SCF'
+ scf_spec['vaspinputset_name'] = scf_spec['task_type'] + " DictSet"
+ scf_spec['prev_task_type'] = fw_spec['task_type']
+ scf_spec['prev_vasp_dir'] = os.getcwd()
+ scf_tasks = [DictVaspSetupTask()]
+ functional = scf_spec["functional"]
+ if functional != "PBE":
+ scf_tasks.append(ScanFunctionalSetupTask())
+ from mpworks.firetasks.custodian_task import get_custodian_task
+ scf_tasks.append(get_custodian_task(scf_spec))
+ scf_tasks.append(TagFileChecksumTask({"files": ["CHGCAR"]}))
+ scf_vasp_fwid = cur_fwid
+ cur_fwid -= 1
+ vasp_fw = Firework(scf_tasks, scf_spec, name=get_slug(nick_name + '--' + scf_spec['task_type']),
+ fw_id=scf_vasp_fwid)
+ fws.append(vasp_fw)
+
+ scf_db_fwid = cur_fwid
+ cur_fwid -= 1
+ scf_db_type_class = VaspToDBTask
+ from mpworks.workflows.snl_to_wf_nmr import get_nmr_db_fw
+ scf_db_fw = get_nmr_db_fw(nick_name=nick_name, fwid=scf_db_fwid, prev_task_type=scf_spec['task_type'],
+ priority=priority, task_class=scf_db_type_class)
+ fws.append(scf_db_fw)
+
+ # Single Kpt CS Generation
+ gen_spec = copy.deepcopy(no_jobs_spec)
+ gen_spec['input_set_config_dict']['INCAR']['ISMEAR'] = 0
+ gen_spec['input_set_config_dict']['INCAR']['ICHARG'] = 11
+ gen_spec['task_type'] = 'Single Kpt CS Generation'
+ gen_spec['vaspinputset_name'] = gen_spec['task_type'] + " DictSet"
+ gen_tasks = [ChemicalShiftKptsAverageGenerationTask()]
+ gen_fwid = cur_fwid
+ cur_fwid -= 1
+ gen_fw = Firework(gen_tasks, gen_spec,
+ name=get_slug(nick_name + '--' + gen_spec['task_type']),
+ fw_id=gen_fwid)
+ fws.append(gen_fw)
+ connections = {scf_vasp_fwid: scf_db_fwid,
+ scf_db_fwid: gen_fwid}
+ wf = Workflow(fws, connections)
+ return wf
+
+
+class NmrVaspToDBTask(VaspToDBTask):
+ _fw_name = "NMR Tensor to Database Task"
+
+ def __init__(self, parameters=None):
+ super(NmrVaspToDBTask, self).__init__(parameters)
+
+ def run_task(self, fw_spec):
+ _change_garden_setting()
+ prev_dir = get_loc(fw_spec['prev_vasp_dir'])
+ outcar = Outcar(zpath(os.path.join(prev_dir, "OUTCAR")))
+ prev_task_type = fw_spec['prev_task_type']
+ nmr_fields = dict()
+ update_spec = None
+ if prev_task_type == "NMR CS":
+ outcar.read_chemical_shifts()
+ cs_fiels = {"chemical_shifts": [x.as_dict() for x in outcar.data["chemical_shifts"]["valence_only"]]}
+ nmr_fields.update(cs_fiels)
+ elif prev_task_type == "Single Kpt CS":
+ update_spec = dict()
+ update_spec["total_kpts"] = fw_spec['total_kpts']
+ update_spec['scf_vasp_dir'] = fw_spec['scf_vasp_dir']
+ cs_kpt_name = fw_spec['kpoint_tag']
+ update_spec[cs_kpt_name] = dict()
+ update_spec[cs_kpt_name]["kpt_vasp_dir"] = prev_dir
+ outcar.read_chemical_shifts()
+ update_spec[cs_kpt_name]["chemical_shifts"] = outcar.data["chemical_shifts"]
+ elif prev_task_type == 'Single Kpt CS Collect':
+ for k in ['chemical_shifts', 'manual_kpt_average', 'rmsd',
+ 'rmsd_header', 'manual_kpt_data']:
+ nmr_fields[k] = fw_spec[k]
+ sub_dir_name = "fake_nmr_vasp_files"
+ shutil.copytree(prev_dir, sub_dir_name)
+ for fn in ["CHGCAR", "CHGCAR.gz"]:
+ ffn = os.path.join(sub_dir_name, fn)
+ if os.path.exists(ffn):
+ os.remove(ffn)
+ fake_prev_dir = os.path.abspath(sub_dir_name)
+ fw_spec['prev_vasp_dir'] = fake_prev_dir
+ with zopen(zpath(os.path.join(fake_prev_dir, 'FW.json')), 'rt') as f:
+ fw_dict = json.load(f)
+ fw_dict["spec"]["task_type"] = "NMR CS"
+ with zopen(zpath(os.path.join(fake_prev_dir, 'FW.json')), 'wt') as f:
+ json.dump(fw_dict, f, sort_keys=True, indent=4)
+ elif prev_task_type == "NMR EFG":
+ outcar.read_nmr_efg()
+ efg_fields = {"efg": outcar.data["efg"]}
+ nmr_fields.update(efg_fields)
+ else:
+ raise ValueError("Unsupported Task Type: \"{}\"".format(prev_task_type))
+ self.additional_fields.update(nmr_fields)
+ m_action = super(NmrVaspToDBTask, self).run_task(fw_spec)
+ if update_spec is not None:
+ update_spec.update(m_action.update_spec)
+ m_action.update_spec = update_spec
+ return m_action
+
+
+class TripleJumpRelaxVaspToDBTask(VaspToDBTask):
+ _fw_name = "Triple Jump Relax to Database Task"
+
+ def __init__(self, parameters=None):
+ super(TripleJumpRelaxVaspToDBTask, self).__init__(parameters)
+
+ def run_task(self, fw_spec):
+ _change_garden_setting()
+ return super(TripleJumpRelaxVaspToDBTask, self).run_task(fw_spec)
+
+
+class SetupTripleJumpRelaxS3UnconvergedHandlerTask(SetupUnconvergedHandlerTask):
+ _fw_name = "Triple Jump Relax S3 Unconverged Handler Task"
+
+ def run_task(self, fw_spec):
+ module_dir = os.path.abspath(os.path.dirname(__file__))
+ config_file = os.path.join(module_dir, "triple_jump_relax_set.yaml")
+ config_key = "STEP_DYNA3"
+ with open(config_file) as f:
+ parent_config_dict = yaml.load(stream=f)
+ config_dict = parent_config_dict[config_key]
+ incar_update = config_dict["INCAR"]
+ actions = [{"dict": "INCAR",
+ "action": {"_set": incar_update}}]
+ from custodian.vasp.interpreter import VaspModder
+ VaspModder().apply_actions(actions)
+ parent_action = super(SetupTripleJumpRelaxS3UnconvergedHandlerTask, self).run_task(fw_spec)
+ return parent_action
+
+
+class DictVaspSetupTask(FireTaskBase, FWSerializable):
+ _fw_name = "Dict Vasp Input Setup Task"
+
+ def __init__(self, parameters=None):
+ parameters = parameters if parameters else {}
+ default_files = ["INCAR", "POSCAR", "POTCAR", "KPOINTS"]
+ self.update(parameters)
+ self.files = parameters.get("files", default_files)
+
+ @staticmethod
+ def _sort_structure_by_encut(structure, config_dict):
+ # put the larger ENMAX specie first
+ trial_vis = DictSet(structure, config_dict=config_dict)
+ trial_potcar = trial_vis.potcar
+ enmax_dict = {p.symbol.split("_")[0]: p.keywords["ENMAX"] + p.keywords["ENMIN"] * 1.0E-3
+ for p in trial_potcar}
+ structure = structure.get_sorted_structure(key=lambda site: enmax_dict[site.specie.symbol], reverse=True)
+ return structure
+
+ @staticmethod
+ def _reorder_nqm(vis, parameters):
+ incar = vis.incar
+ old_quad_efg_set = set(incar["QUAD_EFG"])
+ module_dir = os.path.abspath(os.path.dirname(__file__))
+ config_file = os.path.join(module_dir, "nmr_tensor_set.yaml")
+ with open(config_file) as f:
+ parent_config_dict = yaml.load(stream=f)
+ nqm_map = parent_config_dict["EFG"]["INCAR"]["QUAD_EFG_MAP"]
+ all_elements = [sp.element for sp in vis.potcar]
+ quad_efg = [_get_nuclear_quadrupole_moment(el, nqm_map, parameters) for el in all_elements]
+ incar["QUAD_EFG"] = quad_efg
+ assert old_quad_efg_set == set(incar["QUAD_EFG"])
+ return incar
+
+ def run_task(self, fw_spec):
+ config_dict = fw_spec["input_set_config_dict"]
+ incar_enforce = fw_spec["input_set_incar_enforce"]
+ mpsnl = fw_spec["mpsnl"]
+ structure = self._sort_structure_by_encut(mpsnl.structure, config_dict)
+ vis = DictSet(structure, config_dict=config_dict,
+ user_incar_settings=incar_enforce,
+ sort_structure=False)
+ if "INCAR" in self.files:
+ incar = vis.incar
+ if fw_spec["task_type"] == "NMR EFG":
+ incar = self._reorder_nqm(vis, fw_spec["parameters"])
+ incar.write_file("INCAR")
+ if "POSCAR" in self.files:
+ vis.poscar.write_file("POSCAR")
+ if "POTCAR" in self.files:
+ vis.potcar.write_file("POTCAR")
+ if "KPOINTS" in self.files:
+ if "kpoints_enforce" not in fw_spec:
+ vis.kpoints.write_file("KPOINTS")
+ else:
+ fw_spec["kpoints_enforce"].write_file("KPOINTS")
+ return FWAction(stored_data={"vasp_input_set": vis.as_dict()})
+
+
+class ScanFunctionalSetupTask(FireTaskBase, FWSerializable):
+ """
+ This class is to setup the SCAN functional calculation for the
+ hack version of VASP. If official SCAN functional supported VASP
+ is release, the run_task() method body can be set to "pass". It
+ will make the workflow compatible with the new VASP version.
+ """
+ _fw_name = "SCAN Functional Setup Task"
+
+ def run_task(self, fw_spec):
+ functional = fw_spec.get("functional", "PBE")
+ if functional == "SCAN":
+ incar_update = {"METAGGA": "Rtpss",
+ "LASPH": True}
+ actions = [{"dict": "INCAR",
+ "action": {"_set": incar_update}}]
+ from custodian.vasp.interpreter import VaspModder
+ VaspModder().apply_actions(actions)
+
+ # guarantee VASP is the hacked version
+ fw_env = fw_spec.get("_fw_env", {})
+ vasp_cmd = fw_env.get("vasp_cmd", "vasp")
+ if os.path.exists(vasp_cmd):
+ vasp_path = vasp_cmd
+ else:
+ vasp_path = shutil.which("vasp")
+ hacked_path = "/global/common/matgen/das/vasp/5.3.5-scan-beta/bin/vasp"
+ if vasp_path != hacked_path:
+ my_name = str(self.__class__).replace("", "")
+ raise ValueError("'{}' is designed to support the hack of VASP, "
+ "upon official release of VASP SCAN function, this class"
+ "should be modified".format(my_name))
+ else:
+ pass
+
+
+class ChemicalShiftKptsAverageGenerationTask(FireTaskBase, FWSerializable):
+ """
+ This class is to spawn the dynamical fws to calculate NMR chemical shfit on each
+ individual and then do K-points weighted average manually.
+ """
+ _fw_name = "Chemical Shift K-Points Average Generation Task"
+
+ def run_task(self, fw_spec):
+ no_jobs_spec = copy.deepcopy(fw_spec)
+ no_jobs_spec.pop('jobs', None)
+ no_jobs_spec.pop('handlers', None)
+ no_jobs_spec.pop('max_errors', None)
+ no_jobs_spec.pop('_tasks', None)
+ no_jobs_spec.pop('custodian_default_input_set', None)
+ no_jobs_spec.pop('task_type', None)
+ no_jobs_spec.pop('vaspinputset_name', None)
+ nick_name = no_jobs_spec['parameters']['nick_name']
+ priority = no_jobs_spec['_priority']
+ no_jobs_spec['input_set_config_dict']['INCAR']['ISMEAR'] = 0
+ no_jobs_spec['input_set_config_dict']['INCAR']['ICHARG'] = 11
+ no_jobs_spec['input_set_incar_enforce'] = {"KPAR": 1}
+ no_jobs_spec['task_type'] = 'Single Kpt CS'
+ no_jobs_spec['vaspinputset_name'] = no_jobs_spec['task_type'] + " DictSet"
+ no_jobs_spec["scf_vasp_dir"] = fw_spec['prev_vasp_dir']
+
+ fws = []
+ connections = dict()
+ db_fwids = []
+ cur_fwid = -1
+ prev_dir = get_loc(fw_spec['prev_vasp_dir'])
+ scf_kpoint_filename = zpath(os.path.join(prev_dir, 'IBZKPT'))
+ whole_kpts = Kpoints.from_file(scf_kpoint_filename)
+ no_jobs_spec['total_kpts'] = len(whole_kpts.kpts)
+
+ for (i, kpt) in enumerate(whole_kpts.kpts):
+ kweight = int(whole_kpts.kpts_weights[i])
+ task_tag = "kpt_#{:d}_weight_{:d}".format(i + 1, kweight)
+ comment = "Individual {}th Kpoint for CS Calculation".format(i + 1)
+ cur_kpoints = Kpoints(comment=comment, num_kpts=1,
+ style=Kpoints.supported_modes.Reciprocal,
+ kpts=[kpt], kpts_weights=[1],
+ tet_number=0)
+
+ # Individual K-Point Chemical Shift VASP
+ kpt_cs_spec = copy.deepcopy(no_jobs_spec)
+ kpt_cs_spec['run_tags'].append(task_tag)
+ kpt_cs_spec['kpoints_enforce'] = cur_kpoints
+ kpt_cs_spec["kpoint_tag"] = task_tag
+
+ kpt_cs_tasks = [DictVaspSetupTask({'files': ['INCAR', "KPOINTS"]}),
+ VaspCopyTask({'files': ['CHGCAR', "POTCAR"],
+ 'use_CONTCAR': True,
+ 'keep_velocities': False})]
+ functional = kpt_cs_spec["functional"]
+ if functional != "PBE":
+ kpt_cs_tasks.append(ScanFunctionalSetupTask())
+ kpt_cs_tasks.append(TagFileChecksumTask({"files": ["CHGCAR"]}))
+ from mpworks.firetasks.custodian_task import get_custodian_task
+ kpt_cs_tasks.append(get_custodian_task(kpt_cs_spec))
+ kpt_cs_tasks.append(DeleteFileTask({"files": ["CHGCAR"]}))
+ kpt_cs_task_name = get_slug(nick_name + '--' + kpt_cs_spec['task_type'] + "--#{}".format(i))
+ kpt_cs_vasp_fwid = cur_fwid # Links
+ cur_fwid -= 1
+ vasp_fw = Firework(kpt_cs_tasks, kpt_cs_spec, name=kpt_cs_task_name,
+ fw_id=kpt_cs_vasp_fwid)
+ fws.append(vasp_fw)
+
+ # Individual K-Point Chemical Shift VASP DB Insertion
+ kpt_cs_db_fwid = cur_fwid # Links
+ cur_fwid -= 1
+ kpt_cs_db_type_class = NmrVaspToDBTask
+ from mpworks.workflows.snl_to_wf_nmr import get_nmr_db_fw
+ kpt_cs_db_fw = get_nmr_db_fw(nick_name=nick_name, fwid=kpt_cs_db_fwid,
+ prev_task_type=kpt_cs_spec['task_type'],
+ priority=priority, task_class=kpt_cs_db_type_class)
+ fws.append(kpt_cs_db_fw)
+ connections[kpt_cs_vasp_fwid] = kpt_cs_db_fwid
+ db_fwids.append(kpt_cs_db_fwid)
+
+ # K-Points Average Collect
+ collect_spec = copy.deepcopy(no_jobs_spec)
+ collect_spec['task_type'] = 'Single Kpt CS Collect'
+ collect_spec['vaspinputset_name'] = collect_spec['task_type'] + " DictSet"
+ collect_tasks = [ChemicalShiftKptsAverageCollectTask()]
+ collect_fwid = cur_fwid
+ cur_fwid -= 1
+ collect_fw = Firework(collect_tasks, collect_spec,
+ name=get_slug(nick_name + '--' + collect_spec['task_type']),
+ fw_id=collect_fwid)
+ fws.append(collect_fw)
+ for dbid in db_fwids:
+ connections[dbid] = collect_fwid
+ wf = Workflow(fws, connections)
+ update_spec = {'total_kpts': no_jobs_spec['total_kpts'],
+ "scf_vasp_dir": fw_spec['prev_vasp_dir'],
+ 'prev_vasp_dir': fw_spec['prev_vasp_dir'],
+ 'prev_task_type': fw_spec['task_type']}
+ stored_data = {'total_kpts': no_jobs_spec['total_kpts'],
+ "scf_vasp_dir": fw_spec['prev_vasp_dir']}
+ return FWAction(update_spec=update_spec, stored_data=stored_data,
+ detours=wf)
+
+class ChemicalShiftKptsAverageCollectTask(FireTaskBase, FWSerializable):
+ """
+ This class do K-points weighted chemical shift average from the previous K-points
+ specific calculations.
+ """
+ _fw_name = "Chemical Shift K-Points Average Collect Task"
+
+ def run_task(self, fw_spec):
+ kpt_name_pattern = re.compile(r'kpt_#(?P\d+)_weight_(?P\d+)')
+ kpt_name_weigths = []
+ for kpt_name in fw_spec.keys():
+ m = kpt_name_pattern.match(kpt_name)
+ if m:
+ kpt_weight = m.group("weight")
+ kpt_name_weigths.append([kpt_name, kpt_weight])
+ num_kpts = fw_spec["total_kpts"]
+ assert len(kpt_name_weigths) == num_kpts
+ num_atoms = len(fw_spec[kpt_name_weigths[0][0]]['chemical_shifts']['valence_only'])
+ num_ave_components = 7
+ atom_cs_weight_vo_vc = [[list() for _ in range(num_ave_components)]
+ for _ in range(num_atoms)]
+ for i_kpt, (kpt_name, weight) in enumerate(kpt_name_weigths):
+ kpt_cs = fw_spec[kpt_name]['chemical_shifts']
+ for i_atom in range(num_atoms):
+ vo_tensor_notation = NMRChemicalShiftNotation.from_dict(kpt_cs['valence_only'][i_atom])
+ vc_tensor_notation = NMRChemicalShiftNotation.from_dict(kpt_cs['valence_and_core'][i_atom])
+ val_only_tensor_pas = vo_tensor_notation.mehring_values[1:4]
+ val_core_tensor_pas = vc_tensor_notation.mehring_values[1:4]
+ components = (float(weight),) + val_only_tensor_pas + val_core_tensor_pas
+ for i_comp in range(num_ave_components):
+ atom_cs_weight_vo_vc[i_atom][i_comp].append(components[i_comp])
+ for i_atom in range(num_atoms):
+ for i_comp in range(num_ave_components):
+ assert len(atom_cs_weight_vo_vc[i_atom][i_comp]) == num_kpts
+ ave_pas_tensors = []
+ tensor_rmsd = []
+ for i_atom in range(num_atoms):
+ atom_ave_tensor = []
+ atom_tensor_rmsd = []
+ for i_comp in range(1, num_ave_components):
+ sum_value = sum([weight * tensor for weight, tensor
+ in zip(atom_cs_weight_vo_vc[i_atom][0],
+ atom_cs_weight_vo_vc[i_atom][i_comp])])
+ sum_weights = sum(atom_cs_weight_vo_vc[i_atom][0])
+ ave_value = sum_value / sum_weights
+ atom_ave_tensor.append(ave_value)
+ sum_square_dev = sum([weight * ((tensor - ave_value) ** 2) for weight, tensor
+ in zip(atom_cs_weight_vo_vc[i_atom][0],
+ atom_cs_weight_vo_vc[i_atom][i_comp])])
+ rmsd_value = math.sqrt(sum_square_dev / sum_weights)
+ atom_tensor_rmsd.append(rmsd_value)
+ ave_pas_tensors.append(atom_ave_tensor)
+ tensor_rmsd.append(atom_tensor_rmsd)
+ ave_tensor_notations = {"valence_only": [], 'valence_and_core': []}
+ for pas in ave_pas_tensors:
+ assert len(pas) == 6
+ for comp_indices, comp_key in [[range(0, 3), "valence_only"],
+ [range(3, 6), 'valence_and_core']]:
+ sigmas = [pas[i] for i in comp_indices]
+ notation = NMRChemicalShiftNotation(*sigmas)
+ ave_tensor_notations[comp_key].append(notation.as_dict())
+ single_kpt_vasp_calcs = {kpt_name: fw_spec[kpt_name] for kpt_name, weight
+ in kpt_name_weigths}
+ cs_fields = {"chemical_shifts": ave_tensor_notations,
+ "manual_kpt_average": True,
+ "rmsd": tensor_rmsd,
+ "rmsd_header": ["valence_only_11", "valence_only_22", "valence_only_33",
+ "valence_and_core_11", "valence_and_core_22", "valence_and_core_33"],
+ "manual_kpt_data": {
+ "total_kpts": fw_spec["total_kpts"],
+ "single_kpt_vasp_calcs": single_kpt_vasp_calcs
+ }}
+ stored_data = copy.deepcopy(cs_fields)
+ update_spec = copy.deepcopy(cs_fields)
+ update_spec['prev_task_type'] = fw_spec['task_type']
+ update_spec['prev_vasp_dir'] = fw_spec['scf_vasp_dir']
+ for k in ['scf_vasp_dir', 'functional']:
+ update_spec[k] = fw_spec[k]
+ return FWAction(stored_data=stored_data, update_spec=update_spec)
+
+class TagFileChecksumTask(FireTaskBase, FWSerializable):
+
+ _fw_name = "Tag File Checksum Task"
+
+ def __init__(self, parameters=None):
+ parameters = parameters if parameters else {}
+ default_files = ["CHGCAR", "WAVCAR"]
+ self.update(parameters)
+ self.files = parameters.get("files", default_files)
+
+ def run_task(self, fw_spec):
+ file_checksums = dict()
+ blocksize = 10 * 2 ** 20 # 10 MB
+ for fn in self.files:
+ with zopen(zpath(fn), 'rb') as f:
+ hash = hashlib.sha224()
+ for block in iter(lambda: f.read(blocksize), b""):
+ hash.update(block)
+ checksum = hash.hexdigest()
+ file_checksums[fn] = {"type": "sha224",
+ "value": checksum}
+ with open("checksum.{}.{}".format(fn, checksum[:10]), "w") as f:
+ f.write("sha224")
+ stored_data = {"file_checksum": file_checksums}
+ return FWAction(stored_data=stored_data)
+
+
+class DeleteFileTask(FireTaskBase, FWSerializable):
+
+ _fw_name = "Delete File Task"
+
+ def __init__(self, parameters=None):
+ parameters = parameters if parameters else {}
+ default_files = ["CHGCAR", "WAVCAR"]
+ self.update(parameters)
+ self.files = parameters.get("files", default_files)
+
+ def run_task(self, fw_spec):
+ for fn in self.files:
+ gzfn = fn + ".gz"
+ if os.path.exists(fn):
+ os.remove(fn)
+ if os.path.exists(gzfn):
+ os.remove(gzfn)
+
diff --git a/mpworks/firetasks/nmr_tensor_set.yaml b/mpworks/firetasks/nmr_tensor_set.yaml
new file mode 100644
index 00000000..0cc412a3
--- /dev/null
+++ b/mpworks/firetasks/nmr_tensor_set.yaml
@@ -0,0 +1,180 @@
+CS:
+ INCAR:
+ DQ: 0.001
+ EDIFF: -1.0e-10
+ ENCUT_ENHANCE_RATIO: 0.3
+ ICHIBARE: 1
+ ISMEAR: -5
+ ISTART: 0
+ ISYM: 0
+ LCHARG: false
+ LCHIMAG: true
+ LNMR_SYM_RED: true
+ LREAL: AUTO
+ LWAVE: false
+ NELMIN: 10
+ NSLPLINE: true
+ PREC: ACCURATE
+ SIGMA: 0.01
+ KPOINTS:
+ length: 32
+ POTCAR:
+ C: C_h
+ H: H_h
+ Mg: Mg_sv
+ O: O_h
+ N: N_h
+ F: F_h
+ Na: Na_sv
+ Al: Al
+ Si: Si_h
+ P: P_h
+ Cl: Cl_h
+ K: K_sv
+ Ca: Ca_sv
+ Y: Y_sv
+ Gd: Gd
+ Be: Be_sv
+ Fe: Fe_sv_h
+ Ge: Ge_h
+ Li: Li_sv
+ S: S_h
+ Zn: Zn_pv
+ Ti: Ti_sv_h
+ Zr: Zr_sv_new
+ Sr: Sr_sv
+ Ba: Ba_sv
+ La: La
+ In: In_d
+ B: B_h
+ Pb: Pb_d
+
+EFG:
+ INCAR:
+ ALGO: FAST
+ EDIFF: -1.0e-10
+ ENCUT_ENHANCE_RATIO: 0.3
+ ISMEAR: -5
+ ISTART: 0
+ ISYM: 0
+ LCHARG: false
+ LEFG: true
+ LREAL: AUTO
+ LWAVE: false
+ NELMIN: 10
+ PREC: ACCURATE
+ QUAD_EFG_MAP:
+ H:
+ H-2: 2.860
+ Li:
+ Li-6: -0.808
+ Li-7: -40.1
+ Be:
+ Be-9: 52.88
+ B:
+ B-10: 84.59
+ B-11: 40.59
+ C:
+ C-11: 33.27
+ N:
+ N-14: 20.44
+ O:
+ O-17: -25.58
+ F:
+ F-19: -94.2
+ Ne:
+ Ne-21: 101.55
+ Na:
+ Na-23: 104.1
+ Mg:
+ Mg-25: 199.4
+ Al:
+ Al-27: 146.6
+ S:
+ S-33: -67.8
+ S-35: 47.1
+ Cl:
+ Cl-35: -81.65
+ Cl-37: -64.35
+ K:
+ K-39: 58.5
+ K-40: -73.0
+ K-41: 71.1
+ Ca:
+ Ca-41: -66.5
+ Ca-43: -40.8
+ Sc:
+ Sc-45: -220.2
+ Ti:
+ Ti-47: 302.10
+ Ti-49: 247.11
+ V:
+ V-50: 210.40
+ V-51: -52.10
+ Cr:
+ Cr-53: -150.50
+ Mn:
+ Mn-55: 330.10
+ Fe:
+ Fe-57: 160.0
+ Co:
+ Co-59: 420.30
+ Ni:
+ Ni-61: 162.15
+ Cu:
+ Cu-63: -220.15
+ Cu-65: -204.14
+ Zn:
+ Zn-67: 150.15
+ Sr:
+ Sr-87: 305.2
+ In:
+ In-113: 759.8
+ In-115: 770.8
+ Sn:
+ Sn-119: -132.1
+ Sb:
+ Sb-121: -543.11
+ Sb-123: -692.14
+ I:
+ I-127: -696.12
+ I-129: -604.10
+ La:
+ La-139: 200.6
+ Hg:
+ Hg-201: 387.6
+ Ra:
+ Ra-223: 1210.3
+ SIGMA: 0.01
+ KPOINTS:
+ length: 32
+ POTCAR:
+ C: C_h
+ H: H_h
+ Mg: Mg_sv
+ O: O_h
+ N: N_h
+ F: F_h
+ Na: Na_sv
+ Al: Al
+ Si: Si_h
+ P: P_h
+ Cl: Cl_h
+ K: K_sv
+ Ca: Ca_sv
+ Y: Y_sv
+ Gd: Gd
+ Be: Be_sv
+ Fe: Fe_sv_h
+ Ge: Ge_h
+ Li: Li_sv
+ S: S_h
+ Zn: Zn_pv
+ Ti: Ti_sv_h
+ Zr: Zr_sv_new
+ Sr: Sr_sv
+ Ba: Ba_sv
+ La: La
+ In: In_d
+ B: B_h
+ Pb: Pb_d
diff --git a/mpworks/firetasks/triple_jump_relax_set.yaml b/mpworks/firetasks/triple_jump_relax_set.yaml
new file mode 100644
index 00000000..304e66e7
--- /dev/null
+++ b/mpworks/firetasks/triple_jump_relax_set.yaml
@@ -0,0 +1,169 @@
+STEP1:
+ INCAR:
+ ALGO: FAST
+ EDIFF: -1.0e-06
+ EDIFFG: -0.1
+ ENCUT_ENHANCE_RATIO: 0.05
+ IBRION: 1
+ ISIF: 3
+ ISMEAR: -5
+ ISTART: 0
+ LCHARG: false
+ LREAL: AUTO
+ LWAVE: false
+ NELMIN: 5
+ NSW: 200
+ POTIM: 0.3
+ PREC: ACCURATE
+ SIGMA: 0.1
+ KPOINTS:
+ length: 16
+ POTCAR:
+ C: C
+ H: H
+ Mg: Mg
+ O: O
+ N: N
+ F: F
+ Na: Na
+ Al: Al
+ Si: Si
+ P: P
+ Cl: Cl
+ K: K_pv
+ Ca: Ca_pv
+ Y: Y_sv
+ Gd: Gd
+ Be: Be_sv
+ Fe: Fe_sv
+ Ge: Ge_d
+ Li: Li_sv
+ S: S
+ Zn: Zn_pv
+ Ti: Ti_sv_new
+ Zr: Zr_sv_new
+ Sr: Sr_sv
+ Ba: Ba_sv
+ La: La
+ In: In_d
+ B: B
+ Pb: Pb_d
+
+STEP2:
+ INCAR:
+ ADDGRID: true
+ ALGO: FAST
+ EDIFF: -1.0e-08
+ EDIFFG: -0.01
+ ENCUT_ENHANCE_RATIO: 0.2
+ IBRION: 3
+ IOPT: 7
+ ISIF: 3
+ ISMEAR: -5
+ ISTART: 0
+ ISYM: 0
+ LCHARG: false
+ LREAL: AUTO
+ LWAVE: false
+ NELMIN: 5
+ NSW: 200
+ POTIM: 0
+ PREC: ACCURATE
+ SIGMA: 0.03
+ KPOINTS:
+ length: 24
+ POTCAR:
+ C: C_h
+ H: H_h
+ Mg: Mg_sv
+ O: O_h
+ N: N_h
+ F: F_h
+ Na: Na_sv
+ Al: Al
+ Si: Si_h
+ P: P_h
+ Cl: Cl_h
+ K: K_sv
+ Ca: Ca_sv
+ Y: Y_sv
+ Gd: Gd
+ Be: Be_sv
+ Fe: Fe_sv_h
+ Ge: Ge_h
+ Li: Li_sv
+ S: S_h
+ Zn: Zn_pv
+ Ti: Ti_sv_h
+ Zr: Zr_sv_new
+ Sr: Sr_sv
+ Ba: Ba_sv
+ La: La
+ In: In_d
+ B: B_h
+ Pb: Pb_d
+
+STEP3:
+ INCAR:
+ ADDGRID: true
+ ALGO: FAST
+ EDIFF: -1.0e-10
+ EDIFFG: -0.002
+ ENCUT_ENHANCE_RATIO: 0.3
+ FTIMEMAX: 0.1
+ IBRION: 3
+ IOPT: 7
+ ISIF: 3
+ ISMEAR: -5
+ ISTART: 0
+ ISYM: 0
+ LCHARG: false
+ LREAL: AUTO
+ LWAVE: false
+ MAXMOVE: 0.02
+ NELMIN: 10
+ NSW: 100
+ POTIM: 0
+ PREC: ACCURATE
+ SIGMA: 0.01
+ TIMESTEP: 0.01
+ FNMIN: 3
+ KPOINTS:
+ length: 32
+ POTCAR:
+ C: C_h
+ H: H_h
+ Mg: Mg_sv
+ O: O_h
+ N: N_h
+ F: F_h
+ Na: Na_sv
+ Al: Al
+ Si: Si_h
+ P: P_h
+ Cl: Cl_h
+ K: K_sv
+ Ca: Ca_sv
+ Y: Y_sv
+ Gd: Gd
+ Be: Be_sv
+ Fe: Fe_sv_h
+ Ge: Ge_h
+ Li: Li_sv
+ S: S_h
+ Zn: Zn_pv
+ Ti: Ti_sv_h
+ Zr: Zr_sv_new
+ Sr: Sr_sv
+ Ba: Ba_sv
+ La: La
+ In: In_d
+ B: B_h
+ Pb: Pb_d
+
+STEP_DYNA3:
+ INCAR:
+ FTIMEMAX: 0.05
+ MAXMOVE: 0.01
+ TIMESTEP: 0.005
+ FNMIN: 2
diff --git a/mpworks/firetasks/vasp_io_tasks.py b/mpworks/firetasks/vasp_io_tasks.py
index 596fd136..14adb2d4 100644
--- a/mpworks/firetasks/vasp_io_tasks.py
+++ b/mpworks/firetasks/vasp_io_tasks.py
@@ -9,6 +9,9 @@
import os
import shutil
import sys
+
+from fireworks.fw_config import FWData
+from monty.io import zopen
from monty.os.path import zpath
from custodian.vasp.handlers import UnconvergedErrorHandler
from fireworks.core.launchpad import LaunchPad
@@ -20,7 +23,7 @@
from mpworks.dupefinders.dupefinder_vasp import DupeFinderVasp
from mpworks.firetasks.custodian_task import get_custodian_task
from mpworks.firetasks.vasp_setup_tasks import SetupUnconvergedHandlerTask
-from mpworks.workflows.wf_settings import QA_VASP, QA_DB, MOVE_TO_GARDEN_PROD, MOVE_TO_GARDEN_DEV
+from mpworks.workflows.wf_settings import WFSettings, QA_VASP, QA_DB
from mpworks.workflows.wf_utils import last_relax, get_loc, move_to_garden
from pymatgen import Composition
from pymatgen.io.vasp.inputs import Incar, Poscar, Potcar, Kpoints
@@ -72,6 +75,8 @@ def __init__(self, parameters=None):
self.files = parameters.get('files', default_files) # files to move
self.use_contcar = parameters.get('use_CONTCAR', True) # whether to move CONTCAR to POSCAR
+ self.keep_velocities = parameters.get('keep_velocities', True) # whether to keep the
+ # velocities in POSCAR/CONTCAR, if set to False, velocities will be removed.
if self.use_contcar:
self.files.append('CONTCAR')
@@ -89,21 +94,22 @@ def run_task(self, fw_spec):
if prev_filename.endswith('.gz'):
dest_file += '.gz'
- print 'COPYING', prev_filename, dest_file
+ print('COPYING', prev_filename, dest_file)
if self.missing_CHGCAR_OK and 'CHGCAR' in dest_file and not os.path.exists(zpath(prev_filename)):
- print 'Skipping missing CHGCAR'
+ print('Skipping missing CHGCAR')
else:
shutil.copy2(prev_filename, dest_file)
if '.gz' in dest_file:
# unzip dest file
- f = gzip.open(dest_file, 'rb')
- file_content = f.read()
- with open(dest_file[0:-3], 'wb') as f_out:
- f_out.writelines(file_content)
- f.close()
+ with gzip.open(dest_file, 'rb') as f_in:
+ with open(dest_file[0:-3], 'wb') as f_out:
+ shutil.copyfileobj(f_in, f_out)
os.remove(dest_file)
-
+ if self.use_contcar and not self.keep_velocities:
+ shutil.move("POSCAR", "POSCAR.orig.velocity")
+ poscar = Poscar.from_file("POSCAR.orig.velocity", read_velocities=False)
+ poscar.write_file(filename="POSCAR")
return FWAction(stored_data={'copied_files': self.files})
@@ -125,6 +131,20 @@ def __init__(self, parameters=None):
self.additional_fields = self.get('additional_fields', {})
self.update_duplicates = self.get('update_duplicates', False) # off so DOS/BS doesn't get entered twice
+ def same_fw_occurrences_in_cur_wflow(self, prev_dir, lp):
+ with zopen(zpath(os.path.join(prev_dir, 'FW.json')), 'rt') as f:
+ fw_dict = json.load(f)
+ prev_vasp_fw_id = fw_dict["launches"][0]["fw_id"]
+ prev_vasp_launch_id = fw_dict["launches"][0]["launch_id"]
+ prev_vasp_launch_assoc_fw_ids = [doc["fw_id"] for doc in
+ lp.fireworks.find({"launches": prev_vasp_launch_id}, projection=["fw_id"])]
+
+ cur_wf_fw_ids = lp.workflows.find({"nodes": prev_vasp_fw_id})[0]["nodes"]
+ # preferably current fw_id, however, there no mechanism to get it.
+
+ num_occurrences = len(set(cur_wf_fw_ids) & set(prev_vasp_launch_assoc_fw_ids))
+ return num_occurrences
+
def run_task(self, fw_spec):
if '_fizzled_parents' in fw_spec and not 'prev_vasp_dir' in fw_spec:
prev_dir = get_loc(fw_spec['_fizzled_parents'][0]['launches'][0]['launch_dir'])
@@ -143,10 +163,10 @@ def run_task(self, fw_spec):
else:
self.additional_fields['run_tags'] = fw_spec['_fizzled_parents'][0]['spec']['run_tags']
- if MOVE_TO_GARDEN_DEV:
+ if WFSettings().MOVE_TO_GARDEN_DEV:
prev_dir = move_to_garden(prev_dir, prod=False)
- elif MOVE_TO_GARDEN_PROD:
+ elif WFSettings().MOVE_TO_GARDEN_PROD:
prev_dir = move_to_garden(prev_dir, prod=True)
# get the directory containing the db file
@@ -159,6 +179,8 @@ def run_task(self, fw_spec):
sh = logging.StreamHandler(stream=sys.stdout)
sh.setLevel(getattr(logging, 'INFO'))
logger.addHandler(sh)
+ lp = LaunchPad.auto_load()
+ launch_coll = lp.launches
with open(db_path) as f:
db_creds = json.load(f)
drone = MPVaspDrone(host=db_creds['host'], port=db_creds['port'],
@@ -167,30 +189,37 @@ def run_task(self, fw_spec):
collection=db_creds['collection'], parse_dos=parse_dos,
additional_fields=self.additional_fields,
update_duplicates=self.update_duplicates)
- t_id, d = drone.assimilate(prev_dir, launches_coll=LaunchPad.auto_load().launches)
+ t_id, d = drone.assimilate(prev_dir, launches_coll=launch_coll)
mpsnl = d['snl_final'] if 'snl_final' in d else d['snl']
snlgroup_id = d['snlgroup_id_final'] if 'snlgroup_id_final' in d else d['snlgroup_id']
update_spec.update({'mpsnl': mpsnl, 'snlgroup_id': snlgroup_id})
+ if 'functional' in fw_spec:
+ d['functional'] = fw_spec['functional']
- print 'ENTERED task id:', t_id
+ print('ENTERED task id:', t_id)
stored_data = {'task_id': t_id}
if d['state'] == 'successful':
update_spec['analysis'] = d['analysis']
update_spec['output'] = d['output']
- update_spec['vasp']={'incar':d['calculations'][-1]['input']['incar'],
- 'kpoints':d['calculations'][-1]['input']['kpoints']}
+ if self.get("update_input", True):
+ update_spec['vasp']={'incar':d['calculations'][-1]['input']['incar'],
+ 'kpoints':d['calculations'][-1]['input']['kpoints']}
update_spec["task_id"]=t_id
return FWAction(stored_data=stored_data, update_spec=update_spec)
# not successful - first test to see if UnconvergedHandler is needed
if not fizzled_parent:
unconverged_tag = 'unconverged_handler--{}'.format(fw_spec['prev_task_type'])
+ if self.same_fw_occurrences_in_cur_wflow(prev_dir, lp) > 1:
+ raise ValueError("Same Dynamics FW launch has been already existed in"
+ "the database for more than twice, stop spawn new FW"
+ "to avoid infinite loop")
output_dir = last_relax(os.path.join(prev_dir, 'vasprun.xml'))
ueh = UnconvergedErrorHandler(output_filename=output_dir)
# TODO: make this a little more flexible
if ueh.check() and unconverged_tag not in fw_spec['run_tags']:
- print 'Unconverged run! Creating dynamic FW...'
+ print('Unconverged run! Creating dynamic FW...')
spec = {'prev_vasp_dir': prev_dir,
'prev_task_type': fw_spec['task_type'],
@@ -207,6 +236,8 @@ def run_task(self, fw_spec):
snl = StructureNL.from_dict(spec['mpsnl'])
spec['run_tags'].append(unconverged_tag)
spec['_queueadapter'] = QA_VASP
+ if 'functional' in fw_spec:
+ spec['functional'] = fw_spec['functional']
fws = []
connections = {}
@@ -214,9 +245,15 @@ def run_task(self, fw_spec):
f = Composition(
snl.structure.composition.reduced_formula).alphabetical_formula
+ if fw_spec['prev_task_type'] == "Triple Jump Relax S3":
+ from mpworks.firetasks.nmr_tasks import SetupTripleJumpRelaxS3UnconvergedHandlerTask
+ unconv_handler_task = SetupTripleJumpRelaxS3UnconvergedHandlerTask()
+ else:
+ unconv_handler_task = SetupUnconvergedHandlerTask()
+
fws.append(Firework(
[VaspCopyTask({'files': ['INCAR', 'KPOINTS', 'POSCAR', 'POTCAR', 'CONTCAR'],
- 'use_CONTCAR': False}), SetupUnconvergedHandlerTask(),
+ 'use_CONTCAR': False}), unconv_handler_task,
get_custodian_task(spec)], spec, name=get_slug(f + '--' + spec['task_type']),
fw_id=-2))
diff --git a/mpworks/firetasks/vasp_setup_tasks.py b/mpworks/firetasks/vasp_setup_tasks.py
index c93f3486..05c8f1e5 100644
--- a/mpworks/firetasks/vasp_setup_tasks.py
+++ b/mpworks/firetasks/vasp_setup_tasks.py
@@ -44,7 +44,7 @@ def run_task(self, fw_spec):
kppra_vol = self.kpoints_density / vol
new_set = MPStaticSet.from_prev_calc(
os.getcwd(),
- user_incar_settings=self.user_incar_settings,
+ user_incar_settings=self.user_incar_settings,
reciprocal_density=kppra_vol)
new_set.write_input('.')
structure = new_set.structure
diff --git a/mpworks/firetasks_staging/surface_tasks.py b/mpworks/firetasks_staging/surface_tasks.py
index 7ea82491..2d1dea5d 100644
--- a/mpworks/firetasks_staging/surface_tasks.py
+++ b/mpworks/firetasks_staging/surface_tasks.py
@@ -154,10 +154,10 @@ def run_task(self, fw_spec):
dec.process_decoded(self.get("potcar_fuctional", 'PBE'))
# Will continue an incomplete job from a previous contcar file if it exists
- print 'cwd is %s' %(os.getcwd())
- print 'the folder is %s' %(folder)
- print os.path.join(os.getcwd(), folder)
- print cwd+'/'+folder
+ print('cwd is %s' %(os.getcwd()))
+ print('the folder is %s' %(folder))
+ print(os.path.join(os.getcwd(), folder))
+ print(cwd+'/'+folder)
path = cwd+'/'+folder
# path = os.path.join(os.getcwd(), folder)
@@ -170,17 +170,17 @@ def run_task(self, fw_spec):
# print os.stat(os.path.join(path, 'CONTCAR.gz')).st_size !=0
def continue_vasp(contcar):
- print folder, 'already exists, will now continue calculation'
- print 'making prev_run folder'
+ print(folder, 'already exists, will now continue calculation')
+ print('making prev_run folder')
os.system('mkdir %s' %(newfolder))
- print 'moving outputs to prev_run'
+ print('moving outputs to prev_run')
os.system('mv %s/* %s/prev_run' %(path, path))
- print 'moving outputs as inputs for next calculation'
+ print('moving outputs as inputs for next calculation')
os.system('cp %s/%s %s/INCAR %s/POTCAR %s/KPOINTS %s'
%(newfolder, contcar, newfolder, newfolder, newfolder, path))
- print 'unzipping new inputs'
+ print('unzipping new inputs')
os.system('gunzip %s/*' %(path))
- print 'copying contcar as new poscar'
+ print('copying contcar as new poscar')
if contcar == 'CONTCAR.relax1.gz':
os.system('mv %s/CONTCAR.relax1 %s/POSCAR' %(path , path))
else:
@@ -273,7 +273,7 @@ def run_task(self, fw_spec):
min_vacuum_size = dec.process_decoded(self.get("min_vacuum_size", 10))
miller_index = dec.process_decoded(self.get("miller_index"))
- print 'about to make mplb'
+ print('about to make mplb')
mplb = MPSlabVaspInputSet(user_incar_settings=user_incar_settings,
k_product=k_product,
@@ -284,12 +284,12 @@ def run_task(self, fw_spec):
# cell is already oriented with the miller index, entering (0,0,1)
# into SlabGenerator is the same as obtaining a slab in the
# orienetation of the original miller index.
- print 'about to copy contcar'
+ print('about to copy contcar')
contcar = Poscar.from_file("%s/CONTCAR.relax2.gz" %(cwd+folder))
relax_orient_uc = contcar.structure
- print 'made relaxed oriented structure'
- print relax_orient_uc
- print 'making slab'
+ print('made relaxed oriented structure')
+ print(relax_orient_uc)
+ print('making slab')
slabs = SlabGenerator(relax_orient_uc, (0,0,1),
min_slab_size=min_slab_size,
@@ -298,43 +298,43 @@ def run_task(self, fw_spec):
# Whether or not to create a list of Fireworks
# based on different slab terminations
- print 'deciding terminations'
+ print('deciding terminations')
slab_list = slabs.get_slabs() if terminations else [slabs.get_slab()]
qe = QueryEngine(**vaspdbinsert_parameters)
optional_data = ["state"]
- print 'query bulk entry for job completion'
+ print('query bulk entry for job completion')
bulk_entry = qe.get_entries({'chemsys': relax_orient_uc.composition.reduced_formula,
'structure_type': 'oriented_unit_cell', 'miller_index': miller_index},
optional_data=optional_data)
- print 'chemical formula', relax_orient_uc.composition.reduced_formula
- print 'fomular data type is ', type(relax_orient_uc.composition.reduced_formula)
- print 'checking job completion'
- print bulk_entry
+ print('chemical formula', relax_orient_uc.composition.reduced_formula)
+ print('fomular data type is ', type(relax_orient_uc.composition.reduced_formula))
+ print('checking job completion')
+ print(bulk_entry)
for entry in bulk_entry:
- print 'for loop'
- print entry.data['state']
+ print('for loop')
+ print(entry.data['state'])
if entry.data['state'] != 'successful':
- print "%s bulk calculations were incomplete, cancelling FW" \
- %(relax_orient_uc.composition.reduced_formula)
+ print("%s bulk calculations were incomplete, cancelling FW" \
+ %(relax_orient_uc.composition.reduced_formula))
return FWAction()
else:
- print entry.data['state']
+ print(entry.data['state'])
FWs = []
for slab in slab_list:
- print slab
+ print(slab)
new_folder = folder.replace('bulk', 'slab')+'_shift%s' \
%(slab.shift)
# Will continue an incomplete job from a previous contcar file if it exists
- print 'cwd is %s' %(os.getcwd())
- print 'the folder is %s' %(new_folder)
- print os.path.join(os.getcwd(), new_folder)
- print cwd+'/'+new_folder
+ print('cwd is %s' %(os.getcwd()))
+ print('the folder is %s' %(new_folder))
+ print(os.path.join(os.getcwd(), new_folder))
+ print(cwd+'/'+new_folder)
path = cwd+'/'+new_folder
# path = os.path.join(os.getcwd(), folder)
@@ -347,17 +347,17 @@ def run_task(self, fw_spec):
# print os.stat(os.path.join(path, 'CONTCAR.gz')).st_size !=0
def continue_vasp(contcar):
- print folder, 'already exists, will now continue calculation'
- print 'making prev_run folder'
+ print(folder, 'already exists, will now continue calculation')
+ print('making prev_run folder')
os.system('mkdir %s' %(newfolder))
- print 'moving outputs to prev_run'
+ print('moving outputs to prev_run')
os.system('mv %s/* %s/prev_run' %(path, path))
- print 'moving outputs as inputs for next calculation'
+ print('moving outputs as inputs for next calculation')
os.system('cp %s/%s %s/INCAR %s/POTCAR %s/KPOINTS %s'
%(newfolder, contcar, newfolder, newfolder, newfolder, path))
- print 'unzipping new inputs'
+ print('unzipping new inputs')
os.system('gunzip %s/*' %(path))
- print 'copying contcar as new poscar'
+ print('copying contcar as new poscar')
if contcar == 'CONTCAR.relax1.gz':
os.system('mv %s/CONTCAR.relax1 %s/POSCAR' %(path , path))
else:
diff --git a/mpworks/fix_scripts/add_icsd_materials.py b/mpworks/fix_scripts/add_icsd_materials.py
index 39a8e652..a44f459a 100644
--- a/mpworks/fix_scripts/add_icsd_materials.py
+++ b/mpworks/fix_scripts/add_icsd_materials.py
@@ -62,13 +62,13 @@ def process_material(self, material_id):
icsd_ids = self.get_icsd_ids_from_snlgroup(snlgroup_id)
self.materials.find_and_modify({"task_ids": material_id}, {"$set": {"icsd_id": icsd_ids}})
- print material_id, icsd_ids
- print 'FINISHED', material_id
+ print(material_id, icsd_ids)
+ print('FINISHED', material_id)
except:
- print '-----'
- print 'ENCOUNTERED AN EXCEPTION!!!', material_id
+ print('-----')
+ print('ENCOUNTERED AN EXCEPTION!!!', material_id)
traceback.print_exc()
- print '-----'
+ print('-----')
def get_icsd_ids_from_snlgroup(self, snlgroup_id):
@@ -93,11 +93,11 @@ def _analyze(data):
o = ICSDBuilder()
o.setup()
materials = o.materials
- print materials.count()
+ print(materials.count())
m_data = []
for d in materials.find({}, {'task_id': 1}, timeout=False):
m_data.append(d['task_id'])
pool = multiprocessing.Pool(8)
pool.map(_analyze, m_data)
- print 'DONE'
\ No newline at end of file
+ print('DONE')
\ No newline at end of file
diff --git a/mpworks/fix_scripts/add_old_taskids.py b/mpworks/fix_scripts/add_old_taskids.py
index 13324763..a3c5662e 100644
--- a/mpworks/fix_scripts/add_old_taskids.py
+++ b/mpworks/fix_scripts/add_old_taskids.py
@@ -51,12 +51,12 @@ def process_task(self, task_id):
try:
task_id_deprecated = int(task_id.split('-')[-1])
self.tasks.update({"task_id": task_id}, {"$set": {"task_id_deprecated": task_id_deprecated}})
- print 'FINISHED', task_id
+ print('FINISHED', task_id)
except:
- print '-----'
- print 'ENCOUNTERED AN EXCEPTION!!!', task_id
+ print('-----')
+ print('ENCOUNTERED AN EXCEPTION!!!', task_id)
traceback.print_exc()
- print '-----'
+ print('-----')
def _analyze(data):
@@ -80,4 +80,4 @@ def _analyze(data):
q = {}
for d in tasks.find(q, {'task_id': 1}, timeout=False):
o.process_task(d['task_id'])
- print 'DONE'
\ No newline at end of file
+ print('DONE')
\ No newline at end of file
diff --git a/mpworks/fix_scripts/clear_FWs.py b/mpworks/fix_scripts/clear_FWs.py
index ad510447..96c25ee8 100644
--- a/mpworks/fix_scripts/clear_FWs.py
+++ b/mpworks/fix_scripts/clear_FWs.py
@@ -45,15 +45,15 @@ def _defuse_fw(data):
# archive READY WORKFLOWS
for d in lp.workflows.find({"state": "READY"}, {'nodes': 1}):
fw_ids.append(d['nodes'][0])
- print 'GOT all fw_ids...'
+ print('GOT all fw_ids...')
pool = multiprocessing.Pool(8)
states = pool.map(_archive_fw, fw_ids)
- print 'DONE', all(states)
+ print('DONE', all(states))
# defuse any READY/WAITING FWs
for d in lp.fireworks.find({"state": {"$in":["READY", "WAITING"]}}, {'fw_id': 1}):
fw_ids.append(d['fw_id'])
- print 'GOT all fw_ids...'
+ print('GOT all fw_ids...')
pool = multiprocessing.Pool(8)
states = pool.map(_defuse_fw, fw_ids)
- print 'DONE', all(states)
\ No newline at end of file
+ print('DONE', all(states))
\ No newline at end of file
diff --git a/mpworks/fix_scripts/find_missing_snl.py b/mpworks/fix_scripts/find_missing_snl.py
index d2e15824..bfa254b8 100644
--- a/mpworks/fix_scripts/find_missing_snl.py
+++ b/mpworks/fix_scripts/find_missing_snl.py
@@ -22,26 +22,26 @@
all_snl_ids = [] # snl ids that have a group
all_missing_ids = [] # snl ids missing a group
idx = 0
- print 'GETTING GROUPS'
+ print('GETTING GROUPS')
for x in snldb.snlgroups.find({}, {"all_snl_ids": 1}):
all_snl_ids.extend(x['all_snl_ids'])
- print 'CHECKING SNL'
+ print('CHECKING SNL')
for x in snldb.snl.find({}, {'snl_id': 1}, timeout=False):
- print x['snl_id']
+ print(x['snl_id'])
if x['snl_id'] not in all_snl_ids:
- print x['snl_id'], '*********'
+ print(x['snl_id'], '*********')
all_missing_ids.append(x['snl_id'])
- print 'FIXING / ADDING GROUPS'
- print all_missing_ids
+ print('FIXING / ADDING GROUPS')
+ print(all_missing_ids)
for snl_id in all_missing_ids:
try:
mpsnl = MPStructureNL.from_dict(snldb.snl.find_one({"snl_id": snl_id}))
snldb.build_groups(mpsnl)
- print 'SUCCESSFUL', snl_id
+ print('SUCCESSFUL', snl_id)
except:
- print 'ERROR with snl_id', snl_id
+ print('ERROR with snl_id', snl_id)
traceback.print_exc()
diff --git a/mpworks/fix_scripts/fix_bad_crystals.py b/mpworks/fix_scripts/fix_bad_crystals.py
index e6ba53d3..dfa41acf 100644
--- a/mpworks/fix_scripts/fix_bad_crystals.py
+++ b/mpworks/fix_scripts/fix_bad_crystals.py
@@ -40,7 +40,7 @@ def detect():
n_groups = snlgroups.find({"all_snl_ids":{"$in":[old_s['snl_id'], new_s['snl_id']]}}).count()
if n_groups != 1:
# The crystal_id is bad
- print crystal_id
+ print(crystal_id)
def fix():
@@ -90,7 +90,7 @@ def fix():
for c_id in bad_crystal_ids:
if c_id == 100892 or c_id == 100202:
- print 'SKIP'
+ print('SKIP')
else:
# FIX SNL
@@ -122,7 +122,7 @@ def fix():
for s in submissions.find({'about._materialsproject.deprecated.crystal_id_deprecated': c_id}, {'submission_id': 1}):
submissions.update({'submission_id': s['submission_id']}, {'$pushAll': {"about.remarks": ['DEPRECATED', 'SEVERE BUG IN ICSD CONVERSION']}})
- print 'FIXED', c_id
+ print('FIXED', c_id)
def find_alternate_canonical():
@@ -139,10 +139,10 @@ def find_alternate_canonical():
for s in snl.find({"snl_id": {"$in": g['all_snl_ids']}, "about.remarks": {"$ne": "DEPRECATED"}}):
canonical_mpsnl = MPStructureNL.from_dict(s)
snldb.switch_canonical_snl(g['snlgroup_id'], canonical_mpsnl)
- print g['snlgroup_id']
+ print(g['snlgroup_id'])
break
- print 'DONE'
+ print('DONE')
def archive_deprecated_fws():
# find all snlgroups that are deprecated, and archive all WFs that have deprecated fw_ids so we don't run them
@@ -157,11 +157,11 @@ def archive_deprecated_fws():
for g in snlgroups.find({'canonical_snl.about.remarks':'DEPRECATED'}, {'snlgroup_id': 1}):
while lpdb.fireworks.find_one({'spec.snlgroup_id': g['snlgroup_id'], 'state': {'$ne': 'ARCHIVED'}}, {'fw_id': 1}):
fw = lpdb.fireworks.find_one({'spec.snlgroup_id': g['snlgroup_id'], 'state': {'$ne': 'ARCHIVED'}}, {'fw_id': 1})
- print fw['fw_id']
+ print(fw['fw_id'])
lpdb.archive_wf(fw['fw_id'])
- print 'DONE'
+ print('DONE')
diff --git a/mpworks/fix_scripts/fix_bs_controller_tasks.py b/mpworks/fix_scripts/fix_bs_controller_tasks.py
index 33144ef9..96b20750 100644
--- a/mpworks/fix_scripts/fix_bs_controller_tasks.py
+++ b/mpworks/fix_scripts/fix_bs_controller_tasks.py
@@ -1,14 +1,12 @@
-import time, yaml, sys, os
-from fireworks.core.launchpad import LaunchPad
+import os
+import yaml
from fireworks.core.firework import Firework, Workflow
-from mpworks.firetasks.controller_tasks import AddEStructureTask
+from fireworks.core.launchpad import LaunchPad
from fireworks.utilities.fw_utilities import get_slug
-from mpworks.snl_utils.snl_mongo import SNLMongoAdapter
from pymongo import MongoClient
-from collections import Counter
-from datetime import datetime
-from fnmatch import fnmatch
-from custodian.vasp.handlers import VaspErrorHandler
+
+from mpworks.firetasks.controller_tasks import AddEStructureTask
+from mpworks.snl_utils.snl_mongo import SNLMongoAdapter
cwd = os.getcwd()
@@ -24,7 +22,7 @@
db.authenticate(creds['username'], creds['password'])
materials = db['materials']
tasks = db['tasks']
-print materials.count()
+print(materials.count())
def append_wf(fw_id, parent_fw_id=None):
wf = lpdb.workflows.find_one({'nodes':fw_id}, {'parent_links':1,'links':1,'name':1})
@@ -38,25 +36,25 @@ def append_wf(fw_id, parent_fw_id=None):
if child_fw['spec']['task_type'] == 'Controller: add Electronic Structure v2':
if child_fw['state'] == 'DEFUSED':
lpdb.reignite_fw(child_fw_id)
- print 'AddEStructureTask v2', child_fw_id , 'reignited for', fw_id
+ print('AddEStructureTask v2', child_fw_id , 'reignited for', fw_id)
elif child_fw['state'] == 'FIZZLED':
lpdb.rerun_fw(child_fw_id)
- print 'AddEStructureTask v2', child_fw_id , 'marked for rerun for', fw_id
+ print('AddEStructureTask v2', child_fw_id , 'marked for rerun for', fw_id)
elif child_fw['state'] == 'COMPLETED':
- print 'AddEStructureTask v2 already successfully run for', fw_id
+ print('AddEStructureTask v2 already successfully run for', fw_id)
sec_child_fw_id = wf['links'][str(child_fw_id)][0]
- sec_child_fw = lpdb.fireworks.find_one({'fw_id': sec_child_fw_id}, {'spec.task_type':1, 'state':1})
- if sec_child_fw['state'] == 'FIZZLED':
- lpdb.rerun_fw(sec_child_fw_id)
- print 'FIZZLED -> marked for rerun:', sec_child_fw_id, sec_child_fw['spec']['task_type']
- else:
- print 'AddEStructureTask v2 added but neither DEFUSED, FIZZLED, or COMPLETED for', fw_id
+ sec_child_fw = lpdb.fireworks.find_one({'fw_id': sec_child_fw_id}, {'spec.task_type':1, 'state':1})
+ if sec_child_fw['state'] == 'FIZZLED':
+ lpdb.rerun_fw(sec_child_fw_id)
+ print('FIZZLED -> marked for rerun:', sec_child_fw_id, sec_child_fw['spec']['task_type'])
+ else:
+ print('AddEStructureTask v2 added but neither DEFUSED, FIZZLED, or COMPLETED for', fw_id)
return
f = lpdb.get_wf_summary_dict(fw_id)['name'].replace(' ', '_')
name = get_slug(f + '--' + spec['task_type'])
fw = Firework([AddEStructureTask()], spec, name=name)
lpdb.append_wf(Workflow([fw]), [parent_fw_id])
- print name, 'added for', fw_id
+ print(name, 'added for', fw_id)
except ValueError:
raise ValueError('could not append controller task to wf', wf['name'])
@@ -91,14 +89,14 @@ def append_wf(fw_id, parent_fw_id=None):
#print 'nfws =', nfws
mp_ids = [
- 'mp-2123', 'mp-10886', 'mp-582799', 'mp-21477', 'mp-535', 'mp-21293', 'mp-8700',
- 'mp-9568', 'mp-973', 'mp-505622', 'mp-20839', 'mp-1940', 'mp-16521', 'mp-30354',
- 'mp-568953', 'mp-454', 'mp-1010', 'mp-1416', 'mp-21385', 'mp-27659', 'mp-22481',
- 'mp-569529', 'mp-1057', 'mp-1834', 'mp-2336', 'mp-12857', 'mp-21109', 'mp-30387',
- 'mp-30599', 'mp-21884', 'mp-11397', 'mp-11814', 'mp-510437', 'mp-12565', 'mp-33032',
+ 'mp-2123', 'mp-10886', 'mp-582799', 'mp-21477', 'mp-535', 'mp-21293', 'mp-8700',
+ 'mp-9568', 'mp-973', 'mp-505622', 'mp-20839', 'mp-1940', 'mp-16521', 'mp-30354',
+ 'mp-568953', 'mp-454', 'mp-1010', 'mp-1416', 'mp-21385', 'mp-27659', 'mp-22481',
+ 'mp-569529', 'mp-1057', 'mp-1834', 'mp-2336', 'mp-12857', 'mp-21109', 'mp-30387',
+ 'mp-30599', 'mp-21884', 'mp-11397', 'mp-11814', 'mp-510437', 'mp-12565', 'mp-33032',
'mp-20885', 'mp-1891',
- "mp-987", "mp-1542", "mp-2252", "mp-966", "mp-6945", "mp-1598",
- "mp-7547", "mp-554340", "mp-384", "mp-2437", "mp-1167", "mp-571266",
+ "mp-987", "mp-1542", "mp-2252", "mp-966", "mp-6945", "mp-1598",
+ "mp-7547", "mp-554340", "mp-384", "mp-2437", "mp-1167", "mp-571266",
"mp-560338", "mp-27253", "mp-1705", "mp-2131", "mp-676", "mp-2402", "mp-9588",
"mp-2452", "mp-690", "mp-30033", "mp-10155", "mp-9921", "mp-9548", "mp-569857",
"mp-29487", "mp-909", "mp-1536", "mp-28391", "mp-558811", "mp-1033", "mp-1220",
@@ -140,17 +138,17 @@ def append_wf(fw_id, parent_fw_id=None):
]
mp_ids = [ "mp-134", "mp-127", "mp-58", "mp-135", "mp-70", "mp-1" ]
mp_ids = [doc['task_id'] for doc in materials.find({'has_bandstructure': False}, {'task_id':1})]
- print '#mp_ids =', len(mp_ids)
+ print('#mp_ids =', len(mp_ids))
counter = Counter()
materials_wBS = []
for matidx, material in enumerate(materials.find({'task_id': {'$in': mp_ids}}, {'task_id': 1, '_id': 0, 'snlgroup_id_final': 1, 'has_bandstructure': 1, 'pretty_formula': 1})):
mp_id, snlgroup_id = material['task_id'], material['snlgroup_id_final']
- url = 'https://materialsproject.org/materials/' + mp_id
+ url = 'https://materialsproject.org/materials/' + mp_id
if material['has_bandstructure']:
materials_wBS.append((mp_id, material['pretty_formula']))
counter['has_bandstructure'] += 1
- print matidx, '========', mp_id, snlgroup_id, '============='
+ print(matidx, '========', mp_id, snlgroup_id, '=============')
fw_list = list(lpdb.fireworks.find(
{'spec.snlgroup_id': snlgroup_id},
{'_id': 0, 'state': 1, 'name': 1, 'fw_id': 1, 'spec.snlgroup_id': 1, 'spec.task_type': 1, 'launches': 1}
@@ -162,7 +160,7 @@ def append_wf(fw_id, parent_fw_id=None):
has_gga_static = True
if fw['state'] == 'FIZZLED':
#counter[fw['spec']['task_type']] += 1
- print '--'.join([fw['name'], str(fw['fw_id'])]), fw['state']
+ print('--'.join([fw['name'], str(fw['fw_id'])]), fw['state'])
launch_dir = lpdb.launches.find_one({'launch_id': fw['launches'][0]}, {'launch_dir':1})['launch_dir']
launch_subdir = '/'.join(launch_dir.split('/')[-2:])
if 'oasis' in launch_dir:
@@ -180,12 +178,12 @@ def append_wf(fw_id, parent_fw_id=None):
try:
os.chdir(launch_dir)
except:
- print ' |===> could not find launch directory in usual locations'
+ print(' |===> could not find launch directory in usual locations')
lpdb.rerun_fw(fw['fw_id'])
- print ' |===> marked for RERUN'
+ print(' |===> marked for RERUN')
counter['LOCATION_NOT_FOUND'] += 1
continue
- print ' |===>', launch_dir
+ print(' |===>', launch_dir)
vaspout = os.path.join(launch_dir, "vasp.out")
if not os.path.exists(vaspout):
vaspout = os.path.join(launch_dir, "vasp.out.gz")
@@ -200,9 +198,9 @@ def append_wf(fw_id, parent_fw_id=None):
counter['GGA_static_' + err] += 1
if 'brmix' in d['errors']:
#lpdb.rerun_fw(fw['fw_id'])
- print ' |===> BRMIX error -> marked for RERUN with alternative strategy'
+ print(' |===> BRMIX error -> marked for RERUN with alternative strategy')
else:
- print ' |===> no vasp error indicated -> TODO'
+ print(' |===> no vasp error indicated -> TODO')
counter['GGA_STATIC_NO_VASP_ERROR'] += 1
os.chdir(cwd)
else:
@@ -211,20 +209,20 @@ def append_wf(fw_id, parent_fw_id=None):
{'state': 1, '_id': 0, 'fw_states': 1, 'nodes': 1, 'updated_on': 1, 'parent_links': 1}
)
if workflow is None:
- print ' |==> workflow not found', fw['fw_id']
+ print(' |==> workflow not found', fw['fw_id'])
counter['WF_NOT_FOUND'] += 1
continue
is_new = bool(datetime(2016, 1, 1) < workflow['updated_on'])
if workflow['state'] == 'FIZZLED':
- for fw_id_fizzled, fw_state in workflow['fw_states'].iteritems():
+ for fw_id_fizzled, fw_state in workflow['fw_states'].items():
if fw_state == 'FIZZLED':
fw_fizzled = lpdb.fireworks.find_one({'fw_id': int(fw_id_fizzled)}, {'_id': 0, 'name': 1, 'fw_id': 1, 'spec.task_type': 1})
counter[fw_fizzled['spec']['task_type']] += 1
- print url, is_new, material['has_bandstructure'], fw_id_fizzled
- print 'http://fireworks.dash.materialsproject.org/wf/'+str(fw['fw_id']), workflow['state']
- print ' |==>', '--'.join([fw_fizzled['name'], fw_id_fizzled])
+ print(url, is_new, material['has_bandstructure'], fw_id_fizzled)
+ print('http://fireworks.dash.materialsproject.org/wf/'+str(fw['fw_id']), workflow['state'])
+ print(' |==>', '--'.join([fw_fizzled['name'], fw_id_fizzled]))
if fnmatch(fw_fizzled['spec']['task_type'], '*Boltztrap*'):
- print ' |====> marked for RERUN (Boltztrap, physical constants from scipy, missing libmkl_lapack.so, BoltzTrap_TE -> pymatgen)'
+ print(' |====> marked for RERUN (Boltztrap, physical constants from scipy, missing libmkl_lapack.so, BoltzTrap_TE -> pymatgen)')
#lpdb.rerun_fw(fw_fizzled['fw_id'])
continue
elif fw_fizzled['spec']['task_type'] == 'GGA Uniform v2':
@@ -233,42 +231,42 @@ def append_wf(fw_id, parent_fw_id=None):
fw_id_rerun = str(workflow['parent_links'][fw_id_rerun][-1])
fw_rerun = lpdb.fireworks.find_one({'fw_id': int(fw_id_rerun)}, {'_id': 0, 'spec.task_type': 1})
if fw_rerun['spec']['task_type'] != 'VASP db insertion':
- print 'http://fireworks.dash.materialsproject.org/wf/'+fw_id_rerun
+ print('http://fireworks.dash.materialsproject.org/wf/'+fw_id_rerun)
break
#lpdb.rerun_fw(int(fw_id_rerun))
- print ' |====> marked for RERUN (could not get valid results from prev_vasp_dir, GGAstatic vasprun.xml validation error)'
+ print(' |====> marked for RERUN (could not get valid results from prev_vasp_dir, GGAstatic vasprun.xml validation error)')
elif fw_fizzled['spec']['task_type'] == 'GGA band structure v2':
- print ' |===> marked for RERUN (trial & error)'
+ print(' |===> marked for RERUN (trial & error)')
#try:
# lpdb.rerun_fw(fw_fizzled['fw_id'])
#except:
# print ' |===> could not rerun firework'
# counter['WF_LOCKED'] += 1
elif fw_fizzled['spec']['task_type'] == 'VASP db insertion':
- print ' |===> marked for RERUN (trial & error)'
+ print(' |===> marked for RERUN (trial & error)')
#lpdb.rerun_fw(fw_fizzled['fw_id'])
#sys.exit(0)
break
elif workflow['state'] == 'COMPLETED':
- print url, is_new, material['has_bandstructure'], workflow['nodes'][0]
+ print(url, is_new, material['has_bandstructure'], workflow['nodes'][0])
if not is_new and not material['has_bandstructure']:
#lpdb.rerun_fw(fw['fw_id'])
- print ' |===> marked for RERUN with alternative brmix strategy (WF completed but BS missing)'
+ print(' |===> marked for RERUN with alternative brmix strategy (WF completed but BS missing)')
counter['WF_COMPLETED_MISSING_BS'] += 1
#sys.exit(0)
else:
counter['COMPLETED'] += 1
if not has_gga_static:
- print 'ERROR: no GGA static run found!'
- print '\n'.join([
+ print('ERROR: no GGA static run found!')
+ print('\n'.join([
'--'.join([fw['name'], str(fw['fw_id']), fw['state']]) for fw in fw_list
- ])
+ ]))
counter['NO_GGA_STATIC'] += 1
#break
else:
- print 'ERROR: no fireworks found!'
+ print('ERROR: no fireworks found!')
counter['NO_FWS'] += 1
#break
- print '#mp_ids =', len(mp_ids)
- print counter
+ print('#mp_ids =', len(mp_ids))
+ print(counter)
#print materials_wBS
diff --git a/mpworks/fix_scripts/fix_float_priorities.py b/mpworks/fix_scripts/fix_float_priorities.py
index edfad619..f9f9595b 100644
--- a/mpworks/fix_scripts/fix_float_priorities.py
+++ b/mpworks/fix_scripts/fix_float_priorities.py
@@ -17,7 +17,7 @@
for fw in lpdb.fireworks.find({"spec._tasks.1.max_errors":{"$type": 1}}, {"fw_id": 1, "state": 1, "spec._tasks": 1}, timeout=False):
- print fw['fw_id'], fw['state']
+ print(fw['fw_id'], fw['state'])
lpdb.fireworks.find_and_modify({"fw_id": fw['fw_id']}, {"$set": {"spec._tasks.1.max_errors": int(5)}})
if fw['state'] == 'FIZZLED':
lpdb.rerun_fw(fw['fw_id'])
\ No newline at end of file
diff --git a/mpworks/fix_scripts/fix_mpcomplete.py b/mpworks/fix_scripts/fix_mpcomplete.py
index 83f8534a..d7954771 100644
--- a/mpworks/fix_scripts/fix_mpcomplete.py
+++ b/mpworks/fix_scripts/fix_mpcomplete.py
@@ -34,7 +34,7 @@
projection=projection,
return_document=ReturnDocument.AFTER
)
- print doc['fw_id'], '----> walltime updated'
+ print(doc['fw_id'], '----> walltime updated')
if 'nnodes' in doc['spec']['_queueadapter'] and not 'nodes' in doc['spec']['_queueadapter']:
launchpad.fireworks.find_one_and_update(
{'fw_id': doc['fw_id']},
@@ -42,7 +42,7 @@
projection=projection,
return_document=ReturnDocument.AFTER
)
- print doc['fw_id'], '----> nodes key renamed'
+ print(doc['fw_id'], '----> nodes key renamed')
if 'pre_rocket' in doc['spec']['_queueadapter']:
launchpad.fireworks.find_one_and_update(
m_query,
@@ -50,12 +50,12 @@
projection=projection,
return_document=ReturnDocument.AFTER
)
- print doc['fw_id'], '----> pre_rocket dropped'
+ print(doc['fw_id'], '----> pre_rocket dropped')
if 'prev_vasp_dir' in doc['spec'] and not os.path.exists(doc['spec']['prev_vasp_dir']):
block_dir = doc['spec']['prev_vasp_dir'].split('/')[-2:]
launch_dir = '/'.join('/oasis/projects/nsf/csd436/phuck/garden'.split('/') + block_dir)
if not os.path.exists(launch_dir):
- print doc['fw_id'], '---->', '/'.join(block_dir), 'does not exists!'
- continue
+ print(doc['fw_id'], '---->', '/'.join(block_dir), 'does not exists!')
+ continue
fw_ids.append(doc['fw_id'])
-print 'fixed', fw_ids
+print('fixed', fw_ids)
diff --git a/mpworks/fix_scripts/fix_unmoved_dirs.py b/mpworks/fix_scripts/fix_unmoved_dirs.py
index 17ea77bf..b44cde51 100644
--- a/mpworks/fix_scripts/fix_unmoved_dirs.py
+++ b/mpworks/fix_scripts/fix_unmoved_dirs.py
@@ -26,7 +26,7 @@ def detect():
block_part = get_block_part(d)
garden_dir = os.path.join(GARDEN_PATH, block_part)
if os.path.exists(garden_dir):
- print garden_dir
+ print(garden_dir)
if __name__ == '__main__':
diff --git a/mpworks/fix_scripts/legacy/actions/add_snl_final.py b/mpworks/fix_scripts/legacy/actions/add_snl_final.py
index 9ce82df0..e2a99241 100644
--- a/mpworks/fix_scripts/legacy/actions/add_snl_final.py
+++ b/mpworks/fix_scripts/legacy/actions/add_snl_final.py
@@ -24,4 +24,4 @@
for d in new_tasks.find({'snlgroup_id_final': {'$exists': False}}, {'task_id': 1, 'snl': 1, 'snlgroup_id': 1, 'snlgroup_changed': 1}):
new_tasks.update({'task_id': d['task_id']}, {'$set': {'snl_final': d['snl'], 'snlgroup_id_final': d['snlgroup_id'], 'snlgroup_changed': False}})
count+=1
- print count
+ print(count)
diff --git a/mpworks/fix_scripts/legacy/actions/do_fw_conversion.py b/mpworks/fix_scripts/legacy/actions/do_fw_conversion.py
index 38e6aab6..ac0310fe 100644
--- a/mpworks/fix_scripts/legacy/actions/do_fw_conversion.py
+++ b/mpworks/fix_scripts/legacy/actions/do_fw_conversion.py
@@ -28,7 +28,7 @@
db2.authenticate(db_creds['admin_user'], db_creds['admin_password'])
new_tasks = db2['tasks']
- print new_tasks.count()
+ print(new_tasks.count())
new_tasks.ensure_index("task_id", unique=True)
new_tasks.ensure_index("task_id_deprecated", unique=True)
diff --git a/mpworks/fix_scripts/legacy/actions/do_icsd_to_snl.py b/mpworks/fix_scripts/legacy/actions/do_icsd_to_snl.py
index a0201334..e2ad719f 100644
--- a/mpworks/fix_scripts/legacy/actions/do_icsd_to_snl.py
+++ b/mpworks/fix_scripts/legacy/actions/do_icsd_to_snl.py
@@ -40,6 +40,6 @@
snldb.add_snl(snl)
except:
traceback.print_exc()
- print 'ERROR - icsd id:', icsd_dict['icsd_id']
+ print('ERROR - icsd id:', icsd_dict['icsd_id'])
- print 'DONE'
+ print('DONE')
diff --git a/mpworks/fix_scripts/legacy/actions/do_mps_to_snl.py b/mpworks/fix_scripts/legacy/actions/do_mps_to_snl.py
index 8b4d4223..72794873 100644
--- a/mpworks/fix_scripts/legacy/actions/do_mps_to_snl.py
+++ b/mpworks/fix_scripts/legacy/actions/do_mps_to_snl.py
@@ -36,7 +36,7 @@
prev_ids = [] # MPS ids that we already took care of
- print 'INITIALIZING'
+ print('INITIALIZING')
if RESET:
snldb._reset()
time.sleep(10) # makes me sleep better at night
@@ -45,7 +45,7 @@
for mps in snldb.snl.find({}, {"about._materialsproject.deprecated.mps_ids": 1}):
prev_ids.extend(mps['about']['_materialsproject']['deprecated']['mps_ids'])
- print 'PROCESSING'
+ print('PROCESSING')
for mps in db.mps.find(timeout=False):
try:
if not mps['mps_id'] in prev_ids:
@@ -53,9 +53,9 @@
if snl:
snldb.add_snl(snl)
else:
- print 'SKIPPING', mps['mps_id']
+ print('SKIPPING', mps['mps_id'])
except:
traceback.print_exc()
- print 'ERROR - mps id:', mps['mps_id']
+ print('ERROR - mps id:', mps['mps_id'])
- print 'DONE'
+ print('DONE')
diff --git a/mpworks/fix_scripts/legacy/actions/do_task_conversion.py b/mpworks/fix_scripts/legacy/actions/do_task_conversion.py
index 9bc0670e..37d8b7b5 100644
--- a/mpworks/fix_scripts/legacy/actions/do_task_conversion.py
+++ b/mpworks/fix_scripts/legacy/actions/do_task_conversion.py
@@ -58,12 +58,12 @@ def process_task(self, task_id):
t = self.old_tasks.find_one({'task_id': task_id})
try:
t_id, d = self.drone.assimilate(t)
- print 'ENTERED', t_id
+ print('ENTERED', t_id)
except:
- print 'ERROR entering', t['task_id']
+ print('ERROR entering', t['task_id'])
traceback.print_exc()
else:
- print 'skip'
+ print('skip')
def _analyze(task_id):
@@ -77,10 +77,10 @@ def parallel_build(min, max):
for i in tasks_old.find({'task_id': {'$gte': min, '$lt': max}}, {'task_id': 1}):
task_ids.append(i['task_id'])
- print 'GOT all tasks...'
+ print('GOT all tasks...')
pool = multiprocessing.Pool(16)
pool.map(_analyze, task_ids)
- print 'DONE'
+ print('DONE')
if __name__ == '__main__':
o = OldTaskBuilder()
diff --git a/mpworks/fix_scripts/legacy/actions/do_task_conversion_fixes.py b/mpworks/fix_scripts/legacy/actions/do_task_conversion_fixes.py
index b01dc0bb..17f1bb3c 100644
--- a/mpworks/fix_scripts/legacy/actions/do_task_conversion_fixes.py
+++ b/mpworks/fix_scripts/legacy/actions/do_task_conversion_fixes.py
@@ -54,9 +54,9 @@ def process_task(self, task_id):
t = self.old_tasks.find_one({'task_id': task_id})
try:
t_id, d = self.drone.assimilate(t)
- print 'ENTERED', t_id
+ print('ENTERED', t_id)
except:
- print 'ERROR entering', t['task_id']
+ print('ERROR entering', t['task_id'])
traceback.print_exc()
@@ -83,5 +83,5 @@ def process_task(self, task_id):
t = o.new_tasks.find_one({"task_id": new_task_id}, {"state": 1})
if t:
o.new_tasks.remove({'task_id': new_task_id})
- print 'REPARSING', old_task_id
+ print('REPARSING', old_task_id)
o.process_task(old_task_id)
diff --git a/mpworks/fix_scripts/legacy/mps_to_snl.py b/mpworks/fix_scripts/legacy/mps_to_snl.py
index 1257a53f..563ff741 100644
--- a/mpworks/fix_scripts/legacy/mps_to_snl.py
+++ b/mpworks/fix_scripts/legacy/mps_to_snl.py
@@ -19,7 +19,7 @@ def mps_dict_to_snl(mps_dict):
return None
if 'Carbon Capture Storage Initiative (CCSI)' in m['about']['metadata']['project_names']:
- print 'rejected old CCSI'
+ print('rejected old CCSI')
return None
mps_ids = [m['mps_id']]
@@ -38,7 +38,7 @@ def mps_dict_to_snl(mps_dict):
projects.append(project)
data = {'_materialsproject': {'deprecated': {'mps_ids': mps_ids}}, '_icsd': {}}
- for k, v in m['about']['metadata']['info'].iteritems():
+ for k, v in m['about']['metadata']['info'].items():
if k == 'icsd_comments':
data['_icsd']['comments'] = v
elif k == 'icsd_id':
diff --git a/mpworks/fix_scripts/legacy/old_task_drone.py b/mpworks/fix_scripts/legacy/old_task_drone.py
index 3611924f..b30ef79f 100644
--- a/mpworks/fix_scripts/legacy/old_task_drone.py
+++ b/mpworks/fix_scripts/legacy/old_task_drone.py
@@ -193,7 +193,7 @@ def process_fw(self, old_task, d):
vasp_signals['last_relax_dir'] = last_relax_dir
## see what error signals are present
- print "getting signals for dir :{}".format(last_relax_dir)
+ print("getting signals for dir :{}".format(last_relax_dir))
sl = SignalDetectorList()
sl.append(VASPInputsExistSignal())
diff --git a/mpworks/fix_scripts/legacy/task_to_fw.py b/mpworks/fix_scripts/legacy/task_to_fw.py
index 0bc3c71f..e3bcfc35 100644
--- a/mpworks/fix_scripts/legacy/task_to_fw.py
+++ b/mpworks/fix_scripts/legacy/task_to_fw.py
@@ -57,6 +57,6 @@ def task_dict_to_wf(task_dict, launchpad):
launchpad.add_wf(wf, reassign_all=False)
launchpad._upsert_launch(launches[0])
- print 'ADDED', fw_id
+ print('ADDED', fw_id)
# return fw_id
return fw_id
\ No newline at end of file
diff --git a/mpworks/fix_scripts/reparse_old_tasks.py b/mpworks/fix_scripts/reparse_old_tasks.py
index 4adb4d91..2eec8efc 100644
--- a/mpworks/fix_scripts/reparse_old_tasks.py
+++ b/mpworks/fix_scripts/reparse_old_tasks.py
@@ -73,14 +73,14 @@ def process_task(self, path):
logger.error("Bad run stats for {}.".format(path))
self.tasks.update({'dir_name_full': path}, {'$set': {"run_stats": run_stats}})
- print 'FINISHED', path
+ print('FINISHED', path)
else:
- print 'SKIPPING', path
+ print('SKIPPING', path)
except:
- print '-----'
- print 'ENCOUNTERED AN EXCEPTION!!!', path
+ print('-----')
+ print('ENCOUNTERED AN EXCEPTION!!!', path)
traceback.print_exc()
- print '-----'
+ print('-----')
def _analyze(data):
@@ -104,7 +104,7 @@ def _analyze(data):
q = {'submission_id': {'$exists': True}} # these are all old-style tasks
for d in tasks.find(q, {'dir_name_full': 1}):
m_data.append(d['dir_name_full'])
- print 'GOT all tasks...'
+ print('GOT all tasks...')
pool = multiprocessing.Pool(16)
pool.map(_analyze, m_data)
- print 'DONE'
+ print('DONE')
diff --git a/mpworks/fix_scripts/reparse_old_tasks_again.py b/mpworks/fix_scripts/reparse_old_tasks_again.py
index 232d14cd..186c3ba0 100644
--- a/mpworks/fix_scripts/reparse_old_tasks_again.py
+++ b/mpworks/fix_scripts/reparse_old_tasks_again.py
@@ -73,14 +73,14 @@ def process_task(self, path):
logger.error("Bad run stats for {}.".format(path))
self.tasks.update({'dir_name_full': path}, {'$set': {"run_stats": run_stats}})
- print 'FINISHED', path
+ print('FINISHED', path)
else:
- print 'SKIPPING', path
+ print('SKIPPING', path)
except:
- print '-----'
- print 'ENCOUNTERED AN EXCEPTION!!!', path
+ print('-----')
+ print('ENCOUNTERED AN EXCEPTION!!!', path)
traceback.print_exc()
- print '-----'
+ print('-----')
def _analyze(data):
@@ -105,9 +105,9 @@ def _analyze(data):
for line in f:
old_task = line.split(' ')[1].strip()
m_data.append(tasks.find_one({"task_id":old_task}, {'dir_name_full': 1})["dir_name_full"])
- print 'GOT all tasks...'
+ print('GOT all tasks...')
# print len(m_data)
# print m_data[1]
pool = multiprocessing.Pool(2)
pool.map(_analyze, m_data)
- print 'DONE'
+ print('DONE')
diff --git a/mpworks/fix_scripts/rerun_boltztrap.py b/mpworks/fix_scripts/rerun_boltztrap.py
index 67cd9873..06912dd9 100644
--- a/mpworks/fix_scripts/rerun_boltztrap.py
+++ b/mpworks/fix_scripts/rerun_boltztrap.py
@@ -62,7 +62,7 @@
last_line = ferr.readlines()[-1].strip()
if 'TIME LIMIT' in last_line:
lpdb.rerun_fw(fw_doc['fw_id'])
- print '[{}] rerun due to TIME LIMIT'.format(fw_doc['fw_id'])
+ print('[{}] rerun due to TIME LIMIT'.format(fw_doc['fw_id']))
else:
counter['RECENT_BTZ_FWS_' + fw_doc['state']] += 1
else:
@@ -71,7 +71,7 @@
#parent_fw = lpdb.fireworks.find_one({'fw_id': parent_fw_id}, {'state':1})
#if parent_fw['state'] == 'COMPLETED':
counter['RECENT_BTZ_FWS_' + fw_doc['state']] += 1
-print counter
+print(counter)
nfws = 0
for fw_doc in lpdb.fireworks.find(
@@ -85,8 +85,8 @@
if 'parent job unsuccessful' in last_line or 'Could not find task' in last_line:
parent_fw_id = wf['parent_links'][str(fw_doc['fw_id'])][-1]
lpdb.rerun_fw(parent_fw_id)
- print '[{}] {} --> marked parent {} for rerun'.format(nfws, fw_doc['fw_id'], parent_fw_id)
+ print('[{}] {} --> marked parent {} for rerun'.format(nfws, fw_doc['fw_id'], parent_fw_id))
else:
#lpdb.rerun_fw(fw_doc['fw_id'])
- print '[{}] {} --> {}'.format(nfws, fw_doc['fw_id'], last_line)
+ print('[{}] {} --> {}'.format(nfws, fw_doc['fw_id'], last_line))
nfws += 1
diff --git a/mpworks/fix_scripts/submit_bo_jobs.py b/mpworks/fix_scripts/submit_bo_jobs.py
index 2f2c5105..8f115067 100644
--- a/mpworks/fix_scripts/submit_bo_jobs.py
+++ b/mpworks/fix_scripts/submit_bo_jobs.py
@@ -20,11 +20,11 @@
for s in os.listdir(os.path.join(module_dir, "snls")):
if '.json' in s:
- print 'submitting', s
+ print('submitting', s)
with open(os.path.join(module_dir, "snls",s)) as f:
snl = StructureNL.from_dict(json.load(f))
sma.submit_snl(snl, 'anubhavster@gmail.com', {"priority": 10})
- print 'DONE submitting', s
+ print('DONE submitting', s)
-print 'DONE!'
\ No newline at end of file
+print('DONE!')
\ No newline at end of file
diff --git a/mpworks/maintenance_scripts/classify_fizzled.py b/mpworks/maintenance_scripts/classify_fizzled.py
index 2f644071..243ea3f3 100644
--- a/mpworks/maintenance_scripts/classify_fizzled.py
+++ b/mpworks/maintenance_scripts/classify_fizzled.py
@@ -69,7 +69,7 @@ def get_task_info(fw_id, tdb):
except_str = l['action']['stored_data'].get('_exception')
if 'Disk quota exceeded' in except_str:
except_dict['DISK_QUOTA_EXCEEDED'] = except_dict['DISK_QUOTA_EXCEEDED']+1
- print l['fw_id'], '*'
+ print(l['fw_id'], '*')
lpdb.rerun_fw(l['fw_id'])
elif 'No such file' in except_str:
# this is due to missing CHGCAR from Michael's old runs
@@ -110,7 +110,7 @@ def get_task_info(fw_id, tdb):
else:
except_dict[except_str] = except_dict[except_str]+1
- print '-----'
- for k, v in except_dict.iteritems():
- print {"{}\t{}".format(v, k)}
+ print('-----')
+ for k, v in except_dict.items():
+ print({"{}\t{}".format(v, k)})
diff --git a/mpworks/maintenance_scripts/icsd2012_to_snl.py b/mpworks/maintenance_scripts/icsd2012_to_snl.py
index c7b3c79b..c5751d8a 100644
--- a/mpworks/maintenance_scripts/icsd2012_to_snl.py
+++ b/mpworks/maintenance_scripts/icsd2012_to_snl.py
@@ -23,7 +23,7 @@ def icsd_dict_to_snl(icsd_dict):
data = {'_icsd': {}}
excluded_data = ['_id', 'a_len', 'b_len', 'c_len', 'alpha', 'beta', 'gamma', 'compostion', 'composition', 'created_at', 'crystal_id', 'idnum', 'journal', 'tstruct', 'updated_at', 'username']
- for k, v in icsd_dict.iteritems():
+ for k, v in icsd_dict.items():
if k not in excluded_data:
if isinstance(v, datetime.datetime):
v = v.strftime(format='%Y-%m-%d %H:%M:%S')
diff --git a/mpworks/maintenance_scripts/modify_snl.py b/mpworks/maintenance_scripts/modify_snl.py
index 08044fb4..8863dd81 100644
--- a/mpworks/maintenance_scripts/modify_snl.py
+++ b/mpworks/maintenance_scripts/modify_snl.py
@@ -66,35 +66,35 @@ def modify_snl(snl_id, new_snl, colls, reject_bad_tasks=False):
snl_d['snl_timestamp'] = snl_old['snl_timestamp']
# insert the new SNL into the snl collection
- print 'INSERTING SNL_ID', {'snl_id': snl_id}, snl_d
+ print('INSERTING SNL_ID', {'snl_id': snl_id}, snl_d)
colls.snl.update({'snl_id': snl_id}, snl_d)
# update the canonical SNL of the group
for s in colls.snlgroups.find({'canonical_snl.about._materialsproject.snl_id': snl_id}, {'snlgroup_id': 1}):
- print 'CHANGING SNLGROUP_ID', s['snlgroup_id']
+ print('CHANGING SNLGROUP_ID', s['snlgroup_id'])
colls.snlgroups.find_and_modify({'snlgroup_id': s['snlgroup_id']}, {'$set': {'canonical_snl': snl_d}})
# update FWs pt 1
for f in colls.fireworks.find({'spec.mpsnl.about._materialsproject.snl_id': snl_id}, {'fw_id': 1}):
- print 'CHANGING FW_ID', f['fw_id']
+ print('CHANGING FW_ID', f['fw_id'])
colls.fireworks.find_and_modify({'fw_id': f['fw_id']}, {'$set': {'spec.mpsnl': snl_d}})
# update FWs pt 2
for f in colls.fireworks.find({'spec.force_mpsnl.about._materialsproject.snl_id': snl_id}, {'fw_id': 1}):
- print 'CHANGING FW_ID', f['fw_id']
+ print('CHANGING FW_ID', f['fw_id'])
colls.fireworks.find_and_modify({'fw_id': f['fw_id']}, {'$set': {'spec.force_mpsnl': snl_d}})
# update Launches
for l in colls.launches.find({'action.update_spec.mpsnl.about._materialsproject.snl_id': snl_id}, {'launch_id': 1}):
- print 'CHANGING LAUNCH_ID', l['launch_id']
+ print('CHANGING LAUNCH_ID', l['launch_id'])
colls.launches.find_and_modify({'launch_id': l['launch_id']}, {'$set': {'action.update_spec.mpsnl': snl_d}})
# update tasks initial
for t in colls.tasks.find({'snl.about._materialsproject.snl_id': snl_id}, {'task_id': 1}):
- print 'CHANGING init TASK_ID', t['task_id']
+ print('CHANGING init TASK_ID', t['task_id'])
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$set': {'snl': snl_d}})
if reject_bad_tasks:
- print 'REJECTING TASK_ID', t['task_id']
+ print('REJECTING TASK_ID', t['task_id'])
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$set': {'state': 'rejected'}})
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$push': {'analysis.errors_MP.critical_signals': 'BAD STRUCTURE SNL'}})
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$inc': {'analysis.errors_MP.num_critical': 1}})
@@ -102,17 +102,17 @@ def modify_snl(snl_id, new_snl, colls, reject_bad_tasks=False):
# update tasks final
for t in colls.tasks.find({'snl_final.about._materialsproject.snl_id': snl_id}, {'task_id': 1}):
- print 'CHANGING final TASK_ID', t['task_id']
+ print('CHANGING final TASK_ID', t['task_id'])
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$set': {'snl_final': snl_d}})
if reject_bad_tasks:
- print 'REJECTING TASK_ID', t['task_id']
+ print('REJECTING TASK_ID', t['task_id'])
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$set': {'state': 'rejected'}})
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$push': {'analysis.errors_MP.critical_signals': 'BAD STRUCTURE SNL'}})
colls.tasks.find_and_modify({'task_id': t['task_id']}, {'$inc': {'analysis.errors_MP.num_critical': 1}})
# note: for now we are not fixing submissions in order to keep a record of submissions accurate, and also because the SNL assignment comes after submission
- print 'DONE PROCESSING', snl_id
+ print('DONE PROCESSING', snl_id)
def get_deprecated_snl(snl_id, colls):
@@ -128,6 +128,6 @@ def get_deprecated_snl(snl_id, colls):
snl_id = 1579
snl_new = get_deprecated_snl(snl_id, colls)
- print snl_new.as_dict()
+ print(snl_new.as_dict())
modify_snl(snl_id, snl_new, colls, reject_bad_tasks=True)
\ No newline at end of file
diff --git a/mpworks/maintenance_scripts/reparse_tasks.py b/mpworks/maintenance_scripts/reparse_tasks.py
index f8c7f057..6e7c171f 100644
--- a/mpworks/maintenance_scripts/reparse_tasks.py
+++ b/mpworks/maintenance_scripts/reparse_tasks.py
@@ -63,12 +63,12 @@ def process_task(self, data):
self.tasks.update({"task_id": t_id}, {"$set": {"snl_final": prev_info['snl_final'], "snlgroup_id_final": prev_info['snlgroup_id_final'], "snlgroup_changed": prev_info['snlgroup_changed']}})
- print 'FINISHED', t_id
+ print('FINISHED', t_id)
except:
- print '-----'
- print 'ENCOUNTERED AN EXCEPTION!!!', data[0]
+ print('-----')
+ print('ENCOUNTERED AN EXCEPTION!!!', data[0])
traceback.print_exc()
- print '-----'
+ print('-----')
def _analyze(data):
@@ -108,8 +108,8 @@ def _analyze(data):
for d in tasks.find(q, {'dir_name_full': 1, 'task_type': 1, 'task_id': 1}, timeout=False):
if d['task_id'] in finished_tasks:
- print 'DUPLICATE', d['task_id']
+ print('DUPLICATE', d['task_id'])
else:
o.process_task((d['dir_name_full'], 'Uniform' in d['task_type']))
# m_data.append((d['dir_name_full'], 'Uniform' in d['task_type']))
- print 'DONE'
\ No newline at end of file
+ print('DONE')
\ No newline at end of file
diff --git a/mpworks/osti_doi/__main__.py b/mpworks/osti_doi/__main__.py
index 4adbda01..b67a74d1 100644
--- a/mpworks/osti_doi/__main__.py
+++ b/mpworks/osti_doi/__main__.py
@@ -24,15 +24,15 @@
logger.setLevel(getattr(logging, loglevel))
db_yaml = 'materials_db_{}.yaml'.format('prod' if args.prod else 'dev')
-print db_yaml
+print(db_yaml)
if args.reset or args.info or args.plotly:
matad = OstiMongoAdapter.from_config(db_yaml=db_yaml)
if args.reset:
matad._reset()
elif args.info:
- print '{} DOIs in DOI collection.'.format(matad.doicoll.count())
+ print('{} DOIs in DOI collection.'.format(matad.doicoll.count()))
dois = matad.get_all_dois()
- print '{}/{} materials have DOIs.'.format(len(dois), matad.matcoll.count())
+ print('{}/{} materials have DOIs.'.format(len(dois), matad.matcoll.count()))
elif args.plotly:
import os, datetime
import plotly.plotly as py
@@ -56,7 +56,7 @@
) for idx,count in enumerate(counts)
])
filename = 'dois_{}'.format(today)
- print py.plot(data, filename=filename, auto_open=False)
+ print(py.plot(data, filename=filename, auto_open=False))
else:
# generate records for either n or all (n=0) not-yet-submitted materials
# OR generate records for specific materials (submitted or not)
diff --git a/mpworks/osti_doi/osti_record.py b/mpworks/osti_doi/osti_record.py
index cc9547d3..3d14871c 100644
--- a/mpworks/osti_doi/osti_record.py
+++ b/mpworks/osti_doi/osti_record.py
@@ -93,10 +93,10 @@ def insert_dois(self, dois):
dois_insert = [
{'_id': mpid, 'doi': d['doi'], 'valid': False,
'created_at': datetime.datetime.now().isoformat()}
- for mpid,d in dois.iteritems() if not d['updated']
+ for mpid,d in dois.items() if not d['updated']
]
if dois_insert: logger.info(self.doicoll.insert(dois_insert))
- dois_update = [ mpid for mpid,d in dois.iteritems() if d['updated'] ]
+ dois_update = [ mpid for mpid,d in dois.items() if d['updated'] ]
if dois_update:
logger.info(self.doicoll.update(
{'_id': {'$in': dois_update}},
diff --git a/mpworks/processors/process_submissions.py b/mpworks/processors/process_submissions.py
index 0bce2c72..a1833b6b 100644
--- a/mpworks/processors/process_submissions.py
+++ b/mpworks/processors/process_submissions.py
@@ -3,8 +3,6 @@
from fireworks.core.launchpad import LaunchPad
from mpworks.snl_utils.mpsnl import MPStructureNL
from mpworks.submission.submission_mongo import SubmissionMongoAdapter
-from mpworks.workflows.snl_to_wf import snl_to_wf
-from mpworks.workflows.snl_to_wf_elastic import snl_to_wf_elastic
from mpworks.workflows.wf_utils import NO_POTCARS
from pymatgen.matproj.snl import StructureNL
@@ -30,11 +28,11 @@ def run(self, sleep_time=None, infinite=False):
sleep_time = sleep_time if sleep_time else 30
while True:
self.submit_all_new_workflows()
- print "Updating existing workflows..."
+ print("Updating existing workflows...")
self.update_existing_workflows() # for updating the display
if not infinite:
break
- print 'sleeping', sleep_time
+ print('sleeping', sleep_time)
time.sleep(sleep_time)
def submit_all_new_workflows(self):
@@ -44,7 +42,7 @@ def submit_all_new_workflows(self):
def submit_new_workflow(self):
# finds a submitted job, creates a workflow, and submits it to FireWorks
- job = self.jobs.find_and_modify({'state': 'SUBMITTED'}, {'$set': {'state': 'WAITING'}})
+ job = self.jobs.find_one_and_update({'state': 'SUBMITTED'}, {'$set': {'state': 'WAITING'}})
if job:
submission_id = job['submission_id']
try:
@@ -54,37 +52,47 @@ def submit_new_workflow(self):
snl = StructureNL.from_dict(job)
if len(snl.structure.sites) > SubmissionProcessor.MAX_SITES:
self.sma.update_state(submission_id, 'REJECTED', 'too many sites', {})
- print 'REJECTED WORKFLOW FOR {} - too many sites ({})'.format(
- snl.structure.formula, len(snl.structure.sites))
+ print('REJECTED WORKFLOW FOR {} - too many sites ({})'.format(
+ snl.structure.formula, len(snl.structure.sites)))
elif not job['is_valid']:
self.sma.update_state(submission_id, 'REJECTED',
'invalid structure (atoms too close)', {})
- print 'REJECTED WORKFLOW FOR {} - invalid structure'.format(
- snl.structure.formula)
+ print('REJECTED WORKFLOW FOR {} - invalid structure'.format(
+ snl.structure.formula))
elif len(set(NO_POTCARS) & set(job['elements'])) > 0:
self.sma.update_state(submission_id, 'REJECTED',
'invalid structure (no POTCAR)', {})
- print 'REJECTED WORKFLOW FOR {} - invalid element (No POTCAR)'.format(
- snl.structure.formula)
+ print('REJECTED WORKFLOW FOR {} - invalid element (No POTCAR)'.format(
+ snl.structure.formula))
elif not job['is_ordered']:
self.sma.update_state(submission_id, 'REJECTED',
'invalid structure (disordered)', {})
- print 'REJECTED WORKFLOW FOR {} - invalid structure'.format(
- snl.structure.formula)
+ print('REJECTED WORKFLOW FOR {} - invalid structure'.format(
+ snl.structure.formula))
else:
snl.data['_materialsproject'] = snl.data.get('_materialsproject', {})
snl.data['_materialsproject']['submission_id'] = submission_id
# create a workflow
if "Elasticity" in snl.projects:
- wf=snl_to_wf_elastic(snl, job['parameters'])
+ from mpworks.workflows.snl_to_wf_elastic import snl_to_wf_elastic
+ wf = snl_to_wf_elastic(snl, job['parameters'])
+ elif "NMR" in snl.projects:
+ # The deferred imported is a dirty fix to avoid the import
+ # error from pymatgen.io.vasp.sets, although pointing to
+ # sets_deprecated would make things work temporally, the
+ # ultimate solution would be to use the new style VaspInputSets
+ # in pymatgen. NMR workflow uses the new style API.
+ from mpworks.workflows.snl_to_wf_nmr import snl_to_wf_nmr
+ wf = snl_to_wf_nmr(snl, job['parameters'])
else:
+ from mpworks.workflows.snl_to_wf import snl_to_wf
wf = snl_to_wf(snl, job['parameters'])
self.launchpad.add_wf(wf)
- print 'ADDED WORKFLOW FOR {}'.format(snl.structure.formula)
+ print('ADDED WORKFLOW FOR {}'.format(snl.structure.formula))
except:
- self.jobs.find_and_modify({'submission_id': submission_id},
- {'$set': {'state': 'ERROR'}})
+ self.jobs.find_one_and_update({'submission_id': submission_id},
+ {'$set': {'state': 'ERROR'}})
traceback.print_exc()
return submission_id
@@ -99,7 +107,7 @@ def update_existing_workflows(self):
try:
self.update_wf_state(submission_id)
except:
- print 'ERROR while processing s_id', submission_id
+ print('ERROR while processing s_id', submission_id)
traceback.print_exc()
@@ -109,10 +117,10 @@ def update_wf_state(self, submission_id):
wf = self.launchpad.workflows.find_one({'metadata.submission_id': submission_id},
sort=[('updated_on', -1)])
- if not wf:
- # submission_id from jobs collection doesn't exist in workflows collection
- # workflow has probably been removed manually by user via `lpad delete_wflows`
- return
+ if not wf:
+ # submission_id from jobs collection doesn't exist in workflows collection
+ # workflow has probably been removed manually by user via `lpad delete_wflows`
+ return
details = '(none)'
for e in self.launchpad.fireworks.find({'fw_id': {'$in' : wf['nodes']}},
diff --git a/mpworks/processors/submit_canonical.py b/mpworks/processors/submit_canonical.py
index e3e57e72..6f07d5dc 100644
--- a/mpworks/processors/submit_canonical.py
+++ b/mpworks/processors/submit_canonical.py
@@ -34,9 +34,10 @@ def clear_env():
lp.reset('', require_password=False)
snl._reset()
- conn = MongoClient(db_creds['host'], db_creds['port'])
+ conn = MongoClient(db_creds['host'], db_creds['port'], connect=False)
db = conn[db_creds['database']]
- db.authenticate(db_creds['admin_user'], db_creds['admin_password'])
+ if db_creds['admin_user'] is not None:
+ db.authenticate(db_creds['admin_user'], db_creds['admin_password'])
db.tasks.remove()
db.boltztrap.remove()
db.counter.remove()
@@ -63,7 +64,7 @@ def submit_tests(names=None, params=None):
mpr = MPRester()
- for name, sid in compounds.iteritems():
+ for name, sid in compounds.items():
if not names or name in names:
sid = mpr.get_materials_id_from_task_id("mp-{}".format(sid))
s = mpr.get_structure_by_material_id(sid, final=False)
diff --git a/mpworks/snl_utils/mpsnl.py b/mpworks/snl_utils/mpsnl.py
index cee62fa7..efd831b2 100644
--- a/mpworks/snl_utils/mpsnl.py
+++ b/mpworks/snl_utils/mpsnl.py
@@ -142,7 +142,7 @@ def as_dict(self):
d['all_snl_ids'] = self.all_snl_ids
d['num_snl'] = len(self.all_snl_ids)
d['species_snl'] = [s.as_dict() for s in self.species_snl]
- d['species_groups'] = dict([(str(k), v) for k, v in self.species_groups.iteritems()])
+ d['species_groups'] = dict([(str(k), v) for k, v in self.species_groups.items()])
d['snlgroup_key'] = self.canonical_snl.snlgroup_key
return d
@@ -150,7 +150,7 @@ def as_dict(self):
def from_dict(cls, d):
sp_snl = [MPStructureNL.from_dict(s) for s in d['species_snl']] if 'species_snl' in d else None
# to account for no int keys in Mongo dicts
- species_groups = dict([(int(k), v) for k, v in d['species_groups'].iteritems()]) if 'species_groups' in d else None
+ species_groups = dict([(int(k), v) for k, v in d['species_groups'].items()]) if 'species_groups' in d else None
return SNLGroup(d['snlgroup_id'], MPStructureNL.from_dict(d['canonical_snl']),
d['all_snl_ids'], sp_snl, species_groups)
@@ -171,19 +171,27 @@ def add_if_belongs(self, cand_snl):
chemsys = '-'.join(elsyms)
if (
cand_snl.structure.num_sites > 1500 or self.canonical_structure.num_sites > 1500) and chemsys == 'C-Ce':
- print 'SKIPPING LARGE C-Ce'
+ print('SKIPPING LARGE C-Ce')
return False, None
# make sure the structure is not already in all_structures
if cand_snl.snl_id in self.all_snl_ids:
- print 'WARNING: add_if_belongs() has detected that you are trying to add the same SNL id twice!'
+ print('WARNING: add_if_belongs() has detected that you are trying to add the same SNL id twice!')
return False, None
#try a structure fit to the canonical structure
- # use default Structure Matcher params from April 24, 2013, as suggested by Shyue
- # we are using the ElementComparator() because this is how we want to group results
- sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True,
+ if "NMR" not in cand_snl.projects:
+ # use default Structure Matcher params from April 24, 2013, as suggested by Shyue
+ # we are using the ElementComparator() because this is how we want to group results
+ ltol = 0.2
+ stol = 0.3
+ angle_tol = 5.0
+ else:
+ ltol = 0.00002
+ stol = 0.00003
+ angle_tol = 0.0005
+ sm = StructureMatcher(ltol=ltol, stol=stol, angle_tol=angle_tol, primitive_cell=True, scale=True,
attempt_supercell=False, comparator=ElementComparator())
if not sm.fit(cand_snl.structure, self.canonical_structure):
@@ -198,8 +206,9 @@ def add_if_belongs(self, cand_snl):
if has_species_properties(cand_snl.structure):
for snl in self.species_snl:
- sms = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True,
- attempt_supercell=False, comparator=SpeciesComparator())
+ sms = StructureMatcher(ltol=ltol, stol=stol, angle_tol=angle_tol, primitive_cell=True,
+ scale=True, attempt_supercell=False,
+ comparator=SpeciesComparator())
if sms.fit(cand_snl.structure, snl.structure):
spec_group = snl.snl_id
self.species_groups[snl.snl_id].append(cand_snl.snl_id)
diff --git a/mpworks/snl_utils/snl_mongo.py b/mpworks/snl_utils/snl_mongo.py
index b0394566..bdc45a5a 100644
--- a/mpworks/snl_utils/snl_mongo.py
+++ b/mpworks/snl_utils/snl_mongo.py
@@ -28,7 +28,7 @@ def __init__(self, host='localhost', port=27017, db='snl', username=None,
self.username = username
self.password = password
- self.connection = MongoClient(host, port, j=False)
+ self.connection = MongoClient(host, port, j=False, connect=False)
self.database = self.connection[db]
if self.username:
self.database.authenticate(username, password)
@@ -122,9 +122,9 @@ def add_mpsnl(self, mpsnl, force_new=False, snlgroup_guess=None):
def _add_if_belongs(self, snlgroup, mpsnl, testing_mode):
match_found, spec_group = snlgroup.add_if_belongs(mpsnl)
if match_found:
- print 'MATCH FOUND, grouping (snl_id, snlgroup): {}'.format((mpsnl.snl_id, snlgroup.snlgroup_id))
+ print('MATCH FOUND, grouping (snl_id, snlgroup): {}'.format((mpsnl.snl_id, snlgroup.snlgroup_id)))
if not testing_mode:
- self.snlgroups.update_one({'snlgroup_id': snlgroup.snlgroup_id}, {'$set': snlgroup.as_dict()})
+ self.snlgroups.update_one({'snlgroup_id': snlgroup.snlgroup_id}, {'$set': snlgroup.as_dict()})
return match_found, spec_group
@@ -181,7 +181,7 @@ def lock_db(self, n_tried=0, n_max_tries=10):
# DB was already locked by another process in a race condition
self.lock_db(n_tried=n_tried, n_max_tries=n_max_tries)
else:
- raise ValueError('DB locked by another process! Could not lock even after {} minutes!'.format(n_max_tries/60))
+ raise ValueError('DB locked by another process! Could not lock even after {} minutes!'.format(n_max_tries//60))
def release_lock(self):
self.id_assigner.update_many({}, {'$set':{'lock': False}})
diff --git a/mpworks/submission/submission_mongo.py b/mpworks/submission/submission_mongo.py
index 3cfb2523..9b87a57b 100644
--- a/mpworks/submission/submission_mongo.py
+++ b/mpworks/submission/submission_mongo.py
@@ -1,6 +1,7 @@
import json
import os
import datetime
+import sys
from pymongo import MongoClient, DESCENDING
from mpworks.snl_utils.mpsnl import MPStructureNL
@@ -34,7 +35,11 @@ def reconstitute_dates(obj_dict):
if isinstance(obj_dict, list):
return [reconstitute_dates(v) for v in obj_dict]
- if isinstance(obj_dict, basestring):
+ if sys.version_info[0] > 2:
+ str_type = str
+ else:
+ str_type = basestring
+ if isinstance(obj_dict, str_type):
try:
return datetime.datetime.strptime(obj_dict, "%Y-%m-%dT%H:%M:%S.%f")
except ValueError:
@@ -73,7 +78,7 @@ def __init__(self, host='localhost', port=27017, db='snl', username=None,
self.username = username
self.password = password
- self.connection = MongoClient(host, port, j=False)
+ self.connection = MongoClient(host, port, j=False, connect=False)
self.database = self.connection[db]
if self.username:
self.database.authenticate(username, password)
@@ -88,13 +93,13 @@ def _reset(self):
self.jobs.remove()
def _update_indices(self):
- self.jobs.ensure_index('submission_id', unique=True)
- self.jobs.ensure_index('state')
- self.jobs.ensure_index('submitter_email')
+ self.jobs.create_index('submission_id', unique=True)
+ self.jobs.create_index('state')
+ self.jobs.create_index('submitter_email')
def _get_next_submission_id(self):
- return self.id_assigner.find_and_modify(
- query={}, update={'$inc': {'next_submission_id': 1}})[
+ return self.id_assigner.find_one_and_update(
+ filter={}, update={'$inc': {'next_submission_id': 1}})[
'next_submission_id']
def _restart_id_assigner_at(self, next_submission_id):
@@ -140,7 +145,7 @@ def resubmit(self, submission_id, snl_db=None):
updates['parameters'] = self.jobs.find_one({'submission_id': submission_id}, {'parameters': 1})['parameters']
updates['parameters'].update({"mpsnl": mpsnl.as_dict(), "snlgroup_id": snlgroup_id})
- self.jobs.find_and_modify({'submission_id': submission_id}, {'$set': updates})
+ self.jobs.find_one_and_update({'submission_id': submission_id}, {'$set': updates})
def cancel_submission(self, submission_id):
@@ -165,8 +170,8 @@ def to_dict(self):
return d
def update_state(self, submission_id, state, state_details, task_dict):
- self.jobs.find_and_modify({'submission_id': submission_id},
- {'$set': {'state': state, 'state_details': state_details, 'task_dict': task_dict}})
+ self.jobs.find_one_and_update({'submission_id': submission_id},
+ {'$set': {'state': state, 'state_details': state_details, 'task_dict': task_dict}})
@classmethod
def from_dict(cls, d):
diff --git a/mpworks/workflows/snl_to_wf.py b/mpworks/workflows/snl_to_wf.py
index 40f00dcc..35fad742 100644
--- a/mpworks/workflows/snl_to_wf.py
+++ b/mpworks/workflows/snl_to_wf.py
@@ -119,7 +119,7 @@ def snl_to_wf(snl, parameters=None):
# insert into DB - GGA structure optimization
spec = {'task_type': 'VASP db insertion', '_priority': priority*2,
- '_allow_fizzled_parents': True, '_queueadapter': QA_DB,
+ '_allow_fizzled_parents': True, '_queueadapter': QA_DB,
"_dupefinder": DupeFinderDB().to_dict(), '_trackers': trackers_db}
fws.append(Firework([VaspToDBTask()], spec, fw_id=2,
name=get_slug(f + '--' + spec['task_type'])))
@@ -131,7 +131,7 @@ def snl_to_wf(snl, parameters=None):
if not parameters.get('skip_bandstructure', False) and \
(not ggau_compound or parameters.get('force_gga_bandstructure', False)):
- spec = {'task_type': 'Controller: add Electronic Structure v2',
+ spec = {'task_type': 'Controller: add Electronic Structure v2',
'_priority': priority, '_queueadapter': QA_CONTROL}
fws.append(Firework([AddEStructureTask()], spec, fw_id=3,
name=get_slug(f + '--' + spec['task_type'])))
@@ -149,16 +149,16 @@ def snl_to_wf(snl, parameters=None):
connections[2].append(10)
spec = {'task_type': 'VASP db insertion', '_queueadapter': QA_DB,
- '_allow_fizzled_parents': True, '_priority': priority,
- "_dupefinder": DupeFinderDB().to_dict(),
+ '_allow_fizzled_parents': True, '_priority': priority,
+ "_dupefinder": DupeFinderDB().to_dict(),
'_trackers': trackers_db}
fws.append(
- Firework([VaspToDBTask()], spec,
+ Firework([VaspToDBTask()], spec,
name=get_slug(f + '--' + spec['task_type']), fw_id=11))
connections[10] = [11]
if not parameters.get('skip_bandstructure', False):
- spec = {'task_type': 'Controller: add Electronic Structure v2',
+ spec = {'task_type': 'Controller: add Electronic Structure v2',
'_priority': priority, '_queueadapter': QA_CONTROL}
fws.append(
Firework([AddEStructureTask()], spec, fw_id=12,
diff --git a/mpworks/workflows/snl_to_wf_nmr.py b/mpworks/workflows/snl_to_wf_nmr.py
new file mode 100644
index 00000000..3aa456f3
--- /dev/null
+++ b/mpworks/workflows/snl_to_wf_nmr.py
@@ -0,0 +1,156 @@
+import copy
+from collections import defaultdict
+
+from fireworks import Firework
+from fireworks.core.firework import Tracker, Workflow
+from fireworks.utilities.fw_utilities import get_slug
+from pymatgen import Composition
+
+from mpworks.dupefinders.dupefinder_vasp import DupeFinderDB
+from mpworks.firetasks.custodian_task import get_custodian_task
+from mpworks.firetasks.nmr_tasks import snl_to_nmr_spec, NmrVaspToDBTask, DictVaspSetupTask, \
+ TripleJumpRelaxVaspToDBTask, ScanFunctionalSetupTask
+from mpworks.firetasks.snl_tasks import AddSNLTask
+from mpworks.firetasks.vasp_io_tasks import VaspWriterTask, VaspCopyTask, VaspToDBTask
+from mpworks.snl_utils.mpsnl import MPStructureNL, get_meta_from_structure
+from mpworks.workflows.wf_settings import QA_DB, QA_VASP
+
+__author__ = 'Xiaohui Qu'
+__copyright__ = 'Copyright 2016, The Materials Project'
+__version__ = '0.1'
+__maintainer__ = 'Xiaohui Qu'
+__email__ = 'xhqu1981@gmail.com'
+__date__ = 'May 31, 2016'
+
+
+"""
+This is modified from Wei Chen's snl_to_wf_elastic.
+"""
+
+
+def get_nmr_vasp_fw(fwid, copy_contcar, istep, nick_name, parameters, priority, structure, additional_run_tags):
+ spec = snl_to_nmr_spec(structure, istep, parameters, additional_run_tags)
+ trackers = [Tracker('FW_job.out'), Tracker('FW_job.error'), Tracker('vasp.out'), Tracker('OUTCAR'),
+ Tracker('OSZICAR'), Tracker('OUTCAR.relax1'), Tracker('OUTCAR.relax2')]
+ spec['_priority'] = priority
+ spec['_queueadapter'] = QA_VASP
+ spec['_trackers'] = trackers
+ tasks = [DictVaspSetupTask()]
+ functional = parameters.get("functional", "PBE")
+ spec["functional"] = functional
+ if functional != "PBE":
+ tasks.append(ScanFunctionalSetupTask())
+ tasks.append(get_custodian_task(spec))
+ vasp_fw = Firework(tasks, spec, name=get_slug(nick_name + '--' + spec['task_type']),
+ fw_id=fwid)
+ return vasp_fw
+
+
+def get_nmr_db_fw(nick_name, fwid, prev_task_type, priority, task_class):
+ trackers_db = [Tracker('FW_job.out'), Tracker('FW_job.error')]
+ spec = {'task_type': 'VASP db insertion', '_priority': priority * 2,
+ '_allow_fizzled_parents': True, '_queueadapter': QA_DB, "_dupefinder": DupeFinderDB().to_dict(),
+ '_trackers': trackers_db}
+ db_fw = Firework([task_class(parameters={"update_input": False})], spec, name=get_slug(nick_name + '--' + spec['task_type'] +
+ '--' + prev_task_type),
+ fw_id=fwid)
+ return db_fw
+
+
+def snl_to_wf_nmr(snl, parameters):
+ # parameters["user_vasp_settings"] specifies user defined incar/kpoints parameters
+ fws = []
+ connections = defaultdict(list)
+ cur_fwid = 0
+ parameters = parameters if parameters else {}
+
+ snl_priority = parameters.get('priority', 1)
+ priority = snl_priority * 2 # once we start a job, keep going!
+
+ f = Composition(snl.structure.composition.reduced_formula).alphabetical_formula
+ nick_name = parameters.get("nick_name", f)
+ functional = parameters.get("functional", "PBE")
+ if functional != "PBE":
+ nick_name += "_FUNC_" + functional
+
+ if 'exact_structure' in parameters and parameters['exact_structure']:
+ structure = snl.structure
+ else:
+ structure = snl.structure.get_primitive_structure()
+
+ additional_run_tags = []
+ # add exact structure run tag automatically if we have a unique situation
+ if 'exact_structure' in parameters and parameters['exact_structure'] and \
+ snl.structure != structure:
+ additional_run_tags.append('exact_structure')
+
+ # add the SNL to the SNL DB and figure out duplicate group
+ tasks = [AddSNLTask()]
+ spec = {'task_type': 'Add to SNL database', 'snl': snl.as_dict(),
+ '_queueadapter': QA_DB, '_priority': snl_priority}
+ if 'snlgroup_id' in parameters and isinstance(snl, MPStructureNL):
+ spec['force_mpsnl'] = snl.as_dict()
+ spec['force_snlgroup_id'] = parameters['snlgroup_id']
+ del spec['snl']
+ addsnl_fwid = cur_fwid
+ cur_fwid += 1
+ fws.append(Firework(tasks, spec,
+ name=get_slug(nick_name + '--' + spec['task_type']), fw_id=addsnl_fwid))
+
+ parameters["exact_structure"] = True
+ # run Triple Jump Structure Relaxation to Converge to a Very Small Force
+ geom_calc_fwid = None
+ geom_db_fwid = None
+ for istep in [1, 2, 3]:
+ # Geometry Optimization
+ copy_contcar = istep >= 2
+ geom_calc_fwid = cur_fwid
+ cur_fwid += 1
+ vasp_fw = get_nmr_vasp_fw(geom_calc_fwid, copy_contcar, istep, nick_name,
+ copy.deepcopy(parameters), priority, copy.deepcopy(structure),
+ additional_run_tags)
+ fws.append(vasp_fw)
+ geom_task_type = vasp_fw.spec['task_type']
+ if istep == 1:
+ connections[addsnl_fwid] = [geom_calc_fwid]
+ else:
+ prev_db_fwid = geom_db_fwid
+ connections[prev_db_fwid] = [geom_calc_fwid]
+
+ # insert into DB
+ task_class = TripleJumpRelaxVaspToDBTask
+ prev_task_type = geom_task_type
+ geom_db_fwid = cur_fwid
+ cur_fwid += 1
+ db_fw = get_nmr_db_fw(nick_name, geom_db_fwid, prev_task_type, priority, task_class)
+ fws.append(db_fw)
+ connections[geom_calc_fwid] = [geom_db_fwid]
+
+ # Calculate NMR Tensors
+ for istep in [-1, -2]:
+ # -1: Chemical Shift, -2: EFG
+ # Geometry Optimization
+ nmr_calc_fwid = cur_fwid
+ cur_fwid += 1
+ vasp_fw = get_nmr_vasp_fw(nmr_calc_fwid, True, istep, nick_name, copy.deepcopy(parameters),
+ priority, copy.deepcopy(structure), additional_run_tags)
+ fws.append(vasp_fw)
+ nmr_task_type = vasp_fw.spec['task_type']
+ connections[geom_db_fwid].extend([nmr_calc_fwid])
+
+ # insert into DB
+ task_class = NmrVaspToDBTask
+ prev_task_type = nmr_task_type
+ nmr_db_fwid = cur_fwid
+ cur_fwid += 1
+ db_fw = get_nmr_db_fw(nick_name, nmr_db_fwid, prev_task_type, priority, task_class)
+ fws.append(db_fw)
+ connections[nmr_calc_fwid] = [nmr_db_fwid]
+
+ wf_meta = get_meta_from_structure(snl.structure)
+ wf_meta['run_version'] = 'June 2016 (1)'
+
+ if '_materialsproject' in snl.data and 'submission_id' in snl.data['_materialsproject']:
+ wf_meta['submission_id'] = snl.data['_materialsproject']['submission_id']
+
+ return Workflow(fws, connections, name=nick_name, metadata=wf_meta)
diff --git a/mpworks/workflows/surface_wf.py b/mpworks/workflows/surface_wf.py
index 51038b19..16a1be8b 100644
--- a/mpworks/workflows/surface_wf.py
+++ b/mpworks/workflows/surface_wf.py
@@ -103,9 +103,9 @@ def __init__(self, api_key, list_of_elements=[], indices_dict=None,
spa = SpacegroupAnalyzer(prim_unit_cell, symprec=symprec,
angle_tolerance=angle_tolerance)
conv_unit_cell = spa.get_conventional_standard_structure()
- print conv_unit_cell
+ print(conv_unit_cell)
unit_cells_dict[el] = [conv_unit_cell, min(e_per_atom)]
- print el
+ print(el)
self.api_key = api_key
@@ -146,9 +146,9 @@ def from_max_index(self, max_index, max_normal_search=True,
get_symmetrically_distinct_miller_indices(self.unit_cells_dict[el][0],
max_index)
- print 'surface ', el
+ print('surface ', el)
- print '# ', el
+ print('# ', el)
if max_only:
for hkl in list_of_indices:
@@ -310,17 +310,17 @@ def launch_workflow(self, launchpad_dir="", k_product=50, job=None,
for key in self.miller_dict.keys():
# Enumerate through all compounds in the dictionary,
# the key is the compositional formula of the compound
- print key
+ print(key)
for miller_index in self.miller_dict[key]:
# Enumerates through all miller indices we
# want to create slabs of that compound from
- print str(miller_index)
+ print(str(miller_index))
max_norm = max(miller_index) if self.max_normal_search else None
# Whether or not we want to use the
# max_normal_search algorithm from surface.py
- print 'true or false max norm is ', max_norm, self.max_normal_search
+ print('true or false max norm is ', max_norm, self.max_normal_search)
slab = SlabGenerator(self.unit_cells_dict[key][0], miller_index,
self.ssize, self.vsize, max_normal_search=max_norm)
diff --git a/mpworks/workflows/wf_settings.py b/mpworks/workflows/wf_settings.py
index 01ea9e39..242f45e8 100644
--- a/mpworks/workflows/wf_settings.py
+++ b/mpworks/workflows/wf_settings.py
@@ -1,3 +1,7 @@
+import os
+
+from monty.design_patterns import singleton
+
__author__ = 'Anubhav Jain'
__copyright__ = 'Copyright 2013, The Materials Project'
__version__ = '0.1'
@@ -12,18 +16,30 @@
QA_DB = {'nnodes': 1, 'nodes' : 1, 'walltime': '2:00:00'}
QA_CONTROL = {'nnodes': 1, 'nodes': 1, 'walltime': '00:30:00'}
-MOVE_TO_GARDEN_DEV = False
-MOVE_TO_GARDEN_PROD = False
+@singleton
+class WFSettings(object):
+ """
+ This class stores settings for the Workflows. Use Singleton to enable runtime dynamic chage
+ """
+
+ def __init__(self):
+ self.MOVE_TO_GARDEN_DEV = False
+ self.MOVE_TO_GARDEN_PROD = False
+ if "GARDEN_LOC" in os.environ:
+ self.GARDEN = os.environ["GARDEN_LOC"]
+ else:
+ self.GARDEN = '/project/projectdirs/matgen/garden'
-GARDEN = '/project/projectdirs/matgen/garden'
+ @property
+ def RUN_LOCS(self):
+ return [self.GARDEN, self.GARDEN + '/dev',
+ '/project/projectdirs/matgen/garden/control_blocks',
+ '/project/projectdirs/matgen/scratch',
+ '/global/scratch/sd/matcomp/', '/global/homes/m/matcomp',
+ '/scratch/scratchdirs/matcomp/', '/scratch2/scratchdirs/matcomp/',
+ '/global/scratch/sd/matcomp/aj_tests/',
+ '/global/scratch/sd/matcomp/wc_tests/',
+ '/global/scratch/sd/matcomp/aj_prod/',
+ '/global/scratch2/sd/matcomp/mp_prod/',
+ '/global/scratch2/sd/matcomp/mp_prod_hopper/']
-RUN_LOCS = [GARDEN, GARDEN+'/dev',
- '/project/projectdirs/matgen/garden/control_blocks',
- '/project/projectdirs/matgen/scratch',
- '/global/scratch/sd/matcomp/', '/global/homes/m/matcomp',
- '/scratch/scratchdirs/matcomp/', '/scratch2/scratchdirs/matcomp/',
- '/global/scratch/sd/matcomp/aj_tests/',
- '/global/scratch/sd/matcomp/wc_tests/',
- '/global/scratch/sd/matcomp/aj_prod/',
- '/global/scratch2/sd/matcomp/mp_prod/',
- '/global/scratch2/sd/matcomp/mp_prod_hopper/']
diff --git a/mpworks/workflows/wf_utils.py b/mpworks/workflows/wf_utils.py
index 79897a9d..237677d9 100644
--- a/mpworks/workflows/wf_utils.py
+++ b/mpworks/workflows/wf_utils.py
@@ -10,7 +10,7 @@
import re
from monty.os.path import zpath
-from mpworks.workflows.wf_settings import RUN_LOCS, GARDEN
+from mpworks.workflows.wf_settings import WFSettings
__author__ = 'Anubhav Jain'
@@ -68,9 +68,13 @@ def get_block_part(m_dir):
def get_loc(m_dir):
if os.path.exists(m_dir):
return m_dir
+ if re.match("/global/cscratch1/sd/\w+[.]new/.+", m_dir):
+ new_scr = m_dir.replace(".new", "")
+ if os.path.exists(new_scr):
+ return new_scr
block_part = get_block_part(m_dir)
- for preamble in RUN_LOCS:
+ for preamble in WFSettings().RUN_LOCS:
new_loc = os.path.join(preamble, block_part)
if os.path.exists(new_loc):
return new_loc
@@ -80,7 +84,7 @@ def get_loc(m_dir):
def move_to_garden(m_dir, prod=False):
block_part = get_block_part(m_dir)
- garden_part = GARDEN if prod else GARDEN+'/dev'
+ garden_part = WFSettings().GARDEN if prod else WFSettings().GARDEN+'/dev'
f_dir = os.path.join(garden_part, block_part)
if os.path.exists(m_dir) and not os.path.exists(f_dir) and m_dir != f_dir:
try:
diff --git a/requirements.txt b/requirements.txt
index 78067974..f7d512ed 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,6 @@ monty==0.6.4
pybtex==0.18
PyYAML==3.11
requests==2.6.0
-six==1.9.0
+six==1.10.0
xmltodict==0.9.2
pymatgen>=4.0.0
diff --git a/setup.py b/setup.py
index 3eb14f93..1fa73930 100644
--- a/setup.py
+++ b/setup.py
@@ -7,18 +7,22 @@
__email__ = "ajain@lbl.gov"
__date__ = "Mar 15, 2013"
-from setuptools import setup, find_packages
+import os, sys
+
from mpworks import __version__
-import os
-import multiprocessing, logging # AJ: for some reason this is needed to not have "python setup.py test" freak out
+from setuptools import setup, find_packages
module_dir = os.path.dirname(os.path.abspath(__file__))
if __name__ == "__main__":
+ if sys.version_info[0] > 2:
+ readme_text = open(os.path.join(module_dir, 'README.rst'), encoding="UTF-16").read()
+ else:
+ readme_text = open(os.path.join(module_dir, 'README.rst')).read()
setup(name='MPWorks',
version=__version__,
description='Materials Project codes',
- long_description=open(os.path.join(module_dir, 'README.rst')).read(),
+ long_description=readme_text,
url='https://github.com/materialsproject/MPWorks',
author='Anubhav Jain',
author_email='anubhavster@gmail.com',