Esempio n. 1
0
    def _extract_charge(arg: str):
        """
        Receive a `str` representing an element, isotope, or ion.
        Return a `tuple` containing a `str` that should represent an
        element or isotope, and either an `int` representing the
        charge or `None` if no charge information is provided.  Raise
        an `~plasmapy.utils.InvalidParticleError` if charge information
        is inputted incorrectly.
        """

        invalid_charge_errmsg = (f"Invalid charge information in the particle string '{arg}'.")

        if arg.count(' ') == 1:  # Cases like 'H 1-' and 'Fe-56 1+'
            isotope_info, charge_info = arg.split(' ')

            sign_indicator_only_on_one_end = (
                charge_info.endswith(('-', '+')) ^
                charge_info.startswith(('-', '+')))

            just_one_sign_indicator = (
                (charge_info.count('-') == 1 and
                 charge_info.count('+') == 0) or
                (charge_info.count('-') == 0 and
                 charge_info.count('+') == 1))

            if not sign_indicator_only_on_one_end and just_one_sign_indicator:
                raise InvalidParticleError(invalid_charge_errmsg) from None

            charge_str = charge_info.strip('+-')

            try:
                if roman.is_roman_numeral(charge_info):
                    Z_from_arg = roman.from_roman(charge_info) - 1
                elif '-' in charge_info:
                    Z_from_arg = - int(charge_str)
                elif '+' in charge_info:
                    Z_from_arg = int(charge_str)
                else:
                    raise InvalidParticleError(invalid_charge_errmsg) from None
            except ValueError:
                raise InvalidParticleError(invalid_charge_errmsg) from None

        elif arg.endswith(('-', '+')):  # Cases like 'H-' and 'Pb-209+++'
            char = arg[-1]
            match = re.match(f"[{char}]*", arg[::-1])
            Z_from_arg = match.span()[1]
            isotope_info = arg[0:len(arg) - match.span()[1]]

            if char == '-':
                Z_from_arg = -Z_from_arg
            if isotope_info.endswith(('-', '+')):
                raise InvalidParticleError(invalid_charge_errmsg) from None
        else:
            isotope_info = arg
            Z_from_arg = None

        return isotope_info, Z_from_arg
Esempio n. 2
0
File: base.py Progetto: vlslv/fiasco
 def __init__(self, ion_name, hdf5_dbase_root=None, **kwargs):
     self._element, ion = ion_name.split()
     if '+' in ion:
         ion = f"{int(ion.strip('+')) + 1}"
     if roman.is_roman_numeral(ion.upper()):
         ion = roman.from_roman(ion.upper())
     self.ionization_stage = int(ion)
     self.charge_state = self.ionization_stage - 1
     if hdf5_dbase_root is None:
         self.hdf5_dbase_root = fiasco.defaults['hdf5_dbase_root']
     else:
         self.hdf5_dbase_root = hdf5_dbase_root
     check_database(self.hdf5_dbase_root, **kwargs)
     if self.ion_name not in fiasco.list_ions(self.hdf5_dbase_root,
                                              sort=False):
         raise MissingIonError(
             f'{self.ion_name} not found in {self.hdf5_dbase_root}')
Esempio n. 3
0
def extract_charge(arg: str):
    """
    Receive a `str` representing an element, isotope, or ion.
    Return a `tuple` containing a `str` that should represent an
    element or isotope, and either an `int` representing the
    charge or `None` if no charge information is provided.  Raise
    an `~plasmapy.particles.exceptions.InvalidParticleError` if charge information
    is inputted incorrectly.
    """

    invalid_charge_errmsg = (
        f"Invalid charge information in the particle string '{arg}'.")

    match = re.fullmatch(
        r"\s*(?P<isotope>\w+(-[0-9]+)*([+-]*)*)"
        r"(\s*(?P<charge>[+-]?[IVXLCDM0-9]+[+-]?)*)*\s*",
        arg,
    )

    if match is None:
        raise InvalidParticleError(invalid_charge_errmsg) from None

    isotope_info = match.groupdict()["isotope"]
    charge_info = match.groupdict()["charge"]
    Z_from_arg = None

    if charge_info is not None and isotope_info.endswith(("-", "+")):
        # charge info is defined on both the charge_info and isotope_into strings
        raise InvalidParticleError(invalid_charge_errmsg) from None
    elif charge_info is not None:  # Cases like 'H 1-' and 'Fe-56 1+'

        sign_indicator_only_on_one_end = charge_info.endswith(
            ("-", "+")) ^ charge_info.startswith(("-", "+"))

        just_one_sign_indicator = (charge_info.count("-") == 1
                                   and charge_info.count("+")
                                   == 0) or (charge_info.count("-") == 0
                                             and charge_info.count("+") == 1)

        if not sign_indicator_only_on_one_end and just_one_sign_indicator:
            raise InvalidParticleError(invalid_charge_errmsg) from None

        charge_str = charge_info.strip("+-")

        try:
            if roman.is_roman_numeral(charge_info):
                Z_from_arg = roman.from_roman(charge_info) - 1
            elif "-" in charge_info:
                Z_from_arg = -int(charge_str)
            elif "+" in charge_info:
                Z_from_arg = int(charge_str)
            else:
                raise InvalidParticleError(invalid_charge_errmsg) from None
        except ValueError:
            raise InvalidParticleError(invalid_charge_errmsg) from None

    elif isotope_info.endswith(("-", "+")):  # Cases like 'H-' and 'Pb-209+++'
        match = re.fullmatch(
            r"\s*(?P<isotope>\w+(-[0-9]+)?)(?P<charge>[-+]+)\s*",
            isotope_info,
        )
        isotope_info = match.groupdict()["isotope"]
        charge_info = match.groupdict()["charge"]

        if len(set(charge_info)) != 1:
            raise InvalidParticleError(invalid_charge_errmsg) from None

        Z_from_arg = len(charge_info)
        if charge_info[0] == "-":
            Z_from_arg = -Z_from_arg

    return isotope_info, Z_from_arg