Ejemplo n.º 1
0
    def _prepare_for_submission(self, tempfolder, inputdict):
        from aiida.orm.calculation.job.codtools import commandline_params_from_dict
        import shutil

        try:
            cif = inputdict.pop(self.get_linkname('cif'))
        except KeyError:
            raise InputValidationError(
                "no CIF file is specified for this calculation")
        if not isinstance(cif, CifData):
            raise InputValidationError("cif is not of type CifData")

        parameters = inputdict.pop(self.get_linkname('parameters'), None)
        if parameters is None:
            parameters = ParameterData(dict={})
        if not isinstance(parameters, ParameterData):
            raise InputValidationError(
                "parameters is not of type ParameterData")

        code = inputdict.pop(self.get_linkname('code'), None)
        if code is None:
            raise InputValidationError("Code not found in input")

        self._validate_resources(**self.get_resources())

        input_filename = tempfolder.get_abs_path(self._DEFAULT_INPUT_FILE)
        shutil.copy(cif.get_file_abs_path(), input_filename)

        commandline_params = self._default_commandline_params
        commandline_params.extend(
            commandline_params_from_dict(parameters.get_dict()))

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        # The command line parameters should be generated from 'parameters'
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = [
            self._DEFAULT_OUTPUT_FILE, self._DEFAULT_ERROR_FILE
        ]
        calcinfo.retrieve_singlefile_list = []

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = commandline_params
        codeinfo.stdin_name = self._DEFAULT_INPUT_FILE
        codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE
        codeinfo.stderr_name = self._DEFAULT_ERROR_FILE
        codeinfo.code_uuid = code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
Ejemplo n.º 2
0
    def _prepare_for_submission(self, tempfolder, inputdict):
        import numpy as np

        try:
            struct = inputdict.pop(self.get_linkname('structure'))
        except KeyError:
            raise InputValidationError(
                "no structure is specified for this calculation")
        if not isinstance(struct, StructureData):
            raise InputValidationError("struct is not of type StructureData")

        try:
            code = inputdict.pop(self.get_linkname('code'))
        except KeyError:
            raise InputValidationError(
                "no code is specified for this calculation")

        atoms = struct.get_ase()

        lat_lengths = [
            (atoms.cell[0]**2).sum()**0.5,
            (atoms.cell[1]**2).sum()**0.5,
            (atoms.cell[2]**2).sum()**0.5,
        ]

        lat_angles = np.arccos([
            np.vdot(atoms.cell[1], atoms.cell[2]) / lat_lengths[1] /
            lat_lengths[2],
            np.vdot(atoms.cell[0], atoms.cell[2]) / lat_lengths[0] /
            lat_lengths[2],
            np.vdot(atoms.cell[0], atoms.cell[1]) / lat_lengths[0] /
            lat_lengths[1],
        ]) / np.pi * 180

        parameters = inputdict.pop(self.get_linkname('parameters'), None)
        if parameters is None:
            parameters = ParameterData(dict={})
        if not isinstance(parameters, ParameterData):
            raise InputValidationError(
                "parameters is not of type ParameterData")
        par = parameters.get_dict()

        abbreviation = par.pop('abbreviation', 'aiida_calc')
        title = par.pop('title', 'AiiDA NWChem calculation')
        basis = par.pop('basis', None)
        task = par.pop('task', 'scf')
        add_cell = par.pop('add_cell', True)

        if basis is None:
            basis = dict()
            for atom_type in set(atoms.get_chemical_symbols()):
                basis[atom_type] = 'library 6-31g'

        input_filename = tempfolder.get_abs_path(self._DEFAULT_INPUT_FILE)
        with open(input_filename, 'w') as f:
            f.write('start {}\ntitle "{}"\n\n'.format(abbreviation, title))
            f.write('geometry units au\n')
            if add_cell:
                f.write('  system crystal\n')
                f.write('    lat_a {}\n    lat_b {}\n    lat_c {}\n'.format(
                    *lat_lengths))
                f.write('    alpha {}\n    beta  {}\n    gamma {}\n'.format(
                    *lat_angles))
                f.write('  end\n')
            for i, atom_type in enumerate(atoms.get_chemical_symbols()):
                f.write('    {} {} {} {}\n'.format(
                    atom_type,
                    atoms.get_positions()[i][0],
                    atoms.get_positions()[i][1],
                    atoms.get_positions()[i][2]))
            f.write('end\nbasis\n')
            for atom_type, b in basis.iteritems():
                f.write('    {} {}\n'.format(atom_type, b))
            f.write('end\ntask {}\n'.format(task))
            f.flush()

        commandline_params = self._default_commandline_params

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = [
            self._DEFAULT_OUTPUT_FILE, self._DEFAULT_ERROR_FILE
        ]
        calcinfo.retrieve_singlefile_list = []

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = commandline_params
        codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE
        codeinfo.stderr_name = self._DEFAULT_ERROR_FILE
        codeinfo.code_uuid = code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
