Пример #1
0
    def read_coords_occs(results, match):
        if results['in_input']:
            coordstr = 'sgcoords'
            occstr = 'sgoccupancies'
            seenstr = 'sgseen'
            idxstr = 'sgidx'
        elif results['in_output']:
            coordstr = 'coords'
            occstr = 'occupancies'
            seenstr = 'seen'
            idxstr = 'idx'
        else:
            return

        newcoord = (match.group(2), match.group(3), match.group(4))
        #newcoord = FracVector.create([match.group(2),match.group(3),match.group(4)]).limit_denominator(5000000).simplify()
        species = match.group(1).split("/")
        occups = match.group(6).split("/")

        for j in range(len(species)):        
            occup = {'atom': periodictable.atomic_number(species[j]), 'ratio': FracVector.create(occups[j]), }
    
            if newcoord in results[seenstr]:
                idx = results[seenstr][newcoord]
                #print("OLD",results[occstr],idx)
                results[occstr][idx].append(occup)
            else:
                results[seenstr][newcoord] = results[idxstr]
                results[coordstr].append(newcoord)
                results[occstr].append([occup])
                results[idxstr] += 1
Пример #2
0
def poscar_to_structure(f, included_decimals=''):
    cell, scale, volume, coords, coords_reduced, counts, occupations, comment = poscar_to_strs(
        f, included_decimals)

    frac_cell = FracVector.create(cell, simplify=True)
    counts = [int(x) for x in counts]

    if coords_reduced:
        frac_coords = cartesian_to_reduced(cell, coords)
    else:
        frac_coords = FracVector.create(coords, simplify=True)

    if volume is not None:
        volume = FracScalar.create(volume)

    if scale is not None:
        scale = FracScalar.create(scale)

    newoccupations = []
    for occupation in occupations:
        newoccupations.append(periodictable.atomic_number(occupation))

    struct = Structure.create(uc_basis=frac_cell,
                              uc_volume=volume,
                              uc_scale=scale,
                              uc_reduced_coords=frac_coords,
                              uc_counts=counts,
                              assignments=newoccupations,
                              tags={'comment': comment},
                              periodicity=0)

    return struct
Пример #3
0
    def create(cls,
               siteassignment=None,
               atom=None,
               weight=None,
               ratio=None,
               magnetic_moment=[None, None, None]):
        """
        Create a new siteassignment object
          site: integer for the site number that this atom is assigned to
          atomic number or symbol
        """
        #TODO: Convert assignments into strict internal representation
        if isinstance(siteassignment, Assignment):
            return siteassignment

        if isinstance(siteassignment, dict):
            if 'atom' in siteassignment:
                atom = siteassignment['atom']
            if 'weight' in siteassignment:
                weight = FracScalar.use(siteassignment['weight'])
            if 'ratio' in siteassignment:
                ratio = FracScalar.use(siteassignment['ratio'])
            if 'magnetic_moment' in siteassignment:
                magnetic_moment = siteassignment['magnetic_moment']
        elif siteassignment is not None:
            return cls(periodictable.atomic_number(siteassignment), None,
                       FracScalar.create(1), [None, None, None])

        if atom is None:
            raise Exception(
                "SiteAssignment needs at least an atom specification")

        atom = periodictable.atomic_number(atom)

        if magnetic_moment is None:
            magnetic_moment = [None, None, None]

        if ratio is None:
            ratio = FracScalar.create(1)

        return cls(atom, weight, ratio, magnetic_moment)
Пример #4
0
def generate_fake_potentials_try2(species):
    potentials = ""
    potentials += "epsilon\n"
    for s1 in species:
        ss1 = periodictable.atomic_symbol(s1)
        ns1 = periodictable.atomic_number(s1)
        #potentials += "%s core %.4f %.4f 0 0\n" % (ss1,sqrt(0.5*ns1),pow(0.75*ns1,3.0/2.0))
        #        potentials += "%s core %.4f %.4f 0 0\n" % (ss1,pow(ns1,0.9783276738),pow(ns1,1.124243243))
        potentials += "%s core %.4f %.4f 0 0\n" % (ss1, 0.1 * ns1, 0.1 * ns1)

    potentials += "lennard zero epsilon combine all\n"
    potentials += "0.0 12.0\n"

    return potentials
