def _COD_search(self): from .search.cod import cod_check from aiida.tools.dbimporters.plugins.cod import CodDbImporter """ Deals with the retrieval of a structure from the COD database, according to the request dictionary Returns a database search object (array of arrays of structures) """ kwords = cod_check(Dict(dict=self.ctx.db)) self.ctx.db_valid = kwords.dict.valid self.ctx.db_invalid = kwords.dict.invalid # empty dictionary if not bool(self.ctx.db_valid): self.report('No valid keywords in search tag in json') return self.exit_codes.ERROR_MISSING_KEY # query the database for structures importer = CodDbImporter() self.ctx.allcifs = importer.query(**self.ctx.db_valid) self.ctx.n_structures = len(self.ctx.allcifs) if self.ctx.n_structures == 0: self.report('No structure retrieved') self.ctx.cif = None return self.exit_codes.ERROR_NO_STRUCTURE else: s = self.ctx.allcifs[0].get_aiida_structure() s.store() self.ctx.cif = s if self.ctx.n_structures >= 2: self.report('{} structure satisfy the request'.format( self.ctx.n_structures))
def create_spinel_structurelist(): from aiida.tools.dbimporters.plugins.cod import CodDbImporter from icet.tools import get_primitive_structure # Import the ordered MgAl2O4 from COD db importer = CodDbImporter() mgalo = importer.query(id=1010129)[0] ase_mgalo = mgalo.get_ase_structure() primitive_structure = get_primitive_structure(ase_mgalo) chemical_symbols = [['Mg', 'Al'] for i in range(6)] + [['O'] for i in range(8)] # The concentration of A is 2/14 \in (0.1428, 0.1429) concentration_restrictions = {'Mg': (0.1428, 0.1429)} ase_structurelist = [] for structure in enumerate_structures( primitive_structure, range(1, 3), chemical_symbols, concentration_restrictions=concentration_restrictions): ase_structurelist.append(structure) return ase_structurelist
def _query(idn=None, formula=None): """Make the actual query.""" importer = CodDbImporter() if idn is not None: return importer.query(id=idn) if formula is not None: return importer.query(formula=formula) return None
def cod_query(cod_values): """ performs a search of any CIF structure that is provided according to the data coming from the input JSON request returns a list of structures and an error code if there is something wrong with things """ qlist = cod_values.get_dict() importer = CodDbImporter() found = importer.query(**qlist) found_list = found.fetch_all() x = [i.source['id'] for i in found_list] # returned list of retrieved structures return List(list=x)
def test_query_construction_1(self): """Test query construction.""" from aiida.tools.dbimporters.plugins.cod import CodDbImporter import re codi = CodDbImporter() q_sql = codi.query_sql( id=['1000000', 3000000], element=['C', 'H', 'Cl'], number_of_elements=5, chemical_name=['caffeine', 'serotonine'], formula=['C6 H6'], volume=[100, 120.005], spacegroup='P -1', a=[10.0 / 3, 1], alpha=[10.0 / 6, 0], measurement_temp=[0, 10.5], measurement_pressure=[1000, 1001], determination_method=['single crystal', None] ) # Rounding errors occur in Python 3 thus they are averted using # the following precision stripping regular expressions. q_sql = re.sub(r'(\d\.\d{6})\d+', r'\1', q_sql) q_sql = re.sub(r'(120.00)39+', r'\g<1>4', q_sql) self.assertEqual(q_sql, \ 'SELECT file, svnrevision FROM data WHERE ' "(status IS NULL OR status != 'retracted') AND " '(a BETWEEN 3.332333 AND 3.334333 OR ' 'a BETWEEN 0.999 AND 1.001) AND ' '(alpha BETWEEN 1.665666 AND 1.667666 OR ' 'alpha BETWEEN -0.001 AND 0.001) AND ' "(chemname LIKE '%caffeine%' OR " "chemname LIKE '%serotonine%') AND " "(method IN ('single crystal') OR method IS NULL) AND " "(formula REGEXP ' C[0-9 ]' AND " "formula REGEXP ' H[0-9 ]' AND " "formula REGEXP ' Cl[0-9 ]') AND " "(formula IN ('- C6 H6 -')) AND " '(file IN (1000000, 3000000)) AND ' '(cellpressure BETWEEN 999 AND 1001 OR ' 'cellpressure BETWEEN 1000 AND 1002) AND ' '(celltemp BETWEEN -0.001 AND 0.001 OR ' 'celltemp BETWEEN 10.499 AND 10.501) AND ' "(nel IN (5)) AND (sg IN ('P -1')) AND " '(vol BETWEEN 99.999 AND 100.001 OR ' 'vol BETWEEN 120.004 AND 120.006)')
def test_datatype_checks(self): """ Rather complicated, but wide-coverage test for data types, accepted and rejected by CodDbImporter._*_clause methods. """ from aiida.tools.dbimporters.plugins.cod import CodDbImporter codi = CodDbImporter() messages = ["", "incorrect value for keyword 'test' -- " + \ "only integers and strings are accepted", "incorrect value for keyword 'test' -- " + \ "only strings are accepted", "incorrect value for keyword 'test' -- " + \ "only integers and floats are accepted", "invalid literal for int() with base 10: 'text'"] values = [10, 'text', u'text', '10', 1.0 / 3, [1, 2, 3]] methods = [ codi._int_clause, codi._str_exact_clause, codi._formula_clause, codi._str_fuzzy_clause, codi._composition_clause, codi._volume_clause ] results = [[0, 4, 4, 0, 1, 1], [0, 0, 0, 0, 1, 1], [2, 0, 2, 0, 2, 2], [0, 0, 0, 0, 1, 1], [2, 0, 0, 0, 2, 2], [0, 3, 3, 3, 0, 3]] for i in range(0, len(methods)): for j in range(0, len(values)): message = messages[0] try: methods[i]("test", "test", [values[j]]) except ValueError as e: message = e.message self.assertEquals(message, messages[results[i][j]])
def test_datatype_checks(self): """Rather complicated, but wide-coverage test for data types, accepted and rejected by CodDbImporter._*_clause methods.""" from aiida.tools.dbimporters.plugins.cod import CodDbImporter codi = CodDbImporter() messages = [ '', "incorrect value for keyword 'test' only integers and strings are accepted", "incorrect value for keyword 'test' only strings are accepted", "incorrect value for keyword 'test' only integers and floats are accepted", "invalid literal for int() with base 10: 'text'" ] values = [10, 'text', 'text', '10', 1.0 / 3, [1, 2, 3]] methods = [ # pylint: disable=protected-access codi._int_clause, codi._str_exact_clause, codi._formula_clause, codi._str_fuzzy_clause, codi._composition_clause, codi._volume_clause ] results = [[0, 4, 4, 0, 1, 1], [0, 0, 0, 0, 1, 1], [2, 0, 0, 0, 2, 2], [0, 0, 0, 0, 1, 1], [2, 0, 0, 0, 2, 2], [0, 3, 3, 3, 0, 3]] for i, _ in enumerate(methods): for j, _ in enumerate(values): message = messages[0] try: methods[i]('test', 'test', [values[j]]) except ValueError as exc: message = str(exc) self.assertEqual(message, messages[results[i][j]])
def cod_check(cod_dict): """ Tries to infere which of the search keywords are actually valid :cod_dict input dictionary :output cod_rec valid keywords :output cod_unrec not valid keywords """ importer = CodDbImporter() supported = importer.get_supported_keywords() # return supported keywords and unsupported keywords for the search # defaultdict append method create lists for duplicated k:v # keeps only one value if key is duplicated cod_rec = {} cod_unrec = {} for k, v in six.iteritems(cod_dict.get_dict()): if k in supported: cod_rec.update({k: v}) else: cod_unrec.update({k: v}) return Dict(dict={'valid': cod_rec, 'invalid': cod_unrec})
def test_query_construction_1(self): from aiida.tools.dbimporters.plugins.cod import CodDbImporter codi = CodDbImporter() q = codi.query_sql(id=["1000000", 3000000], element=["C", "H", "Cl"], number_of_elements=5, chemical_name=["caffeine", "serotonine"], formula=["C6 H6"], volume=[100, 120.005], spacegroup="P -1", a=[10.0 / 3, 1], alpha=[10.0 / 6, 0], measurement_temp=[0, 10.5], measurement_pressure=[1000, 1001], determination_method=["single crystal", None]) self.assertEquals(q, \ "SELECT file, svnrevision FROM data WHERE " "(status IS NULL OR status != 'retracted') AND " "(method IN ('single crystal') OR method IS NULL) AND " "(file IN (1000000, 3000000)) AND " "(chemname LIKE '%caffeine%' OR " "chemname LIKE '%serotonine%') AND " "(formula IN ('- C6 H6 -')) AND " "(a BETWEEN 3.33233333333 AND 3.33433333333 OR " "a BETWEEN 0.999 AND 1.001) AND " "(celltemp BETWEEN -0.001 AND 0.001 OR " "celltemp BETWEEN 10.499 AND 10.501) AND " "(vol BETWEEN 99.999 AND 100.001 OR " "vol BETWEEN 120.004 AND 120.006) AND " "(alpha BETWEEN 1.66566666667 AND 1.66766666667 OR " "alpha BETWEEN -0.001 AND 0.001) AND " "(cellpressure BETWEEN 999 AND 1001 OR " "cellpressure BETWEEN 1000 AND 1002) AND " "(formula REGEXP ' C[0-9 ]' AND " "formula REGEXP ' H[0-9 ]' AND " "formula REGEXP ' Cl[0-9 ]') AND " "(nel IN (5)) AND (sg IN ('P -1'))")
except IndexError: codename = None queue = None settings = None code = test_and_get_code(codename, expected_code_type='quantumespresso.pw') max_seconds = 600 kpoints = KpointsData() kpoints_mesh = 4 kpoints.set_kpoints_mesh([kpoints_mesh, kpoints_mesh, kpoints_mesh]) from aiida.tools.dbimporters.plugins.cod import CodDbImporter from aiida.orm.data.cif import parse_formula codi = CodDbImporter() launched_calcs = {} ## SQL query, executed in the COD database: ## select file, formula ## from data ## where nel = 3 and a < 5 and b < 5 and c < 5 and ## alpha = 90 and beta = 90 and gamma = 90 ## order by file for entry in [ # 1001184, # 1001185, # 1001186, # 1001619,