Exemple #1
0
    def prepare_for_submission(self, folder):

        # create code info
        codeinfo = CodeInfo()
        codeinfo.code_uuid = self.inputs.code.uuid
        codeinfo.cmdline_params = [
            self.PARENT_FOLDER_NAME + "/" + self.inputs.chk_name.value, self.DEFAULT_OUTPUT_FILE
        ]
        codeinfo.withmpi = self.inputs.metadata.options.withmpi

        # create calculation info
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.codes_info = [codeinfo]
        calcinfo.retrieve_list = []

        if self.inputs.retrieve_fchk:
            calcinfo.retrieve_list.append(self.DEFAULT_OUTPUT_FILE)

        # symlink or copy to parent calculation
        calcinfo.remote_symlink_list = []
        calcinfo.remote_copy_list = []
        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
Exemple #2
0
    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
Exemple #3
0
    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
        """

        settings = self.inputs.settings.get_dict(
        ) if 'settings' in self.inputs else {}

        param_dict = self.inputs.parameters.get_dict()

        # ---------------------------------------------------
        # Write params.ini file
        params_fn = folder.get_abs_path("params.ini")
        with open(params_fn, 'w') as f:
            for key, val in param_dict.items():
                line = str(key) + " "
                if isinstance(val, list):
                    line += " ".join(str(v) for v in val)
                else:
                    line += str(val)
                f.write(line + '\n')
        # ---------------------------------------------------

        # create code info
        codeinfo = CodeInfo()
        codeinfo.code_uuid = self.inputs.code.uuid
        codeinfo.withmpi = False

        # create calc info
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.codes_info = [codeinfo]

        # file lists
        calcinfo.remote_symlink_list = []
        calcinfo.local_copy_list = [
            (self.inputs.atomtypes.uuid, self.inputs.atomtypes.filename,
             'atomtypes.ini')
        ]
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = ["*/*/*.npy"]

        # 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()
            copy_info = (comp_uuid, remote_path, 'parent_calc_folder/')
            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


# EOF
Exemple #4
0
    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):
        """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
        """

        # create code info
        codeinfo = CodeInfo()
        codeinfo.code_uuid = self.inputs.code.uuid

        param_dict = self.inputs.parameters.get_dict()

        cmdline = []
        for key in param_dict:
            cmdline += [key]
            if param_dict[key] != '':
                if isinstance(param_dict[key], list):
                    cmdline += param_dict[key]
                else:
                    cmdline += [param_dict[key]]

        codeinfo.cmdline_params = cmdline

        # create calc info
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.cmdline_params = codeinfo.cmdline_params
        calcinfo.codes_info = [codeinfo]

        # file lists
        calcinfo.remote_symlink_list = []
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = ["*.npy", "*.npz"]

        # 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()
            copy_info = (comp_uuid, remote_path, 'parent_calc_folder/')
            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)

        if 'ppm_calc_folder' in self.inputs:
            comp_uuid = self.inputs.ppm_calc_folder.computer.uuid
            remote_path = self.inputs.ppm_calc_folder.get_remote_path()
            copy_info = (comp_uuid, remote_path, 'ppm_calc_folder/')
            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
Exemple #6
0
    def prepare_for_submission(self, tempfolder):  # pylint: disable=unused-argument,arguments-differ
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.remote_copy_list = []

        codeinfo = CodeInfo()
        codeinfo.code_uuid = self.inputs.code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo, codeinfo
 def prepare_for_submission(self, folder):
     """
     The baseclass will only setup the basic calcinfo arguments but will
     not write **any** files which has to be implemented in the subclassed
     prepare_for_submission() method
     """
     # if no custodian code is defined directly run the VASP calculation,
     # i.e. initialize the CodeInfo for the passed VASP code
     if not self.inputs.custodian.get('code', False):
         codeinfo = CodeInfo()
         codeinfo.code_uuid = self.inputs.code.uuid
         codeinfo.stdout_name = self._default_output_file
         codeinfo.stderr_name = self._default_error_file
     # otherwise wrap in Custodian calculation and initialize CodeInfo for
     # the passed Custodian code (This is sufficient as AiiDA will scan all
     # Code-inputs to generate the required prepend / append lines)
     else:
         codeinfo = CodeInfo()
         codeinfo.code_uuid = self.inputs.custodian.code.uuid
         # define custodian-exe command line arguments
         codeinfo.cmdline_params = ['run', PluginDefaults.CSTDN_SPEC_FNAME]
         # never add the MPI command to custodian since it will call
         # VASP using MPI itself
         codeinfo.withmpi = False
     calcinfo = CalcInfo()
     calcinfo.uuid = self.uuid
     calcinfo.codes_info = [codeinfo]
     # those list are set defined in the inherited classes
     calcinfo.local_copy_list = []
     calcinfo.remote_copy_list = []
     calcinfo.remote_symlink_list = []
     # retrieve lists are defined on the base class
     calcinfo.retrieve_temporary_list = self.retrieve_temporary_list()
     calcinfo.retrieve_list = self.retrieve_permanent_list()
     # need to set run mode since presubmit() takes all code inputs into
     # account and would complain if both vasp and custodian codes are set
     calcinfo.codes_run_mode = CodeRunMode.SERIAL
     # finally write the neccessary calculation inputs to the calculation's
     # input folder
     calcinfo = self.create_calculation_inputs(folder, calcinfo)
     return calcinfo
    def prepare_for_submission(self, folder):
        
         # create calculation info
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.codes_info = []
        calcinfo.retrieve_list = []

        for key, params in self.inputs.parameters.get_dict().items():
            
            cube_name = key+".cube"
            kind_str = params["kind"]
            npts = params["npts"]

            # create code info 
            codeinfo = CodeInfo()

            codeinfo.cmdline_params = []
            codeinfo.cmdline_params.append(str(self.inputs.metadata.options.resources['tot_num_mpiprocs']))
            codeinfo.cmdline_params.append(kind_str)
            codeinfo.cmdline_params.append(self._PARENT_FOLDER_NAME + "/" + self._DEFAULT_INPUT_FILE)
            codeinfo.cmdline_params.append(cube_name)
            codeinfo.cmdline_params.append(str(npts))

            codeinfo.code_uuid = self.inputs.code.uuid
            codeinfo.withmpi = self.inputs.metadata.options.withmpi

            calcinfo.codes_info.append(codeinfo)

            if self.inputs.retrieve_cubes.value:
                calcinfo.retrieve_list.append(cube_name)

        extra_prepend = "\nexport GAUSS_MEMDEF=%dMB\n" % self.inputs.gauss_memdef
        if not hasattr(calcinfo, 'prepend_text') or not calcinfo.prepend_text:
            calcinfo.prepend_text = extra_prepend
        else:
            calcinfo.prepend_text += extra_prepend

         # symlink or copy to parent calculation
        calcinfo.remote_symlink_list = []
        calcinfo.remote_copy_list = []
        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
Exemple #9
0
    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
        """

        self.logger.info("prepare_for_submission")

        # These three lists are updated in self._create_additional_files(folder)
        self._internal_retrieve_list = []
        self._additional_cmd_params = []
        self._calculation_cmd = []
        self._create_additional_files(folder)

        # ================= prepare the python input files =================

        # BORN
        if (not self.inputs.fc_only and 'nac_params' in self.inputs
                and 'primitive' in self.inputs
                and 'symmetry_tolerance' in self.inputs.settings.attributes):
            born_txt = get_BORN_txt(self.inputs.nac_params,
                                    self.inputs.primitive,
                                    self.inputs.settings['symmetry_tolerance'])
            with folder.open(self._INPUT_NAC, 'w', encoding='utf8') as handle:
                handle.write(born_txt)
            for params in self._additional_cmd_params:
                params.append('--nac')

        # ============================ calcinfo ===============================

        local_copy_list = []
        remote_copy_list = []

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.local_copy_list = local_copy_list
        calcinfo.remote_copy_list = remote_copy_list
        calcinfo.retrieve_list = self._internal_retrieve_list

        calcinfo.codes_info = []
        for i, (default_params, additional_params) in enumerate(
                zip(self._calculation_cmd, self._additional_cmd_params)):
            codeinfo = CodeInfo()
            codeinfo.cmdline_params = default_params + additional_params
            codeinfo.code_uuid = self.inputs.code.uuid
            codeinfo.stdout_name = "%s%d" % (self.options.output_filename,
                                             i + 1)
            codeinfo.withmpi = False
            calcinfo.codes_info.append(codeinfo)

        return calcinfo