Пример #5
0
def generate_fake_potentials(species):
    potentials = ""
    potentials += "atomab\n"
    for s1 in species:
        ss1 = periodictable.atomic_symbol(s1)
        ns1 = periodictable.atomic_number(s1)
        potentials += "%s core %.4f %.4f 0 0\n" % (ss1, sqrt(
            0.5 * ns1), pow(0.75 * ns1, 3.0 / 2.0))
    #potentials = "lennard combine 12 6\n"
    potentials += "lennard 12 6 combine all\n"
    potentials += "0.0 20.0\n"
    #for s1 in species:
    #    ss1 = periodictable.atomic_symbol(s1)
    #    for s2 in species:
    #        ss2 = periodictable.atomic_symbol(s2)
    #        potentials += "%s core %s core %.4f %.4f\n" % (ss1, ss2,0.0,10.0)

    return potentials
Пример #6
0
 def coords(results, match):
     newcoord = httk.FracVector.create([match.group(5), match.group(6), match.group(7)])
     occup = {'atom': periodictable.atomic_number(match.group(2)), 'ratio': FracVector.create(match.group(8)), }
     if match.group(4) == 'alpha':
         wyckoff = '&'
     else:
         wyckoff = match.group(4)
     multiplicities = int(match.group(3))
     if newcoord in results['seen_coords']:
         idx = results['seen_coords'][newcoord]
         results['occups'][idx].append(occup)
     else:
         results['seen_coords'][newcoord] = results['idx']
         results['coords'].append(newcoord)
         results['occups'].append([occup])
         results['wyckoff'].append(wyckoff)
         results['multiplicities'].append(multiplicities)
         results['idx'] += 1
Пример #7
0
    def read_coords(results, match):
        sys.stdout.write("\n>>|")
        #for i in range(1,14):
        #    sys.stdout.write(match.group(i)+"|")
        species = periodictable.atomic_number(match.group(1))
        ratio = FracVector.create(re.sub(r'\([^)]*\)', '', match.group(11)))
        
        a1 = re.sub(r'\([^)]*\)', '', match.group(2))
        b1 = re.sub(r'\([^)]*\)', '', match.group(3))
        c1 = re.sub(r'\([^)]*\)', '', match.group(4))

        a = match.group(2).replace('(', '').replace(')', '')
        b = match.group(3).replace('(', '').replace(')', '')
        c = match.group(4).replace('(', '').replace(')', '')
        coord = FracVector.create([a1, b1, c1]).normalize()
        sys.stdout.write(str(species)+" "+str(coord.to_floats()))
        limcoord = FracVector.create([a1, b1, c1]).normalize()
        coordtuple = ((species, ratio.to_tuple()), limcoord.to_tuple())
        if coordtuple in seen_coords:
            return
        results['occupancies'].append((species, float(ratio)))
        results['coords'].append(coord)
        seen_coords.add(coordtuple)
Пример #8
0
 def read_coords(results, match):
     results['occupancies'].append(periodictable.atomic_number(match.group(1)))
     results['coords'].append([float(match.group(2)), float(match.group(3)), float(match.group(4))])
