def run_task(self, fw_spec): input_file = os.path.join(self.get("write_to_dir", ""), self.get("input_file", "mol.qin")) # these if statements might need to be reordered at some point # if a full QChemDictSet object was provided if hasattr(self["qchem_input_set"], "write_file"): qcin = self["qchem_input_set"] # if a molecule is being passed through fw_spec elif fw_spec.get("prev_calc_molecule"): mol = fw_spec.get("prev_calc_molecule") qcin_cls = load_class("pymatgen.io.qchem.sets", self["qchem_input_set"]) qcin = qcin_cls(mol, **self.get("qchem_input_params", {})) # if a molecule is included as an optional parameter elif self.get("molecule"): qcin_cls = load_class("pymatgen.io.qchem.sets", self["qchem_input_set"]) qcin = qcin_cls(self.get("molecule"), **self.get("qchem_input_params", {})) # if no molecule is present raise an error else: raise KeyError( "No molecule present, add as an optional param or check fw_spec" ) qcin.write_file(input_file)
def run_task(self, fw_spec): # If a full VaspInputSet object was provided if hasattr(self['vasp_input_set'], 'write_input'): input_set = self['vasp_input_set'] # Check if the user has also provided optional params if any(i in self.keys() for i in WriteVaspFromIOSet.optional_params): warnings.warn("Vasp input set was provided as an instance of a " "VaspInputSet, however optional parameter were also " "specified. These will not be used to overwrite the " "settings specified in the VaspInputSet, and will " "hence be ignored!") # TODO: fix this # If VaspInputSet String + parameters was provided else: # If the user has provided a full module path to class if "." in self["vasp_input_set"]: classname = self["vasp_input_set"].split(".")[-1] modulepath = ".".join(self["vasp_input_set"].split(".")[:-1]) input_set_cls = load_class(modulepath, classname) else: # Try our sets first try: input_set_cls = load_class("vscworkflows.setup.sets", self["vasp_input_set"]) # Check the pymatgen sets for the requested set except ModuleNotFoundError: input_set_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"]) if "structure" in self.keys(): input_set = input_set_cls(self["structure"], **self.get("vasp_input_params", {})) elif "parents" in self.keys(): try: structure = fw_spec["final_geometry"] except KeyError: try: parent_dir = self["parents"]["spec"]["_launch_dir"] except KeyError: # TODO Check this branch for atomate parents parent_dir = self["parents"]["launches"][-1]["launch_dir"] structure = _load_structure_from_dir(parent_dir) input_set = input_set_cls(structure, **self.get("vasp_input_params", {})) elif fw_spec["parents"]: parent_dir = fw_spec["parents"]["spec"]["_launch_dir"] structure = _load_structure_from_dir(parent_dir) input_set = input_set_cls(structure, **self.get("vasp_input_params", {})) else: raise ValueError("You must provide either an input structure or " "parent firework to WriteVaspFromIOSet!") input_set.write_input(".")
def run_task(self, fw_spec): input_file = os.path.join(self.get("write_to_dir", ""), self.get("input_file", "mol.qin")) # if a full QChemDictSet object was provided if hasattr(self["qchem_input_set"], "write_file"): qcin = self["qchem_input_set"] # if a molecule is being passed through fw_spec elif fw_spec.get("prev_calc_molecule"): prev_calc_mol = fw_spec.get("prev_calc_molecule") # if a molecule is also passed as an optional parameter if self.get("molecule"): mol = self.get("molecule") # check if mol and prev_calc_mol are isomorphic mol_graph = MoleculeGraph.with_local_env_strategy( mol, OpenBabelNN(), reorder=False, extend_structure=False) prev_mol_graph = MoleculeGraph.with_local_env_strategy( prev_calc_molecule, OpenBabelNN(), reorder=False, extend_structure=False, ) # If they are isomorphic, aka a previous FW has not changed bonding, # then we will use prev_calc_mol. If bonding has changed, we will use mol. if mol_graph.isomorphic_to(prev_mol_graph): mol = prev_calc_mol elif self["qchem_input_set"] != "OptSet": print( "WARNING: Molecule from spec is not isomorphic to passed molecule!" ) mol = prev_calc_mol else: print( "Not using prev_calc_mol as it is not isomorphic to passed molecule!" ) else: mol = prev_calc_mol qcin_cls = load_class("pymatgen.io.qchem.sets", self["qchem_input_set"]) qcin = qcin_cls(mol, **self.get("qchem_input_params", {})) # if a molecule is only included as an optional parameter elif self.get("molecule"): qcin_cls = load_class("pymatgen.io.qchem.sets", self["qchem_input_set"]) qcin = qcin_cls(self.get("molecule"), **self.get("qchem_input_params", {})) # if no molecule is present raise an error else: raise KeyError( "No molecule present, add as an optional param or check fw_spec" ) qcin.write(input_file)
def run_task(self, fw_spec): # get the directory that contains the dir to parse calc_dir = os.getcwd() if "calc_dir" in self: calc_dir = self["calc_dir"] elif self.get("calc_loc"): calc_dir = get_calc_loc(self["calc_loc"], fw_spec["calc_locs"])["path"] # parse the calc directory logger.info("PARSING DIRECTORY: {} USING DRONE: {}".format( calc_dir, self['drone'].__class__.__name__)) # get the database connection db_file = env_chk(self.get('db_file'), fw_spec) drone = self['drone'].__class__() task_doc = drone.assimilate(calc_dir) if not db_file: with open("task.json", "w") as f: f.write(json.dumps(task_doc, default=DATETIME_HANDLER)) else: mmdb_str = self["mmdb"] modname, classname = mmdb_str.strip().rsplit(".", 1) cls_ = load_class(modname, classname) db = cls_.from_db_file(db_file) # insert the task document t_id = db.insert(task_doc) logger.info("Finished parsing with task_id: {}".format(t_id)) return FWAction(stored_data={"task_id": task_doc.get("task_id", None)}, defuse_children=(task_doc["state"] != "successful"))
def run_task(self, fw_spec): # get the directory that contains the dir to parse calc_dir = os.getcwd() if "calc_dir" in self: calc_dir = self["calc_dir"] elif self.get("calc_loc"): calc_dir = get_calc_loc(self["calc_loc"], fw_spec["calc_locs"])["path"] # parse the calc directory logger.info("PARSING DIRECTORY: {} USING DRONE: {}".format( calc_dir, self["drone"].__class__.__name__)) # get the database connection db_file = env_chk(self.get("db_file"), fw_spec) drone = self["drone"].__class__() task_doc = drone.assimilate(calc_dir) if not db_file: with open("task.json", "w") as f: f.write(json.dumps(task_doc, default=DATETIME_HANDLER)) else: mmdb_str = self["mmdb"] modname, classname = mmdb_str.strip().rsplit(".", 1) cls_ = load_class(modname, classname) db = cls_.from_db_file(db_file) # insert the task document t_id = db.insert(task_doc) logger.info(f"Finished parsing with task_id: {t_id}") return FWAction( stored_data={"task_id": task_doc.get("task_id", None)}, defuse_children=(task_doc["state"] != "successful"), )
def __init__( self, tasks, task_types, input_sets=None, kpts_tolerance=0.9, **kwargs ): """ Creates task_types from tasks and type definitions Args: tasks (Store): Store of task documents task_types (Store): Store of task_types for tasks input_sets (Dict): dictionary of task_type and pymatgen input set to validate against kpts_tolerance (float): the minimum kpt density as dictated by the InputSet to require """ self.tasks = tasks self.task_types = task_types self.input_sets = input_sets or { "GGA Structure Optimization": "MPRelaxSet", "GGA+U Structure Optimization": "MPRelaxSet", } self.kpts_tolerance = kpts_tolerance self._input_sets = { name: load_class("pymatgen.io.vasp.sets", inp_set) for name, inp_set in self.input_sets.items() } self.kwargs = kwargs super().__init__( source=tasks, target=task_types, ufn=self.calc, projection=["orig_inputs", "output.structure"], **kwargs, )
def run_task(self, fw_spec): # Get interpolated structure. structure = GetInterpolatedPOSCAR.interpolate_poscar(self, fw_spec) # Assumes VaspInputSet String + parameters was provided vis_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"]) vis = vis_cls(structure, **self.get("vasp_input_params", {})) vis.write_input(".")
def load_input_sets(cls, values): input_sets = {} for name, inp_set in values.items(): if isinstance(inp_set, str): _module = ".".join(inp_set.split(".")[:-1]) _class = inp_set.split(".")[-1] input_sets[name] = load_class(_module, _class) return input_sets
def run_task(self, fw_spec): # if a full VaspInputSet object was provided if hasattr(self['vasp_input_set'], 'write_input'): vis = self['vasp_input_set'] # if VaspInputSet String + parameters was provided else: vis_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"]) vis = vis_cls(self["structure"], **self.get("vasp_input_params", {})) vis.write_input(".")
def run_task(self, fw_spec): # if a full QChemDictSet object was provided if hasattr(self['qchem_input_set'], 'write_file'): qcin = self['qchem_input_set'] # if QCInputSet String + parameters was provided else: qcin_cls = load_class("pymatgen.io.qchem_io.sets", self["qchem_input_set"]) qcin = qcin_cls(self["molecule"], **self.get("qchem_input_params", {})) # we might need to add the filename as a required param qcin.write_file("mol.qin")
def run_task(self, fw_spec): # if a full object is provided. if hasattr(self['feff_input_set'], 'write_input'): fis = self['feff_input_set'] # if inputset String + parameters was provided else: fis_cls = load_class("pymatgen.io.feff.sets", self["feff_input_set"]) fis = fis_cls(self["absorbing_atom"], self["structure"], self.get("radius", 10.0), **self.get("other_params", {})) fis.write_input(".")
def run_task(self, fw_spec): pass_dict = self.get("pass_dict") parse_kwargs = self.get("parse_kwargs") pc_string = self.get("parse_class") parse_class = load_class(*pc_string.rsplit(".", 1)) calc_dir = self.get("calc_dir", ".") with monty.os.cd(calc_dir): result = parse_class(**parse_kwargs) pass_dict = recursive_get_result(pass_dict, result) mod_spec_key = self.get("mod_spec_key", "prev_calc_result") mod_spec_cmd = self.get("mod_spec_cmd", "_set") return FWAction(mod_spec=[{mod_spec_cmd: {mod_spec_key: pass_dict}}])
def __init__(self, source, materials, wf_function, material_filter=None, lpad=None, **kwargs): """ Adds workflows to a launchpad based on material inputs. This is primarily to be used for derivative property workflows but could in principles used to generate workflows for any workflow that can be invoked from structure data Args: source (Store): store of properties materials (Store): Store of materials properties material_filter (dict): dict filter for getting items to process e. g. {"elasticity": None} wf_function (string or method): method to generate a workflow based on structure in document with missing property can be a string to be loaded or a custom method. Note that the builder/runner will not be serializable with custom methods. lpad (LaunchPad or dict): fireworks launchpad to use for adding workflows, can either be None (autoloaded), a LaunchPad instance, or a dict from which the LaunchPad will be invoked **kwargs (kwargs): kwargs for builder """ self.source = source self.materials = materials # Will this be pickled properly for multiprocessing? could just put # it into the processor if that's the case if isinstance(wf_function, six.string_types): self.wf_function = load_class(*wf_function.rsplit('.', 1)) self._wf_function_string = wf_function elif callable(wf_function): self.wf_function = wf_function self._wf_function_string = None else: raise ValueError("wf_function must be callable or a string " "corresponding to a loadable method") self.material_filter = material_filter if lpad is None: self.lpad = LaunchPad.auto_load() elif isinstance(lpad, dict): self.lpad = LaunchPad.from_dict(lpad) else: self.lpad = lpad super().__init__(sources=[source, materials], targets=[], **kwargs)
def run_task(self, fw_spec): struct = Structure.from_file('POSCAR') # if a full VaspInputSet object was provided if hasattr(self['vasp_input_set'], 'write_input'): vis = self['vasp_input_set'] vis.structure = struct # if VaspInputSet String + parameters was provided else: vis_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"]) vis = vis_cls(struct, **self.get("vasp_input_params", {})) # add site properties if they were added for prop, vals in self.get("site_properties", dict()).items(): vis.structure.add_site_property(prop, vals) vis.write_input(".")
def run_task(self, fw_spec): logger.info("PARSING final lammps positions to VASP.") data = LammpsData.from_file(self['structure_loc'], atom_style=self.get('atom_style', 'full'), sort_id=True) struc = data.structure structure = Structure(lattice=struc.lattice, species=[s.specie for s in struc.sites], coords=[s.coords for s in struc.sites], coords_are_cartesian=True) vis_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"]) vis = vis_cls(structure, **self.get("vasp_input_params", {})) vis.write_input(".")
def __init__(self, absorbing_atom, structure, spectrum_type, edge="K", radius=10., name="EELS spectroscopy", beam_energy=100, beam_direction=None, collection_angle=1, convergence_angle=1, user_eels_settings=None, feff_input_set=None, feff_cmd="feff", override_default_feff_params=None, db_file=None, parents=None, metadata=None, **kwargs): """ Write the input set for FEFF-EELSS spectroscopy, run feff and insert the core-loss spectrum to the database(or dump to a json file if db_file=None). Args: absorbing_atom (str): absorbing atom symbol structure (Structure): input structure spectrum_type (str): "ELNES" or "EXELFS" edge (str): absorption edge radius (float): cluster radius in angstroms name (str) feff_input_set (FeffDictSet) feff_cmd (str): path to the feff binary override_default_feff_params (dict): override feff tag settings. db_file (str): path to the db file. parents (Firework): Parents of this particular Firework. FW or list of FWS. metadata (dict): meta data **kwargs: Other kwargs that are passed to Firework.__init__. """ override_default_feff_params = override_default_feff_params or {} if not feff_input_set: fis_cls = load_class("pymatgen.io.feff.sets", "MP{}Set".format(spectrum_type)) feff_input_set = fis_cls(absorbing_atom, structure, edge, radius, beam_energy, beam_direction, collection_angle, convergence_angle, user_eels_settings=user_eels_settings, **override_default_feff_params) t = [WriteFeffFromIOSet(absorbing_atom=absorbing_atom, structure=structure, radius=radius, feff_input_set=feff_input_set), RunFeffDirect(feff_cmd=feff_cmd), SpectrumToDbTask(absorbing_atom=absorbing_atom, structure=structure, db_file=db_file, spectrum_type=spectrum_type, edge=edge, output_file="eels.dat", metadata=metadata)] super(EELSFW, self).__init__(t, parents=parents, name="{}-{}". format(structure.composition.reduced_formula, name), **kwargs)
def get_feff_input_set_obj(fis, *args, **kwargs): """ returns feff input set object. Args: fis (str or FeffDictSet subclass): The inputset for setting params. If string then the entire path to the class or the spectrum type must be provided e.g. "pymatgen.io.feff.sets.MPXANESSet" or "XANES" args (tuple): feff input set args kwargs (dict): feff input set kwargs Returns: FeffDictSet object """ # e.g. "pymatgen.io.feff.sets.MPXANESSet" or "XANES" if isinstance(fis, str): fis_ = f"pymatgen.io.feff.sets.MP{fis}Set" if "pymatgen" not in fis else fis modname, classname = fis_.strip().rsplit(".", 1) fis_cls = load_class(modname, classname) return fis_cls(*args, **kwargs) else: return fis
def run_task(self, fw_spec): # if a full VaspInputSet object was provided if hasattr(self["vasp_input_set"], "write_input"): vis = self["vasp_input_set"] # if VaspInputSet String + parameters was provided else: vis_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"]) vis = vis_cls(self["structure"], **self.get("vasp_input_params", {})) # over-write structure with fw_spec structure spec_structure_key = self.get("spec_structure_key", None) if spec_structure_key is not None: fw_struct = fw_spec.get(spec_structure_key) dd = vis.as_dict() dd["structure"] = fw_struct vis.from_dict(dd) potcar_spec = self.get("potcar_spec", False) vis.write_input(".", potcar_spec=potcar_spec)
def get_feff_input_set_obj(fis, *args, **kwargs): """ returns feff input set object. Args: fis (str or FeffDictSet subclass): The inputset for setting params. If string then the entire path to the class or the spectrum type must be provided e.g. "pymatgen.io.feff.sets.MPXANESSet" or "XANES" args (tuple): feff input set args kwargs (dict): feff input set kwargs Returns: FeffDictSet object """ # e.g. "pymatgen.io.feff.sets.MPXANESSet" or "XANES" if isinstance(fis, string_types): fis_ = "pymatgen.io.feff.sets.MP{}Set".format(fis) if "pymatgen" not in fis else fis modname, classname = fis_.strip().rsplit(".", 1) fis_cls = load_class(modname, classname) return fis_cls(*args, **kwargs) else: return fis