def prepare_for_submission(self, folder): """ This is the routine to be called when you want to create the input files and related stuff with a plugin. :param folder: a aiida.common.folders.Folder subclass where the plugin should put all its files. """ if 'structure' in self.inputs: pmg_structure = self.inputs.structure.get_pymatgen_molecule() else: # If structure is not specified, it is read from the chk file pmg_structure = None # Generate the input file input_string = GaussianCalculation._render_input_string_from_params( self.inputs.parameters.get_dict(), pmg_structure) with open(folder.get_abs_path(self.INPUT_FILE), "w") as out_file: out_file.write(input_string) settings = self.inputs.settings.get_dict( ) if "settings" in self.inputs else {} # create code info codeinfo = CodeInfo() codeinfo.cmdline_params = settings.pop("cmdline", []) codeinfo.code_uuid = self.inputs.code.uuid codeinfo.stdin_name = self.INPUT_FILE codeinfo.stdout_name = self.OUTPUT_FILE codeinfo.withmpi = self.inputs.metadata.options.withmpi # create calculation info calcinfo = CalcInfo() calcinfo.remote_copy_list = [] calcinfo.local_copy_list = [] calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self.INPUT_FILE calcinfo.stdout_name = self.OUTPUT_FILE calcinfo.codes_info = [codeinfo] calcinfo.retrieve_list = [self.OUTPUT_FILE] # symlink or copy to parent calculation calcinfo.remote_symlink_list = [] calcinfo.remote_copy_list = [] if "parent_calc_folder" in self.inputs: comp_uuid = self.inputs.parent_calc_folder.computer.uuid remote_path = self.inputs.parent_calc_folder.get_remote_path() copy_info = (comp_uuid, remote_path, self.PARENT_FOLDER_NAME) if (self.inputs.code.computer.uuid == comp_uuid): # if running on the same computer - make a symlink # if not - copy the folder calcinfo.remote_symlink_list.append(copy_info) else: calcinfo.remote_copy_list.append(copy_info) return calcinfo
def prepare_for_submission(self, folder): """Create the input files from the input nodes passed to this instance of the `CalcJob`. :param folder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.datastructures.CalcInfo` instance """ from aiida_orca.utils import OrcaInput # create input structure(s) if 'structure' in self.inputs: self._write_structure(self.inputs.structure, folder, self._INPUT_COORDS_FILE) settings = self.inputs.settings.get_dict( ) if 'settings' in self.inputs else {} # create code info codeinfo = CodeInfo() codeinfo.cmdline_params = settings.pop('cmdline', []) + [self._INPUT_FILE] codeinfo.stdout_name = self._OUTPUT_FILE codeinfo.join_files = True codeinfo.code_uuid = self.inputs.code.uuid # create calc info calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._INPUT_FILE calcinfo.stdout_name = self._OUTPUT_FILE calcinfo.codes_info = [codeinfo] # files or additional structures if 'file' in self.inputs: calcinfo.local_copy_list = [] for name, obj in self.inputs.file.items(): if name == 'gbw': calcinfo.local_copy_list.append( (obj.uuid, obj.filename, 'aiida_old.gbw')) else: calcinfo.local_copy_list.append( (obj.uuid, obj.filename, obj.filename)) # Retrive list calcinfo.retrieve_list = [ self._OUTPUT_FILE, self._GBW_FILE, self._HESSIAN_FILE, self._RELAX_COORDS_FILE ] calcinfo.retrieve_list += settings.pop('additional_retrieve_list', []) # create ORCA input file # inp = OrcaInput(self.inputs.parameters.get_dict(), remote_path=remote_path) inp = OrcaInput(self.inputs.parameters.get_dict()) with io.open(folder.get_abs_path(self._INPUT_FILE), mode='w') as fobj: fobj.write(inp.render()) return calcinfo
def prepare_for_submission(self, folder): """ This is the routine to be called when you want to create the input files and related stuff with a plugin. :param folder: a aiida.common.folders.Folder subclass where the plugin should put all its files. """ # create calc info calcinfo = CalcInfo() calcinfo.remote_copy_list = [] calcinfo.local_copy_list = [] # The main input try: input_string = GaussianCalculation._render_input_string_from_params( self.inputs.parameters.get_dict(), self.inputs.structure ) # If structure is not specified the user might want to restart from a chk except AttributeError: input_string = GaussianCalculation._render_input_string_from_params( self.inputs.parameters.get_dict(), None ) # Parse additional link1 sections if "extra_link1_sections" in self.inputs: for l1_name, l1_params in self.inputs.extra_link1_sections.items(): input_string += "--Link1--\n" # The link1 secions don't support their own geometries. input_string += GaussianCalculation._render_input_string_from_params( l1_params.get_dict(), None ) with open(folder.get_abs_path(self.INPUT_FILE), "w") as out_file: out_file.write(input_string) settings = self.inputs.settings.get_dict() if "settings" in self.inputs else {} # create code info codeinfo = CodeInfo() codeinfo.cmdline_params = settings.pop("cmdline", []) codeinfo.code_uuid = self.inputs.code.uuid codeinfo.stdin_name = self.INPUT_FILE codeinfo.stdout_name = self.OUTPUT_FILE codeinfo.withmpi = self.inputs.metadata.options.withmpi # create calculation info calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self.INPUT_FILE calcinfo.stdout_name = self.OUTPUT_FILE calcinfo.codes_info = [codeinfo] calcinfo.retrieve_list = [self.OUTPUT_FILE] # symlink or copy to parent calculation calcinfo.remote_symlink_list = [] calcinfo.remote_copy_list = [] if "parent_calc_folder" in self.inputs: comp_uuid = self.inputs.parent_calc_folder.computer.uuid remote_path = self.inputs.parent_calc_folder.get_remote_path() copy_info = (comp_uuid, remote_path, "parent_calc") if ( self.inputs.code.computer.uuid == comp_uuid ): # if running on the same computer - make a symlink # if not - copy the folder calcinfo.remote_symlink_list.append(copy_info) else: calcinfo.remote_copy_list.append(copy_info) return calcinfo
def prepare_for_submission(self, tempfolder): # Setup template with open(self.inputs.template, 'r') as tempfile: temp_contents = tempfile.read() lmp_template = Template(temp_contents) # # check variables # for variable in self.inputs.variables.values(): # if not isinstance(variable, list): # raise TypeError('Values in variables must be list') # check kinds if 'kinds' in self.inputs: kind_var = { kind: kind_index + 1 for kind_index, kind in enumerate(self.inputs.kinds) } lmp_template = Template(lmp_template.safe_substitute(**kind_var)) for i, case in enumerate(self.inputs.cases): structure = case.pop('structure') if isinstance(structure, StructureData): structure_txt, struct_transform = generate_lammps_structure( structure, kinds=self.inputs.kinds) elif isinstance(structure, SinglefileData): structure_txt = structure.get_content() else: raise TypeError( 'Input structure must be StructureData or SinglefileData') input_txt = lmp_template.safe_substitute(**case) # ========================= dump to file =========================== tempfolder.get_subfolder(i, create=True) input_filename = tempfolder.get_abs_path( f'{i}/{self._INPUT_FILE_NAME}') with open(input_filename, 'w') as infile: infile.write(input_txt) structure_filename = tempfolder.get_abs_path( f'{i}/{self._INPUT_STRUCTURE}') with open(structure_filename, 'w') as infile: infile.write(structure_txt) case_filename = tempfolder.get_abs_path(f'{i}/case.json') case.update({'structure pk': structure.pk}) with open(case_filename, 'w') as infile: json.dump(case, infile, sort_keys=True, indent=2) # ============================ calcinfo ================================ settings = self.inputs.settings.get_dict() \ if 'settings' in self.inputs else {} codeinfo = CodeInfo() codeinfo.cmdline_params = self._cmdline_params codeinfo.code_uuid = self.inputs.code.uuid codeinfo.stdout_name = self._stdout_name codeinfo.join_files = True calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.prepend_text = (f'for i in $(seq 0 {i})\n' 'do\n' 'cd "${i}" || exit') calcinfo.append_text = ('cd ..\n' 'done') calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._INPUT_FILE_NAME calcinfo.stdout_name = self._stdout_name calcinfo.retrieve_list = self._retrieve_list + [ self.options.output_filename ] calcinfo.retrieve_list += settings.pop('additional_retrieve_list', []) calcinfo.retrieve_temporary_list = self._retrieve_temporary_list calcinfo.codes_info = [codeinfo] # =========================== local_copy_list ========================== if 'file' in self.inputs: calcinfo.local_copy_list = [] for name, obj in self.inputs.file.items(): calcinfo.local_copy_list.append( (obj.uuid, obj.filename, f'{name}.pb')) return calcinfo
def prepare_for_submission(self, tempfolder): # Setup structure if isinstance(self.inputs.structure, StructureData): structure_txt, struct_transform = generate_lammps_structure( self.inputs.structure, kinds=self.inputs.kinds) elif isinstance(self.inputs.structure, SinglefileData): structure_txt = self.inputs.structure.get_content() else: raise TypeError( 'Input structure must be StructureData or SinglefileData') with open(self.inputs.template, 'r') as tempfile: temp_contents = tempfile.read() init_temp = Template(temp_contents) input_txt = init_temp.safe_substitute(**self.inputs.variables) if 'kinds' in self.inputs: kind_temp = Template(input_txt) kind_var = { kind: kind_index + 1 for kind_index, kind in enumerate(self.inputs.kinds) } input_txt = kind_temp.safe_substitute(**kind_var) # =========================== dump to file ============================= input_filename = tempfolder.get_abs_path(self._INPUT_FILE_NAME) with open(input_filename, 'w') as infile: infile.write(input_txt) structure_filename = tempfolder.get_abs_path(self._INPUT_STRUCTURE) with open(structure_filename, 'w') as infile: infile.write(structure_txt) # ============================ calcinfo ================================ settings = self.inputs.settings.get_dict() \ if 'settings' in self.inputs else {} codeinfo = CodeInfo() codeinfo.cmdline_params = self._cmdline_params codeinfo.code_uuid = self.inputs.code.uuid codeinfo.stdout_name = self._stdout_name codeinfo.join_files = True calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._INPUT_FILE_NAME calcinfo.stdout_name = self._stdout_name calcinfo.retrieve_list = self._retrieve_list + [ self.options.output_filename ] calcinfo.retrieve_list += settings.pop('additional_retrieve_list', []) calcinfo.retrieve_temporary_list = self._retrieve_temporary_list calcinfo.codes_info = [codeinfo] # =========================== local_copy_list ========================== if 'file' in self.inputs: calcinfo.local_copy_list = [] for name, obj in self.inputs.file.items(): calcinfo.local_copy_list.append( (obj.uuid, obj.filename, f'{name}.pb')) return calcinfo
def prepare_for_submission(self, folder): """Create the input files from the input nodes passed to this instance of the `CalcJob`. :param folder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.datastructures.CalcInfo` instance """ from aiida_cp2k.utils import Cp2kInput # create cp2k input file inp = Cp2kInput(self.inputs.parameters.get_dict()) inp.add_keyword("GLOBAL/PROJECT", self._DEFAULT_PROJECT_NAME) # create input structure(s) if 'structure' in self.inputs: # As far as I understand self.inputs.structure can't deal with tags # self.inputs.structure.export(folder.get_abs_path(self._DEFAULT_COORDS_FILE_NAME), fileformat="xyz") self._write_structure(self.inputs.structure, folder, self._DEFAULT_COORDS_FILE_NAME) # modify the input dictionary accordingly for i, letter in enumerate('ABC'): inp.add_keyword('FORCE_EVAL/SUBSYS/CELL/' + letter, '{:<15} {:<15} {:<15}'.format( *self.inputs.structure.cell[i]), override=False, conflicting_keys=[ 'ABC', 'ALPHA_BETA_GAMMA', 'CELL_FILE_NAME' ]) topo = "FORCE_EVAL/SUBSYS/TOPOLOGY" inp.add_keyword(topo + "/COORD_FILE_NAME", self._DEFAULT_COORDS_FILE_NAME, override=False) inp.add_keyword(topo + "/COORD_FILE_FORMAT", "XYZ", override=False, conflicting_keys=['COORDINATE']) with io.open(folder.get_abs_path(self._DEFAULT_INPUT_FILE), mode="w", encoding="utf-8") as fobj: try: fobj.write(inp.render()) except ValueError as exc: six.raise_from( InputValidationError( "invalid keys or values in input parameters found"), exc) settings = self.inputs.settings.get_dict( ) if 'settings' in self.inputs else {} # create code info codeinfo = CodeInfo() codeinfo.cmdline_params = settings.pop( 'cmdline', []) + ["-i", self._DEFAULT_INPUT_FILE] codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE codeinfo.join_files = True codeinfo.code_uuid = self.inputs.code.uuid # create calc info calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._DEFAULT_INPUT_FILE calcinfo.stdout_name = self._DEFAULT_OUTPUT_FILE calcinfo.codes_info = [codeinfo] # files or additional structures if 'file' in self.inputs: calcinfo.local_copy_list = [] for name, obj in self.inputs.file.items(): if isinstance(obj, SinglefileData): calcinfo.local_copy_list.append( (obj.uuid, obj.filename, obj.filename)) elif isinstance(obj, StructureData): self._write_structure(obj, folder, name + '.xyz') calcinfo.retrieve_list = [ self._DEFAULT_OUTPUT_FILE, self._DEFAULT_RESTART_FILE_NAME, self._DEFAULT_TRAJECT_FILE_NAME ] calcinfo.retrieve_list += settings.pop('additional_retrieve_list', []) # symlinks calcinfo.remote_symlink_list = [] calcinfo.remote_copy_list = [] if 'parent_calc_folder' in self.inputs: comp_uuid = self.inputs.parent_calc_folder.computer.uuid remote_path = self.inputs.parent_calc_folder.get_remote_path() copy_info = (comp_uuid, remote_path, self._DEFAULT_PARENT_CALC_FLDR_NAME) if self.inputs.code.computer.uuid == comp_uuid: # if running on the same computer - make a symlink # if not - copy the folder calcinfo.remote_symlink_list.append(copy_info) else: calcinfo.remote_copy_list.append(copy_info) # check for left over settings if settings: raise InputValidationError( "The following keys have been found " + "in the settings input node {}, ".format(self.pk) + "but were not understood: " + ",".join(settings.keys())) return calcinfo
def prepare_for_submission(self, folder): """Create the input files from the input nodes passed to this instance of the `CalcJob`. :param folder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.datastructures.CalcInfo` instance """ from .utils import Cp2kInput # create input structure if "structure" in self.inputs: self.inputs.structure.export(folder.get_abs_path( self._DEFAULT_COORDS_FILE_NAME), fileformat="xyz") # create cp2k input file inp = Cp2kInput(self.inputs.parameters.get_dict()) inp.add_keyword("GLOBAL/PROJECT", self._DEFAULT_PROJECT_NAME) if "structure" in self.inputs: for i, letter in enumerate("ABC"): inp.add_keyword( "FORCE_EVAL/SUBSYS/CELL/" + letter, "{:<15} {:<15} {:<15}".format( *self.inputs.structure.cell[i]), ) topo = "FORCE_EVAL/SUBSYS/TOPOLOGY" inp.add_keyword(topo + "/COORD_FILE_NAME", self._DEFAULT_COORDS_FILE_NAME) inp.add_keyword(topo + "/COORD_FILE_FORMAT", "XYZ") with io.open(folder.get_abs_path(self._DEFAULT_INPUT_FILE), mode="w", encoding="utf-8") as fobj: try: inp.to_file(fobj) except ValueError as exc: six.raise_from( InputValidationError( "invalid keys or values in input parameters found"), exc, ) if "settings" in self.inputs: settings = self.inputs.settings.get_dict() else: settings = {} # create code info codeinfo = CodeInfo() codeinfo.cmdline_params = settings.pop("cmdline", []) + [ "-i", self._DEFAULT_INPUT_FILE, ] codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE codeinfo.join_files = True codeinfo.code_uuid = self.inputs.code.uuid # create calc info calcinfo = CalcInfo() calcinfo.stdin_name = self._DEFAULT_INPUT_FILE calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._DEFAULT_INPUT_FILE calcinfo.stdout_name = self._DEFAULT_OUTPUT_FILE calcinfo.codes_info = [codeinfo] # file lists calcinfo.remote_symlink_list = [] if "file" in self.inputs: calcinfo.local_copy_list = [] for fobj in self.inputs.file.values(): calcinfo.local_copy_list.append( (fobj.uuid, fobj.filename, fobj.filename)) calcinfo.remote_copy_list = [] calcinfo.retrieve_list = [ self._DEFAULT_OUTPUT_FILE, self._DEFAULT_RESTART_FILE_NAME, ] calcinfo.retrieve_list += settings.pop("additional_retrieve_list", []) # symlinks if "parent_calc_folder" in self.inputs: comp_uuid = self.inputs.parent_calc_folder.computer.uuid remote_path = self.inputs.parent_calc_folder.get_remote_path() symlink = (comp_uuid, remote_path, self._DEFAULT_PARENT_CALC_FLDR_NAME) calcinfo.remote_symlink_list.append(symlink) # check for left over settings if settings: raise InputValidationError( "The following keys have been found " + "in the settings input node {}, ".format(self.pk) + "but were not understood: " + ",".join(settings.keys())) return calcinfo
def prepare_for_submission(self, folder): """Create the input files from the input nodes passed to this instance of the `CalcJob`. :param folder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.datastructures.CalcInfo` instance """ # pylint: disable=too-many-statements,too-many-branches # Create cp2k input file. inp = Cp2kInput(self.inputs.parameters.get_dict()) inp.add_keyword("GLOBAL/PROJECT", self._DEFAULT_PROJECT_NAME) # Create input structure(s). if 'structure' in self.inputs: # As far as I understand self.inputs.structure can't deal with tags # self.inputs.structure.export(folder.get_abs_path(self._DEFAULT_COORDS_FILE_NAME), fileformat="xyz") self._write_structure(self.inputs.structure, folder, self._DEFAULT_COORDS_FILE_NAME) # modify the input dictionary accordingly for i, letter in enumerate('ABC'): inp.add_keyword('FORCE_EVAL/SUBSYS/CELL/' + letter, '{:<15} {:<15} {:<15}'.format(*self.inputs.structure.cell[i]), override=False, conflicting_keys=['ABC', 'ALPHA_BETA_GAMMA', 'CELL_FILE_NAME']) topo = "FORCE_EVAL/SUBSYS/TOPOLOGY" inp.add_keyword(topo + "/COORD_FILE_NAME", self._DEFAULT_COORDS_FILE_NAME, override=False) inp.add_keyword(topo + "/COORD_FILE_FORMAT", "XYZ", override=False, conflicting_keys=['COORDINATE']) if 'basissets' in self.inputs: validate_basissets(inp, self.inputs.basissets, self.inputs.structure if 'structure' in self.inputs else None) write_basissets(inp, self.inputs.basissets, folder) if 'pseudos' in self.inputs: validate_pseudos(inp, self.inputs.pseudos, self.inputs.structure if 'structure' in self.inputs else None) write_pseudos(inp, self.inputs.pseudos, folder) # Kpoints. if 'kpoints' in self.inputs: try: mesh, _ = self.inputs.kpoints.get_kpoints_mesh() except AttributeError: raise InputValidationError("K-point sampling for SCF must be given in mesh form.") inp.add_keyword('FORCE_EVAL/DFT/KPOINTS', {'WAVEFUNCTIONS': ' COMPLEX', 'FULL_GRID': '.TRUE.'}) inp.add_keyword('FORCE_EVAL/DFT/KPOINTS/SCHEME MONKHORST-PACK', f'{mesh[0]} {mesh[1]} {mesh[2]}') with io.open(folder.get_abs_path(self._DEFAULT_INPUT_FILE), mode="w", encoding="utf-8") as fobj: try: fobj.write(inp.render()) except ValueError as exc: raise InputValidationError("Invalid keys or values in input parameters found") from exc settings = self.inputs.settings.get_dict() if 'settings' in self.inputs else {} # Create code info. codeinfo = CodeInfo() codeinfo.cmdline_params = settings.pop('cmdline', []) + ["-i", self._DEFAULT_INPUT_FILE] codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE codeinfo.join_files = True codeinfo.code_uuid = self.inputs.code.uuid # Create calc info. calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._DEFAULT_INPUT_FILE calcinfo.stdout_name = self._DEFAULT_OUTPUT_FILE calcinfo.codes_info = [codeinfo] # Files or additional structures. if 'file' in self.inputs: calcinfo.local_copy_list = [] for name, obj in self.inputs.file.items(): if isinstance(obj, SinglefileData): calcinfo.local_copy_list.append((obj.uuid, obj.filename, obj.filename)) elif isinstance(obj, StructureData): self._write_structure(obj, folder, name + '.xyz') calcinfo.retrieve_list = [ self._DEFAULT_OUTPUT_FILE, self._DEFAULT_RESTART_FILE_NAME, self._DEFAULT_TRAJECT_FILE_NAME ] calcinfo.retrieve_list += settings.pop('additional_retrieve_list', []) # Symlinks. calcinfo.remote_symlink_list = [] calcinfo.remote_copy_list = [] if 'parent_calc_folder' in self.inputs: comp_uuid = self.inputs.parent_calc_folder.computer.uuid remote_path = self.inputs.parent_calc_folder.get_remote_path() copy_info = (comp_uuid, remote_path, self._DEFAULT_PARENT_CALC_FLDR_NAME) # If running on the same computer - make a symlink. if self.inputs.code.computer.uuid == comp_uuid: calcinfo.remote_symlink_list.append(copy_info) # If not - copy the folder. else: calcinfo.remote_copy_list.append(copy_info) # Check for left over settings. if settings: raise InputValidationError( f"The following keys have been found in the settings input node {self.pk}, but were not understood: " + ",".join(settings.keys())) return calcinfo
def prepare_for_submission(self, folder): """Create the input files from the input nodes passed to this instance of the `CalcJob`. :param folder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.datastructures.CalcInfo` instance """ # from aiida_deepmd.utils import DpInput # create json input file # input = DpInput(self.inputs.model.get_dict(), self.inputs.learning_rate.get_dict(), self.inputs.loss.get_dict(), self.inputs.training.get_dict()) input = dict() input['model'] = self.inputs.model.get_dict() input['learning_rate'] = self.inputs.learning_rate.get_dict() input['loss'] = self.inputs.loss.get_dict() input['training'] = self.inputs.training.get_dict() json_str = json.dumps(input, indent=4, sort_keys=False) with io.open(folder.get_abs_path(self._DEFAULT_INPUT_FILE), mode="w", encoding="utf-8") as fobj: try: fobj.write(json_str) except ValueError as exc: raise InputValidationError("invalid keys or values in input parameters found") local_copy_list = [] # Create the subfolder that will contain the train data folder.get_subfolder(self._TRAIN_DATA_SUBFOLDER, create=True) for fn in self.inputs.file: fobj = self.inputs.file[fn] src_path = fobj.filename dst_path = os.path.join(self._TRAIN_DATA_SUBFOLDER, fobj.filename) local_copy_list.append((fobj.uuid, src_path, dst_path)) def create_array_from_files(files): for f in files: content = f.get_content() # function from aiida_ce pass return data_array # create train set and store the data in data_array = create_array_from_files(self.inputs.file) # for simplicity do not split the folder n = 0 set_folder = folder.get_subfolder(os.path.join(self._TRAIN_DATA_SUBFOLDER, self._TRAIN_SET_PRFIX + str(n)), create=True) with io.open(set_folder.get_abs_path(coord.npy), mode="w") as fobj: try: np.dump(fobj, array=data_array) except ValueError as exc: raise InputValidationError("invalid keys or values in input parameters found") # settings = self.inputs.settings.get_dict() if 'settings' in self.inputs else {} # create code info codeinfo = CodeInfo() codeinfo.cmdline_params = ["train", self._DEFAULT_INPUT_FILE] codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE codeinfo.join_files = True codeinfo.code_uuid = self.inputs.code.uuid # create calc info calcinfo = CalcInfo() calcinfo.uuid = self.uuid calcinfo.cmdline_params = codeinfo.cmdline_params calcinfo.stdin_name = self._DEFAULT_INPUT_FILE calcinfo.stdout_name = self._DEFAULT_OUTPUT_FILE calcinfo.local_copy_list = local_copy_list calcinfo.codes_info = [codeinfo] calcinfo.retrieve_list = [ # self._DEFAULT_OUTPUT_FILE, # self._DEFAULT_OUTPUT_INFO_FILE, # self._DEFAULT_CHECK_META_FILE, # self._DEFAULT_CHECK_INDEX_FILE, ] return calcinfo
def prepare_for_submission(self, tempfolder): """ Create the input files from the input nodes passed to this instance of the `CalcJob`. :param tempfolder: an `aiida.common.folders.Folder` to temporarily write files on disk :return: `aiida.common.datastructures.CalcInfo` instance """ ##################################################### # BEGINNING OF INITIAL INPUT CHECK # # All input ports that are defined via spec.input # # are checked by default, only need to asses their # # presence in case they are optional # ##################################################### code = self.inputs.code structure = self.inputs.structure parameters = self.inputs.parameters if 'kpoints' in self.inputs: kpoints = self.inputs.kpoints else: kpoints = None if 'basis' in self.inputs: basis = self.inputs.basis else: basis = None if 'settings' in self.inputs: settings = self.inputs.settings.get_dict() settings_dict = _uppercase_dict(settings, dict_name='settings') else: settings_dict = {} if 'bandskpoints' in self.inputs: bandskpoints = self.inputs.bandskpoints else: bandskpoints = None if 'parent_calc_folder' in self.inputs: parent_calc_folder = self.inputs.parent_calc_folder else: parent_calc_folder = None pseudos = self.inputs.pseudos kinds = [kind.name for kind in structure.kinds] if set(kinds) != set(pseudos.keys()): raise ValueError( 'Mismatch between the defined pseudos and the list of kinds of the structure.\n', 'Pseudos: {} \n'.format(', '.join(list(pseudos.keys()))), 'Kinds: {}'.format(', '.join(list(kinds))), ) # List of the file to copy in the folder where the calculation # runs, for instance pseudo files local_copy_list = [] # List of files for restart remote_copy_list = [] ############################## # END OF INITIAL INPUT CHECK # ############################## # ============== Preprocess of input parameters =============== # There should be a warning for duplicated (canonicalized) keys # in the original dictionary in the script input_params = FDFDict(parameters.get_dict()) # Look for blocked keywords and # add the proper values to the dictionary for blocked_key in self._aiida_blocked_keywords: canonical_blocked = FDFDict.translate_key(blocked_key) for key in input_params: if key == canonical_blocked: raise InputValidationError( "You cannot specify explicitly the '{}' flag in the " "input parameters".format( input_params.get_last_key(key))) input_params.update({'system-name': self._PREFIX}) input_params.update({'system-label': self._PREFIX}) input_params.update({'use-tree-timer': 'T'}) input_params.update({'xml-write': 'T'}) input_params.update({'number-of-species': len(structure.kinds)}) input_params.update({'number-of-atoms': len(structure.sites)}) # Regarding the lattice-constant parameter: # -- The variable "alat" is not typically kept anywhere, and # has already been used to define the vectors. # We need to specify that the units of these vectors are Ang... input_params.update({'lattice-constant': '1.0 Ang'}) # Note that this will break havoc with the band-k-points "pi/a" # option. The use of this option should be banned. # Note that the implicit coordinate convention of the Structure # class corresponds to the "Ang" convention in Siesta. # That is why the "atomic-coordinates-format" keyword is blocked # and reset. input_params.update({'atomic-coordinates-format': 'Ang'}) # ============== Preparation of input data =============== # ---------------- CELL_PARAMETERS ------------------------ cell_parameters_card = "%block lattice-vectors\n" for vector in structure.cell: cell_parameters_card += ("{0:18.10f} {1:18.10f} {2:18.10f}" "\n".format(*vector)) cell_parameters_card += "%endblock lattice-vectors\n" # --------------ATOMIC_SPECIES & PSEUDOS------------------- # I create the subfolder that will contain the pseudopotentials tempfolder.get_subfolder(self._PSEUDO_SUBFOLDER, create=True) # I create the subfolder with the output data tempfolder.get_subfolder(self._OUTPUT_SUBFOLDER, create=True) atomic_species_card_list = [] # Dictionary to get the atomic number of a given element datmn = dict([(v['symbol'], k) for k, v in six.iteritems(elements)]) spind = {} spcount = 0 for kind in structure.kinds: spcount += 1 # species count spind[kind.name] = spcount atomic_species_card_list.append("{0:5} {1:5} {2:5}\n".format( spind[kind.name], datmn[kind.symbol], kind.name.rjust(6))) ps = pseudos[kind.name] # Add this pseudo file to the list of files to copy, with # the appropiate name. In the case of sub-species # (different kind.name but same kind.symbol, e.g., # 'C_surf', sharing the same pseudo with 'C'), we will # copy the file ('C.psf') twice, once as 'C.psf', and once # as 'C_surf.psf'. This is required by Siesta. # ... list of tuples with format ('node_uuid', 'filename', relativedestpath') # We probably should be pre-pending 'self._PSEUDO_SUBFOLDER' in the # last slot, for generality... if isinstance(ps, PsfData): local_copy_list.append((ps.uuid, ps.filename, kind.name + ".psf")) elif isinstance(ps, PsmlData): local_copy_list.append((ps.uuid, ps.filename, kind.name + ".psml")) else: pass atomic_species_card_list = (["%block chemicalspecieslabel\n"] + list(atomic_species_card_list)) atomic_species_card = "".join(atomic_species_card_list) atomic_species_card += "%endblock chemicalspecieslabel\n" # Free memory del atomic_species_card_list # --------------------- ATOMIC_POSITIONS ----------------------- atomic_positions_card_list = [ "%block atomiccoordinatesandatomicspecies\n" ] countatm = 0 for site in structure.sites: countatm += 1 atomic_positions_card_list.append( "{0:18.10f} {1:18.10f} {2:18.10f} {3:4} {4:6} {5:6}\n".format( site.position[0], site.position[1], site.position[2], spind[site.kind_name], site.kind_name.rjust(6), countatm)) atomic_positions_card = "".join(atomic_positions_card_list) del atomic_positions_card_list # Free memory atomic_positions_card += "%endblock atomiccoordinatesandatomicspecies\n" # -------------------- K-POINTS ---------------------------- # It is optional, if not specified, gamma point only is performed, # this is default of siesta if kpoints is not None: # # Get a mesh for sampling # NOTE that there is not yet support for the 'kgrid-cutoff' # option in Siesta. # try: mesh, offset = kpoints.get_kpoints_mesh() has_mesh = True except AttributeError: raise InputValidationError("K-point sampling for scf " "must be given in mesh form") kpoints_card_list = ["%block kgrid_monkhorst_pack\n"] # # This will fail if has_mesh is False (for the case of a list), # since in that case 'offset' is undefined. # kpoints_card_list.append("{0:6} {1:6} {2:6} {3:18.10f}\n".format( mesh[0], 0, 0, offset[0])) kpoints_card_list.append("{0:6} {1:6} {2:6} {3:18.10f}\n".format( 0, mesh[1], 0, offset[1])) kpoints_card_list.append("{0:6} {1:6} {2:6} {3:18.10f}\n".format( 0, 0, mesh[2], offset[2])) kpoints_card = "".join(kpoints_card_list) kpoints_card += "%endblock kgrid_monkhorst_pack\n" del kpoints_card_list # ----------------- K-POINTS-FOR-BANDS ---------------------- #Two possibility are supported in Siesta: BandLines ad BandPoints #At the moment the user can't choose directly one of the two options #BandsLine is set automatically if bandskpoints has labels, #BandsPoints if bandskpoints has no labels #BandLinesScale =pi/a is not supported at the moment because currently #a=1 always. BandLinesScale ReciprocalLatticeVectors is always set if bandskpoints is not None: bandskpoints_card_list = [ "BandLinesScale ReciprocalLatticeVectors\n" ] if bandskpoints.labels == None: bandskpoints_card_list.append("%block BandPoints\n") for s in bandskpoints.get_kpoints(): bandskpoints_card_list.append( "{0:8.3f} {1:8.3f} {2:8.3f} \n".format( s[0], s[1], s[2])) fbkpoints_card = "".join(bandskpoints_card_list) fbkpoints_card += "%endblock BandPoints\n" else: bandskpoints_card_list.append("%block BandLines\n") savs = [] listforbands = bandskpoints.get_kpoints() for s, m in bandskpoints.labels: savs.append(s) rawindex = 0 for s, m in bandskpoints.labels: rawindex = rawindex + 1 x, y, z = listforbands[s] if rawindex == 1: bandskpoints_card_list.append( "{0:3} {1:8.3f} {2:8.3f} {3:8.3f} {4:1} \n".format( 1, x, y, z, m)) else: bandskpoints_card_list.append( "{0:3} {1:8.3f} {2:8.3f} {3:8.3f} {4:1} \n".format( s - savs[rawindex - 2], x, y, z, m)) fbkpoints_card = "".join(bandskpoints_card_list) fbkpoints_card += "%endblock BandLines\n" del bandskpoints_card_list # ================ Operations for restart ======================= # The presence of a 'parent_calc_folder' input node signals # that we want to get something from there, as indicated in the # self._restart_copy_from attribute. # In Siesta's case, for now, it is just the density-matrix file # # It will be copied to the current calculation's working folder. # NOTE: This mechanism is not flexible enough. # Maybe we should pass the information about which file(s) to # copy in the metadata 'options' dictionary if parent_calc_folder is not None: remote_copy_list.append( (parent_calc_folder.computer.uuid, os.path.join(parent_calc_folder.get_remote_path(), self._restart_copy_from), self._restart_copy_to)) input_params.update({'dm-use-save-dm': "T"}) # ====================== FDF file creation ======================== # To have easy access to inputs metadata options metadataoption = self.inputs.metadata.options # input_filename = self.inputs.metadata.options.input_filename input_filename = tempfolder.get_abs_path(metadataoption.input_filename) with open(input_filename, 'w') as infile: # here print keys and values tp file # for k, v in sorted(six.iteritems(input_params)): for k, v in sorted(input_params.get_filtered_items()): infile.write("%s %s\n" % (k, v)) # Basis set info is processed just like the general # parameters section. Some discipline is needed to # put any basis-related parameters (including blocks) # in the basis dictionary in the input script. # if basis is not None: infile.write("#\n# -- Basis Set Info follows\n#\n") for k, v in six.iteritems(basis.get_dict()): infile.write("%s %s\n" % (k, v)) # Write previously generated cards now infile.write("#\n# -- Structural Info follows\n#\n") infile.write(atomic_species_card) infile.write(cell_parameters_card) infile.write(atomic_positions_card) if kpoints is not None: infile.write("#\n# -- K-points Info follows\n#\n") infile.write(kpoints_card) if bandskpoints is not None: infile.write("#\n# -- Bandlines/Bandpoints Info follows\n#\n") infile.write(fbkpoints_card) # Write max wall-clock time infile.write("#\n# -- Max wall-clock time block\n#\n") infile.write("max.walltime {}".format( metadataoption.max_wallclock_seconds)) # ====================== Code and Calc info ======================== # Code information object and Calc information object are now # only used to set up the CMDLINE (the bash line that launches siesta) # and to set up the list of files to retrieve. cmdline_params = settings_dict.pop('CMDLINE', []) codeinfo = CodeInfo() codeinfo.cmdline_params = list(cmdline_params) codeinfo.stdin_name = metadataoption.input_filename codeinfo.stdout_name = metadataoption.output_filename codeinfo.code_uuid = code.uuid calcinfo = CalcInfo() calcinfo.uuid = str(self.uuid) if cmdline_params: calcinfo.cmdline_params = list(cmdline_params) calcinfo.local_copy_list = local_copy_list calcinfo.remote_copy_list = remote_copy_list calcinfo.stdin_name = metadataoption.input_filename calcinfo.stdout_name = metadataoption.output_filename calcinfo.codes_info = [codeinfo] # Retrieve by default: the output file, the xml file, the # messages file, and the json timing file. # If bandskpoints, also the bands file is added to the retrieve list. calcinfo.retrieve_list = [] calcinfo.retrieve_list.append(metadataoption.output_filename) calcinfo.retrieve_list.append(self._DEFAULT_XML_FILE) calcinfo.retrieve_list.append(self._DEFAULT_JSON_FILE) calcinfo.retrieve_list.append(self._DEFAULT_MESSAGES_FILE) if bandskpoints is not None: calcinfo.retrieve_list.append(self._DEFAULT_BANDS_FILE) # Any other files specified in the settings dictionary settings_retrieve_list = settings_dict.pop('ADDITIONAL_RETRIEVE_LIST', []) calcinfo.retrieve_list += settings_retrieve_list return calcinfo