Exemple #10
0
    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.
        """
        parameters = self.inputs.parameters.get_dict()

        # get settings
        settings = self.inputs.settings.get_dict() if 'setting' in self.inputs else {}

        # if 'setting' in self.inputs:
        #     settings = self.inputs.settings.get_dict()
        # else:
        #     settings = {}

        # Writing the input
        inp = PorousMaterialsInput(parameters)

        with open(folder.get_abs_path(self.INPUT_FILE), 'w') as fobj:
            fobj.write(inp.render())

        # create code information
        codeinfo = CodeInfo()
        codeinfo.cmdline_params = settings.pop('cmdline', []) + [self.INPUT_FILE]
        codeinfo.code_uuid = self.inputs.code.uuid

        # Create calc information
        calcinfo = CalcInfo()
        calcinfo.stdin_name = self.INPUT_FILE
        calcinfo.uuid = self.uuid
        calcinfo.cmdline_params = codeinfo.cmdline_params
        calcinfo.codes_info = [codeinfo]

        # file list
        calcinfo.local_copy_list = []

        if 'structure' in self.inputs:
            for name, fobj in self.inputs.structure.items():
                calcinfo.local_copy_list.append((fobj.uuid, fobj.filename, name + '.cif'))

        if 'acc_voronoi_nodes' in self.inputs:
            for name, fobj in self.inputs.acc_voronoi_nodes.items():
                calcinfo.local_copy_list.append((fobj.uuid, fobj.filename, name + '.voro_accessible'))

        calcinfo.retrieve_list = [self.OUTPUT_FOLDER]

        return calcinfo
Exemple #11
0
    def prepare_for_submission(self, folder):

        # create code info
        codeinfo = CodeInfo()
        codeinfo.code_uuid = self.inputs.code.uuid
        codeinfo.cmdline_params = [self._INPUT_FILE]

        # create calculation info
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.codes_info = [codeinfo]
        calcinfo.retrieve_list = [self._OUTPUT_FILE]

        return calcinfo
Exemple #12
0
    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: an `aiida.common.folders.Folder` to temporarily write files on disk
        :return: `aiida.common.datastructures.CalcInfo` instance
        """
        code = self.inputs.code  # an aiida Code
        parameters = self.inputs.parameters  # an aiida Dict

        input_dict = parameters.get_dict()  # a python dict
        if 'x1' not in input_dict or 'x2' not in input_dict:
            raise InputValidationError(
                'The input parameters node should contain both keys "x1" and "x2", '
                'but it doesn\'t.')

        ##############################
        # END OF INITIAL INPUT CHECK #
        ##############################

        input_filename = self.inputs.metadata.options.input_filename
        output_filename = self.inputs.metadata.options.output_filename

        # write all the input to a file
        with folder.open(input_filename, 'w') as infile:
            json.dump(input_dict, infile)

        # ============================ calcinfo ================================

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = [output_filename]
        calcinfo.retrieve_temporary_list = [[
            'path/hugefiles*[0-9].xml', '.', '1'
        ]]

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = [input_filename, output_filename]
        codeinfo.code_uuid = code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
