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
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
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
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
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