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
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
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)
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
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
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
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)
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))])
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.")
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