Ejemplo n.º 3
0
    def _prepare_for_submission(self, tempfolder, inputdict):
        from aiida.orm.data.cif import CifData
        from aiida.orm.data.parameter import ParameterData
        from aiida.orm.calculation.job.codtools import commandline_params_from_dict
        import shutil

        try:
            cif = inputdict.pop(self.get_linkname('cif'))
        except KeyError:
            raise InputValidationError(
                "no CIF file is specified for deposition")
        if not isinstance(cif, CifData):
            raise InputValidationError("cif is not of type CifData")

        parameters = inputdict.pop(self.get_linkname('parameters'), None)
        if parameters is None:
            parameters = ParameterData(dict={})
        if not isinstance(parameters, ParameterData):
            raise InputValidationError(
                "parameters is not of type ParameterData")

        code = inputdict.pop(self.get_linkname('code'), None)
        if code is None:
            raise InputValidationError("No code found in input")

        parameters_dict = parameters.get_dict()

        deposit_file_rel = "deposit.cif"
        deposit_file_abs = tempfolder.get_abs_path(deposit_file_rel)
        shutil.copy(cif.get_file_abs_path(), deposit_file_abs)

        input_filename = tempfolder.get_abs_path(self._DEFAULT_INPUT_FILE)
        with open(input_filename, 'w') as f:
            f.write("{}\n".format(deposit_file_rel))
            f.flush()

        config_file_abs = tempfolder.get_abs_path(self._CONFIG_FILE)
        with open(config_file_abs, 'w') as f:
            for k in self._config_keys:
                if k in parameters_dict.keys():
                    f.write("{}={}\n".format(k, parameters_dict.pop(k)))
            f.flush()

        commandline_params = self._default_commandline_params
        commandline_params.extend(
            commandline_params_from_dict(parameters_dict))

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        # The command line parameters should be generated from 'parameters'
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = [
            self._DEFAULT_OUTPUT_FILE, self._DEFAULT_ERROR_FILE
        ]
        calcinfo.retrieve_singlefile_list = []

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = commandline_params
        codeinfo.stdin_name = self._DEFAULT_INPUT_FILE
        codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE
        codeinfo.stderr_name = self._DEFAULT_ERROR_FILE
        codeinfo.code_uuid = code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo
