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 run_task(self, fw_spec): sma = SNLMongoAdapter.auto_load() snl = StructureNL.from_dict(fw_spec['snl']) mpsnl, snlgroup_id, spec_group = sma.add_snl(snl) mod_spec = [{"_push": {"run_tags": "species_group={}".format(spec_group)}}] if spec_group else None return FWAction(update_spec={'mpsnl': mpsnl.to_dict, 'snlgroup_id': snlgroup_id}, mod_spec=mod_spec)
def from_snl(snl, snl_id, pointgroup): # make a copy of SNL snl2 = StructureNL.from_dict(snl.as_dict()) if '_electrolytegenome' not in snl2.data: snl2.data['_electrolytegenome'] = {} snl2.data['_electrolytegenome']['snl_id'] = snl_id snl2.data['_electrolytegenome']['pointgroup'] = pointgroup return EGStructureNL.from_dict(snl2.as_dict())
def get_snls(self, species): o = [] for e in self.structures.find({ 'nspecies': len(species), 'species': { '$all': species } }): o.append(StructureNL.from_dict(e['snl'])) return o
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' }}) if job: submission_id = job['submission_id'] try: if 'snl_id' in job: snl = MPStructureNL.from_dict(job) else: 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)) 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) 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) 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) 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']) else: wf = snl_to_wf(snl, job['parameters']) self.launchpad.add_wf(wf) print 'ADDED WORKFLOW FOR {}'.format(snl.structure.formula) except: self.jobs.find_and_modify({'submission_id': submission_id}, {'$set': { 'state': 'ERROR' }}) traceback.print_exc() return submission_id
def run_task(self, fw_spec): # pass-through option for when we start with an mpsnl and don't actually want to add if 'force_mpsnl' in fw_spec and 'force_snlgroup_id' in fw_spec: print 'USING FORCED MPSNL' return FWAction(update_spec={'mpsnl': fw_spec['force_mpsnl'], 'snlgroup_id': fw_spec['force_snlgroup_id']}) sma = SNLMongoAdapter.auto_load() snl = StructureNL.from_dict(fw_spec['snl']) mpsnl, snlgroup_id = sma.add_snl(snl) return FWAction(update_spec={'mpsnl': mpsnl.to_dict, 'snlgroup_id': snlgroup_id})
def run_task(self, fw_spec): # get the SNL mongo adapter sma = SNLMongoAdapter.auto_load() # get the SNL snl = StructureNL.from_dict(fw_spec['snl']) # add snl mpsnl, snlgroup_id = sma.add_snl(snl) return FWAction(update_spec={'mpsnl': mpsnl.to_dict, 'snlgroup_id': snlgroup_id})
def from_snl(snl, snl_id, sg_num, sg_symbol, hall, xtal_system, lattice_type): # make a copy of SNL snl2 = StructureNL.from_dict(snl.to_dict) if '_materialsproject' not in snl2.data: snl2.data['_materialsproject'] = {} snl2.data['_materialsproject']['snl_id'] = snl_id snl2.data['_materialsproject']['sg_num'] = sg_num snl2.data['_materialsproject']['sg_symbol'] = sg_symbol snl2.data['_materialsproject']['hall'] = hall snl2.data['_materialsproject']['xtal_system'] = xtal_system snl2.data['_materialsproject']['lattice_type'] = lattice_type return MPStructureNL.from_dict(snl2.to_dict)
def run_task(self, fw_spec): sma = SNLMongoAdapter.auto_load() snl = StructureNL.from_dict(fw_spec['snl']) mpsnl, snlgroup_id, spec_group = sma.add_snl(snl) mod_spec = [{ "_push": { "run_tags": "species_group={}".format(spec_group) } }] if spec_group else None return FWAction(update_spec={ 'mpsnl': mpsnl.to_dict, 'snlgroup_id': snlgroup_id }, mod_spec=mod_spec)
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'}}) if job: submission_id = job['submission_id'] try: if 'snl_id' in job: snl = MPStructureNL.from_dict(job) else: 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)) 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) 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) 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) else: snl.data['_materialsproject'] = snl.data.get('_materialsproject', {}) snl.data['_materialsproject']['submission_id'] = submission_id # create a workflow if "Elasticity" in snl.projects: from mpworks.workflows.snl_to_wf_phonon import snl_to_wf_phonon wf=snl_to_wf_phonon(snl, job['parameters']) else: wf = snl_to_wf(snl, job['parameters']) self.launchpad.add_wf(wf) print 'ADDED WORKFLOW FOR {}'.format(snl.structure.formula) except: self.jobs.find_and_modify({'submission_id': submission_id}, {'$set': {'state': 'ERROR'}}) traceback.print_exc() return submission_id
def from_snl(snl, snl_id, sg_num, sg_symbol, hall, xtal_system, lattice_type, pointgroup): # make a copy of SNL snl2 = StructureNL.from_dict(snl.as_dict()) if '_materialsproject' not in snl2.data: snl2.data['_materialsproject'] = {} snl2.data['_materialsproject']['snl_id'] = snl_id snl2.data['_materialsproject']['spacegroup'] = {} sg = snl2.data['_materialsproject']['spacegroup'] sg['symbol'] = sg_symbol sg['number'] = sg_num sg['point_group'] = pointgroup sg['crystal_system'] = xtal_system sg['hall'] = hall sg['lattice_type'] = lattice_type return MPStructureNL.from_dict(snl2.as_dict())
def from_snl(snl, snl_id, sg_num, sg_symbol, hall, xtal_system, lattice_type, pointgroup): # make a copy of SNL snl2 = StructureNL.from_dict(snl.as_dict()) if "_materialsproject" not in snl2.data: snl2.data["_materialsproject"] = {} snl2.data["_materialsproject"]["snl_id"] = snl_id snl2.data["_materialsproject"]["spacegroup"] = {} sg = snl2.data["_materialsproject"]["spacegroup"] sg["symbol"] = sg_symbol sg["number"] = sg_num sg["point_group"] = pointgroup sg["crystal_system"] = xtal_system sg["hall"] = hall sg["lattice_type"] = lattice_type return MPStructureNL.from_dict(snl2.as_dict())
def from_snl(snl, snl_id, sg_num, sg_symbol, hall, xtal_system, lattice_type, pointgroup): # make a copy of SNL snl2 = StructureNL.from_dict(snl.to_dict) if '_materialsproject' not in snl2.data: snl2.data['_materialsproject'] = {} snl2.data['_materialsproject']['snl_id'] = snl_id snl2.data['_materialsproject']['spacegroup'] = {} sg = snl2.data['_materialsproject']['spacegroup'] sg['symbol'] = sg_symbol sg['number'] = sg_num sg['point_group'] = pointgroup sg['crystal_system'] = xtal_system sg['hall'] = hall sg['lattice_type'] = lattice_type return MPStructureNL.from_dict(snl2.to_dict)
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' }}) if job: submission_id = job['submission_id'] # noinspection PyBroadException try: if 'snl_id' in job: snl = EGStructureNL.from_dict(job) else: snl = StructureNL.from_dict(job) if len(snl.structure.sites) > SubmissionProcessorEG.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))) 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)) else: snl.data['_electrolytegenome'] = \ snl.data.get('_electrolytegenome', {}) snl.data['_electrolytegenome']['submission_id'] \ = submission_id # create a workflow wf = snl_to_eg_wf(snl, job['parameters']) self.launchpad.add_wf(wf) print('ADDED WORKFLOW FOR {}'.format( snl.structure.formula)) except: self.jobs.find_and_modify({'submission_id': submission_id}, {'$set': { 'state': 'ERROR' }}) traceback.print_exc() return submission_id
def run_task(self, fw_spec): # pass-through option for when we start with an mpsnl and don't actually want to add if 'force_mpsnl' in fw_spec and 'force_snlgroup_id' in fw_spec: print 'USING FORCED MPSNL' return FWAction( update_spec={ 'mpsnl': fw_spec['force_mpsnl'], 'snlgroup_id': fw_spec['force_snlgroup_id'] }) sma = SNLMongoAdapter.auto_load() snl = StructureNL.from_dict(fw_spec['snl']) mpsnl, snlgroup_id = sma.add_snl(snl) return FWAction(update_spec={ 'mpsnl': mpsnl.to_dict, 'snlgroup_id': snlgroup_id })
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'}}) if job: submission_id = job['submission_id'] try: snl = StructureNL.from_dict(job) snl.data['_materialsproject'] = snl.data.get('_materialsproject', {}) snl.data['_materialsproject']['submission_id'] = submission_id # create a workflow wf = snl_to_wf(snl) self.launchpad.add_wf(wf) print 'ADDED WORKFLOW FOR {}'.format(snl.structure.formula) except: self.jobs.find_and_modify({'submission_id': submission_id}, {'$set': {'state': 'error'}}) traceback.print_exc() return submission_id
def run_task(self, fw_spec): sma = EGSNLMongoAdapter.auto_load() if isinstance(fw_spec['snl'], dict): snl = StructureNL.from_dict(fw_spec['snl']) else: snl = fw_spec['snl'] egsnl, snlgroup_id = sma.add_snl(snl) mol = egsnl.structure bb = BabelMolAdaptor(mol) pbmol = bb.pybel_mol inchi_root = pbmol.write(str("inchi")).strip() return FWAction( update_spec={ 'egsnl': egsnl.as_dict(), 'snlgroup_id': snlgroup_id, 'inchi_root': inchi_root })
def job_is_submittable(job): snl = StructureNL.from_dict(job) # mpworks.processors.process_submissions.SubmissionProcessor#submit_new_workflow max_sites = 200 # SubmissionProcessor.MAX_SITES above # from mpworks.workflows.wf_utils import NO_POTCARS no_potcars = ['Po', 'At', 'Rn', 'Fr', 'Ra', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm', 'Md', 'No', 'Lr'] if len(snl.structure.sites) > max_sites: print 'REJECTED WORKFLOW FOR {} - too many sites ({})'.format( snl.structure.formula, len(snl.structure.sites)) elif not job['is_valid']: print 'REJECTED WORKFLOW FOR {} - invalid structure (atoms too close)'.format( snl.structure.formula) elif len(set(no_potcars) & set(job['elements'])) > 0: print 'REJECTED WORKFLOW FOR {} - invalid element (No POTCAR)'.format( snl.structure.formula) elif not job['is_ordered']: print 'REJECTED WORKFLOW FOR {} - invalid structure (disordered)'.format( snl.structure.formula) else: return True return False
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']) update_spec = {} # add this later when creating new FW fizzled_parent = True parse_dos = False else: prev_dir = get_loc(fw_spec['prev_vasp_dir']) update_spec = {'prev_vasp_dir': prev_dir, 'prev_task_type': fw_spec['prev_task_type'], 'run_tags': fw_spec['run_tags'], 'parameters': fw_spec.get('parameters')} fizzled_parent = False parse_dos = 'Uniform' in fw_spec['prev_task_type'] if 'run_tags' in fw_spec: self.additional_fields['run_tags'] = fw_spec['run_tags'] else: self.additional_fields['run_tags'] = fw_spec['_fizzled_parents'][0]['spec']['run_tags'] if MOVE_TO_GARDEN_DEV: prev_dir = move_to_garden(prev_dir, prod=False) elif MOVE_TO_GARDEN_PROD: prev_dir = move_to_garden(prev_dir, prod=True) # get the directory containing the db file db_dir = os.environ['DB_LOC'] db_path = os.path.join(db_dir, 'tasks_db.json') logging.basicConfig(level=logging.INFO) logger = logging.getLogger('MPVaspDrone') logger.setLevel(logging.INFO) sh = logging.StreamHandler(stream=sys.stdout) sh.setLevel(getattr(logging, 'INFO')) logger.addHandler(sh) with open(db_path) as f: db_creds = json.load(f) drone = MPVaspDrone( host=db_creds['host'], port=db_creds['port'], database=db_creds['database'], user=db_creds['admin_user'], password=db_creds['admin_password'], 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) 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}) 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'] 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']) output_dir = last_relax(os.path.join(prev_dir, 'vasprun.xml')) ueh = UnconvergedErrorHandler(output_filename=output_dir) if ueh.check() and unconverged_tag not in fw_spec['run_tags']: print 'Unconverged run! Creating dynamic FW...' spec = {'prev_vasp_dir': prev_dir, 'prev_task_type': fw_spec['task_type'], 'mpsnl': mpsnl, 'snlgroup_id': snlgroup_id, 'task_type': fw_spec['prev_task_type'], 'run_tags': list(fw_spec['run_tags']), 'parameters': fw_spec.get('parameters'), '_dupefinder': DupeFinderVasp().to_dict(), '_priority': fw_spec['_priority']} snl = StructureNL.from_dict(spec['mpsnl']) spec['run_tags'].append(unconverged_tag) spec['_queueadapter'] = QA_VASP fws = [] connections = {} f = Composition.from_formula( snl.structure.composition.reduced_formula).alphabetical_formula fws.append(FireWork( [VaspCopyTask({'files': ['INCAR', 'KPOINTS', 'POSCAR', 'POTCAR', 'CONTCAR'], 'use_CONTCAR': False}), SetupUnconvergedHandlerTask(), get_custodian_task(spec)], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-2)) spec = {'task_type': 'VASP db insertion', '_allow_fizzled_parents': True, '_priority': fw_spec['_priority'], '_queueadapter': QA_DB, 'run_tags': list(fw_spec['run_tags'])} spec['run_tags'].append(unconverged_tag) fws.append( FireWork([VaspToDBTask()], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-1)) connections[-2] = -1 wf = Workflow(fws, connections) return FWAction(detours=wf) # not successful and not due to convergence problem - FIZZLE raise ValueError("DB insertion successful, but don't know how to fix this FireWork! Can't continue with workflow...")
def equilibrium_constant_fws(mission, solvent, solvent_method, use_vdw_surface, qm_method, reaction_id, dupefinder=None, priority=1, parent_fwid=None, additional_user_tags=None, depend_on_parent=False): energy_method, sol_qm_method, geom_method = qm_method.split("//") if '||' in energy_method: sp_qm_method, bsse_qm_method = energy_method.split("||") qm_method = "//".join([sp_qm_method, sol_qm_method, geom_method]) else: bsse_qm_method = energy_method coll = get_reactions_collection() reaction_doc = coll.find_one(filter={"reaction_id": reaction_id}) reactant_snls = [StructureNL.from_dict(s) for s in reaction_doc["reactant_snls"]] product_snls = [StructureNL.from_dict(s) for s in reaction_doc["product_snls"]] reactant_nicknames = reaction_doc['reactant_nicknames'] product_nicknames = reaction_doc['product_nicknames'] reactant_charges = reaction_doc['reactant_charges'] product_charges = reaction_doc['product_charges'] reactant_spin_multiplicities = reaction_doc['reactant_spin_multiplicities'] product_spin_multiplicities = reaction_doc['product_spin_multiplicities'] reactant_fragments = reaction_doc['reactant_fragments'] product_fragments = reaction_doc['product_fragments'] fwid_base = 1 if parent_fwid: if not (isinstance(parent_fwid, int) or isinstance(parent_fwid, list)): raise ValueError("Parent FireWork ID must be integer or list") parent_fwid = parent_fwid if isinstance(parent_fwid, list) \ else [parent_fwid] fwid_base = max(parent_fwid) + 1 current_fwid = fwid_base fws = [] links_dict = dict() for snl, nick_name, charge, spin, fragments in \ zip(reactant_snls + product_snls, reactant_nicknames + product_nicknames, reactant_charges + product_charges, reactant_spin_multiplicities + product_spin_multiplicities, reactant_fragments + product_fragments): mol = snl.structure mol.set_charge_and_spin(charge, spin) snl_tasks = [AddEGSNLTask()] snl_spec = {'task_type': 'Add to SNL database', 'snl': snl.as_dict(), '_priority': priority} priority *= 2 # once we start a job, keep going! snl_fw = Firework(snl_tasks, snl_spec, name=get_slug(nick_name + ' -- Add to SNL database'), fw_id=current_fwid) fws.append(snl_fw) sp_fws, sp_links_dict = single_point_energy_fws( mol, name=nick_name, mission=mission, solvent=solvent, solvent_method=solvent_method, use_vdW_surface=use_vdw_surface, qm_method=qm_method, pop_method=None, dupefinder=dupefinder, priority=priority, parent_fwid=snl_fw.fw_id, additional_user_tags=additional_user_tags, depend_on_parent_fw=True, large=True) fws.extend(sp_fws) sp_children = set() sp_parents = set() for k, v2 in sp_links_dict.items(): v1 = links_dict.get(k, []) links_dict[k] = list((set(v1) if isinstance(v1, list) else {v1}) | (set(v2) if isinstance(v2, list) else {v2})) if isinstance(k, list): sp_parents |= set(k) else: sp_parents.add(k) if isinstance(v2, list): sp_children |= set(v2) else: sp_children.add(v2) sp_last_fwids = list(sp_children - sp_parents) bsse_fws, bsse_links_dict = counterpoise_correction_generation_fw( molname=nick_name, charge=charge, spin_multiplicity=spin, qm_method=bsse_qm_method, fragments=fragments, mission=mission, priority=priority, parent_fwid=sp_last_fwids, additional_user_tags=additional_user_tags, large=True) fws.extend(bsse_fws) for k, v2 in bsse_links_dict.items(): v1 = links_dict.get(k, []) links_dict[k] = list((set(v1) if isinstance(v1, list) else {v1}) | (set(v2) if isinstance(v2, list) else {v2})) current_fwid = max([fw.fw_id for fw in bsse_fws]) + 1 if depend_on_parent: all_fwids = [fw.fw_id for fw in fws] for p_fwid in parent_fwid: links_dict[p_fwid] = all_fwids return fws, links_dict
def get_snls(self, species): o = [] for e in self.structures.find({'nspecies' : len(species), 'species' : {'$all' : species}}): o.append(StructureNL.from_dict(e['snl'])) return o
def submit_reaction(self, reactant_snls, product_snls, reactant_fragments, product_fragments, submitter_email, parameters=None): """ Submit a reaction. This task will be separated to several single point energy calculations, and submitted as individual molecule. Args: reactant_snls: List of tuple(snl, count, nickname). product_snls: List of tuple(snl, count, nickname). reactant_fragments: BSSE fragments definition. (BSSEFragment) product_fragments: BSSE fragments definition. (BSSEFragment) submitter_email: Email. parameters: dict of parameter. Expected parameters are 1) method: QChem theoretival method. e.g. B3LYP-XDM/6-31+G*; 2) solvent: implicit solvent in energy calcuation. e.g. THF; ... """ reaction_element_count = defaultdict(lambda: 0) for snl, n, nick_name in reactant_snls: mol = snl.structure for site in mol.sites: element = site.specie.symbol reaction_element_count[element] += n product_element_count = defaultdict(lambda: 0) for snl, n, nick_name in product_snls: mol = snl.structure for site in mol.sites: element = site.specie.symbol product_element_count[element] += n if reaction_element_count != product_element_count: raise Exception( "Number of atoms is inconsistant in reactant and product") reactant_inchis = [] product_inchis = [] num_reactants = [] num_products = [] reactant_nicknames = [] product_nicknames = [] reactant_charges = [] product_charges = [] reactant_spin_multiplicities = [] product_spin_multiplicities = [] for snl, n, nick_name in reactant_snls: mol = snl.structure bb = BabelMolAdaptor(mol) pbmol = bb.pybel_mol inchi = pbmol.write("inchi").strip() reactant_inchis.append(inchi) reactant_nicknames.append(nick_name) num_reactants.append(n) reactant_charges.append(mol.charge) reactant_spin_multiplicities.append(mol.spin_multiplicity) for snl, n, nick_name in product_snls: mol = snl.structure bb = BabelMolAdaptor(mol) pbmol = bb.pybel_mol inchi = pbmol.write("inchi").strip() product_inchis.append(inchi) product_nicknames.append(nick_name) num_products.append(n) product_charges.append(mol.charge) product_spin_multiplicities.append(mol.spin_multiplicity) all_inchis = reactant_inchis + product_inchis d = dict() d['submitter_email'] = submitter_email d['parameters'] = parameters d['state'] = 'SUBMITTED' d['reaction_id'] = self._get_next_reaction_id() d['submitted_at'] = datetime.datetime.utcnow().isoformat() d["reactant_snls"] = [s[0].as_dict() for s in reactant_snls] d["product_snls"] = [s[0].as_dict() for s in product_snls] d['all_inchis'] = all_inchis d['reactant_inchis'] = reactant_inchis d['product_inchis'] = product_inchis d['num_reactants'] = num_reactants d['num_products'] = num_products d['reactant_nicknames'] = reactant_nicknames d['product_nicknames'] = product_nicknames d['reactant_charges'] = reactant_charges d['product_charges'] = product_charges d['reactant_spin_multiplicities'] = reactant_spin_multiplicities d['product_spin_multiplicities'] = product_spin_multiplicities d['reactant_fragments'] = [[frag.to_dict() for frag in specie] for specie in reactant_fragments] d['product_fragments'] = [[frag.to_dict() for frag in specie] for specie in product_fragments] self.reactions.insert(d) dummy_snl = StructureNL.from_dict(d["reactant_snls"][0]) parameters['reaction_id'] = d['reaction_id'] self.submit_snl(dummy_snl, submitter_email, parameters) return d['reaction_id']
def run_task(self, fw_spec): 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) if fw_spec['analysis']['bandgap'] >= self.gap_cutoff: print 'Adding more runs...' type_name = 'GGA+U' if 'GGA+U' in fw_spec[ 'prev_task_type'] else 'GGA' snl = StructureNL.from_dict(fw_spec['mpsnl']) f = Composition( snl.structure.composition.reduced_formula).alphabetical_formula fws = [] connections = {} priority = fw_spec['_priority'] # run GGA static spec = fw_spec # pass all the items from the current spec to the new # one spec.update({ 'task_type': '{} static'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority }) fws.append( Firework([ VaspCopyTask({'use_CONTCAR': True}), SetupStaticRunTask(), get_custodian_task(spec) ], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-10)) # insert into DB - GGA static spec = { 'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority, "_dupefinder": DupeFinderDB().to_dict() } fws.append( Firework([VaspToDBTask()], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-9)) connections[-10] = -9 # run GGA Uniform spec = { 'task_type': '{} Uniform'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority } fws.append( Firework([ VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({'mode': 'uniform'}), get_custodian_task(spec) ], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-8)) connections[-9] = -8 # insert into DB - GGA Uniform spec = { 'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority, "_dupefinder": DupeFinderDB().to_dict() } fws.append( Firework([VaspToDBTask({'parse_uniform': True})], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-7)) connections[-8] = -7 # run GGA Band structure spec = { 'task_type': '{} band structure'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority } fws.append( Firework([ VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({'mode': 'line'}), get_custodian_task(spec) ], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-6)) connections[-7] = -6 # insert into DB - GGA Band structure spec = { 'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority, "_dupefinder": DupeFinderDB().to_dict() } fws.append( Firework([VaspToDBTask({})], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-5)) connections[-6] = -5 wf = Workflow(fws, connections) print 'Done adding more runs...' return FWAction(additions=wf) return FWAction()
def run_task(self, fw_spec): 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) if fw_spec['analysis']['bandgap'] >= self.gap_cutoff: static_dens = 90 uniform_dens = 1000 line_dens = 20 else: static_dens = 450 uniform_dens = 1500 line_dens = 30 if fw_spec['analysis']['bandgap'] <= self.metal_cutoff: user_incar_settings = {"ISMEAR": 1, "SIGMA": 0.2} else: user_incar_settings = {} print 'Adding more runs...' type_name = 'GGA+U' if 'GGA+U' in fw_spec['prev_task_type'] else 'GGA' snl = StructureNL.from_dict(fw_spec['mpsnl']) f = Composition( snl.structure.composition.reduced_formula).alphabetical_formula fws = [] connections = {} priority = fw_spec['_priority'] trackers = [ Tracker('FW_job.out'), Tracker('FW_job.error'), Tracker('vasp.out'), Tracker('OUTCAR'), Tracker('OSZICAR') ] trackers_db = [Tracker('FW_job.out'), Tracker('FW_job.error')] # run GGA static spec = fw_spec # pass all the items from the current spec to the new spec.update({ 'task_type': '{} static v2'.format(type_name), '_queueadapter': QA_VASP_SMALL, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority, '_trackers': trackers }) fws.append( Firework([ VaspCopyTask({ 'use_CONTCAR': True, 'skip_CHGCAR': True }), SetupStaticRunTask({ "kpoints_density": static_dens, 'user_incar_settings': user_incar_settings }), get_custodian_task(spec) ], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-10)) # insert into DB - GGA static spec = { 'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority * 2, "_dupefinder": DupeFinderDB().to_dict(), '_trackers': trackers_db } fws.append( Firework([VaspToDBTask()], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-9)) connections[-10] = -9 # run GGA Uniform spec = { 'task_type': '{} Uniform v2'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority, '_trackers': trackers } fws.append( Firework([ VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({ 'mode': 'uniform', "kpoints_density": uniform_dens }), get_custodian_task(spec) ], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-8)) connections[-9] = -8 # insert into DB - GGA Uniform spec = { 'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority * 2, "_dupefinder": DupeFinderDB().to_dict(), '_trackers': trackers_db } fws.append( Firework([VaspToDBTask({'parse_uniform': True})], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-7)) connections[-8] = -7 # run GGA Band structure spec = { 'task_type': '{} band structure v2'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority, '_trackers': trackers } fws.append( Firework([ VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({ 'mode': 'line', "kpoints_line_density": line_dens }), get_custodian_task(spec) ], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-6)) connections[-7] = [-6] # insert into DB - GGA Band structure spec = { 'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority * 2, "_dupefinder": DupeFinderDB().to_dict(), '_trackers': trackers_db } fws.append( Firework([VaspToDBTask({})], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-5)) connections[-6] = -5 if fw_spec.get('parameters') and fw_spec['parameters'].get( 'boltztrap'): # run Boltztrap from mpworks.firetasks.boltztrap_tasks import BoltztrapRunTask spec = { 'task_type': '{} Boltztrap'.format(type_name), '_queueadapter': QA_DB, '_dupefinder': DupeFinderDB().to_dict(), '_priority': priority } fws.append( Firework([BoltztrapRunTask()], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-4)) connections[-7].append(-4) wf = Workflow(fws, connections) print 'Done adding more runs...' return FWAction(additions=wf)
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
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']) update_spec = {} # add this later when creating new FW fizzled_parent = True parse_dos = False else: prev_dir = get_loc(fw_spec['prev_vasp_dir']) update_spec = { 'prev_vasp_dir': prev_dir, 'prev_task_type': fw_spec['prev_task_type'], 'run_tags': fw_spec['run_tags'], 'parameters': fw_spec.get('parameters') } fizzled_parent = False parse_dos = 'Uniform' in fw_spec['prev_task_type'] if 'run_tags' in fw_spec: self.additional_fields['run_tags'] = fw_spec['run_tags'] else: self.additional_fields['run_tags'] = fw_spec['_fizzled_parents'][ 0]['spec']['run_tags'] if MOVE_TO_GARDEN_DEV: prev_dir = move_to_garden(prev_dir, prod=False) elif MOVE_TO_GARDEN_PROD: prev_dir = move_to_garden(prev_dir, prod=True) # get the directory containing the db file db_dir = os.environ['DB_LOC'] db_path = os.path.join(db_dir, 'tasks_db.json') logging.basicConfig(level=logging.INFO) logger = logging.getLogger('MPVaspDrone') logger.setLevel(logging.INFO) sh = logging.StreamHandler(stream=sys.stdout) sh.setLevel(getattr(logging, 'INFO')) logger.addHandler(sh) with open(db_path) as f: db_creds = json.load(f) drone = MPVaspDrone(host=db_creds['host'], port=db_creds['port'], database=db_creds['database'], user=db_creds['admin_user'], password=db_creds['admin_password'], 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) 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}) 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'] } 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']) 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...' spec = { 'prev_vasp_dir': prev_dir, 'prev_task_type': fw_spec['task_type'], 'mpsnl': mpsnl, 'snlgroup_id': snlgroup_id, 'task_type': fw_spec['prev_task_type'], 'run_tags': list(fw_spec['run_tags']), 'parameters': fw_spec.get('parameters'), '_dupefinder': DupeFinderVasp().to_dict(), '_priority': fw_spec['_priority'] } # Pass elastic tensor spec if 'deformation_matrix' in fw_spec.keys(): spec['deformation_matrix'] = fw_spec['deformation_matrix'] spec['original_task_id'] = fw_spec['original_task_id'] snl = StructureNL.from_dict(spec['mpsnl']) spec['run_tags'].append(unconverged_tag) spec['_queueadapter'] = QA_VASP fws = [] connections = {} f = Composition(snl.structure.composition.reduced_formula ).alphabetical_formula fws.append( Firework([ VaspCopyTask({ 'files': [ 'INCAR', 'KPOINTS', 'POSCAR', 'POTCAR', 'CONTCAR' ], 'use_CONTCAR': False }), SetupUnconvergedHandlerTask(), get_custodian_task(spec) ], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-2)) spec = { 'task_type': 'VASP db insertion', '_allow_fizzled_parents': True, '_priority': fw_spec['_priority'], '_queueadapter': QA_DB, 'run_tags': list(fw_spec['run_tags']) } if 'deformation_matrix' in fw_spec.keys(): spec['deformation_matrix'] = fw_spec['deformation_matrix'] spec['original_task_id'] = fw_spec['original_task_id'] spec['run_tags'].append(unconverged_tag) fws.append( Firework([VaspToDBTask()], spec, name=get_slug(f + '--' + spec['task_type']), fw_id=-1)) connections[-2] = -1 wf = Workflow(fws, connections) return FWAction(detours=wf) # not successful and not due to convergence problem - FIZZLE raise ValueError("DB insertion successful, but don't know how to \ fix this Firework! Can't continue with workflow...")
def run_task(self, fw_spec): 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) if fw_spec['analysis']['bandgap'] >= self.gap_cutoff: print 'Adding more runs...' type_name = 'GGA+U' if 'GGA+U' in fw_spec['prev_task_type'] else 'GGA' snl = StructureNL.from_dict(fw_spec['mpsnl']) f = Composition.from_formula(snl.structure.composition.reduced_formula).alphabetical_formula fws = [] connections = {} priority = fw_spec['_priority'] # run GGA static spec = fw_spec # pass all the items from the current spec to the new # one spec.update({'task_type': '{} static'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority}) fws.append( FireWork( [VaspCopyTask({'use_CONTCAR': True}), SetupStaticRunTask(), get_custodian_task(spec)], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-10)) # insert into DB - GGA static spec = {'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority} fws.append( FireWork([VaspToDBTask()], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-9)) connections[-10] = -9 # run GGA Uniform spec = {'task_type': '{} Uniform'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority} fws.append(FireWork( [VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({'mode': 'uniform'}), get_custodian_task(spec)], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-8)) connections[-9] = -8 # insert into DB - GGA Uniform spec = {'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority} fws.append( FireWork([VaspToDBTask({'parse_uniform': True})], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-7)) connections[-8] = -7 # run GGA Band structure spec = {'task_type': '{} band structure'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority} fws.append(FireWork([VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({'mode': 'line'}), get_custodian_task(spec)], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-6)) connections[-7] = -6 # insert into DB - GGA Band structure spec = {'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority} fws.append(FireWork([VaspToDBTask({})], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-5)) connections[-6] = -5 wf = Workflow(fws, connections) print 'Done adding more runs...' return FWAction(additions=wf) return FWAction()
def run_task(self, fw_spec): 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) if fw_spec['analysis']['bandgap'] >= self.gap_cutoff: static_dens = 90 uniform_dens = 1000 line_dens = 20 else: static_dens = 450 uniform_dens = 1500 line_dens = 30 if fw_spec['analysis']['bandgap'] <= self.metal_cutoff: user_incar_settings = {"ISMEAR": 1, "SIGMA": 0.2} else: user_incar_settings = {} print 'Adding more runs...' type_name = 'GGA+U' if 'GGA+U' in fw_spec['prev_task_type'] else 'GGA' snl = StructureNL.from_dict(fw_spec['mpsnl']) f = Composition(snl.structure.composition.reduced_formula).alphabetical_formula fws = [] connections = {} priority = fw_spec['_priority'] trackers = [Tracker('FW_job.out'), Tracker('FW_job.error'), Tracker('vasp.out'), Tracker('OUTCAR'), Tracker('OSZICAR')] trackers_db = [Tracker('FW_job.out'), Tracker('FW_job.error')] # run GGA static spec = fw_spec # pass all the items from the current spec to the new spec.update({'task_type': '{} static v2'.format(type_name), '_queueadapter': QA_VASP_SMALL, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority, '_trackers': trackers}) fws.append( Firework( [VaspCopyTask({'use_CONTCAR': True, 'skip_CHGCAR': True}), SetupStaticRunTask({"kpoints_density": static_dens, 'user_incar_settings': user_incar_settings}), get_custodian_task(spec)], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-10)) # insert into DB - GGA static spec = {'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority*2, "_dupefinder": DupeFinderDB().to_dict(), '_trackers': trackers_db} fws.append( Firework([VaspToDBTask()], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-9)) connections[-10] = -9 # run GGA Uniform spec = {'task_type': '{} Uniform v2'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority, '_trackers': trackers} fws.append(Firework( [VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({'mode': 'uniform', "kpoints_density": uniform_dens}), get_custodian_task(spec)], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-8)) connections[-9] = -8 # insert into DB - GGA Uniform spec = {'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority*2, "_dupefinder": DupeFinderDB().to_dict(), '_trackers': trackers_db} fws.append( Firework([VaspToDBTask({'parse_uniform': True})], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-7)) connections[-8] = -7 # run GGA Band structure spec = {'task_type': '{} band structure v2'.format(type_name), '_queueadapter': QA_VASP, '_dupefinder': DupeFinderVasp().to_dict(), '_priority': priority, '_trackers': trackers} fws.append(Firework([VaspCopyTask({'use_CONTCAR': False}), SetupNonSCFTask({'mode': 'line', "kpoints_line_density": line_dens}), get_custodian_task(spec)], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-6)) connections[-7] = [-6] # insert into DB - GGA Band structure spec = {'task_type': 'VASP db insertion', '_queueadapter': QA_DB, '_allow_fizzled_parents': True, '_priority': priority*2, "_dupefinder": DupeFinderDB().to_dict(), '_trackers': trackers_db} fws.append(Firework([VaspToDBTask({})], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-5)) connections[-6] = -5 if fw_spec.get('parameters') and fw_spec['parameters'].get('boltztrap'): # run Boltztrap spec = {'task_type': '{} Boltztrap'.format(type_name), '_queueadapter': QA_DB, '_dupefinder': DupeFinderDB().to_dict(), '_priority': priority} fws.append(Firework( [BoltztrapRunTask()], spec, name=get_slug(f+'--'+spec['task_type']), fw_id=-4)) connections[-7].append(-4) wf = Workflow(fws, connections) print 'Done adding more runs...' return FWAction(additions=wf)
def run_task(self, fw_spec): 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) if fw_spec["analysis"]["bandgap"] >= self.gap_cutoff: print "Adding more runs..." type_name = "GGA+U" if "GGA+U" in fw_spec["prev_task_type"] else "GGA" snl = StructureNL.from_dict(fw_spec["mpsnl"]) f = Composition(snl.structure.composition.reduced_formula).alphabetical_formula fws = [] connections = {} priority = fw_spec["_priority"] # run GGA static spec = fw_spec # pass all the items from the current spec to the new # one spec.update( { "task_type": "{} static".format(type_name), "_queueadapter": QA_VASP, "_dupefinder": DupeFinderVasp().to_dict(), "_priority": priority, } ) fws.append( Firework( [VaspCopyTask({"use_CONTCAR": True}), SetupStaticRunTask(), get_custodian_task(spec)], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-10, ) ) # insert into DB - GGA static spec = { "task_type": "VASP db insertion", "_queueadapter": QA_DB, "_allow_fizzled_parents": True, "_priority": priority, "_dupefinder": DupeFinderDB().to_dict(), } fws.append(Firework([VaspToDBTask()], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-9)) connections[-10] = -9 # run GGA Uniform spec = { "task_type": "{} Uniform".format(type_name), "_queueadapter": QA_VASP, "_dupefinder": DupeFinderVasp().to_dict(), "_priority": priority, } fws.append( Firework( [ VaspCopyTask({"use_CONTCAR": False}), SetupNonSCFTask({"mode": "uniform"}), get_custodian_task(spec), ], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-8, ) ) connections[-9] = -8 # insert into DB - GGA Uniform spec = { "task_type": "VASP db insertion", "_queueadapter": QA_DB, "_allow_fizzled_parents": True, "_priority": priority, "_dupefinder": DupeFinderDB().to_dict(), } fws.append( Firework( [VaspToDBTask({"parse_uniform": True})], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-7 ) ) connections[-8] = -7 # run GGA Band structure spec = { "task_type": "{} band structure".format(type_name), "_queueadapter": QA_VASP, "_dupefinder": DupeFinderVasp().to_dict(), "_priority": priority, } fws.append( Firework( [VaspCopyTask({"use_CONTCAR": False}), SetupNonSCFTask({"mode": "line"}), get_custodian_task(spec)], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-6, ) ) connections[-7] = -6 # insert into DB - GGA Band structure spec = { "task_type": "VASP db insertion", "_queueadapter": QA_DB, "_allow_fizzled_parents": True, "_priority": priority, "_dupefinder": DupeFinderDB().to_dict(), } fws.append(Firework([VaspToDBTask({})], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-5)) connections[-6] = -5 wf = Workflow(fws, connections) print "Done adding more runs..." return FWAction(additions=wf) return FWAction()
def run_task(self, fw_spec): 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) if fw_spec["analysis"]["bandgap"] >= self.gap_cutoff: static_dens = 90 uniform_dens = 1000 line_dens = 20 else: static_dens = 450 uniform_dens = 1500 line_dens = 30 if fw_spec["analysis"]["bandgap"] <= self.metal_cutoff: user_incar_settings = {"ISMEAR": 1, "SIGMA": 0.2} else: user_incar_settings = {} print "Adding more runs..." type_name = "GGA+U" if "GGA+U" in fw_spec["prev_task_type"] else "GGA" snl = StructureNL.from_dict(fw_spec["mpsnl"]) f = Composition(snl.structure.composition.reduced_formula).alphabetical_formula fws = [] connections = {} priority = fw_spec["_priority"] trackers = [ Tracker("FW_job.out"), Tracker("FW_job.error"), Tracker("vasp.out"), Tracker("OUTCAR"), Tracker("OSZICAR"), ] trackers_db = [Tracker("FW_job.out"), Tracker("FW_job.error")] # run GGA static spec = fw_spec # pass all the items from the current spec to the new spec.update( { "task_type": "{} static v2".format(type_name), "_queueadapter": QA_VASP_SMALL, "_dupefinder": DupeFinderVasp().to_dict(), "_priority": priority, "_trackers": trackers, } ) fws.append( Firework( [ VaspCopyTask({"use_CONTCAR": True, "skip_CHGCAR": True}), SetupStaticRunTask({"kpoints_density": static_dens, "user_incar_settings": user_incar_settings}), get_custodian_task(spec), ], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-10, ) ) # insert into DB - GGA static spec = { "task_type": "VASP db insertion", "_queueadapter": QA_DB, "_allow_fizzled_parents": True, "_priority": priority * 2, "_dupefinder": DupeFinderDB().to_dict(), "_trackers": trackers_db, } fws.append(Firework([VaspToDBTask()], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-9)) connections[-10] = -9 # run GGA Uniform spec = { "task_type": "{} Uniform v2".format(type_name), "_queueadapter": QA_VASP, "_dupefinder": DupeFinderVasp().to_dict(), "_priority": priority, "_trackers": trackers, } fws.append( Firework( [ VaspCopyTask({"use_CONTCAR": False}), SetupNonSCFTask({"mode": "uniform", "kpoints_density": uniform_dens}), get_custodian_task(spec), ], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-8, ) ) connections[-9] = -8 # insert into DB - GGA Uniform spec = { "task_type": "VASP db insertion", "_queueadapter": QA_DB, "_allow_fizzled_parents": True, "_priority": priority * 2, "_dupefinder": DupeFinderDB().to_dict(), "_trackers": trackers_db, } fws.append( Firework( [VaspToDBTask({"parse_uniform": True})], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-7 ) ) connections[-8] = -7 # run GGA Band structure spec = { "task_type": "{} band structure v2".format(type_name), "_queueadapter": QA_VASP, "_dupefinder": DupeFinderVasp().to_dict(), "_priority": priority, "_trackers": trackers, } fws.append( Firework( [ VaspCopyTask({"use_CONTCAR": False}), SetupNonSCFTask({"mode": "line", "kpoints_line_density": line_dens}), get_custodian_task(spec), ], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-6, ) ) connections[-7] = [-6] # insert into DB - GGA Band structure spec = { "task_type": "VASP db insertion", "_queueadapter": QA_DB, "_allow_fizzled_parents": True, "_priority": priority * 2, "_dupefinder": DupeFinderDB().to_dict(), "_trackers": trackers_db, } fws.append(Firework([VaspToDBTask({})], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-5)) connections[-6] = -5 if fw_spec.get("parameters") and fw_spec["parameters"].get("boltztrap"): # run Boltztrap from mpworks.firetasks.boltztrap_tasks import BoltztrapRunTask spec = { "task_type": "{} Boltztrap".format(type_name), "_queueadapter": QA_DB, "_dupefinder": DupeFinderDB().to_dict(), "_priority": priority, } fws.append(Firework([BoltztrapRunTask()], spec, name=get_slug(f + "--" + spec["task_type"]), fw_id=-4)) connections[-7].append(-4) wf = Workflow(fws, connections) print "Done adding more runs..." return FWAction(additions=wf)
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 run_task(self, fw_spec): from mpworks.workflows.snl_to_wf import _get_metadata, \ _get_custodian_task # TODO: only add the workflow if the gap is > 1.0 eV # TODO: add stored data? if fw_spec['analysis']['bandgap'] >= self.gap_cutoff: type_name = 'GGA+U' if 'GGA+U' in fw_spec['prev_task_type'] else 'GGA' snl = StructureNL.from_dict(fw_spec['mpsnl']) fws = [] connections = {} # run GGA static spec = fw_spec # pass all the items from the current spec to the new # one spec.update({'task_type': '{} static'.format(type_name), '_dupefinder': DupeFinderVasp().to_dict()}) spec.update(_get_metadata(snl)) fws.append( FireWork( [VaspCopyTask({'extension': '.relax2'}), SetupStaticRunTask(), _get_custodian_task(spec)], spec, name=spec['task_type'], fw_id=-10)) # insert into DB - GGA static spec = {'task_type': 'VASP db insertion', '_allow_fizzled_parents': True} spec.update(_get_metadata(snl)) fws.append( FireWork([VaspToDBTask()], spec, name=spec['task_type'], fw_id=-9)) connections[-10] = -9 # run GGA Uniform spec = {'task_type': '{} Uniform'.format(type_name), '_dupefinder': DupeFinderVasp().to_dict()} spec.update(_get_metadata(snl)) fws.append(FireWork( [VaspCopyTask(), SetupNonSCFTask({'mode': 'uniform'}), _get_custodian_task(spec)], spec, name=spec['task_type'], fw_id=-8)) connections[-9] = -8 # insert into DB - GGA Uniform spec = {'task_type': 'VASP db insertion', '_allow_fizzled_parents': True} spec.update(_get_metadata(snl)) fws.append( FireWork([VaspToDBTask({'parse_uniform': True})], spec, name=spec['task_type'], fw_id=-7)) connections[-8] = -7 # run GGA Band structure spec = {'task_type': '{} band structure'.format(type_name), '_dupefinder': DupeFinderVasp().to_dict()} spec.update(_get_metadata(snl)) fws.append(FireWork([VaspCopyTask(), SetupNonSCFTask({'mode': 'line'}), _get_custodian_task(spec)], spec, name=spec['task_type'], fw_id=-6)) connections[-7] = -6 # insert into DB - GGA Band structure spec = {'task_type': 'VASP db insertion', '_allow_fizzled_parents': True} spec.update(_get_metadata(snl)) fws.append(FireWork([VaspToDBTask({})], spec, name=spec['task_type'], fw_id=-5)) connections[-6] = -5 wf = Workflow(fws, connections) return FWAction(additions=wf) return FWAction()
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.as_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.as_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.as_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 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
import json import os from fireworks.core.launchpad import LaunchPad from mpworks.submission.submission_mongo import SubmissionMongoAdapter from pymatgen.matproj.snl import StructureNL __author__ = 'Anubhav Jain' __copyright__ = 'Copyright 2014, The Materials Project' __version__ = '0.1' __maintainer__ = 'Anubhav Jain' __email__ = '*****@*****.**' __date__ = 'Jan 24, 2014' if __name__ == "__main__": sma = SubmissionMongoAdapter.from_file('submission.yaml') module_dir = os.path.dirname(os.path.abspath(__file__)) lp_f = os.path.join(module_dir, 'my_launchpad.yaml') lpdb = LaunchPad.from_file(lp_f) for s in os.listdir(os.path.join(module_dir, "snls")): if '.json' in 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, '*****@*****.**', {"priority": 10}) print 'DONE submitting', s print 'DONE!'