"""Definition of a base QChem Maker."""from__future__importannotationsimportloggingfromdataclassesimportdataclass,fieldfrompathlibimportPathfromtypingimportTYPE_CHECKINGfromemmet.core.qc_tasksimportTaskDocfromjobflowimportMaker,Response,jobfrommonty.serializationimportdumpfnfrommonty.shutilimportgzip_dirfrompymatgen.io.qchem.inputsimportQCInputfromatomate2.qchem.filesimportcopy_qchem_outputsfromatomate2.qchem.runimportrun_qchem,should_stop_childrenfromatomate2.qchem.sets.baseimportQCInputGeneratorifTYPE_CHECKING:fromcollections.abcimportCallablefrompymatgen.core.structureimportMoleculelogger=logging.getLogger(__name__)
[docs]defqchem_job(method:Callable)->job:""" Decorate the ``make`` method of QChem job makers. This is a thin wrapper around :obj:`~jobflow.core.job.Job` that configures common settings for all QChem jobs. It also configures the output schema to be a QChem :obj:`.TaskDoc`. Any makers that return QChem jobs (not flows) should decorate the ``make`` method with @qchem_job. For example: .. code-block:: python class MyQChemMaker(BaseQChemMaker): @qchem_job def make(molecule): # code to run QChem job. pass Parameters ---------- method : callable A BaseQChemMaker.make method. This should not be specified directly and is implied by the decorator. Returns ------- callable A decorated version of the make function that will generate QChem jobs. """returnjob(method,data=QCInput,output_schema=TaskDoc)
[docs]@dataclassclassBaseQCMaker(Maker):""" Base QChem job maker. Parameters ---------- name : str The job name. input_set_generator : .QChemInputGenerator A generator used to make the input set. write_input_set_kwargs : dict Keyword arguments that will get passed to :obj:`.write_qchem_input_set`. copy_qchem_kwargs : dict Keyword arguments that will get passed to :obj:`.copy_qchem_outputs`. run_qchem_kwargs : dict Keyword arguments that will get passed to :obj:`.run_qchem`. task_document_kwargs : dict Keyword arguments that will get passed to :obj:`.TaskDoc.from_directory`. stop_children_kwargs : dict Keyword arguments that will get passed to :obj:`.should_stop_children`. write_additional_data : dict Additional data to write to the current directory. Given as a dict of {filename: data}. Note that if using FireWorks, dictionary keys cannot contain the "." character which is typically used to denote file extensions. To avoid this, use the ":" character, which will automatically be converted to ".". E.g. ``{"my_file:txt": "contents of the file"}``. """name:str="base qchem job"input_set_generator:QCInputGenerator=field(default_factory=lambda:QCInputGenerator(job_type="sp",scf_algorithm="diis",basis_set="def2-qzvppd"))write_input_set_kwargs:dict=field(default_factory=dict)copy_qchem_kwargs:dict=field(default_factory=dict)run_qchem_kwargs:dict=field(default_factory=dict)task_document_kwargs:dict=field(default_factory=dict)stop_children_kwargs:dict=field(default_factory=dict)write_additional_data:dict=field(default_factory=dict)task_type:str|None=None
[docs]@qchem_jobdefmake(self,molecule:Molecule,prev_dir:str|Path|None=None,prev_qchem_dir:str|Path|None=None,)->Response:"""Run a QChem calculation. Parameters ---------- molecule : Molecule A pymatgen molecule object. prev_dir : str or Path or None A previous calculation directory to copy output files from. prev_qchem_dir (deprecated): str or Path or None A previous QChem calculation directory to copy output files from. """# copy previous inputsifprev_qchem_dirisnotNone:logger.warning("`prev_qchem_dir` will be deprecated in a future release. ""Please use `prev_dir` instead.")ifprev_dirisnotNone:logger.warning("You set both `prev_dir` and `prev_qchem_dir`, ""only `prev_dir` will be used.")else:prev_dir=prev_qchem_diriffrom_prev:=(prev_dirisnotNone):copy_qchem_outputs(prev_dir,**self.copy_qchem_kwargs)self.write_input_set_kwargs.setdefault("from_prev",from_prev)# write qchem input files# self.input_set_generator.get_input_set(molecule).write_inputs()self.input_set_generator.get_input_set(molecule)self.input_set_generator.get_input_set(molecule).write_input(directory=Path.cwd())# write any additional dataforfilename,datainself.write_additional_data.items():dumpfn(data,filename.replace(":","."))# run qchemrun_qchem(**self.run_qchem_kwargs)# parse qchem outputstask_doc=TaskDoc.from_directory(Path.cwd(),**self.task_document_kwargs)# task_doc.task_label = self.nametask_doc.task_type=self.nameifself.task_typeisNoneelseself.task_type# decide whether child jobs should proceedstop_children=should_stop_children(task_doc,**self.stop_children_kwargs)# gzip foldergzip_dir(".")returnResponse(stop_children=stop_children,stored_data={"custodian":task_doc.custodian},output=task_doc,)