Ejemplo n.º 4
0
    def _prepare_for_submission(self, tempfolder, inputdict):
        """
        This is the routine to be called when you want to create
        the input files and related stuff with a plugin.
        
        :param tempfolder: a aiida.common.folders.Folder subclass where
                           the plugin should put all its files.
        :param inputdict: a dictionary with the input nodes, as they would
                be returned by get_inputdata_dict (with the Code(s)!)
        """

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

        # Settings can be undefined, and defaults to an empty dictionary.
        # They will be used for any input that doen't fit elsewhere.
        settings = inputdict.pop(self.get_linkname('settings'), None)
        if settings is None:
            settings_dict = {}
        else:
            if not isinstance(settings, ParameterData):
                raise InputValidationError(
                    "settings, if specified, must be of "
                    "type ParameterData")
            # Settings converted to uppercase
            settings_dict = _uppercase_dict(settings.get_dict(),
                                            dict_name='settings')
        initialise = settings_dict.pop('INITIALISE', None)
        if initialise is not None:
            if not isinstance(initialise, bool):
                raise InputValidationError("INITIALISE must be " " a boolean")
        try:
            parameters = inputdict.pop(self.get_linkname('parameters'))
        except KeyError:
            if not initialise:
                raise InputValidationError(
                    "No parameters specified for this calculation")
            else:
                pass
        if not initialise:
            if not isinstance(parameters, ParameterData):
                raise InputValidationError(
                    "parameters is not of type ParameterData")

        parent_calc_folder = inputdict.pop(self.get_linkname('parent_folder'),
                                           None)
        if parent_calc_folder is None:
            raise InputValidationError(
                "No parent calculation found, it is needed to "
                "use Yambo")
        if not isinstance(parent_calc_folder, RemoteData):
            raise InputValidationError("parent_calc_folder must be of"
                                       " type RemoteData")

        main_code = inputdict.pop(self.get_linkname('code'), None)
        if main_code is None:
            raise InputValidationError("No input code found!")

        preproc_code = inputdict.pop(self.get_linkname('preprocessing_code'),
                                     None)
        if preproc_code is not None:
            if not isinstance(preproc_code, Code):
                raise InputValidationError("preprocessing_code, if specified,"
                                           "must be of type Code")

        parent_calc = parent_calc_folder.get_inputs_dict(
            link_type=LinkType.CREATE)['remote_folder']
        yambo_parent = isinstance(parent_calc, YamboCalculation)

        # flags for yambo interfaces
        try:
            precode_parameters = inputdict.pop(
                self.get_linkname('precode_parameters'))
        except KeyError:
            precode_parameters = ParameterData(dict={})
        if not isinstance(precode_parameters, ParameterData):
            raise InputValidationError('precode_parameters is not '
                                       'of type ParameterData')
        precode_param_dict = precode_parameters.get_dict()

        # check the precode parameters given in input
        input_cmdline = settings_dict.pop('CMDLINE', None)
        import re
        precode_params_list = []
        pattern = re.compile(r"(^\-)([a-zA-Z])")
        for key, value in precode_param_dict.iteritems():
            if re.search(pattern, key) is not None:
                if key == '-O' or key == '-H' or key == '-h' or key == '-F':
                    raise InputValidationError(
                        "Precode flag {} is not allowed".format(str(key)))
                else:
                    if precode_param_dict[key] is True:
                        precode_params_list.append(str(key))
                    elif precode_param_dict[key] is False:
                        pass
                    else:
                        precode_params_list.append('{}'.format(str(key)))
                        precode_params_list.append('{}'.format(str(value)))
            else:
                raise InputValidationError(
                    "Wrong format of precode_parameters")
        # Adding manual cmdline input (e.g. for DB fragmentation)
        if input_cmdline is not None:
            precode_params_list = precode_params_list + input_cmdline

        # TODO: check that remote data must be on the same computer

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

        if not initialise:
            ###################################################
            # Prepare yambo input file
            ###################################################

            params_dict = parameters.get_dict()

            # extract boolean keys
            boolean_dict = {
                k: v
                for k, v in params_dict.iteritems() if isinstance(v, bool)
            }
            params_dict = {
                k: v
                for k, v in params_dict.iteritems()
                if k not in boolean_dict.keys()
            }

            # reorganize the dictionary and create a list of dictionaries with key, value and units
            parameters_list = []
            for k, v in params_dict.iteritems():

                if "_units" in k:
                    continue

                units_key = "{}_units".format(k)
                try:
                    units = params_dict[units_key]
                except KeyError:
                    units = None

                this_dict = {}
                this_dict['key'] = k
                this_dict['value'] = v
                this_dict['units'] = units

                parameters_list.append(this_dict)

            input_filename = tempfolder.get_abs_path(self._INPUT_FILE_NAME)

            with open(input_filename, 'w') as infile:
                infile.write(self._LOGOSTRING)

                for k, v in boolean_dict.iteritems():
                    if v:
                        infile.write("{}\n".format(k))

                for this_dict in parameters_list:
                    key = this_dict['key']
                    value = this_dict['value']
                    units = this_dict['units']

                    if isinstance(value, (tuple, list)):
                        # write the input flags for the Drude term and for the parallelization options of vers. 4
                        # (it can be implemented in a better way)
                        if key.startswith('DrudeW'):
                            value_string = " ( " + ",".join(
                                [str(_) for _ in value]) + " )"
                            the_string = "{} = {}".format(key, value_string)
                            the_string += " {}".format(units)
                            infile.write(the_string + "\n")
                            continue

                        if key == 'SE_CPU':
                            value_string = " \" " + " ".join(
                                [str(_) for _ in value]) + " \" "
                            the_string = "{} = {}".format(key, value_string)
                            infile.write("SE_ROLEs = \" q qp b  \" " + "\n")
                            infile.write(the_string + "\n")
                            continue

                        if key == 'X_all_q_CPU':
                            value_string = " \" " + " ".join(
                                [str(_) for _ in value]) + " \" "
                            the_string = "{} = {}".format(key, value_string)
                            infile.write("X_all_q_ROLEs = \" q k c v  \" " +
                                         "\n")
                            infile.write(the_string + "\n")
                            continue

                        if key == 'X_finite_q_CPU':
                            value_string = " \" " + " ".join(
                                [str(_) for _ in value]) + " \" "
                            the_string = "{} = {}".format(key, value_string)
                            infile.write("X_finite_q_ROLEs = \" q k c v  \" " +
                                         "\n")
                            infile.write(the_string + "\n")
                            continue

                        if key == 'X_q_0_CPU':
                            value_string = " \" " + " ".join(
                                [str(_) for _ in value]) + " \" "
                            the_string = "{} = {}".format(key, value_string)
                            infile.write("X_q_0_ROLEs = \" k c v  \" " + "\n")
                            infile.write(the_string + "\n")
                            continue

                        if key == 'QPkrange' or key == 'QPerange':
                            value_string = ''
                            for v in value:
                                value_string += " | ".join([str(_) for _ in v
                                                            ]) + " |\n"
                            the_string = "% {}\n {}".format(key, value_string)
                            the_string += "%"
                            infile.write(the_string + "\n")
                            continue

                        value_string = " | ".join([str(_)
                                                   for _ in value]) + " |"
                        the_string = "% {}\n {}".format(key, value_string)
                        if units is not None:
                            the_string += " {}".format(units)
                        the_string += "\n%"

                    else:
                        the_value = '"{}"'.format(value) if isinstance(
                            value, basestring) else '{}'.format(value)
                        the_string = "{} = {}".format(key, the_value)
                        if units is not None:
                            the_string += " {}".format(units)

                    infile.write(the_string + "\n")

        ############################################
        # set copy of the parent calculation
        ############################################

        parent_calcs = parent_calc_folder.get_inputs(link_type=LinkType.CREATE)
        if len(parent_calcs) > 1:
            raise UniquenessError(
                "More than one parent totalenergy calculation"
                "has been found for parent_calc_folder {}".format(
                    parent_calc_folder))
        if len(parent_calcs) == 0:
            raise InputValidationError(
                "No parent calculation associated with parent_folder {}".
                format(parent_calc_folder))
        parent_calc = parent_calcs[0]

        if yambo_parent:
            try:
                parent_settings = _uppercase_dict(
                    parent_calc.inp.settings.get_dict(),
                    dict_name='parent settings')
                parent_initialise = parent_settings['INITIALISE']
            except KeyError:
                parent_initialise = False

        if yambo_parent:
            remote_copy_list.append(
                (parent_calc_folder.get_computer().uuid,
                 os.path.join(parent_calc_folder.get_remote_path(),
                              "SAVE"), "SAVE/"))
            if not parent_initialise:
                cancopy = False
                if parent_calc.get_state() == calc_states.FINISHED:
                    cancopy = True
                if 'yambo_wrote' in parent_calc.get_outputs_dict(
                )['output_parameters'].get_dict().keys():
                    if parent_calc.get_outputs_dict(
                    )['output_parameters'].get_dict()['yambo_wrote'] == True:
                        cancopy = True
                    if parent_calc.get_outputs_dict(
                    )['output_parameters'].get_dict()['yambo_wrote'] == False:
                        cancopy = False
                if cancopy:
                    remote_copy_list.append(
                        (parent_calc_folder.get_computer().uuid,
                         os.path.join(parent_calc_folder.get_remote_path(),
                                      "aiida"), "aiida/"))
        else:
            remote_copy_list.append(
                (parent_calc_folder.get_computer().uuid,
                 os.path.join(parent_calc_folder.get_remote_path(),
                              PwCalculation._OUTPUT_SUBFOLDER,
                              "{}.save".format(parent_calc._PREFIX),
                              "*"), "."))
        ############################################
        # set Calcinfo
        ############################################

        calcinfo = CalcInfo()

        calcinfo.uuid = self.uuid

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

        # Retrieve by default the output file and the xml file
        calcinfo.retrieve_list = []
        calcinfo.retrieve_list.append('r*')
        calcinfo.retrieve_list.append('l*')
        calcinfo.retrieve_list.append('o*')
        calcinfo.retrieve_list.append('LOG/l-*_CPU_1')
        extra_retrieved = settings_dict.pop(
            'ADDITIONAL_RETRIEVE_LIST',
            ['aiida/ndb.QP', 'aiida/ndb.HF_and_locXC'])
        for extra in extra_retrieved:
            calcinfo.retrieve_list.append(extra)

        from aiida.common.datastructures import code_run_modes, CodeInfo

        # c1 = interface dft codes and yambo (ex. p2y or a2y)
        c1 = CodeInfo()
        c1.withmpi = True
        c1.cmdline_params = precode_params_list

        # c2 = yambo initialization
        c2 = CodeInfo()
        c2.withmpi = True
        c2.cmdline_params = []
        c2.code_uuid = main_code.uuid

        # if the parent calculation is a yambo calculation skip the interface (c1) and the initialization (c2)
        if yambo_parent:
            c1 = None
            if not parent_initialise:
                c2 = None
        else:
            c1.cmdline_params = precode_params_list
            c1.code_uuid = preproc_code.uuid

        # c3 = yambo calculation
        c3 = CodeInfo()
        c3.withmpi = self.get_withmpi()
        c3.cmdline_params = [
            "-F", self._INPUT_FILE_NAME, '-J', self._OUTPUT_FILE_NAME
        ]
        c3.code_uuid = main_code.uuid

        if initialise:
            c2 = None
            c3 = None

        #calcinfo.codes_info = [c1, c2, c3] if not yambo_parent else [c3]
        if yambo_parent:
            if not parent_initialise:
                calcinfo.codes_info = [c3]
            else:
                calcinfo.codes_info = [c2, c3]
        elif initialise:
            calcinfo.codes_info = [c1]
        else:
            calcinfo.codes_info = [c1, c2, c3]

        calcinfo.codes_run_mode = code_run_modes.SERIAL

        if settings_dict:
            raise InputValidationError(
                "The following keys have been found in "
                "the settings input node, but were not understood: {}".format(
                    ",".join(settings_dict.keys())))

        return calcinfo
