Beispiel #1
0
def get_cell_v_for_t(elements, t0=250, t1=350):
    """
    Extracts the cell volumes within the certain temperature

    Args:
        elements: (list) chemical elements to retrieve, the first is metal
        t0, t1: (numeric) temperature boundaries, K

    Returns: dict of volumes per phase
    """
    phases_volumes = {}

    for item in mpds_api.get_data(dict(elements='-'.join(elements), classes=supported_arities[len(elements)]), fields={
    'P': [
        lambda: 'P',
        'sample.material.phase_id',
        lambda: None,
        'sample.measurement[0].condition[0].name',
        'sample.measurement[0].condition[0].units',
        'sample.measurement[0].condition[0].scalar',
        'sample.material.entry'
    ],
    'S':[
        lambda: 'S',
        'phase_id',
        'v',
        lambda: 'Temperature',
        lambda: 'K',
        'condition', # four values
        'entry',
        'occs_noneq',
        'cell_abc',
        'sg_n',
        'basis_noneq',
        'els_noneq'
    ]}):
        if not item or not item[1] or item[3] != 'Temperature' or item[4] != 'K':
            # Other entry type, or no phase assigned, or irrelevant condition given
            continue

        if item[0] == 'P':
            # P-entry, TODO: consider temperature
            if item[5] and (item[5] < t0 or item[5] > t1):
                print('Phase %s, P: OUT OF BOUNDS TEMPERATURE: %s K (%s)' % (item[1], item[5], item[6]))

        else:
            # S-entry
            if item[5] and item[5][0] and (item[5][0] < t0 or item[5][0] > t1):
                print('Phase %s, S: OUT OF BOUNDS TEMPERATURE: %s K (%s)' % (item[1], item[5][0], item[6]))
                continue

            ase_obj = MPDSDataRetrieval.compile_crystal(item, 'ase')
            if not ase_obj:
                continue
            n_metal_atoms = len([p for p in ase_obj if p.symbol == elements[0]])
            phases_volumes.setdefault(item[1], []).append(det(ase_obj.cell) / n_metal_atoms)

    return phases_volumes
Beispiel #2
0
    def get_geometry(self):
        """ Getting geometry from MPDS database
        """
        key = os.getenv('MPDS_KEY')
        client = MPDSDataRetrieval(api_key=key, verbose=False)
        query_dict = self.inputs.mpds_query.get_dict()

        # Add direct structures submitting support: FIXME
        assert query_dict or self.inputs.struct_in
        if not query_dict:
            return self.inputs.struct_in

        # insert props: atomic structure to query. Might check if it's already set to smth
        query_dict['props'] = 'atomic structure'
        try:
            answer = client.get_data(
                query_dict,
                fields={'S': [
                    'cell_abc',
                    'sg_n',
                    'basis_noneq',
                    'els_noneq'
                ]}
            )
        except APIError as ex:
            if ex.code == 429:
                self.logger.warning("Too many parallel MPDS requests, chilling")
                time.sleep(random.choice([2 * 2**m for m in range(5)]))
                return self.get_geometry()
            else: raise

        structs = [client.compile_crystal(line, flavor='ase') for line in answer]
        structs = list(filter(None, structs))
        if not structs:
            raise APIError('No crystal structures returned')
        minimal_struct = min([len(s) for s in structs])

        # get structures with minimal number of atoms and find the one with median cell vectors
        cells = np.array([s.get_cell().reshape(9) for s in structs if len(s) == minimal_struct])
        median_cell = np.median(cells, axis=0)
        median_idx = int(np.argmin(np.sum((cells - median_cell) ** 2, axis=1) ** 0.5))
        return get_data_class('structure')(ase=structs[median_idx])
Beispiel #3
0
                        lengths.append(dist)
    return lengths


client = MPDSDataRetrieval()

answer = client.get_data({
    "elements": "U-O",
    "props": "atomic structure"
},
                         fields={
                             'S': [
                                 'phase_id', 'entry', 'chemical_formula',
                                 'cell_abc', 'sg_n', 'basis_noneq', 'els_noneq'
                             ]
                         })

lengths = []

for item in answer:
    crystal = MPDSDataRetrieval.compile_crystal(item, 'ase')
    if not crystal: continue
    lengths.extend(calculate_lengths(crystal, 'U', 'O'))

dfrm = pd.DataFrame(sorted(lengths), columns=['length'])
dfrm['occurrence'] = dfrm.groupby('length')['length'].transform('count')
dfrm.drop_duplicates('length', inplace=True)

export = MPDSExport.save_plot(dfrm, ['length', 'occurrence'], 'bar')
print(export)