Exemple #13
0
    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
        """

        # symlinks
        calcinfo.remote_symlink_list = []
        calcinfo.remote_copy_list = []

        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)


        # create code info
        codeinfo = CodeInfo()
        codeinfo.cmdline_params = ["freeze", '-o', self._DEFAULT_OUTPUT_FILE]
        codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE
        codeinfo.code_uuid = self.inputs.code.uuid

        calcinfo.uuid = self.uuid
        calcinfo.cmdline_params = codeinfo.cmdline_params
        calcinfo.codes_info = [codeinfo]
        calcinfo.remote_copy_list = remote_copy_list
        calcinfo.remote_symlink_list = remote_symlink_list

        calcinfo.retrieve_list = [
            self._DEFAULT_OUTPUT_FILE,
        ]

        # 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
Exemple #14
0
    def prepare_for_submission(self, tempfolder):  # pylint: disable=arguments-differ
        ev1_filename = 'eigenvals1.hdf5'
        ev2_filename = 'eigenvals2.hdf5'
        eigenval_file_1 = tempfolder.get_abs_path(ev1_filename)
        write_bands(self.inputs.bands1, eigenval_file_1)
        eigenval_file_2 = tempfolder.get_abs_path(ev2_filename)
        write_bands(self.inputs.bands2, eigenval_file_2)

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = [self._OUTPUT_FILE_NAME]

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = ['plot-bands', ev1_filename, ev2_filename]
        codeinfo.code_uuid = self.inputs.code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
    def prepare_for_submission(self, folder):
        """
        Create input files.

            :param folder: aiida.common.folders.Folder subclass where
                the plugin should put all its files.
        """
        # create input files: d3
        structure = self.inputs.get('structure', None)
        try:
            d3_content = D3(self.inputs.parameters.get_dict(), structure)
        except (ValueError, NotImplementedError) as err:
            raise InputValidationError(
                "an input file could not be created from the parameters: {}".
                format(err))
        with folder.open(self._INPUT_FILE_NAME, "w") as f:
            d3_content.write(f)

        # create input files: fort.9
        with self.inputs.wavefunction.open(mode="rb") as f:
            folder.create_file_from_filelike(f,
                                             self._WAVEFUNCTION_FILE_NAME,
                                             mode="wb")

        # Prepare CodeInfo object for aiida
        codeinfo = CodeInfo()
        codeinfo.code_uuid = self.inputs.code.uuid
        codeinfo.stdin_name = self._INPUT_FILE_NAME
        codeinfo.stdout_name = self._OUTPUT_FILE_NAME
        codeinfo.withmpi = False

        # Prepare CalcInfo object for aiida
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.codes_info = [codeinfo]
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = [self._PROPERTIES_FILE_NAME]
        calcinfo.local_copy_list = []

        return calcinfo
Exemple #16
0
    def prepare_for_submission(self, tempfolder):  # pylint: disable=arguments-differ
        """
        Writes the four minimum output files, INCAR, POSCAR, POTCAR, KPOINTS.

        Delegates the construction and writing / copying to write_<file> methods.
        That way, subclasses can use any form of input nodes and just
        have to implement the write_xxx method accordingly.
        Subclasses can extend by calling the super method and if neccessary
        modifying it's output CalcInfo before returning it.
        """
        # write input files
        incar = tempfolder.get_abs_path('INCAR')
        structure = tempfolder.get_abs_path('POSCAR')
        potentials = tempfolder.get_abs_path('POTCAR')
        kpoints = tempfolder.get_abs_path('KPOINTS')

        remote_copy_list = []

        self.verify_inputs()
        if self._is_restart():
            remote_copy_list.extend(self.remote_copy_restart_folder())
        self.write_incar(incar)
        self.write_poscar(structure)
        self.write_potcar(potentials)
        self.write_kpoints(kpoints)

        # calcinfo
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.retrieve_list = self.max_retrieve_list()
        codeinfo = CodeInfo()
        codeinfo.code_uuid = self.inputs.code.uuid
        codeinfo.code_pk = self.inputs.code.pk
        calcinfo.codes_info = [codeinfo]
        calcinfo.remote_copy_list = remote_copy_list
        # here we need to do the charge density and wave function copy
        # as we need access to the calcinfo
        calcinfo.local_copy_list = []
        self.write_additional(tempfolder, calcinfo)

        return calcinfo
Exemple #17
0
    def _prepare_for_submission(self, tempfolder, input_nodes_raw):
        """
        This method is called prior to job submission with a set of calculation input nodes.
        The inputs will be validated and sanitized, after which the necessary input files will
        be written to disk in a temporary folder. A CalcInfo instance will be returned that contains
        lists of files that need to be copied to the remote machine before job submission, as well
        as file lists that are to be retrieved after job completion.

        :param tempfolder: an aiida.common.folders.Folder to temporarily write files on disk
        :param input_nodes_raw: a dictionary with the raw input nodes
        :returns: CalcInfo instance
        """
        input_nodes = self.validate_input_nodes(input_nodes_raw)
        input_parent_folder = self.validate_input_parent_folder(input_nodes)
        input_parameters = self.validate_input_parameters(input_nodes)
        input_settings = input_nodes[self.get_linkname('settings')].get_dict()
        input_code = input_nodes[self.get_linkname('code')]

        self.write_input_files(tempfolder, input_parameters)

        retrieve_list = self.get_retrieve_list(input_nodes)
        local_copy_list = self.get_local_copy_list(input_nodes)
        remote_copy_list = self.get_remote_copy_list(input_nodes)

        # Empty command line by default
        cmdline_params = input_settings.pop('CMDLINE', [])

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = (list(cmdline_params) +
                                   ['-in', self.input_file_name])
        codeinfo.stdout_name = self.output_file_name
        codeinfo.code_uuid = input_code.uuid

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.codes_info = [codeinfo]
        calcinfo.retrieve_list = retrieve_list
        calcinfo.local_copy_list = local_copy_list
        calcinfo.remote_copy_list = remote_copy_list

        return calcinfo
Exemple #18
0
    def prepare_for_submission(self, folder):
        """
        Create input files.

        :param folder: an `aiida.common.folders.Folder` to temporarily write files on disk
        :return: `aiida.common.datastructures.CalcInfo` instance

        """

        # Prepare CalcInfo to be returned to aiida
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid

        # network infers file format from file extension
        structure = self.inputs.structure
        structure_filename = self.inputs.parameters.get_structure_file_name(
            structure)
        calcinfo.local_copy_list = [(structure.uuid, structure.filename,
                                     structure_filename)]

        if 'atomic_radii' in self.inputs:
            atomic_radii = self.inputs.atomic_radii
            radii_file_name = atomic_radii.filename
            calcinfo.local_copy_list.append(
                (atomic_radii.uuid, atomic_radii.filename,
                 atomic_radii.filename))
        else:
            radii_file_name = None

        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = self.inputs.parameters.output_files

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = self.inputs.parameters.cmdline_params(
            structure_file_name=structure_filename,
            radii_file_name=radii_file_name)
        codeinfo.code_uuid = self.inputs.code.uuid
        codeinfo.withmpi = False
        calcinfo.codes_info = [codeinfo]

        return calcinfo
Exemple #19
0
    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
        """

        # Write input to file
        input_filename = folder.get_abs_path(self._DEFAULT_INPUT_FILE)
        with open(input_filename, 'w') as infile:
            infile.write(input_render(self.inputs.parameters.get_dict()))

        # Prepare CalcInfo to be returned to aiida
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.remote_symlink_list = []
        calcinfo.retrieve_list = [
            self._DEFAULT_OUTPUT_FILE,
            [self._DEFAULT_ADDITIONAL_RETRIEVE_LIST, '.', 0],
        ]

        # Charge-density remotefolder (now working only for CP2K)
        if 'charge_density_folder' in self.inputs:
            charge_density_folder = self.inputs.charge_density_folder
            comp_uuid = charge_density_folder.computer.uuid
            remote_path = os.path.join(
                charge_density_folder.get_remote_path(),
                'aiida-ELECTRON_DENSITY-1_0.cube',
            )
            symlink = (comp_uuid, remote_path, 'valence_density.cube')
            calcinfo.remote_symlink_list.append(symlink)

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = []
        codeinfo.code_uuid = self.inputs.code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
    def prepare_for_submission(self, folder):
        """
        Get ready.
        """

        # We wont write anything to the `folder` since the program takes
        # input as commandline parameters

        code_info = CodeInfo()
        code_info.cmdline_params = [str(self.inputs.x.value), str(self.inputs.y.value)]
        code_info.stdout_name = self.options.output_filename
        code_info.code_uuid = self.inputs.code.uuid

        calc_info = CalcInfo()
        calc_info.uuid = str(self.node.uuid)  # ?
        calc_info.codes_info = [code_info]
        calc_info.retrieve_list = [self.options.output_filename]
        calc_info.local_copy_list = []  # Anything that we have localy and could use
        calc_info.remote_copy_list = []  # Anything that we have remotely and could use

        return calc_info
