<commit_before>"""Tools for handling ion mutation."""

import itertools
import json
import os
import re
from operator import itemgetter
from typing import Callable, Optional, Tuple

import numpy as np
import pandas as pd
import pymatgen.analysis.structure_prediction as pymatgen_sp
from .utilities import parse_spec
from .structure import SmactStructure


class CationMutator:
    """Handles cation mutation of SmactStructures based on substitution probability.
    
    Based on the algorithm presented in:
        <NAME>., <NAME>., <NAME>., <NAME>., and <NAME>. (2011)
        Data Mined Ionic Substitutions for the Discovery of New Compounds.
        Inorganic Chemistry, 50(2), 656-663.
        `doi:10.1021/ic102031h <https://pubs.acs.org/doi/10.1021/ic102031h>`_
    
    """

    def __init__(
      self,
      lambda_json: Optional[str] = None,
      alpha: Optional[Callable[[str, str], float]] = (lambda s1, s2: -5.0),
    ):
        """Assign attributes and get lambda table."""
        if lambda_json is not None:
            with open(lambda_json, 'r') as f:
                lambda_dat = json.load(f)
        else:
            # Get pymatgen lambda table
            py_sp_dir = os.path.dirname(pymatgen_sp.__file__)
            pymatgen_lambda = os.path.join(py_sp_dir, "data", "lambda.json")
            with open(pymatgen_lambda, 'r') as f:
                lambda_dat = json.load(f)
            # Get rid of 'D1+' values
            # NOTE The author doesn't know why they exist
            # in the pymatgen lambda table, but they appear
            # obsolete
            lambda_dat = [x for x in lambda_dat if 'D1+' not in x]
<commit_msg>Clarified 'D1+' removal comment<commit_after>"""Tools for handling ion mutation."""

import itertools
import json
import os
import re
from operator import itemgetter
from typing import Callable, Optional, Tuple

import numpy as np
import pandas as pd
import pymatgen.analysis.structure_prediction as pymatgen_sp
from .utilities import parse_spec
from .structure import SmactStructure


class CationMutator:
    """Handles cation mutation of SmactStructures based on substitution probability.
    
    Based on the algorithm presented in:
        <NAME>., <NAME>., <NAME>., <NAME>., and <NAME>. (2011)
        Data Mined Ionic Substitutions for the Discovery of New Compounds.
        Inorganic Chemistry, 50(2), 656-663.
        `doi:10.1021/ic102031h <https://pubs.acs.org/doi/10.1021/ic102031h>`_
    
    """

    def __init__(
      self,
      lambda_json: Optional[str] = None,
      alpha: Optional[Callable[[str, str], float]] = (lambda s1, s2: -5.0),
    ):
        """Assign attributes and get lambda table."""
        if lambda_json is not None:
            with open(lambda_json, 'r') as f:
                lambda_dat = json.load(f)
        else:
            # Get pymatgen lambda table
            py_sp_dir = os.path.dirname(pymatgen_sp.__file__)
            pymatgen_lambda = os.path.join(py_sp_dir, "data", "lambda.json")
            with open(pymatgen_lambda, 'r') as f:
                lambda_dat = json.load(f)

            # Get rid of 'D1+' values to reflect pymatgen
            # implementation
            lambda_dat = [x for x in lambda_dat if 'D1+' not in x]

{'fraction_non_alphanumeric': 0.0971322849213691, 'fraction_numerical': 0.02682701202590194, 'mean_word_length': 2.533769063180828, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1674057', 'n_tokens_mistral': 1059, 'n_tokens_neox': 984, 'n_words': 322}