Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coincided atoms handling #43

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion matinfio/cif/cif.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ namespace $ {
atom.overlays.label = atom.label
if( !atom.symbol ) atom.symbol = atom.label.replace( /[0-9]/g, '' )
}
if( !( $optimade_cifplayer_matinfio_chemical_elements.JmolColors as any )[ atom.symbol ]
if( ! $optimade_cifplayer_matinfio_chemical_elements.JmolColors[ atom.symbol ]
&& atom.symbol
&& atom.symbol.length > 1
) {
Expand Down
23 changes: 8 additions & 15 deletions matinfio/matinfio.web.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
namespace $ {

export const $optimade_cifplayer_matinfio_chemical_elements = {
export const $optimade_cifplayer_matinfio_chemical_elements: {
JmolColors: Record< string, string >,
AseRadii: Record< string, number >,
} = {
JmolColors: { "D": "#FFFFC0", "H": "#FFFFFF", "He": "#D9FFFF", "Li": "#CC80FF", "Be": "#C2FF00", "B": "#FFB5B5", "C": "#909090", "N": "#3050F8", "O": "#FF0D0D", "F": "#90E050", "Ne": "#B3E3F5", "Na": "#AB5CF2", "Mg": "#8AFF00", "Al": "#BFA6A6", "Si": "#F0C8A0", "P": "#FF8000", "S": "#FFFF30", "Cl": "#1FF01F", "Ar": "#80D1E3", "K": "#8F40D4", "Ca": "#3DFF00", "Sc": "#E6E6E6", "Ti": "#BFC2C7", "V": "#A6A6AB", "Cr": "#8A99C7", "Mn": "#9C7AC7", "Fe": "#E06633", "Co": "#F090A0", "Ni": "#50D050", "Cu": "#C88033", "Zn": "#7D80B0", "Ga": "#C28F8F", "Ge": "#668F8F", "As": "#BD80E3", "Se": "#FFA100", "Br": "#A62929", "Kr": "#5CB8D1", "Rb": "#702EB0", "Sr": "#00FF00", "Y": "#94FFFF", "Zr": "#94E0E0", "Nb": "#73C2C9", "Mo": "#54B5B5", "Tc": "#3B9E9E", "Ru": "#248F8F", "Rh": "#0A7D8C", "Pd": "#006985", "Ag": "#C0C0C0", "Cd": "#FFD98F", "In": "#A67573", "Sn": "#668080", "Sb": "#9E63B5", "Te": "#D47A00", "I": "#940094", "Xe": "#429EB0", "Cs": "#57178F", "Ba": "#00C900", "La": "#70D4FF", "Ce": "#FFFFC7", "Pr": "#D9FFC7", "Nd": "#C7FFC7", "Pm": "#A3FFC7", "Sm": "#8FFFC7", "Eu": "#61FFC7", "Gd": "#45FFC7", "Tb": "#30FFC7", "Dy": "#1FFFC7", "Ho": "#00FF9C", "Er": "#00E675", "Tm": "#00D452", "Yb": "#00BF38", "Lu": "#00AB24", "Hf": "#4DC2FF", "Ta": "#4DA6FF", "W": "#2194D6", "Re": "#267DAB", "Os": "#266696", "Ir": "#175487", "Pt": "#D0D0E0", "Au": "#FFD123", "Hg": "#B8B8D0", "Tl": "#A6544D", "Pb": "#575961", "Bi": "#9E4FB5", "Po": "#AB5C00", "At": "#754F45", "Rn": "#428296", "Fr": "#420066", "Ra": "#007D00", "Ac": "#70ABFA", "Th": "#00BAFF", "Pa": "#00A1FF", "U": "#008FFF", "Np": "#0080FF", "Pu": "#006BFF", "Am": "#545CF2", "Cm": "#785CE3", "Bk": "#8A4FE3", "Cf": "#A136D4", "Es": "#B31FD4", "Fm": "#B31FBA", "Md": "#B30DA6", "No": "#BD0D87", "Lr": "#C70066", "Rf": "#CC0059", "Db": "#D1004F", "Sg": "#D90045", "Bh": "#E00038", "Hs": "#E6002E", "Mt": "#EB0026" },

// NB starting from Bk the radii data are incorrect
Expand Down Expand Up @@ -30,7 +33,7 @@ namespace $ {
x: number,
y: number,
z: number,
},
} | null,
x: number,
y: number,
z: number,
Expand Down Expand Up @@ -60,19 +63,7 @@ namespace $ {
symlabel?: string,
},
overlayed: Record< string, string >,
atoms: {
fract: {
x: number,
y: number,
z: number,
} | null,
x: number,
y: number,
z: number,
c: string, //color
r: number, //radius
overlays: Record< string, string | number >,
}[],
atoms: $optimade_cifplayer_matinfio_internal_obj_atom[]
sg_name: string,
ng_name: number,
info: string,
Expand All @@ -82,6 +73,8 @@ namespace $ {

export class $optimade_cifplayer_matinfio extends $mol_object2 {

static pos_overlap_limit = 0.1

static log = this.$.$optimade_cifplayer_matinfio_log

/** Guessing what to do */
Expand Down
146 changes: 97 additions & 49 deletions matinfio/player/player.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,63 +37,98 @@ namespace $ {
mpds_data: crystal.mpds_data,
mpds_demo: crystal.mpds_demo
}
const pos2els: any = {}
const hashes: any = {}

const groups: { fpos: number[] | null, cpos: number[], atoms: $optimade_cifplayer_matinfio_internal_obj_atom[] }[] = []

// make atoms unique, i.e. remove collisions;
for( let i = 0; i < crystal.atoms.length; i++ ) {
const pos = [ crystal.atoms[ i ].x, crystal.atoms[ i ].y, crystal.atoms[ i ].z ]
const hash = pos.map( function( item ) { return item.toFixed( 2 ) } ).join( ',' )
// make atoms unique, i.e. remove collisions;
// makes special sense for partial occupancies
if( hashes.hasOwnProperty( hash ) ) {
var update = ""
for( let oprop in render.atoms[ hashes[ hash ] ].overlays ) {
const atom = crystal.atoms[ i ]

const pos = [ atom.x, atom.y, atom.z ]

// CIF has fractional positions
// OPTIMADE has cartesian positions
// POSCAR may have either of two
const fpos: number[] | null = crystal.cartesian
? cell_matrix ? math.divide( pos, cell_matrix ).map( fract_cord_norm ) : null
: pos.map( fract_cord_norm )

const cpos: number[] = fpos ? math.multiply( fpos, cell_matrix ) : pos

if( groups.some( group => {
if( is_overlap( cpos, group.cpos, $optimade_cifplayer_matinfio.pos_overlap_limit ) ) {

const AseRadii = $optimade_cifplayer_matinfio_chemical_elements.AseRadii[ atom.symbol ]
const pos = group.atoms.findIndex( atom2 => {
return AseRadii > $optimade_cifplayer_matinfio_chemical_elements.AseRadii[ atom2.symbol ]
} )

if( pos == -1 ) group.atoms.push( atom )
else group.atoms.splice( pos, 0, atom )

return true

}
} ) ) {
continue
}

groups.push( { fpos, cpos, atoms: [ atom ] } )
}

for( let i = 0; i < groups.length; i++ ) {

const { fpos, cpos, atoms } = groups[i]

const overlays: Record< string, string | number > = {
"S": atoms[0].symbol,
"N": i + 1,
}
for( let oprop in atoms[0].overlays ) {
overlays[ oprop ] = atoms[0].overlays[ oprop ]
}

atoms.slice(1).forEach( atom => {
for( let oprop in overlays ) {

if( oprop == 'S' ) {
if( pos2els[ hash ].indexOf( crystal.atoms[ i ].symbol ) == -1 ) {
update = " " + crystal.atoms[ i ].symbol
pos2els[ hash ].push( crystal.atoms[ i ].symbol )
if( atoms.every( a => a.symbol != atom.symbol ) ) {
overlays[ oprop ] += ' ' + atom.symbol
}

} else if( oprop == 'N' ) {
overlays[ oprop ] += ', ' + ( i + 1 )

} else if( oprop == '_atom_site_occupancy' ) {
overlays[ oprop ] += '+' + atom.overlays[ oprop ]

} else {
overlays[ oprop ] += ' ' + atom.overlays[ oprop ]
}
else if( oprop == 'N' )
update = ", " + ( i + 1 )
else if( oprop == '_atom_site_occupancy' )
update = "+" + crystal.atoms[ i ].overlays[ oprop ]
else
update = " " + crystal.atoms[ i ].overlays[ oprop ]

render.atoms[ hashes[ hash ] ].overlays[ oprop ] += update
}
} else {
const color = ($optimade_cifplayer_matinfio_chemical_elements.JmolColors as any)[ crystal.atoms[ i ].symbol ] || '#FFFF00'
const radius = ($optimade_cifplayer_matinfio_chemical_elements.AseRadii as any)[ crystal.atoms[ i ].symbol ] || 0.66

const overlays: Record< string, string | number > = {
"S": crystal.atoms[ i ].symbol,
"N": i + 1,
}
for( let oprop in crystal.atoms[ i ].overlays ) {
overlays[ oprop ] = crystal.atoms[ i ].overlays[ oprop ]

}
} )

// CIF has fractional positions
// OPTIMADE has cartesian positions
// POSCAR may have either of two
const cpos = crystal.cartesian ? pos : math.multiply( pos, cell_matrix )
const fpos = !crystal.cartesian ? pos : cell_matrix ? math.divide( pos, cell_matrix ) : null
const fract = fpos ? { 'x': fpos[ 0 ], 'y': fpos[ 1 ], 'z': fpos[ 2 ] } : null

render.atoms.push( {
'fract': fract,
'x': cpos[ 0 ],
'y': cpos[ 1 ],
'z': cpos[ 2 ],
'c': color,
'r': radius,
'overlays': overlays
} )
hashes[ hash ] = render.atoms.length - 1
pos2els[ hash ] = [ crystal.atoms[ i ].symbol ]
const color = $optimade_cifplayer_matinfio_chemical_elements.JmolColors[ atoms[0].symbol ] || '#FFFF00'
const radius = $optimade_cifplayer_matinfio_chemical_elements.AseRadii[ atoms[0].symbol ] || 0.66
const atom_result = {
fract: fpos ? {
x: fpos[ 0 ],
y: fpos[ 1 ],
z: fpos[ 2 ],
} : null,
x: cpos[ 0 ],
y: cpos[ 1 ],
z: cpos[ 2 ],
c: color,
r: radius,
overlays,
symbol: atoms[0].symbol,
label: atoms[0].label,
}

render.atoms.push( atom_result )

}

for( let oprop in crystal.atoms.at(-1)!.overlays ) {
Expand All @@ -102,5 +137,18 @@ namespace $ {

return render
}


function fract_cord_norm( cord: number ){
const res = cord % 1
return res > 0 ? res : res + 1
}

function is_overlap( pos1: number[], pos2: number[], threshold: number ) {
for( let i = 0; i < 3; i++ ) {
if ( pos1[i] < pos2[i] - threshold || pos1[i] > pos2[i] + threshold ) return false
}
return true
}

}
11 changes: 5 additions & 6 deletions matinfio/spacegroup/spacegroup.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ namespace $ {
const spans = symmetry.split( ',' )

const fract = {
x: fract_cord_norm( calc_symmetry_span( spans[ 0 ], atom.fract ) ),
y: fract_cord_norm( calc_symmetry_span( spans[ 1 ], atom.fract ) ),
z: fract_cord_norm( calc_symmetry_span( spans[ 2 ], atom.fract ) ),
x: fract_cord_norm( calc_symmetry_span( spans[ 0 ], atom.fract! ) ),
y: fract_cord_norm( calc_symmetry_span( spans[ 1 ], atom.fract! ) ),
z: fract_cord_norm( calc_symmetry_span( spans[ 2 ], atom.fract! ) ),
}

const [ x, y, z ] = math.multiply( [ fract.x, fract.y, fract.z ], cell )
Expand Down Expand Up @@ -96,9 +96,8 @@ namespace $ {
}

function fract_cord_norm( cord: number ){
let res = cord % 1
if( res < 0 ) res = res + 1
return res
const res = cord % 1
return res > 0 ? res : res + 1
}

}
2 changes: 1 addition & 1 deletion player/player.view.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ namespace $.$$ {
for (const name of next_symmetries) {

const atoms = this.symmetry_atoms( name )!
if( is_overlap( data, atoms, 0.01 ) ) {
if( is_overlap( data, atoms, $optimade_cifplayer_matinfio.pos_overlap_limit ) ) {
return
}
}
Expand Down
Loading