Ejemplo n.º 5
0
    def _prepare_for_submission(self,tempfolder,inputdict):
        import numpy as np

        try:
            struct = inputdict.pop(self.get_linkname('structure'))
        except KeyError:
            raise InputValidationError("no structure is specified for this calculation")
        if not isinstance(struct, StructureData):
            raise InputValidationError("struct is not of type StructureData")

        try:
            code = inputdict.pop(self.get_linkname('code'))
        except KeyError:
            raise InputValidationError("no code is specified for this calculation")

        atoms = struct.get_ase()

     
        parameters = inputdict.pop(self.get_linkname('parameters'), None)
        if parameters is None:
            parameters = ParameterData(dict={})
        if not isinstance(parameters, ParameterData):
            raise InputValidationError("parameters is not of type ParameterData")
        par = parameters.get_dict()

        charge= par.pop('CHARGE', '0')
        cpus=par.pop ('CPUS','1')
        mult= par.pop(' MULTIPLICITY', '1')
        basis = par.pop('BASIS','6-31G')
        jobtype = par.pop('JOB_TYPE','SP')
        dft_d=par.pop('DFT_D','FALSE')
        total=par.pop('MEM_TOTAL', '7500')
        method=par.pop('METHOD', 'HF')
        convergence=par.pop('SCF_CONVERGENCE', 'Tight')
        title=par.pop('TITLE', 'A generic title')
        cycles=par.pop('SCF_MAX_CYCLES', '50')
        integral=par.pop('INTEGRAL','Integral(Grid=UltraFine)') # Note this default will generated a pruned a grid with 99,590 points
        unrestricted=par.pop('UNRESTRICTED', 'R')
        add_cell = par.pop('add_cell',False)


        input_filename = tempfolder.get_abs_path(self._DEFAULT_INPUT_FILE)
        with open(input_filename,'w') as f:
            f.write('%Mem={}mb\n'.format(total))
            if method == 'PM6':
               f.write('#p {} {} \n'.format(method,jobtype))
            else:
               f.write('#p {}{}/{} {} {} SCF={}\n'.format(unrestricted,method,basis,jobtype,integral,convergence))
               if dft_d != 'FALSE':
                    f.write('EmpiricalDispersion={}\n'.format(dft_d))
            f.write('\n')
            f.write('{}\n'.format(title))
            f.write('\n')
            f.write('{} {} \n'.format(charge,mult))
            for i,atom_type in enumerate(atoms.get_chemical_symbols()):
                x='{0:.7f}'.format(float(atoms.get_positions()[i][0]))
                y='{0:.7f}'.format(float(atoms.get_positions()[i][1]))
                z='{0:.7f}'.format(float(atoms.get_positions()[i][2]))
                f.write(' {} {} {} {} \n'.format(atom_type,x,y,z))
            f.write('\n')
            f.flush()


        self._default_commandline_params = []

        commandline_params = self._default_commandline_params

        calcinfo = CalcInfo()
        calcinfo.uuid = self.uuid
        calcinfo.local_copy_list = []
        calcinfo.remote_copy_list = []
        calcinfo.retrieve_list = [self._DEFAULT_OUTPUT_FILE,
                                  self._DEFAULT_ERROR_FILE]
        calcinfo.retrieve_singlefile_list = []

        codeinfo = CodeInfo()
        codeinfo.cmdline_params = commandline_params
        codeinfo.stdin_name = self._DEFAULT_INPUT_FILE
        codeinfo.stdout_name = self._DEFAULT_OUTPUT_FILE
        codeinfo.stderr_name = self._DEFAULT_ERROR_FILE
        codeinfo.code_uuid = code.uuid
        calcinfo.codes_info = [codeinfo]

        return calcinfo