Exemple #21
0
    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.CalcInfo` instance
        """
        # assert that the potential and structure have the same kind elements
        if self.inputs.potential.allowed_element_names is not None and not set(
            k.symbol for k in self.inputs.structure.kinds
        ).issubset(self.inputs.potential.allowed_element_names):
            raise ValidationError(
                "the structure and potential are not compatible (different kind elements)"
            )

        # Setup structure
        structure_txt, struct_transform = generate_lammps_structure(
            self.inputs.structure, self.inputs.potential.atom_style
        )

        with open(
            tempfolder.get_abs_path(self.options.cell_transform_filename), "w+b"
        ) as handle:
            np.save(handle, struct_transform)

        if "parameters" in self.inputs:
            parameters = self.inputs.parameters
        else:
            parameters = Dict()

        # Setup input parameters
        input_txt = self.create_main_input_content(
            parameter_data=parameters,
            potential_data=self.inputs.potential,
            kind_symbols=[kind.symbol for kind in self.inputs.structure.kinds],
            structure_filename=self._INPUT_STRUCTURE,
            trajectory_filename=self.options.trajectory_suffix,
            system_filename=self.options.system_suffix,
            restart_filename=self.options.restart_filename,
        )

        input_filename = tempfolder.get_abs_path(self._INPUT_FILE_NAME)

        with open(input_filename, "w") as infile:
            infile.write(input_txt)

        self.validate_parameters(parameters, self.inputs.potential)
        retrieve_list, retrieve_temporary_list = self.get_retrieve_lists()
        retrieve_list.extend(
            [self.options.output_filename, self.options.cell_transform_filename]
        )

        # prepare extra files if needed
        self.prepare_extra_files(tempfolder, self.inputs.potential)

        # =========================== dump to file =============================

        structure_filename = tempfolder.get_abs_path(self._INPUT_STRUCTURE)
        with open(structure_filename, "w") as infile:
            infile.write(structure_txt)

        for name, content in self.inputs.potential.get_external_files().items():
            fpath = tempfolder.get_abs_path(name)
            with open(fpath, "w") as infile:
                infile.write(content)

        # ============================ calcinfo ================================

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = list(self._cmdline_params)
        codeinfo.code_uuid = self.inputs.code.uuid
        codeinfo.withmpi = self.metadata.options.withmpi
        codeinfo.stdout_name = self._stdout_name

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.retrieve_list = retrieve_list
        calcinfo.retrieve_temporary_list = retrieve_temporary_list
        calcinfo.codes_info = [codeinfo]

        return calcinfo
Exemple #22
0
    def prepare_for_submission(self, folder):
        """Prepare the calculation job for submission by transforming input nodes into input files.

        In addition to the input files being written to the sandbox folder, a `CalcInfo` instance will be returned that
        contains lists of files that need to be copied to the remote machine before job submission, as well as file
        lists that are to be retrieved after job completion.

        :param folder: a sandbox folder to temporarily write files on disk.
        :return: :py:`~aiida.common.datastructures.CalcInfo` instance.
        """
        # pylint: disable=too-many-branches,too-many-statements
        import numpy as np

        local_copy_list = []
        remote_copy_list = []
        remote_symlink_list = []

        # Convert settings dictionary to have uppercase keys, or create an empty one if none was given.
        if 'settings' in self.inputs:
            settings_dict = _uppercase_dict(self.inputs.settings.get_dict(), dict_name='settings')
        else:
            settings_dict = {}

        first_structure = self.inputs.first_structure
        last_structure = self.inputs.last_structure

        # Check that the first and last image have the same cell
        if abs(np.array(first_structure.cell) - np.array(last_structure.cell)).max() > 1.e-4:
            raise InputValidationError('Different cell in the fist and last image')

        # Check that the first and last image have the same number of sites
        if len(first_structure.sites) != len(last_structure.sites):
            raise InputValidationError('Different number of sites in the fist and last image')

        # Check that sites in the initial and final structure have the same kinds
        if first_structure.get_site_kindnames() != last_structure.get_site_kindnames():
            raise InputValidationError(
                'Mismatch between the kind names and/or order between '
                'the first and final image'
            )

        # Check that a pseudo potential was specified for each kind present in the `StructureData`
        # self.inputs.pw.pseudos is a plumpy.utils.AttributesFrozendict
        kindnames = [kind.name for kind in first_structure.kinds]
        if set(kindnames) != set(self.inputs.pw.pseudos.keys()):
            raise InputValidationError(
                'Mismatch between the defined pseudos and the list of kinds of the structure.\nPseudos: {};\n'
                'Kinds: {}'.format(', '.join(list(self.inputs.pw.pseudos.keys())), ', '.join(list(kindnames)))
            )

        ##############################
        # END OF INITIAL INPUT CHECK #
        ##############################

        # Create the subfolder that will contain the pseudopotentials
        folder.get_subfolder(self._PSEUDO_SUBFOLDER, create=True)
        # Create the subfolder for the output data (sometimes Quantum ESPRESSO codes crash if the folder does not exist)
        folder.get_subfolder(self._OUTPUT_SUBFOLDER, create=True)

        # We first prepare the NEB-specific input file.
        neb_input_filecontent = self._generate_input_files(self.inputs.parameters, settings_dict)
        with folder.open(self.inputs.metadata.options.input_filename, 'w') as handle:
            handle.write(neb_input_filecontent)

        # We now generate the PW input files for each input structure
        local_copy_pseudo_list = []
        for i, structure in enumerate([first_structure, last_structure]):
            # We need to a pass a copy of the settings_dict for each structure
            this_settings_dict = copy.deepcopy(settings_dict)
            pw_input_filecontent, this_local_copy_pseudo_list = PwCalculation._generate_PWCPinputdata(  # pylint: disable=protected-access
                self.inputs.pw.parameters, this_settings_dict, self.inputs.pw.pseudos, structure, self.inputs.pw.kpoints
            )
            local_copy_pseudo_list += this_local_copy_pseudo_list
            with folder.open(f'pw_{i + 1}.in', 'w') as handle:
                handle.write(pw_input_filecontent)

        # We need to pop the settings that were used in the PW calculations
        for key in list(settings_dict.keys()):
            if key not in list(this_settings_dict.keys()):
                settings_dict.pop(key)

        # We avoid to copy twice the same pseudopotential to the same filename
        local_copy_pseudo_list = set(local_copy_pseudo_list)
        # We check that two different pseudopotentials are not copied
        # with the same name (otherwise the first is overwritten)
        if len({filename for (uuid, filename, local_path) in local_copy_pseudo_list}) < len(local_copy_pseudo_list):
            raise InputValidationError('Same filename for two different pseudopotentials')

        local_copy_list += local_copy_pseudo_list

        # If present, add also the Van der Waals table to the pseudo dir. Note that the name of the table is not checked
        # but should be the one expected by Quantum ESPRESSO.
        vdw_table = self.inputs.get('pw.vdw_table', None)
        if vdw_table:
            local_copy_list.append(
                (vdw_table.uuid, vdw_table.filename, os.path.join(self._PSEUDO_SUBFOLDER, vdw_table.filename))
            )

        # operations for restart
        parent_calc_folder = self.inputs.get('parent_folder', None)
        symlink = settings_dict.pop('PARENT_FOLDER_SYMLINK', self._default_symlink_usage)  # a boolean
        if symlink:
            if parent_calc_folder is not None:
                # I put the symlink to the old parent ./out folder
                remote_symlink_list.append((
                    parent_calc_folder.computer.uuid,
                    os.path.join(parent_calc_folder.get_remote_path(), self._OUTPUT_SUBFOLDER,
                                 '*'),  # asterisk: make individual symlinks for each file
                    self._OUTPUT_SUBFOLDER
                ))
                # and to the old parent prefix.path
                remote_symlink_list.append((
                    parent_calc_folder.computer.uuid,
                    os.path.join(parent_calc_folder.get_remote_path(), f'{self._PREFIX}.path'), f'{self._PREFIX}.path'
                ))
        else:
            # copy remote output dir and .path file, if specified
            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._OUTPUT_SUBFOLDER,
                                 '*'), self._OUTPUT_SUBFOLDER
                ))
                # and copy the old parent prefix.path
                remote_copy_list.append((
                    parent_calc_folder.computer.uuid,
                    os.path.join(parent_calc_folder.get_remote_path(), f'{self._PREFIX}.path'), f'{self._PREFIX}.path'
                ))

        # here we may create an aiida.EXIT file
        create_exit_file = settings_dict.pop('ONLY_INITIALIZATION', False)
        if create_exit_file:
            exit_filename = f'{self._PREFIX}.EXIT'
            with folder.open(exit_filename, 'w') as handle:
                handle.write('\n')

        calcinfo = CalcInfo()
        codeinfo = CodeInfo()

        calcinfo.uuid = self.uuid
        cmdline_params = settings_dict.pop('CMDLINE', [])
        calcinfo.local_copy_list = local_copy_list
        calcinfo.remote_copy_list = remote_copy_list
        calcinfo.remote_symlink_list = remote_symlink_list
        # In neb calculations there is no input read from standard input!!
        codeinfo.cmdline_params = (['-input_images', '2'] + list(cmdline_params))
        codeinfo.stdout_name = self.inputs.metadata.options.output_filename
        codeinfo.code_uuid = self.inputs.code.uuid
        calcinfo.codes_info = [codeinfo]

        # Retrieve the output files and the xml files
        calcinfo.retrieve_list = []
        calcinfo.retrieve_list.append(self.inputs.metadata.options.output_filename)
        calcinfo.retrieve_list.append((
            os.path.join(self._OUTPUT_SUBFOLDER, self._PREFIX + '_*[0-9]', 'PW.out'),  # source relative path (globbing)
            '.',  # destination relative path
            2  # depth to preserve
        ))

        for xml_filepath in self.xml_filepaths:  # pylint: disable=not-an-iterable
            calcinfo.retrieve_list.append([xml_filepath, '.', 3])

        calcinfo.retrieve_list += settings_dict.pop('ADDITIONAL_RETRIEVE_LIST', [])
        calcinfo.retrieve_list += self._internal_retrieve_list

        # We might still have parser options in the settings dictionary: pop them.
        _pop_parser_options(self, settings_dict)

        if settings_dict:
            unknown_keys = ', '.join(list(settings_dict.keys()))
            raise InputValidationError(f'`settings` contained unexpected keys: {unknown_keys}')

        return calcinfo
Exemple #23
0
    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.
        """

        # initialize input parameters
        inp = RaspaInput(self.inputs.parameters.get_dict())

        # keep order of systems in the extras
        self.node.set_extra('system_order', inp.system_order)

        # handle framework(s) and/or box(es)
        if "System" in inp.params:
            self._handle_system_section(inp.params["System"], folder)

        # handle restart
        if 'retrieved_parent_folder' in self.inputs:
            self._handle_retrieved_parent_folder(inp, folder)
            inp.params['GeneralSettings']['RestartFile'] = True

        # handle binary restart
        remote_copy_list = []
        if 'parent_folder' in self.inputs:
            self._handle_parent_folder(remote_copy_list)
            inp.params['GeneralSettings']['ContinueAfterCrash'] = True

        # get settings
        if 'settings' in self.inputs:
            settings = self.inputs.settings.get_dict()
        else:
            settings = {}

        # write raspa input file
        with open(folder.get_abs_path(self.INPUT_FILE), "w") as fobj:
            fobj.write(inp.render())

        # create code info
        codeinfo = CodeInfo()
        codeinfo.cmdline_params = settings.pop('cmdline',
                                               []) + [self.INPUT_FILE]
        codeinfo.code_uuid = self.inputs.code.uuid

        # create calc info
        calcinfo = CalcInfo()
        calcinfo.stdin_name = self.INPUT_FILE
        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]

        # file lists
        calcinfo.remote_symlink_list = []
        calcinfo.local_copy_list = []
        if 'file' in self.inputs:
            for fobj in self.inputs.file.values():
                calcinfo.local_copy_list.append(
                    (fobj.uuid, fobj.filename, fobj.filename))

        # block pockets
        if 'block_pocket' in self.inputs:
            for name, fobj in self.inputs.block_pocket.items():
                calcinfo.local_copy_list.append(
                    (fobj.uuid, fobj.filename, name + '.block'))

        # continue the previous calculation starting from the binary restart
        calcinfo.remote_copy_list = remote_copy_list

        calcinfo.retrieve_list = [self.OUTPUT_FOLDER, self.RESTART_FOLDER]
        calcinfo.retrieve_list += settings.pop('additional_retrieve_list', [])

        # 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(list(settings.keys())))

        return calcinfo
Exemple #24
0
    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
        """

        self.logger.info("prepare_for_submission")

        self._internal_retrieve_list = []
        self._additional_cmd_params = []
        self._calculation_cmd = []

        settings = self.inputs.settings
        structure = self.inputs.structure
        code = self.inputs.code

        ##############################
        # END OF INITIAL INPUT CHECK #
        ##############################

        # ================= prepare the python input files =================

        self._create_additional_files(folder)

        cell_txt = get_poscar_txt(structure)
        input_txt = get_phonopy_conf_file_txt(settings)

        input_filename = folder.get_abs_path(
            self.inputs.metadata.options.input_filename)
        with open(input_filename, 'w') as infile:
            infile.write(input_txt)

        cell_filename = folder.get_abs_path(self._INPUT_CELL)
        with open(cell_filename, 'w') as infile:
            infile.write(cell_txt)

        if ('nac_params' in self.inputs and 'primitive' in self.inputs):
            born_txt = get_BORN_txt(self.inputs.nac_params,
                                    self.inputs.primitive,
                                    settings['symmetry_tolerance'])

            nac_filename = folder.get_abs_path(self._INPUT_NAC)
            with open(nac_filename, 'w') as infile:
                infile.write(born_txt)
            for params in self._additional_cmd_params:
                params.append('--nac')

        # ============================ calcinfo ===============================

        local_copy_list = []
        remote_copy_list = []

        calcinfo = CalcInfo()

        calcinfo.uuid = self.uuid

        # Empty command line by default
        calcinfo.local_copy_list = local_copy_list
        calcinfo.remote_copy_list = remote_copy_list

        # Retrieve files
        calcinfo.retrieve_list = self._internal_retrieve_list

        calcinfo.codes_info = []
        for default_params, additional_params in zip(
                self._calculation_cmd, self._additional_cmd_params):
            codeinfo = CodeInfo()
            codeinfo.cmdline_params = ([
                self.inputs.metadata.options.input_filename,
            ] + default_params + additional_params)
            codeinfo.code_uuid = code.uuid
            codeinfo.stdout_name = self.inputs.metadata.options.output_filename
            codeinfo.withmpi = False
            calcinfo.codes_info.append(codeinfo)

        return calcinfo
Exemple #25
0
    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
Exemple #26
0
    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
Exemple #27
0
    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
Exemple #28
0
    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
Exemple #29
0
    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
        """

        # Determine atomic densities directory
        pm_dict = self.inputs.parameters.get_dict()

        if DENSITY_DIR_KEY not in pm_dict:
            pm_dict[DENSITY_DIR_KEY] = self.inputs.code.extras.get(
                DENSITY_DIR_EXTRA)

        if not pm_dict[DENSITY_DIR_KEY]:
            raise ValueError(
                f"Please provide '{DENSITY_DIR_KEY}' in the input parameters or set the "
                f"{DENSITY_DIR_EXTRA} extra on the ddec code.")

        # The directory must end with a slash or chargemol crashes
        if not pm_dict[DENSITY_DIR_KEY].endswith('/'):
            pm_dict[DENSITY_DIR_KEY] += '/'

        if not os.path.isabs(pm_dict[DENSITY_DIR_KEY]):
            raise ValueError(
                f"Path to atomic densities directory '{pm_dict[DENSITY_DIR_KEY]}' is not absolute."
            )

        # Create symlink to atomic densities directory
        density_dir_symlink = (self.inputs.code.computer.uuid,
                               pm_dict[DENSITY_DIR_KEY], DENSITY_DIR_SYMLINK)
        pm_dict[DENSITY_DIR_KEY] = DENSITY_DIR_SYMLINK

        # Write input to file
        input_filename = folder.get_abs_path(self._DEFAULT_INPUT_FILE)
        with open(input_filename, 'w') as infile:
            infile.write(input_render(pm_dict))

        # Prepare CalcInfo to be returned to aiida
        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.remote_symlink_list = [density_dir_symlink]
        calcinfo.retrieve_list = [
            self._DEFAULT_OUTPUT_FILE,
            [self._DEFAULT_ADDITIONAL_RETRIEVE_LIST, '.', 0],
        ]

        # Charge-density remote folder (now working only for CP2K)
        if 'charge_density_folder' in self.inputs:
            charge_density_folder = self.inputs.charge_density_folder
            comp_uuid = charge_density_folder.computer.uuid
            remote_path = os.path.join(
                charge_density_folder.get_remote_path(),
                'aiida-ELECTRON_DENSITY-1_0.cube',
            )
            copy_info = (comp_uuid, remote_path, 'valence_density.cube')
            if self.inputs.code.computer.uuid == comp_uuid:  # if running on the same computer - make a symlink
                calcinfo.remote_symlink_list.append(copy_info)
            else:  # if not - copy the folder
                self.report(
                    f"Warning: Transferring cube file {charge_density_folder.get_remote_path()} from "
                    +
                    f"computer {charge_density_folder.computer.label} to computer {self.inputs.code.computer.label}. "
                    + "This may put strain on your network.")
                calcinfo.remote_copy_list.append(copy_info)

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = []
        codeinfo.code_uuid = self.inputs.code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
Exemple #30
0
    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