def test_historynodes(self): a = StructureNL(self.s, self.hulk, history=[self.valid_node]) self.assertEqual(a.history[0].name, "DB 1") self.assertEqual(a.history[0].url, "www.db1URLgoeshere.com") self.assertEqual(a.history[0].description, {"db1_id": 12424}) a = StructureNL(self.s, self.hulk, history=[self.valid_node, self.valid_node2]) self.assertEqual(a.history[1].name, "DB 2") self.assertEqual(a.history[1].url, "www.db2URLgoeshere.com") self.assertEqual(a.history[1].description, {"db2_id": 12424}) # invalid nodes should not work self.assertRaises(Exception, StructureNL, self.s, self.hulk, history=[self.invalid_node]) # too many nodes should not work self.assertRaises(ValueError, StructureNL, self.s, self.hulk, history=[self.valid_node] * 1000)
def test_to_from_dict(self): # no complicated objects in the 'data' or 'nodes' field a = StructureNL(self.s, self.hulk, ['test_project'], self.pmg, ['remark1'], {"_my_data": "string"}, [self.valid_node, self.valid_node2]) b = StructureNL.from_dict(a.as_dict()) self.assertEqual(a, b) # complicated objects in the 'data' and 'nodes' field complicated_node = { "name": "complicated node", "url": "www.complicatednodegoeshere.com", "description": { "structure": self.s2 } } a = StructureNL(self.s, self.hulk, ['test_project'], self.pmg, ['remark1'], {"_my_data": { "structure": self.s2 }}, [complicated_node, self.valid_node]) b = StructureNL.from_dict(a.as_dict()) self.assertEqual( a, b, 'to/from dict is broken when object embedding is ' 'used! Apparently MontyEncoding is broken...') #Test molecule molnl = StructureNL(self.mol, self.hulk, references=self.pmg) b = StructureNL.from_dict(molnl.as_dict()) self.assertEqual(molnl, b)
def test_references(self): # junk reference should not work self.assertRaises(ValueError, StructureNL, self.s, self.hulk, references=self.junk) # good references should be ok StructureNL(self.s, self.hulk, references=self.pmg) # unicode references should work StructureNL(self.s, self.hulk, references=self.unicode_title) # multi-line references should be OK StructureNL(self.s, self.hulk, references='\n'.join([self.matproj, self.pmg])) # super long references are bad self.assertRaises(ValueError, StructureNL, self.s, self.hulk, references=self.superlong)
def to_snl(self, authors, projects=None, references='', remarks=None, data=None, created_at=None): if self.other_parameters: warn('Data in TransformedStructure.other_parameters discarded ' 'during type conversion to SNL') hist = [] for h in self.history: snl_metadata = h.pop('_snl', {}) hist.append({ 'name': snl_metadata.pop('name', 'pymatgen'), 'url': snl_metadata.pop('url', 'http://pypi.python.org/pypi/pymatgen'), 'description': h }) from pymatgen.matproj.snl import StructureNL return StructureNL(self.final_structure, authors, projects, references, remarks, data, hist, created_at)
def test_data(self): # Structure data is OK due to PMGEncoder/Decoder a = StructureNL(self.s, self.hulk, data={"_structure": self.s2}) self.assertEqual(a.data["_structure"], self.s2, 'Data storage is broken') self.assertRaises(ValueError, StructureNL, self.s, self.hulk, data={"bad_key": 1})
def test_remarks(self): a = StructureNL(self.s, self.hulk, remarks="string format") self.assertEqual(a.remarks[0], "string format") self.assertRaises(ValueError, StructureNL, self.s, self.hulk, remarks=self.remark_fail)
def run_task(self, fw_spec): # Read structure from previous relaxation relaxed_struct = fw_spec['output']['crystal'] # Generate deformed structures d_struct_set = DeformedStructureSet(relaxed_struct, ns=0.06) wf=[] for i, d_struct in enumerate(d_struct_set.def_structs): fws=[] connections={} f = Composition(d_struct.formula).alphabetical_formula snl = StructureNL(d_struct, 'Joseph Montoya <*****@*****.**>', projects=["Elasticity"]) tasks = [AddSNLTask()] snl_priority = fw_spec.get('priority', 1) spec = {'task_type': 'Add Deformed Struct to SNL database', 'snl': snl.as_dict(), '_queueadapter': QA_DB, '_priority': snl_priority} if 'snlgroup_id' in fw_spec and isinstance(snl, MPStructureNL): spec['force_mpsnl'] = snl.as_dict() spec['force_snlgroup_id'] = fw_spec['snlgroup_id'] del spec['snl'] fws.append(Firework(tasks, spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-1000+i*10)) connections[-1000+i*10] = [-999+i*10] spec = snl_to_wf._snl_to_spec(snl, parameters={'exact_structure':True}) spec = update_spec_force_convergence(spec) spec['deformation_matrix'] = d_struct_set.deformations[i].tolist() spec['original_task_id'] = fw_spec["task_id"] spec['_priority'] = fw_spec['_priority']*2 #Turn off dupefinder for deformed structure del spec['_dupefinder'] spec['task_type'] = "Optimize deformed structure" fws.append(Firework([VaspWriterTask(), SetupElastConstTask(), get_custodian_task(spec)], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-999+i*10)) priority = fw_spec['_priority']*3 spec = {'task_type': 'VASP db insertion', '_priority': priority, '_allow_fizzled_parents': True, '_queueadapter': QA_DB, 'elastic_constant':"deformed_structure", 'clean_task_doc':True, 'deformation_matrix':d_struct_set.deformations[i].tolist(), 'original_task_id':fw_spec["task_id"]} fws.append(Firework([VaspToDBTask(), AddElasticDataToDBTask()], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-998+i*10)) connections[-999+i*10] = [-998+i*10] wf.append(Workflow(fws, connections)) return FWAction(additions=wf)
def test_authors(self): a = StructureNL(self.s, self.hulk, references=self.pmg) self.assertEqual(a.authors[0].name, "Hulk") self.assertEqual(a.authors[0].email, "*****@*****.**") a = StructureNL(self.s, self.america, references=self.pmg) self.assertEqual(a.authors[0].name, "Captain America") self.assertEqual(a.authors[0].email, "*****@*****.**") a = StructureNL(self.s, self.thor, references=self.pmg) self.assertEqual(a.authors[0].name, "Thor") self.assertEqual(a.authors[0].email, "*****@*****.**") a = StructureNL(self.s, self.duo, references=self.pmg) self.assertEqual(a.authors[0].name, "Iron Man") self.assertEqual(a.authors[0].email, "*****@*****.**") self.assertEqual(a.authors[1].name, "Black Widow") self.assertEqual(a.authors[1].email, "*****@*****.**") StructureNL(self.s, self.hulk, references=self.pmg)
def test_eq(self): # test basic Equal() created_at = datetime.datetime.now() a = StructureNL(self.s, self.hulk, ['test_project'], self.pmg, ['remark1'], {"_my_data": self.s2}, [self.valid_node, self.valid_node2], created_at) b = StructureNL(self.s, self.hulk, ['test_project'], self.pmg, ['remark1'], {"_my_data": self.s2}, [self.valid_node, self.valid_node2], created_at) self.assertEqual(a, b, "__eq__() method is broken! false negative") # change the created at date, now they are no longer equal c = StructureNL(self.s, self.hulk, ['test_project'], self.pmg, ['remark1'], {"_my_data": self.s2}, [self.valid_node, self.valid_node2]) self.assertNotEqual(a, c, "__eq__() method is broken! false positive") # or try a different structure, those should not be equal d = StructureNL(self.s2, self.hulk, ['test_project'], self.pmg, ['remark1'], {"_my_data": self.s2}, [self.valid_node, self.valid_node2], created_at) self.assertNotEqual(a, d, "__eq__() method is broken! false positive")
def test_snl(self): self.trans.set_parameter('author', 'will') with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") snl = self.trans.to_snl([('will', '*****@*****.**')]) self.assertEqual(len(w), 1, 'Warning not raised on type conversion ' 'with other_parameters') ts = TransformedStructure.from_snl(snl) self.assertEqual(ts.history[-1]['@class'], 'SubstitutionTransformation') h = ('testname', 'testURL', {'test' : 'testing'}) snl = StructureNL(ts.final_structure,[('will', '*****@*****.**')], history = [h]) snl = TransformedStructure.from_snl(snl).to_snl([('notwill', '*****@*****.**')]) self.assertEqual(snl.history, [h]) self.assertEqual(snl.authors, [('notwill', '*****@*****.**')])
def icsd_dict_to_snl(icsd_dict): if 'tstruct' not in icsd_dict: return None struct = Structure.from_dict(icsd_dict['tstruct']) references = _get_icsd_reference(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(): if k not in excluded_data: if isinstance(v, datetime.datetime): v = v.strftime(format='%Y-%m-%d %H:%M:%S') data['_icsd'][k] = v projects = None remarks = None history = [{ 'name': 'Inorganic Crystal Structure Database (ICSD)', 'url': 'http://icsd.fiz-karlsruhe.de/', 'description': { 'icsd_id': data['_icsd']['icsd_id'] } }, { 'name': 'pymatgen', 'url': 'https://pypi.python.org/pypi/pymatgen', 'description': { 'comment': 'converted to explicit structure' } }] authors = 'William Davidson Richards <*****@*****.**>, Shyue Ping Ong <*****@*****.**>, Stephen Dacek <*****@*****.**>, Anubhav Jain <*****@*****.**>' return StructureNL(struct, authors, projects, references, remarks, data, history)
def submit_tests(names=None, params=None): sma = SubmissionMongoAdapter.auto_load() # note: TiO2 is duplicated twice purposely, duplicate check should catch this compounds = { "Si": 149, "Al": 134, "ZnO": 2133, "FeO": 18905, "LiCoO2": 601860, "LiFePO4": 585433, "GaAs": 2534, "Ge": 32, "PbTe": 19717, "YbO": 1216, "SiC": 567551, "Fe3C": 510623, "SiO2": 547211, "Na2O": 2352, "InSb (unstable)": 10148, "Sb2O5": 1705, "N2O5": 554368, "BaTiO3": 5020, "Rb2O": 1394, "TiO2": 554278, "TiO2 (2)": 554278, 'BaNbTePO8': 560794, "AgCl": 22922, "AgCl (2)": 570858, "SiO2 (2)": 555211, "Mg2SiO4": 2895, "CO2": 20066, "PbSO4": 22298, "SrTiO3": 5532, "FeAl": 2658, "AlFeCo2": 10884, "NaCoO2": 554427, "ReO3": 547271, "LaH2": 24153, "SiH3I": 28538, "LiBH4": 30209, "H8S5N2": 28143, "LiOH": 23856, "SrO2": 2697, "Mn": 35, "Hg4Pt": 2312, "PdF4": 13868, "Gd2WO6": 651333, 'MnO2': 19395, 'VO2': 504800 } mpr = MPRester() for name, sid in compounds.iteritems(): 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) snl = StructureNL(s, 'Anubhav Jain <*****@*****.**>') parameters = {'priority': 10} if name == 'Si' else None if params: parameters.update(params) sma.submit_snl(snl, '*****@*****.**', parameters=parameters)
def create_SNL(dirbase, molecules, atoms, spc_present, num_each_spc, struct, s): layers = len(molecules) with MPRester("sm5RbuEp83T9Wo7P") as m: first_mol = struct[0] mono_or_homo = 0 #if system is a monolayer or homogeneous use its proper .cif file, else use generic WTe2 for heterostructures if (layers == 1) or all(x == first_mol for x in struct): mono_or_homo = 1 if (first_mol == molec[0]): structure = m.get_structure_by_material_id("mp-2815") #MoS2 ref = m.get_materials_id_references("mp-2815") r1 = np.array([0, 2, 4]) elif (first_mol == molec[1]): structure = m.get_structure_by_material_id("mp-1634") #MoSe2 ref = m.get_materials_id_references("mp-1634") r1 = np.array([0, 2, 4]) elif (first_mol == molec[2]): structure = m.get_structure_by_material_id("mp-602") #MoTe2 ref = m.get_materials_id_references("mp-602") r1 = np.array([1, 2, 5]) elif (first_mol == molec[3]): structure = m.get_structure_by_material_id("mp-224") #WS2 ref = m.get_materials_id_references("mp-224") r1 = np.array([0, 3, 5]) elif (first_mol == molec[4]): structure = m.get_structure_by_material_id("mp-1821") #WSe2 ref = m.get_materials_id_references("mp-1821") r1 = np.array([0, 2, 4]) elif (first_mol == molec[5]): structure = m.get_structure_by_material_id("mp-1019322") #WTe2 ref = m.get_materials_id_references("mp-1019322") r1 = np.array([0, 3, 5]) else: structure = m.get_structure_by_material_id("mp-1019322") #WTe2 ref = m.get_materials_id_references("mp-1019322") r1 = np.array([0, 3, 5]) # initialize history history = [] #half the height of original unit cell...to be used for vacuum length calculation later halfz = (structure.lattice.c) / 2 #make supercell if necessary levels = layers if (levels % 2 == 1): levels = levels + 1 tsuper = SupercellTransformation([[1, 0, 0], [0, 1, 0], [0, 0, (levels) / 2]]) history.append(history_node(tsuper)) supercell = tsuper.apply_transformation(structure) #make species replacements for heterostructures with more than one layer levels = layers if (levels % 2 == 1): levels = levels + 1 #if heterostructure has more than one layer: if (mono_or_homo == 0): for i in range(0, len(molecules)): if (molecules[i] == 5): continue else: TMspc = elems[atoms[2 * i]] TMloc = (levels * 2) + (i % 2) * (levels / 2) + int( np.floor((i) / 2)) DCspc = elems[atoms[2 * i + 1]] DCloc1 = (levels - (levels / 2)) - i % 2 * (levels / 2) + int( np.floor((i) / 2)) DCloc2 = levels + i % 2 * (levels / 2) + int( np.floor((i) / 2)) t1 = ReplaceSiteSpeciesTransformation({TMloc: TMspc}) t2 = ReplaceSiteSpeciesTransformation({DCloc1: DCspc}) t3 = ReplaceSiteSpeciesTransformation({DCloc2: DCspc}) history.append(history_node(t1)) history.append(history_node(t2)) history.append(history_node(t3)) supercell = t1.apply_transformation(supercell) supercell = t2.apply_transformation(supercell) supercell = t3.apply_transformation(supercell) #remove top layer of atom if necessary mult_factor = (layers + 1) / 2 - 1 r = r1 + (r1 + 1) * mult_factor tremove = RemoveSitesTransformation(r) if (layers % 2 == 1): supercell = tremove.apply_transformation(supercell) history.append(history_node(tremove)) #sort structure supercell = supercell.get_sorted_structure() #extend z-axis cell vector to add vaccuum to supercell vacuum = 10.0 old_lattice = supercell.lattice if (layers % 2 == 1): new_c = old_lattice.c - halfz + vacuum else: new_c = old_lattice.c + vacuum new_lattice = Lattice.from_parameters(old_lattice.a, old_lattice.b, new_c, old_lattice.alpha, old_lattice.beta, old_lattice.gamma) final_structure = Structure( new_lattice, supercell.species, supercell.frac_coords * np.array([1., 1., (old_lattice.c / new_lattice.c)]), coords_are_cartesian=False) hnode = { 'name': 'add vaccuum', 'url': '', 'description': 'increase z-direction cell vector by 10 angstroms' } history.append(hnode) #creat final SNL authors = [{"name": "Lindsay Bassman", "email": "*****@*****.**"}] projects = ["TMDC-Heterostructures"] remarks = [ "MAGICS calculation of band structures of 2D TMDC stacked heterostructures" ] final_snl = StructureNL(final_structure, authors, projects=projects, remarks=remarks, references=ref, history=history) #optionally write POSCAR file poscar = Poscar(final_structure, s) poscar.write_file(dirbase + "POSCAR", direct=False)
def process_fw(self, old_task, d): # AJ - this whole section is different sma = SNLMongoAdapter.auto_load() d['old_engine'] = old_task.get('engine') if 'fw_id' in old_task: d['old_fw_id'] = old_task['fw_id'] d['fw_id'] = None d['task_type'] = 'GGA+U optimize structure (2x)' if old_task[ 'is_hubbard'] else 'GGA optimize structure (2x)' d['submission_id'] = None d['vaspinputset_name'] = None snl_d = sma.snl.find_one({'about._materialsproject.deprecated.mps_ids': old_task['mps_id']}) if old_task.get('mps_id', -1) > 0 and snl_d: # grab the SNL from the SNL db del snl_d['_id'] d['snl'] = snl_d d['snlgroup_id'] = sma.snlgroups.find_one({'all_snl_ids': d['snl']['snl_id']}, {'snlgroup_id': 1})['snlgroup_id'] elif 'mps' in old_task and old_task['mps']: snl = mps_dict_to_snl(old_task['mps']) mpsnl, snlgroup_id = sma.add_snl(snl) d['snl'] = mpsnl.to_dict d['snlgroup_id'] = snlgroup_id else: s = Structure.from_dict(old_task['input']['crystal']) snl = StructureNL(s, 'Anubhav Jain <*****@*****.**>', remarks=['origin unknown']) mpsnl, snlgroup_id = sma.add_snl(snl) d['snl'] = mpsnl.to_dict d['snlgroup_id'] = snlgroup_id if 'optimize structure' 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']) history = old_snl.history history.append( {'name': 'Materials Project structure optimization', 'url': 'http://www.materialsproject.org', 'description': {'task_type': d['task_type'], 'fw_id': d['fw_id'], 'task_id': d['task_id']}}) new_snl = StructureNL(new_s, old_snl.authors, old_snl.projects, old_snl.references, old_snl.remarks, old_snl.data, history) # add snl mpsnl, snlgroup_id = sma.add_snl(new_snl, snlgroup_guess=d['snlgroup_id']) d['snl_final'] = mpsnl.to_dict d['snlgroup_id_final'] = snlgroup_id d['snlgroup_changed'] = (d['snlgroup_id'] != d['snlgroup_id_final']) # custom processing for detecting errors dir_name = old_task['dir_name'] new_style = os.path.exists(os.path.join(dir_name, 'FW.json')) vasp_signals = {} critical_errors = ["INPUTS_DONT_EXIST", "OUTPUTS_DONT_EXIST", "INCOHERENT_POTCARS", "VASP_HASNT_STARTED", "VASP_HASNT_COMPLETED", "CHARGE_UNCONVERGED", "NETWORK_QUIESCED", "HARD_KILLED", "WALLTIME_EXCEEDED", "ATOMS_TOO_CLOSE", "DISK_SPACE_EXCEEDED"] last_relax_dir = dir_name if not new_style: # get the last relaxation dir # the order is relax2, current dir, then relax1. This is because # after completing relax1, the job happens in the current dir. # Finally, it gets moved to relax2. # There are some weird cases where both the current dir and relax2 # contain data. The relax2 is good, but the current dir is bad. if is_valid_vasp_dir(os.path.join(dir_name, "relax2")): last_relax_dir = os.path.join(dir_name, "relax2") elif is_valid_vasp_dir(dir_name): pass elif is_valid_vasp_dir(os.path.join(dir_name, "relax1")): last_relax_dir = os.path.join(dir_name, "relax1") vasp_signals['last_relax_dir'] = last_relax_dir ## see what error signals are present print "getting signals for dir :{}".format(last_relax_dir) sl = SignalDetectorList() sl.append(VASPInputsExistSignal()) sl.append(VASPOutputsExistSignal()) sl.append(VASPOutSignal()) sl.append(HitAMemberSignal()) sl.append(SegFaultSignal()) sl.append(VASPStartedCompletedSignal()) signals = sl.detect_all(last_relax_dir) signals = signals.union(WallTimeSignal().detect(dir_name)) if not new_style: root_dir = os.path.dirname(dir_name) # one level above dir_name signals = signals.union(WallTimeSignal().detect(root_dir)) signals = signals.union(DiskSpaceExceededSignal().detect(dir_name)) if not new_style: root_dir = os.path.dirname(dir_name) # one level above dir_name signals = signals.union(DiskSpaceExceededSignal().detect(root_dir)) signals = list(signals) critical_signals = [val for val in signals if val in critical_errors] vasp_signals['signals'] = signals vasp_signals['critical_signals'] = critical_signals vasp_signals['num_signals'] = len(signals) vasp_signals['num_critical'] = len(critical_signals) if len(critical_signals) > 0 and d['state'] == "successful": d["state"] = "error" d['analysis'] = d.get('analysis', {}) d['analysis']['errors_MP'] = vasp_signals d['run_tags'] = ['PBE'] d['run_tags'].extend(d['pseudo_potential']['labels']) d['run_tags'].extend([e+"="+str(d['hubbards'].get(e, 0)) for e in d['elements']])
def main(): import argparse parser = argparse.ArgumentParser( description="Run A QChem Job for a QChem Input File") parser.add_argument( "-d", "--directory", dest="directory", type=str, required=True, help= "the directory contains all the QChem jobs to be pretended to run again" ) parser.add_argument("-p", "--priority", dest="priority", type=int, default=100, help="the FireWorks priority") parser.add_argument("-b", "--batch_size", dest="batch_size", type=int, default=100, help="the number of FireWorks in a Workflow") options = parser.parse_args() fw_priority = options.priority batch_size = options.batch_size lp = LaunchPad.auto_load() src_dir = os.path.abspath(options.directory) src_dir_sub_dirs = glob.glob(os.path.join(src_dir, "*")) num_dirs = len(src_dir_sub_dirs) current_fwid = 1 links_dict = dict() fws_all = [] num_fw_in_current_batch = 0 batch_num = 1 for i, sd in enumerate(src_dir_sub_dirs): if not os.path.isdir(sd): continue fw_json_filename = os.path.join(sd, "FW.json") if not (os.path.exists(fw_json_filename) or os.path.exists(fw_json_filename + ".gz")): continue with zopen(zpath(fw_json_filename), 'rt') as f: fw_dict = json.load(f) print("{percent:4.2%} completed, processing directory {d:s}, " "molecule name {molname:s}," \ " mission {mission:s}".format(percent=i / float(num_dirs), d=sd, molname= fw_dict['spec']['user_tags'][ 'molname'], mission= fw_dict['spec']['user_tags'][ 'mission'])) molname = fw_dict['spec']['user_tags']['molname'] egsnl_tasks = [AddEGSNLTask()] if 'mol' in fw_dict: mol = Molecule.from_dict(fw_dict['spec']['mol']) else: mol = Molecule.from_dict( fw_dict['spec']['qcinp']['jobs'][0]['molecule']) snl = StructureNL(mol, "Xiaohui Qu <*****@*****.**>", "Electrolyte Genome") egsnl_task_spec = { 'task_type': 'Add to SNL database', 'snl': snl.as_dict(), '_category': 'Parse Previous QChem Job', '_priority': fw_priority } snl_fw_id = current_fwid current_fwid += 1 fws_all.append( Firework( egsnl_tasks, egsnl_task_spec, name=get_slug(molname + ' -- Add to SNL database For fake QChem Task'), fw_id=snl_fw_id)) fake_qchem_tasks = [FakeRunQChemTask()] src_qchem_dir = sd fake_qchem_spec = { '_priority': fw_priority * 2, 'src_qchem_dir': src_qchem_dir, '_category': 'Parse Previous QChem Job', 'run_tags': fw_dict['spec']['run_tags'], 'implicit_solvent': fw_dict['spec']['implicit_solvent'], 'task_type': fw_dict['spec']['task_type'], 'charge': fw_dict['spec']['charge'], 'spin_multiplicity': fw_dict['spec']['spin_multiplicity'], 'num_atoms': fw_dict['spec']['num_atoms'], 'user_tags': fw_dict['spec']['user_tags'], 'mol': mol.as_dict(), 'inchi': fw_dict['spec']['inchi'], '_dupefinder': fw_dict['spec']['_dupefinder'], 'qcinp': fw_dict['spec']['qcinp'], 'qm_method': fw_dict['spec']['qm_method'], 'inchi_root': fw_dict['spec']['inchi_root'] } for k in ['mixed_basis', 'mixed_aux_basis']: if k in fw_dict['spec']: fake_qchem_spec[k] = fw_dict['spec'][k] fake_qchem_fw_id = current_fwid current_fwid += 1 fws_all.append( Firework(fake_qchem_tasks, fake_qchem_spec, name='Fake' + fw_dict['name'], fw_id=fake_qchem_fw_id)) links_dict[snl_fw_id] = fake_qchem_fw_id num_fw_in_current_batch += 1 if num_fw_in_current_batch >= 100: wf = Workflow(fws_all, links_dict, "Read Previous QChem Jobs Id-{}".format(batch_num)) lp.add_wf(wf) batch_num += 1 links_dict = dict() fws_all = [] num_fw_in_current_batch = 0 if num_fw_in_current_batch > 0: wf = Workflow(fws_all, links_dict, "Read Previous QChem Jobs") lp.add_wf(wf)
dirname = filename[:-4] if os.path.exists(dirname): print("directory " + dirname + " already exists") print("please delete it before use this script") exit(0) for filename in filenames: dirname = filename[:-4] os.mkdir(dirname) print("reading", filename) text = None with open(filename) as f: text = f.read() mol_tokens = str_to_obmols(text) for (i, (mol, cas)) in enumerate(mol_tokens): print("processing molecule", i + 1, cas, "of", len(mol_tokens), "molecules") try: build3d(mol) except: os.system("echo " + cas + " >> failed_mols.txt") pmg_mols = [(BabelMolAdaptor(obmol).pymatgen_mol, cas) for (obmol, cas) in mol_tokens] snl_texts = [ StructureNL(mol, "Xiaohui Qu <*****@*****.**>", remarks=cas) for (mol, cas) in pmg_mols ] for snl in snl_texts: with open(dirname + "/" + snl.remarks[0] + ".snl", 'w') as f: json.dump(snl.as_dict(), f, indent=4) print("Done")
def submit_snl(self, structures, authors, projects=None, references='', remarks=None, data=None, histories=None, created_at=None): """ Submits a list of structures to the Materials Project as SNL files. The argument list mirrors the arguments for the StructureNL object, except that a list of structures with the same metadata is used as an input. .. note:: As of now, this MP REST feature is open only to a select group of users. Opening up submissions to all users is being planned for the future. Args: structures: A list of Structure objects authors: *List* of {"name":'', "email":''} dicts, *list* of Strings as 'John Doe <*****@*****.**>', or a single String with commas separating authors projects: List of Strings ['Project A', 'Project B']. This applies to all structures. references: A String in BibTeX format. Again, this applies to all structures. remarks: List of Strings ['Remark A', 'Remark B'] data: A list of free form dict. Namespaced at the root level with an underscore, e.g. {"_materialsproject":<custom data>}. The length of data should be the same as the list of structures if not None. histories: List of list of dicts - [[{'name':'', 'url':'', 'description':{}}], ...] The length of histories should be the same as the list of structures if not None. created_at: A datetime object Returns: A list of inserted submission ids. """ try: data = [{}] * len(structures) if data is None else data histories = [[]] * len(structures) if histories is None else \ histories jsondata = [] for i, struct in enumerate(structures): snl = StructureNL(struct, authors, projects=projects, references=references, remarks=remarks, data=data[i], history=histories[i], created_at=created_at) jsondata.append(snl.to_dict) payload = {"snl": json.dumps(jsondata, cls=PMGJSONEncoder)} response = self.session.post("{}/snl/submit".format(self.preamble), data=payload) if response.status_code in [200, 400]: resp = json.loads(response.text, cls=PMGJSONDecoder) if resp["valid_response"]: if resp.get("warning"): warnings.warn(resp["warning"]) return resp['inserted_ids'] else: raise MPRestError(resp["error"]) raise MPRestError( "REST error with status code {} and error {}".format( response.status_code, response.text)) except Exception as ex: raise MPRestError(str(ex))
def mps_dict_to_snl(mps_dict): m = mps_dict if 'deprecated' in m['about']['metadata']['info'] and m['about'][ 'metadata']['info']['deprecated']: return None if 'Carbon Capture Storage Initiative (CCSI)' in m['about']['metadata'][ 'project_names']: print 'rejected old CCSI' return None mps_ids = [m['mps_id']] remarks = [] for remark in m['about']['metadata']['remarks']: if 'This entry replaces deprecated mps_id' in remark: mps_ids.append(int( remark.split()[-1])) # add the deprecated MPS id to this SNL else: remarks.append(remark) for remark in m['about']['metadata']['keywords']: remarks.append(remark) projects = [] for project in m['about']['metadata']['project_names']: projects.append(project) data = { '_materialsproject': { 'deprecated': { 'mps_ids': mps_ids } }, '_icsd': {} } for k, v in m['about']['metadata']['info'].iteritems(): if k == 'icsd_comments': data['_icsd']['comments'] = v elif k == 'icsd_id': data['_icsd']['icsd_id'] = v elif k == 'remark': data['_materialsproject']['ordering_remark'] = v elif 'deprecated' in k or 'original_structure' in k: data['_materialsproject']['deprecated'][k] = v elif 'assert' in k or 'universe' in k or 'mp_duplicates' in k: pass else: data['_materialsproject'][k] = v authors = [] for a in m['about']['authors']: authors.append({'name': a['name'], 'email': a['email']}) for a in m['about']['acknowledgements']: authors.append({'name': a['name'], 'email': a['email']}) cites = [m['about']['please_cite']['bibtex']] if m['about']['supporting_info']: cites.append(m['about']['supporting_info']['bibtex']) references = '\n'.join(cites) history = [] for h in m['about']['links']: if 'direct_copy' in h['description']: del h['description']['direct_copy'] history.append({ 'name': h['name'], 'url': h['url'], 'description': h['description'] }) struct = Structure.from_dict(m) created_at = datetime.datetime.strptime(m['about']['created_at'], "%Y-%m-%d %H:%M:%S") return StructureNL(struct, authors, projects, references, remarks, data, history, created_at)
#els_n1.append("Cu") #els_n1.append("Au") #print els_n1 #MA =[17,35,53,71,89,107,143,215] #2*3*3 system #MA = [7,15,23,31,39,47,63,95] #FA = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,18,19,20,30,31,32,33,34,35]#alpha #FA = [0,1,2,3,4,5,6,7,8,9,12,13,20,21,22,23]#delta #FA = [0,1,2,3,4,5,6,7] #s.remove_sites(FA) #add = [0.7469,0.74726,0.7469] # for 2*2*2 system #add = [0.74626,0.830865,0.8315] #add1 = [0.66667,0.33333,0.34262]#alpha #add1 = [0.33333,0.66667,0.15493]#delta #add = [0.5,0.56901,0.5] #s.append('K',add)#els_n1[9 #add2 = [0.33333,0.66667,0.61381]#alpha #add2 = [0.66667,0.33333,0.65493]#delta #s.append('K',add2) #add3 = [0,0,0.010678]#alpha #s.append('K',add3) #s.to(fmt="poscar",filename="POSCAR4") spacegroup = SpacegroupAnalyzer(s) print('space group symbol:', spacegroup.get_space_group_symbol()) print('space group number:', spacegroup.get_space_group_number()) sma = SubmissionMongoAdapter.auto_load() snl = StructureNL(s, authors='WenQi <*****@*****.**>', remarks=['MAPbI3', 'B-site']) parameters = {'boltztrap': False, 'force_gamma': True} sma.submit_snl(snl, '*****@*****.**', parameters=parameters)
def process_fw(self, dir_name, d): d["task_id_deprecated"] = int( d["task_id"].split('-')[-1]) # useful for WC and AJ # update the run fields to give species group in root, if exists for r in d['run_tags']: if "species_group=" in r: d["species_group"] = int(r.split("=")[-1]) break # custom Materials Project post-processing for FireWorks with zopen(zpath(os.path.join(dir_name, 'FW.json'))) as f: fw_dict = json.load(f) d['fw_id'] = fw_dict['fw_id'] d['snl'] = fw_dict['spec']['mpsnl'] d['snlgroup_id'] = fw_dict['spec']['snlgroup_id'] d['vaspinputset_name'] = fw_dict['spec'].get('vaspinputset_name') d['task_type'] = fw_dict['spec']['task_type'] # Process data for deformed structures if 'deformed' in d['task_type']: 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: # create a new SNL based on optimized structure new_s = Structure.from_dict(d['output']['crystal']) old_snl = StructureNL.from_dict(d['snl']) history = old_snl.history history.append({ 'name': 'Materials Project structure optimization', 'url': 'http://www.materialsproject.org', 'description': { 'task_type': d['task_type'], 'fw_id': d['fw_id'], 'task_id': d['task_id'] } }) new_snl = StructureNL(new_s, old_snl.authors, old_snl.projects, old_snl.references, old_snl.remarks, old_snl.data, history) # enter new SNL into SNL db # get the SNL mongo adapter sma = SNLMongoAdapter.auto_load() # add snl mpsnl, snlgroup_id, spec_group = sma.add_snl( new_snl, snlgroup_guess=d['snlgroup_id']) d['snl_final'] = mpsnl.as_dict() d['snlgroup_id_final'] = snlgroup_id d['snlgroup_changed'] = (d['snlgroup_id'] != d['snlgroup_id_final']) else: d['snl_final'] = d['snl'] d['snlgroup_id_final'] = d['snlgroup_id'] d['snlgroup_changed'] = False # custom processing for detecting errors new_style = os.path.exists(zpath(os.path.join(dir_name, 'FW.json'))) vasp_signals = {} critical_errors = [ "INPUTS_DONT_EXIST", "OUTPUTS_DONT_EXIST", "INCOHERENT_POTCARS", "VASP_HASNT_STARTED", "VASP_HASNT_COMPLETED", "CHARGE_UNCONVERGED", "NETWORK_QUIESCED", "HARD_KILLED", "WALLTIME_EXCEEDED", "ATOMS_TOO_CLOSE", "DISK_SPACE_EXCEEDED", "NO_RELAX2", "POSITIVE_ENERGY" ] last_relax_dir = dir_name if not new_style: # get the last relaxation dir # the order is relax2, current dir, then relax1. This is because # after completing relax1, the job happens in the current dir. # Finally, it gets moved to relax2. # There are some weird cases where both the current dir and relax2 # contain data. The relax2 is good, but the current dir is bad. if is_valid_vasp_dir(os.path.join(dir_name, "relax2")): last_relax_dir = os.path.join(dir_name, "relax2") elif is_valid_vasp_dir(dir_name): pass elif is_valid_vasp_dir(os.path.join(dir_name, "relax1")): last_relax_dir = os.path.join(dir_name, "relax1") vasp_signals['last_relax_dir'] = last_relax_dir ## see what error signals are present print "getting signals for dir :{}".format(last_relax_dir) sl = SignalDetectorList() sl.append(VASPInputsExistSignal()) sl.append(VASPOutputsExistSignal()) sl.append(VASPOutSignal()) sl.append(HitAMemberSignal()) sl.append(SegFaultSignal()) sl.append(VASPStartedCompletedSignal()) if d['state'] == 'successful' and 'optimize structure' in d[ 'task_type']: sl.append(Relax2ExistsSignal()) signals = sl.detect_all(last_relax_dir) signals = signals.union(WallTimeSignal().detect(dir_name)) if not new_style: root_dir = os.path.dirname(dir_name) # one level above dir_name signals = signals.union(WallTimeSignal().detect(root_dir)) signals = signals.union(DiskSpaceExceededSignal().detect(dir_name)) if not new_style: root_dir = os.path.dirname(dir_name) # one level above dir_name signals = signals.union(DiskSpaceExceededSignal().detect(root_dir)) if d.get('output', {}).get('final_energy', None) > 0: signals.add('POSITIVE_ENERGY') signals = list(signals) critical_signals = [val for val in signals if val in critical_errors] vasp_signals['signals'] = signals vasp_signals['critical_signals'] = critical_signals vasp_signals['num_signals'] = len(signals) vasp_signals['num_critical'] = len(critical_signals) if len(critical_signals) > 0 and d['state'] == "successful": d["state"] = "error" d['analysis'] = d.get('analysis', {}) d['analysis']['errors_MP'] = vasp_signals
fws = [] connections = {} # add the root FW (GGA+U) spec = _snl_to_spec(snl, enforce_gga=False) tasks = [VaspWriterTask(), get_custodian_task(spec)] fws.append(Firework(tasks, spec, fw_id=1)) # add GGA insertion to DB spec = {'task_type': 'VASP db insertion', '_priority': 2, '_category': 'VASP', '_queueadapter': QA_VASP} fws.append(Firework([VaspToDBTask()], spec, fw_id=2)) connections[1] = 2 mpvis = MPVaspInputSet() spec['vaspinputset_name'] = mpvis.__class__.__name__ return Workflow(fws, connections, name=Composition(snl.structure.composition.reduced_formula).alphabetical_formula) """ if __name__ == '__main__': s1 = CifParser('test_wfs/Si.cif').get_structures()[0] s2 = CifParser('test_wfs/FeO.cif').get_structures()[0] snl1 = StructureNL(s1, "Anubhav Jain <*****@*****.**>") snl2 = StructureNL(s2, "Anubhav Jain <*****@*****.**>") snl_to_wf(snl1).to_file('test_wfs/wf_si_dupes.json', indent=4) snl_to_wf(snl2).to_file('test_wfs/wf_feo_dupes.json', indent=4)