def test_joins3_user_group(self): from aiida.orm.user import User from aiida.orm.querybuilder import QueryBuilder # Create another user new_email = "[email protected]" user = self.backend.users.create(email=new_email) user.store() # Create a group that belongs to that user from aiida.orm.group import Group group = Group(name="node_group") group.user = user group.store() # Search for the group of the user qb = QueryBuilder() qb.append(User, tag='user', filters={'id': {'==': user.id}}) qb.append(Group, belongs_to='user', filters={'id': {'==': group.id}}) self.assertEquals( qb.count(), 1, "The expected group that belongs to " "the selected user was not found.") # Search for the user that owns a group qb = QueryBuilder() qb.append(Group, tag='group', filters={'id': {'==': group.id}}) qb.append(User, owner_of='group', filters={'id': {'==': user.id}}) self.assertEquals( qb.count(), 1, "The expected user that owns the " "selected group was not found.")
def validate_group(callback_kwargs, ctx, param, value): """ Command line option validator for an AiiDA Group. It expects a string for the value that corresponds to the label or a pk of an AiiDA group. :param callback_kwargs: an optional dictionary with arguments for internal use in the validator :param ctx: internal context of the click.command :param param: the click Parameter, i.e. either the Option or Argument to which the validator is hooked up :param value: a Group label or pk :returns: a Group instance """ from aiida.common.exceptions import NotExistent from aiida.orm import Group if value is None: return value try: group = Group.get_from_string(value) except NotExistent as exception: pass else: return group try: group = Group.get(pk=int(value)) except NotExistent as exception: raise click.BadParameter( "failed to load the Group with the label or pk '{}'\n{}".format( value, exception)) else: return group
def _prepare_group_for_upload(cls, group_name, group_description=None, dry_run=False): """Prepare a (possibly new) group to upload a POTCAR family to.""" if not dry_run: group, group_created = Group.get_or_create( name=group_name, type_string=cls.potcar_family_type_string) else: group = cls.get_potcar_group(group_name) group_created = bool(not group) if not group: group = Group(name=group_name) if group.user.pk != get_current_user().pk: raise UniquenessError( 'There is already a POTCAR family group with name {}, but it belongs to user {}, therefore you cannot modify it' .format(group_name, group.user.email)) if group_description: group.description = group_description elif group_created: raise ValueError( 'A new POTCAR family {} should be created but no description was given!' .format(group_name)) return group
def get_group(): try: g = Group.get_from_string('examples') except NotExistent: g = Group(name='examples') g.store() return g
def create_cif_data(cls): """Create CifData object.""" with tempfile.NamedTemporaryFile(mode='w+') as fhandle: filename = fhandle.name fhandle.write(cls.valid_sample_cif_str) fhandle.flush() a_cif = CifData(file=filename, source={ 'version': '1234', 'db_name': 'COD', 'id': '0000001' }) a_cif.store() g_ne = Group(label='non_empty_group') g_ne.store() g_ne.add_nodes(a_cif) g_e = Group(label='empty_group') g_e.store() cls.cif = a_cif return { DummyVerdiDataListable.NODE_ID_STR: a_cif.id, DummyVerdiDataListable.NON_EMPTY_GROUP_ID_STR: g_ne.id, DummyVerdiDataListable.EMPTY_GROUP_ID_STR: g_e.id }
def create_structure_bands(): """Create bands structure object.""" alat = 4. # angstrom cell = [ [ alat, 0., 0., ], [ 0., alat, 0., ], [ 0., 0., alat, ], ] strct = StructureData(cell=cell) strct.append_atom(position=(0., 0., 0.), symbols='Fe') strct.append_atom(position=(alat / 2., alat / 2., alat / 2.), symbols='O') strct.store() @calcfunction def connect_structure_bands(strct): # pylint: disable=unused-argument alat = 4. cell = np.array([ [alat, 0., 0.], [0., alat, 0.], [0., 0., alat], ]) kpnts = KpointsData() kpnts.set_cell(cell) kpnts.set_kpoints([[0., 0., 0.], [0.1, 0.1, 0.1]]) bands = BandsData() bands.set_kpointsdata(kpnts) bands.set_bands([[1.0, 2.0], [3.0, 4.0]]) return bands bands = connect_structure_bands(strct) # Create 2 groups and add the data to one of them g_ne = Group(label='non_empty_group') g_ne.store() g_ne.add_nodes(bands) g_e = Group(label='empty_group') g_e.store() return { DummyVerdiDataListable.NODE_ID_STR: bands.id, DummyVerdiDataListable.NON_EMPTY_GROUP_ID_STR: g_ne.id, DummyVerdiDataListable.EMPTY_GROUP_ID_STR: g_e.id }
def create_trajectory_data(): """Create TrajectoryData object with two arrays.""" traj = TrajectoryData() # I create sample data stepids = np.array([60, 70]) times = stepids * 0.01 cells = np.array([[[ 2., 0., 0., ], [ 0., 2., 0., ], [ 0., 0., 2., ]], [[ 3., 0., 0., ], [ 0., 3., 0., ], [ 0., 0., 3., ]]]) symbols = ['H', 'O', 'C'] positions = np.array([[[0., 0., 0.], [0.5, 0.5, 0.5], [1.5, 1.5, 1.5]], [[0., 0., 0.], [0.5, 0.5, 0.5], [1.5, 1.5, 1.5]]]) velocities = np.array([[[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]], [[0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [-0.5, -0.5, -0.5]]]) # I set the node traj.set_trajectory( stepids=stepids, cells=cells, symbols=symbols, positions=positions, times=times, velocities=velocities ) traj.store() # Create 2 groups and add the data to one of them g_ne = Group(label='non_empty_group') g_ne.store() g_ne.add_nodes(traj) g_e = Group(label='empty_group') g_e.store() return { DummyVerdiDataListable.NODE_ID_STR: traj.id, DummyVerdiDataListable.NON_EMPTY_GROUP_ID_STR: g_ne.id, DummyVerdiDataListable.EMPTY_GROUP_ID_STR: g_e.id }
def __init__(self, **kwargs): super(TbmodelWorkflow, self).__init__(**kwargs) self.group = None try: self.group = Group.get_from_string('tbmodel') except NotExistent: self.group = Group(name='tbmodel') self.group.store()
def create_structure_bands(): alat = 4. # angstrom cell = [ [ alat, 0., 0., ], [ 0., alat, 0., ], [ 0., 0., alat, ], ] s = StructureData(cell=cell) s.append_atom(position=(0., 0., 0.), symbols='Fe') s.append_atom(position=(alat / 2., alat / 2., alat / 2.), symbols='O') s.store() @calcfunction def connect_structure_bands(structure): alat = 4. cell = np.array([ [alat, 0., 0.], [0., alat, 0.], [0., 0., alat], ]) k = KpointsData() k.set_cell(cell) k.set_kpoints([[0., 0., 0.], [0.1, 0.1, 0.1]]) b = BandsData() b.set_kpointsdata(k) b.set_bands([[1.0, 2.0], [3.0, 4.0]]) return b b = connect_structure_bands(s) # Create 2 groups and add the data to one of them g_ne = Group(label='non_empty_group') g_ne.store() g_ne.add_nodes(b) g_e = Group(label='empty_group') g_e.store() return { TestVerdiDataListable.NODE_ID_STR: b.id, TestVerdiDataListable.NON_EMPTY_GROUP_ID_STR: g_ne.id, TestVerdiDataListable.EMPTY_GROUP_ID_STR: g_e.id }
def get_ref_from_group(element, group): """ Return a structure data node from a given group for a given element. (quit creedy, done straighforward) params: group: group name or pk params: element: string with the element i.e 'Si' returns: AiiDA StructureData node """ report = [] try: group_pk = int(group) except ValueError: group_pk = None group_name = group if group_pk is not None: try: str_group = Group(dbgroup=group_pk) except NotExistent: str_group = None message = ('You have to provide a valid pk for a Group of' 'structures or a Group name. Reference key: "group".' 'given pk= {} is not a valid group' '(or is your group name integer?)'.format(group_pk)) report.append(message) else: try: str_group = Group.get_from_string(group_name) except NotExistent: str_group = None message = ( 'You have to provide a valid pk for a Group of' 'structures or a Group name. Wf_para key: "struc_group".' 'given group name= {} is not a valid group' '(or is your group name integer?)'.format(group_name)) report.append(message) #abort_nowait('I abort, because I have no structures to calculate ...') stru_nodes = str_group.nodes #n_stru = len(stru_nodes) structure = None for struc in stru_nodes: formula = struc.get_formula() eformula = formula.translate(None, digits) # remove digits, !python3 differs if eformula == element: return struc, report report.append('Structure node for element {} not found in group {}' ''.format(element, group)) return structure, report
def get_nodes_from_group(group, return_format='uuid'): """ returns a list of node uuids for a given group as, name, pk, uuid or group object """ from aiida.orm import Group from aiida.common.exceptions import NotExistent nodes = [] g_nodes = [] try: group_pk = int(group) except ValueError: group_pk = None group_name = group if group_pk is not None: try: str_group = Group(dbgroup=group_pk) except NotExistent: str_group = None message = ('You have to provide a valid pk for a Group ' 'or a Group name. Reference key: "group".' 'given pk= {} is not a valid group' '(or is your group name integer?)'.format(group_pk)) print(message) elif group_name is not None: try: str_group = Group.get_from_string(group_name) except NotExistent: str_group = None message = ( 'You have to provide a valid pk for a Group or a Group name.' 'given group name= {} is not a valid group' '(or is your group name integer?)'.format(group_name)) print(message) elif isinstance(group, Group): str_group = group else: str_group = None print( 'I could not handle given input, either Group, pk, or group name please.' ) return nodes g_nodes = str_group.nodes for node in g_nodes: if return_format == 'uuid': nodes.append(node.uuid) elif return_format == 'pk': nodes.append(node.pk) return nodes
def test_queryhelp(self): """ Here I test the queryhelp by seeing whether results are the same as using the append method. I also check passing of tuples. """ from aiida.orm.data.structure import StructureData from aiida.orm.data.parameter import ParameterData from aiida.orm.data import Data from aiida.orm.querybuilder import QueryBuilder from aiida.orm.group import Group from aiida.orm.computer import Computer g = Group(name='helloworld').store() for cls in (StructureData, ParameterData, Data): obj = cls() obj._set_attr('foo-qh2', 'bar') obj.store() g.add_nodes(obj) for cls, expected_count, subclassing in ( (StructureData, 1, True), (ParameterData, 1, True), (Data, 3, True), (Data, 1, False), ((ParameterData, StructureData), 2, True), ((ParameterData, StructureData), 2, False), ((ParameterData, Data), 2, False), ((ParameterData, Data), 3, True), ((ParameterData, Data, StructureData), 3, False), ): qb = QueryBuilder() qb.append(cls, filters={'attributes.foo-qh2': 'bar'}, subclassing=subclassing, project='uuid') self.assertEqual(qb.count(), expected_count) qh = qb.get_json_compatible_queryhelp() qb_new = QueryBuilder(**qh) self.assertEqual(qb_new.count(), expected_count) self.assertEqual(sorted([uuid for uuid, in qb.all()]), sorted([uuid for uuid, in qb_new.all()])) qb = QueryBuilder().append(Group, filters={'name': 'helloworld'}) self.assertEqual(qb.count(), 1) qb = QueryBuilder().append((Group, ), filters={'name': 'helloworld'}) self.assertEqual(qb.count(), 1) qb = QueryBuilder().append(Computer, ) self.assertEqual(qb.count(), 1) qb = QueryBuilder().append(cls=(Computer, )) self.assertEqual(qb.count(), 1)
def setUpClass(cls): """ Create some groups to test the GroupParamType parameter type for the command line infrastructure We create an initial group with a random name and then on purpose create two groups with a name that matches exactly the ID and UUID, respectively, of the first one. This allows us to test the rules implemented to solve ambiguities that arise when determing the identifier type """ super(TestGroupParamType, cls).setUpClass() cls.param = GroupParamType() cls.entity_01 = Group.create(name='group_01') cls.entity_02 = Group.create(name=str(cls.entity_01.pk)) cls.entity_03 = Group.create(name=str(cls.entity_01.uuid))
def get_para_from_group(element, group): """ get structure node for a given element from a given group of structures (quit creedy, done straighforward) """ report = [] try: group_pk = int(group) except ValueError: group_pk = None group_name = group if group_pk is not None: try: para_group = Group(dbgroup=group_pk) except NotExistent: para_group = None message = ('You have to provide a valid pk for a Group of ' 'parameters or a Group name. Reference key: "group".' 'given pk= {} is not a valid group' '(or is your group name integer?)'.format(group_pk)) report.append(message) else: try: para_group = Group.get_from_string(group_name) except NotExistent: para_group = None message = ('You have to provide a valid pk for a Group of ' 'parameters or a Group name. Wf_para key: "para_group".' 'given group name= {} is not a valid group' '(or is your group name integer?)'.format(group_name)) report.append(message) #abort_nowait('I abort, because I have no structures to calculate ...') para_nodes = para_group.nodes #n_stru = len(para_nodes) parameter = None for para in para_nodes: formula = para.get_extras().get('element', None) #eformula = formula.translate(None, digits) # remove digits, !python3 differs if formula == element: return para, report report.append('Parameter node for element {} not found in group {}' ''.format(element, group)) return parameter, report
def group_create(self, *args): """ Create a new empty group. """ if not is_dbenv_loaded(): load_dbenv() import argparse from aiida.orm import Group as G parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Create a new empty group.') parser.add_argument('GROUPNAME', help="The name of the new group") args = list(args) parsed_args = parser.parse_args(args) group_name = parsed_args.GROUPNAME group, created = G.get_or_create(name=group_name) if created: print "Group created with PK = {} and name '{}'".format( group.pk, group.name) else: print "Group '{}' already exists, PK = {}".format( group.name, group.pk)
def get_potcar_group(cls, group_name): """Return the PotcarFamily group with the given name.""" try: group = Group.get(label=group_name, type_string=cls.potcar_family_type_string) except NotExistent: group = None return group
def get_upf_groups(cls, filter_elements=None, user=None): """ Return all names of groups of type UpfFamily, possibly with some filters. :param filter_elements: A string or a list of strings. If present, returns only the groups that contains one Upf for every element present in the list. Default=None, meaning that all families are returned. :param user: if None (default), return the groups for all users. If defined, it should be either a DbUser instance, or a string for the username (that is, the user email). """ from aiida.orm import Group group_query_params = {"type_string": cls.upffamily_type_string} if user is not None: group_query_params['user'] = user if isinstance(filter_elements, basestring): filter_elements = [filter_elements] if filter_elements is not None: actual_filter_elements = {_.capitalize() for _ in filter_elements} group_query_params['node_attributes'] = { 'element': actual_filter_elements} all_upf_groups = Group.query(**group_query_params) groups = [(g.name, g) for g in all_upf_groups] # Sort by name groups.sort() # Return the groups, without name return [_[1] for _ in groups]
def get_upf_group(cls, group_name): """ Return the UpfFamily group with the given name. """ from aiida.orm import Group return Group.get(name=group_name, type_string=cls.upffamily_type_string)
def test_load_group(self): """ Test the functionality of load_group """ name = 'groupie' group = Group(name=name).store() # Load through uuid loaded_group = load_group(group.uuid) self.assertEquals(loaded_group.uuid, group.uuid) # Load through pk loaded_group = load_group(group.pk) self.assertEquals(loaded_group.uuid, group.uuid) # Load through uuid explicitly loaded_group = load_group(uuid=group.uuid) self.assertEquals(loaded_group.uuid, group.uuid) # Load through pk explicitly loaded_group = load_group(pk=group.pk) self.assertEquals(loaded_group.uuid, group.uuid) # Load through partial uuid loaded_group = load_group(uuid=group.uuid[:2]) self.assertEquals(loaded_group.uuid, group.uuid) # Load through partial uuid loaded_group = load_group(uuid=group.uuid[:10]) self.assertEquals(loaded_group.uuid, group.uuid) with self.assertRaises(NotExistent): load_group('non-existent-uuid')
def test_family_show_argument_type(clear_db, run_cli_command, get_pseudo_family): """Test that `aiida-pseudo show` only accepts instances of `PseudoPotentialFamily` or subclasses as argument.""" pseudo_family = get_pseudo_family(label='pseudo-family', cls=PseudoPotentialFamily) normal_group = Group('normal-group').store() run_cli_command(cmd_family_show, [pseudo_family.label]) run_cli_command(cmd_family_show, [normal_group.label], raises=SystemExit)
def get_pseudos_from_structure(structure, family_name): """Given a family name (a Siesta pseudo group in the DB, possibly with mixed psf and psml pseudopotentials) and an AiiDA structure object, return a dictionary associating each 'kind' name in the structure with its object (PsfData or PsmlData). :raise MultipleObjectsError: if more than one pseudo for the same element is found in the group. :raise NotExistent: if no pseudo for an element in the group is found in the group. """ from aiida.common.exceptions import NotExistent, MultipleObjectsError family_pseudos = {} family = Group.get(label=family_name) for node in family.nodes: if isinstance(node, (PsfData, PsmlData)): if node.element in family_pseudos: raise MultipleObjectsError( "More than one pseudo for element {} found in " "family {}".format(node.element, family_name) ) family_pseudos[node.element] = node pseudo_list = {} for kind in structure.kinds: symbol = kind.symbol try: pseudo_list[kind.name] = family_pseudos[symbol] except KeyError: raise NotExistent("No pseudo for element {} found in family {}".format(symbol, family_name)) return pseudo_list
def get_basis_group(cls, group_name): """ Return the BasisFamily group with the given name. """ from aiida.orm import Group return Group.get(name=group_name, type_string=cls.basisfamily_type_string)
def get_upf_family_names(self): """ Get the list of all upf family names to which the pseudo belongs """ from aiida.orm import Group return [_.name for _ in Group.query(nodes=self, type_string=self.upffamily_type_string)]
def get_psml_group(cls, group_label): """ Return the PsmlFamily group with the given name. """ from aiida.orm import Group return Group.get(label=group_label, type_string=cls.psmlfamily_type_string)
def add_to_group(node): try: g = Group.get_from_string('examples') except NotExistent: g = Group(name='examples') g.store() g.add_nodes(node)
def get_upf_group(cls, group_label): """Return the UPF family group with the given label. :param group_label: the family group label :return: the `Group` with the given label, if it exists """ from aiida.orm import Group return Group.get(label=group_label, type_string=cls.upffamily_type_string)
def create_structure_data(): """Create StructureData object.""" alat = 4. # angstrom cell = [ [ alat, 0., 0., ], [ 0., alat, 0., ], [ 0., 0., alat, ], ] # BaTiO3 cubic structure struc = StructureData(cell=cell) struc.append_atom(position=(0., 0., 0.), symbols='Ba') struc.append_atom(position=(alat / 2., alat / 2., alat / 2.), symbols='Ti') struc.append_atom(position=(alat / 2., alat / 2., 0.), symbols='O') struc.append_atom(position=(alat / 2., 0., alat / 2.), symbols='O') struc.append_atom(position=(0., alat / 2., alat / 2.), symbols='O') struc.store() # Create 2 groups and add the data to one of them g_ne = Group(label='non_empty_group') g_ne.store() g_ne.add_nodes(struc) g_e = Group(label='empty_group') g_e.store() return { DummyVerdiDataListable.NODE_ID_STR: struc.id, DummyVerdiDataListable.NON_EMPTY_GROUP_ID_STR: g_ne.id, DummyVerdiDataListable.EMPTY_GROUP_ID_STR: g_e.id }
def launch(input_group, input_structures, target_supercellsize, solute_elements, structure_comments, structure_group_label, structure_group_description, dryrun): """ Script for generating substitutional and vacancy defects for an input structure or all structures in an input group. """ if not dryrun: structure_group = Group.objects.get_or_create( label=structure_group_label, description=structure_group_description)[0] else: structure_group = None if input_group: input_group = Group(input_group) structure_nodes = get_allstructurenodes_fromgroup(input_group) elif input_structures: input_structures = input_structures.split(',') structure_nodes = [load_node(x) for x in input_structures] else: raise Exception("Must use either input group or input structures") solute_elements = prep_elementlist(solute_elements) for structure_node in structure_nodes: extras = { 'input_structure': structure_node.uuid, 'structure_comments': structure_comments } input_structure_ase = structure_node.get_ase() #Unfortunately, we must get the unique sites prior to supercell #creation, meaning changes in site index can cause bugs unique_sites = get_unique_sites(input_structure_ase) if target_supercellsize is not None: target_supercellsize = int(target_supercellsize) extras['target_supercellsize'] = target_supercellsize input_structure_ase = generate_supercell(input_structure_ase, target_supercellsize)[1] for unique_site in unique_sites: site_index, element_index, wyckoff = unique_site extras['site_index'] = site_index extras['element_index'] = element_index extras['wyckoff'] = wyckoff for element in solute_elements: defect_structure = input_structure_ase.copy() extras['element_new'] = element if defect_structure[site_index].symbol == element: continue else: defect_structure[site_index].symbol = element store_asestructure(defect_structure, extras, structure_group, dryrun)
def test_complete(setup_groups, parameter_type): """Test the `complete` method that provides auto-complete functionality.""" entity_01, entity_02, entity_03 = setup_groups entity_04 = Group(label='xavier').store() options = [item[0] for item in parameter_type.complete(None, '')] assert sorted(options) == sorted([entity_01.label, entity_02.label, entity_03.label, entity_04.label]) options = [item[0] for item in parameter_type.complete(None, 'xa')] assert sorted(options) == sorted([entity_04.label])
def test_createsolute_reconstruct_from_extra(self): from aiida_alloy.cli.create_solutesupercell_structures import cli as cli_solute from aiida_alloy.utils import ase_structures_match solute_test_group_name = "__TEST_SOLUTE_STRUCTURE" command = [ "--lattice_size", "4.04", "--supercell_shape", "1,1,1", "--matrix_element", "Al", "--firstsolute_elements", "Mg,Si,Vac", "--secondsolute_elements", "Mg,Si,Vac", "--structure_group_name", solute_test_group_name ] result = self.runner.invoke(cli_solute, command).output solute_test_group = Group.get_from_string(solute_test_group_name) solute_structures = get_all_structure_from_structuregroup( solute_test_group) assert len(solute_structures) == 10 def reconstruct_solute_fromextras(extra): from aiida_alloy.utils import gen_ase_supercell lattice_size = extra['lattice_size'] supercell_shape = extra['supercell_shape'] matrix_element = extra['matrix_element'] reconstruct_ase = gen_ase_supercell(lattice_size, supercell_shape, matrix_element) indexing = np.arange(0, len(reconstruct_ase)) if 'sol1_index' in extra: sol1_index = extra['sol1_index'] if extra['sol1_element'] == 'Vac': del reconstruct_ase[indexing[sol1_index]] indexing = [(lambda x: x - 1 if x >= sol1_index else x)(x) for x in indexing] else: reconstruct_ase[ indexing[sol1_index]].symbol = extra['sol1_element'] if 'sol2_index' in extra: sol2_index = extra['sol2_index'] if extra['sol2_element'] == 'Vac': del reconstruct_ase[indexing[sol2_index]] indexing = [(lambda x: x - 1 if x >= sol1_index else x)(x) for x in indexing] else: reconstruct_ase[ indexing[sol2_index]].symbol = extra['sol2_element'] return reconstruct_ase for solute_structure in solute_structures: original_ase = solute_structure.get_ase() reconstructed_ase = reconstruct_solute_fromextras( solute_structure.extras) assert ase_structures_match(original_ase, reconstructed_ase)
def use_lapwbasis_from_family(self, family_name): from collections import defaultdict try: structure = self.get_inputs_dict()[self.get_linkname('structure')] except AttributeError: raise ValueError("Structure is not set yet! Therefore, the method " "use_lapwbasis_from_family cannot automatically set " "the LAPW basis") from aiida.orm import Group lapwbasis_group = Group.get(family_name, type_string=LapwbasisData.lapwbasisfamily_type_string) lapwbasis_list = {} for node in lapwbasis_group.nodes: if isinstance(node, LapwbasisData): lapwbasis_list[node.chemical_symbol] = node for kind in structure.kinds: symbol = kind.symbol self.use_lapwbasis(lapwbasis_list[symbol], symbol)