Пример #9
0
def uc_reduced_coordgroups_process_with_isotropy(coordgroup,
                                                 cell,
                                                 get_wyckoff=False):
    #print("GURK",struct.formula,len(struct.uc_reduced_coords))

    inputstr = httk.iface.isotropy_if.reduced_coordgroups_to_input(
        coordgroup, cell)
    out, err, completed = isotropy("./", [], inputstr)
    if completed == 0:
        cif = httk.iface.isotropy_if.out_to_cif(
            IoAdapterString(string=out),
            [atomic_symbol(x) for x in range(1,
                                             len(coordgroup) + 1)])
        #print("CIF",cif)
        newstruct = cif_to_struct(IoAdapterString(string=cif),
                                  backends=['cif2cell_reduce'])
        checkstruct = cif_to_struct(IoAdapterString(string=cif),
                                    backends=['cif2cell'])
        only_rc_struct = cif_to_struct(
            IoAdapterString(string=cif),
            backends=['cif_reader_that_can_only_read_isotropy_cif'])
        # This is an illeelegant hack
        newstruct.rc_sites.wyckoff_symbols = only_rc_struct.rc_sites.wyckoff_symbols
        # Cell basis can only be constructed from the cif approximately
        cell_mismatch = sum(
            sum((checkstruct.rc_cell.basis -
                 only_rc_struct.rc_cell.basis))).to_float()
        #print("CELL MISMATCH:",sum(sum((newstruct.cell.maxnorm_basis - only_rc_struct.cell.maxnorm_basis))).to_float())
        only_rc_struct._rc_cell = newstruct.rc_cell
        # Make sure the hexhash is recomputed
        only_rc_struct.rc_sites._hexhash = None
        #print("CHECK THIS:", newstruct.rc_sites.hexhash, only_rc_struct.rc_sites.hexhash)
        #print("CHECK THIS:", newstruct.cell.to_tuple(), only_rc_struct.cell.to_tuple())
        if cell_mismatch > 1e-6 or newstruct.rc_sites.hexhash != only_rc_struct.rc_sites.hexhash:
            print("Cell mismatch:", cell_mismatch)
            print("Structure hashes:", newstruct.rc_sites.hexhash,
                  only_rc_struct.rc_sites.hexhash)
            #print("Structures:", newstruct.rc_sites.to_tuple(), only_rc_struct.rc_sites.to_tuple())
            raise Exception(
                "isotropy_ext.struct_process_with_isotropy: internal error, structures that absolutely should be the same are not, sorry."
            )

        #order = [x.as_integer-1 for x in newstruct.assignments]
        #print("ORDER:",order)

        if get_wyckoff:
            return newstruct.rc_reduced_coordgroups, newstruct.rc_sites.wyckoff_symbols, [
                [atomic_number(x) for x in y]
                for y in newstruct.assigments.symbols_list()
            ]
        else:
            return newstruct.rc_reduced_coordgroups
    else:
        print("ISOTROPY STDERR:")
        #print(inputstr)
        print("========")
        #print(out)
        #print("========")
        print(err)
        print("========")

        raise Exception("isotropy_ext: isotropy did not complete.")
