Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
init_species (str): The species within the structure
to mutate.
final_species (str): The species to replace the
initial species with.
Returns:
A :class:`.~SmactStructure`, with the species
mutated.
"""
struct_buff = deepcopy(structure)
init_spec_tup = parse_spec(init_species)
struct_spec_tups = list(map(itemgetter(0, 1), struct_buff.species))
spec_loc = struct_spec_tups.index(init_spec_tup)
final_spec_tup = parse_spec(final_species)
# Replace species tuple
struct_buff.species[spec_loc] = (*final_spec_tup, struct_buff.species[spec_loc][2])
# Check for charge neutrality
if sum(x[1] * x[2] for x in struct_buff.species) != 0:
raise ValueError("New structure is not charge neutral.")
# Sort species again
struct_buff.species.sort(key=itemgetter(1), reverse=True)
struct_buff.species.sort(key=itemgetter(0))
# Replace sites
struct_buff.sites[final_species] = struct_buff.sites.pop(init_species)
# And sort
species_strs = struct_buff._format_style("{ele}{charge}{sign}").split(" ")
Based on the difference in Shannon radii, the probability is
assumed to be:
.. math::
p = 1 - k \Delta r^2.
Args:
s1: The species being substituted.
s2: The species substituting.
Returns:
The probability of substitution.
"""
spec1 = parse_spec(s1)
spec2 = parse_spec(s2)
try:
ele1_rows = self.shannon_data.loc[spec1[0]]
ele2_rows = self.shannon_data.loc[spec2[0]]
except KeyError as e:
raise KeyError(f"Element not in Shannon radius data file: {e}")
spec1_rows = ele1_rows.loc[ele1_rows["charge"] == spec1[1]]
spec2_rows = ele2_rows.loc[ele2_rows["charge"] == spec2[1]]
# Get mean so we don't need coordination information
mean_spec1_r = spec1_rows["ionic_radius"].mean()
mean_spec2_r = spec2_rows["ionic_radius"].mean()
# Hooke's law-style probability
return 1 - self.k * (mean_spec1_r - mean_spec2_r)**2
Creates a deepcopy of the supplied structure,
such that the original instance is not modified.
Args:
init_species (str): The species within the structure
to mutate.
final_species (str): The species to replace the
initial species with.
Returns:
A :class:`.~SmactStructure`, with the species
mutated.
"""
struct_buff = deepcopy(structure)
init_spec_tup = parse_spec(init_species)
struct_spec_tups = list(map(itemgetter(0, 1), struct_buff.species))
spec_loc = struct_spec_tups.index(init_spec_tup)
final_spec_tup = parse_spec(final_species)
# Replace species tuple
struct_buff.species[spec_loc] = (*final_spec_tup, struct_buff.species[spec_loc][2])
# Check for charge neutrality
if sum(x[1] * x[2] for x in struct_buff.species) != 0:
raise ValueError("New structure is not charge neutral.")
# Sort species again
struct_buff.species.sort(key=itemgetter(1), reverse=True)
struct_buff.species.sort(key=itemgetter(0))
Based on the difference in Shannon radii, the probability is
assumed to be:
.. math::
p = 1 - k \Delta r^2.
Args:
s1: The species being substituted.
s2: The species substituting.
Returns:
The probability of substitution.
"""
spec1 = parse_spec(s1)
spec2 = parse_spec(s2)
try:
ele1_rows = self.shannon_data.loc[spec1[0]]
ele2_rows = self.shannon_data.loc[spec2[0]]
except KeyError as e:
raise KeyError(f"Element not in Shannon radius data file: {e}")
spec1_rows = ele1_rows.loc[ele1_rows["charge"] == spec1[1]]
spec2_rows = ele2_rows.loc[ele2_rows["charge"] == spec2[1]]
# Get mean so we don't need coordination information
mean_spec1_r = spec1_rows["ionic_radius"].mean()
mean_spec2_r = spec2_rows["ionic_radius"].mean()
# Hooke's law-style probability
structure: A :class:`SmactStructure` instance from which to generate compounds.
thresh (float): The probability threshold; discard all substitutions that have
a probability to generate a naturally-occuring compound less than this.
Yields:
Tuples of (:class:`SmactStructure`, probability).
"""
for specie in structure.get_spec_strs():
cond_probs = self.cond_sub_probs(specie)
likely_probs = cond_probs.loc[cond_probs > thresh]
for new_spec, prob in likely_probs.items():
if any([
new_spec == specie,
parse_spec(specie)[1] != parse_spec(new_spec)[1], ]):
continue
yield (self._mutate_structure(structure, specie, new_spec), prob)
# print("Testing parent")
# Filter out any structures with identical species
if parent.has_species(diff_spec):
continue
# Ensure parent has as many species as target
if len(parent.species) != len(species):
continue
## Determine probability
# Get species to be substituted
(alt_spec, ) = (
set(parent.get_spec_strs()) - set(map(unparse_spec, species)) - {diff_spec_str}
)
if parse_spec(alt_spec)[1] != diff_spec[1]:
# Different charge
continue
try:
p = diff_sub_probs.loc[alt_spec]
except:
# Not in the Series
continue
if p > thresh:
try:
mutated = self.cm._mutate_structure(parent, alt_spec, diff_spec_str)
except ValueError:
# Poorly decorated
continue
yield (