Пример #10
0
def cifdata_to_struct(cifdata, debug=False):
    if len(cifdata) > 1:
        raise Exception("httk.atomistic.atomisticio.structure_cif_io: cifdata to struct with more than one image in cifdata.")
    element = cifdata[0][1]

    if debug:
        import pprint
        pp = pprint.PrettyPrinter()
        debugout = dict(element)
        if 'symmetry_equiv_pos_as_xyz' in debugout:
            del debugout['symmetry_equiv_pos_as_xyz']
        if 'space_group_symop_operation_xyz' in debugout:
            del debugout['space_group_symop_operation_xyz']
        if 'space_group_symop_id' in debugout:
            del debugout['space_group_symop_id']
        pp.pprint(debugout)

    rc_lengths = FracVector.create([element['cell_length_a'], element['cell_length_b'], element['cell_length_c']])
    rc_cosangles = FracVector.create_cos([element['cell_angle_alpha'], element['cell_angle_beta'], element['cell_angle_gamma']],degrees=True)

    hall_symbol = None
    hm_symbol = None
    spacegroupnumber = None
    setting = None
    symops = None
    if 'symmetry_space_group_name_hall' in element:
        hall_symbol = element['symmetry_space_group_name_hall']
    if 'space_group_symop_operation_xyz' in element:
        symops = element['space_group_symop_operation_xyz']
    elif 'symmetry_equiv_pos_as_xyz' in element:
        symops = element['symmetry_equiv_pos_as_xyz']
    if 'symmetry_space_group_name_h-m' in element:
        hm_symbol = element['symmetry_space_group_name_h-m']
    if 'symmetry_Int_Tables_number' in element:
        spacegroupnumber = int(element['symmetry_Int_Tables_number'])
    # cif verb symmetry_cell_setting really is not defined as it would seems logical. Due to ensuing confusion, we better simply ignore it
    #if 'symmetry_cell_setting' in element:
    #    setting = element['symmetry_cell_setting']

    if hall_symbol is None and symops is None and hm_symbol is None and spacegroupnumber is None:
        raise Exception("No symmetry information given in cif file, impossible to interpret coordinate data!")

    spacegroup = Spacegroup.create(hall_symbol=hall_symbol, hm_symbol=hm_symbol, spacegroupnumber=spacegroupnumber, setting=setting, symops=symops)

    rc_occupancies = []
    rc_reduced_occupationscoords = []
    wyckoff_symbols = None
    multiplicities = None
    if 'atom_site_wyckoff_symbol' in element:
        wyckoff_symbols = element['atom_site_wyckoff_symbol']
    elif 'atom_site_wyckoff_label' in element:
        wyckoff_symbols = element['atom_site_wyckoff_label']

    if 'atom_site_symmetry_multiplicity' in element:
        multiplicities = [int(x) for x in element['atom_site_symmetry_multiplicity']]

    for atom in range(len(element['atom_site_label'])):
        if 'atom_site_occupancy' in element:
            ratio = element['atom_site_occupancy'][atom]
        else:
            ratio = 1
        symbol = str(re.match('[A-Z][a-z]?',element['atom_site_label'][atom]).group(0))

        occup = {'atom': periodictable.atomic_number(symbol), 'ratio': FracVector.create(ratio), }
        coord = [element['atom_site_fract_x'][atom], element['atom_site_fract_y'][atom], element['atom_site_fract_z'][atom]]

        rc_occupancies += [occup]
        rc_reduced_occupationscoords += [coord]

    #print("X",rc_lengths,rc_angles,rc_reduced_occupationscoords,rc_occupancies,spacegroup,setting,wyckoff_symbols,multiplicities)

    tags = {}
    if 'chemical_name_common' in element:
        if is_sequence(element['chemical_name_common']):
            tags['name'] = element['chemical_name_common'][0]
            tags['names'] = ",".join(element['chemical_name_common'])
        else:
            tags['name'] = element['chemical_name_common']
    elif 'chemical_name_systematic' in element:
        if is_sequence(element['chemical_name_systematic']):
            tags['name'] = element['chemical_name_systematic'][0]
            tags['names'] = ",".join(element['chemical_name_systematic'])
        else:
            tags['name'] = element['chemical_name_systematic']

    authorlist = None
    if 'publ_author_name' in element:
        authorlist = []
        authors = element['publ_author_name']
        if not basic.is_sequence(authors):
            authors = [authors]
        for author in authors:
            authorparts = author.partition(",")
            lastname = authorparts[0].strip()
            givennames = authorparts[2].strip()
            authorlist += [Author.create(lastname, givennames)]

    # I didn't find this in the spec, on the other hand, the publ_ space is "not specified", so, this seems
    # as a logical extension of the author list in case of a cif file that has been published in a book.
    # I see no harm in including it, at least.
    editorlist = None
    if 'publ_editor_name' in element:
        editorlist = []
        editors = element['publ_editor_name']
        if not basic.is_sequence(editors):
            editors = [editors]
        for editor in editors:
            editorparts = editor.partition(",")
            lastname = editorparts[0].strip()
            givennames = editorparts[2].strip()
            editorlist += [Author.create(lastname, givennames)]

    refs = None
    if 'journal_name_full' in element or 'journal_name_abbrev' in element:
        journal = None
        journal_page_first = None
        journal_page_last = None
        journal_volume = None
        journal_title = None
        journal_book_title = None
        journal_year = None
        journal_issue = None
        journal_publisher = None
        journal_publisher_city = None
        if 'journal_name_abbrev' in element:
            journal = element['journal_name_abbrev']
        if 'journal_name_full' in element:
            journal = element['journal_name_full']
        if 'journal_page_first' in element:
            journal_page_first = element['journal_page_first']
        if 'journal_page_last' in element:
            journal_page_last = element['journal_page_last']
        if 'journal_volume' in element:
            journal_volume = element['journal_volume']
        if 'journal_issue' in element:
            journal_issue = element['journal_issue']
        if 'journal_title' in element:
            journal_title = element['journal_title']
        if 'journal_book_title' in element:
            journal_book_title = element['journal_book_title']
        if 'journal_year' in element:
            journal_year = element['journal_year']
        if 'journal_publisher' in element:
            journal_publisher = element['journal_publisher']
        if 'journal_publisher_city' in element:
            journal_publisher_city = element['journal_publisher_city']
        if 'journal_book_publisher' in element:
            journal_publisher = element['journal_book_publisher']
        if 'journal_book_publisher_city' in element:
            journal_publisher_city = element['journal_book_publisher_city']

        refs = [Reference.create(authors=authorlist, editors=editorlist, journal=journal, journal_issue=journal_issue, journal_volume=journal_volume,
                                 page_first=journal_page_first, page_last=journal_page_last, title=journal_title, year=journal_year, book_publisher=journal_publisher,
                                 book_publisher_city=journal_publisher_city, book_title=journal_book_title)]

    # This is based on some assumptions... IF a journal_* type tree exists, then we assume this is a 'published' cif, and
    # in that case the only reference we want to keep is the one to the published work. Citations in the citation_* tree is going to be
    # all the citations from that paper, which we do not want, *unless* they mark citation_coordinate_linkage. However,
    # if no journal_* tree exists, then this is a 'generic' structure cif, where the citations should point to all publications of
    # this structure; and we don't want to assume 'citation_coordinate_linkage'
    add_all_citations = False
    if refs is None or len(refs) == 0:
        add_all_citations = True

    if 'citation_journal_full' in element or 'citation_journal_abbrev' in element or 'citation_book_title' in element:
        if refs is None:
            refs = []
        if 'citation_journal_full' in element:
            N = len(element['citation_journal_full'])
        elif 'citation_journal_abbrev' in element:
            N = len(element['citation_journal_abbrev'])
        elif 'citation_book_title' in element:
            N = len(element['citation_book_title'])
        for i in range(N):
            if not add_all_citations and ('citation_coordinate_linkage' not in element or (element['citation_coordinate_linkage'][i].lower() != 'yes' and element['citation_coordinate_linkage'][i].lower() != 'y')):
                continue
            journal = None
            journal_page_first = None
            journal_page_last = None
            journal_volume = None
            journal_title = None
            journal_book_title = None
            journal_issue = None
            journal_publisher = None
            journal_publisher_city = None
            if 'citation_journal_full' in element:
                journal = element['citation_journal_full'][i]
            if 'citation_journal_abbrev' in element:
                journal = element['citation_journal_abbrev'][i]
            if 'citation_page_first' in element:
                journal_page_first = element['citation_page_first'][i]
            if 'citation_page_last' in element:
                journal_page_last = element['citation_page_last'][i]
            if 'citation_journal_volume' in element:
                journal_volume = element['citation_journal_volume'][i]
            if 'citation_journal_issue' in element:
                journal_issue = element['citation_journal_issue'][i]
            if 'citation_title' in element:
                journal_title = element['citation_title'][i]
            if 'citation_book_title' in element:
                journal_book_title = element['citation_book_title'][i]
            if 'journal_year' in element:
                journal_year = element['journal_year'][i]
            if 'citation_book_publisher' in element:
                journal_publisher = element['citation_book_publisher'][i]
            if 'citation_book_publisher_city' in element:
                journal_publisher_city = element['citation_book_publisher_city'][i]

            refs += [Reference.create(authors=authorlist, editors=editorlist, journal=journal, journal_issue=journal_issue, journal_volume=journal_volume,
                     page_first=journal_page_first, page_last=journal_page_last, title=journal_title, year=journal_year, book_publisher=journal_publisher,
                     book_publisher_city=journal_publisher_city, book_title=journal_book_title)]

    struct = Structure.create(rc_lengths=rc_lengths,
                              rc_cosangles=rc_cosangles,
                              rc_reduced_occupationscoords=rc_reduced_occupationscoords,
                              rc_occupancies=rc_occupancies,
                              spacegroup=spacegroup, setting=setting,
                              periodicity=0,
                              wyckoff_symbols=wyckoff_symbols, multiplicities=multiplicities, tags=tags, refs=refs)

    return struct