Beispiel #1
0
def test_ionic_fraction_comparison_with_different_ions(ion1, ion2):
    """
    Test that a `TypeError` is raised when an `IonicLevel` object
    is compared to an `IonicLevel` object of a different ion.
    """
    fraction = 0.251

    ionic_fraction_1 = IonicLevel(ion=ion1, ionic_fraction=fraction)
    ionic_fraction_2 = IonicLevel(ion=ion2, ionic_fraction=fraction)

    assert ionic_fraction_1 != ionic_fraction_2
Beispiel #2
0
def test_ionic_fraction_invalid_particles(invalid_particle):
    """
    Test that `~plasmapy.particles.IonicLevel` raises the appropriate
    exception when passed a particle that isn't a neutral or ion.
    """
    with pytest.raises(ParticleError):
        IonicLevel(invalid_particle, ionic_fraction=0)
Beispiel #3
0
def test_ionic_level_invalid_inputs(invalid_fraction, expected_exception):
    """
    Test that IonicLevel raises exceptions when the ionic fraction
    is out of the interval [0,1] or otherwise invalid.
    """
    with pytest.raises(expected_exception):
        IonicLevel(ion="Fe 6+", ionic_fraction=invalid_fraction)
Beispiel #4
0
class TestPickling:
    """
    Test that different objects in `plasmapy.particles` can be pickled.
    """

    xfail = pytest.mark.xfail(reason="see issue #1011")

    @pytest.mark.parametrize(
        "instance",
        [
            CustomParticle(mass=1 * u.kg, charge=1 * u.C),
            DimensionlessParticle(mass=5, charge=5),
            pytest.param(Particle("p+"), marks=xfail),
            pytest.param(IonicLevel("p+", 0.1, 1e9 * u.m**-3), marks=xfail),
            pytest.param(IonizationState("H", [0.5, 0.5]), marks=xfail),
            pytest.param(IonizationStateCollection({"H": [0.5, 0.5]}),
                         marks=xfail),
        ],
    )
    def test_pickling(self, instance, tmp_path):
        """
        Test that different objects contained within `plasmapy.particles`
        can be pickled and unpickled.
        """
        filename = tmp_path / "pickled_particles.p"
        with open(filename, "wb") as pickle_file:
            pickle.dump(instance, pickle_file)

        with open(filename, "rb") as pickle_file:
            loaded_particle = pickle.load(pickle_file)

        assert str(instance) == str(loaded_particle)
def test_ionic_fraction_attributes(ion, ionic_fraction, number_density):

    instance = IonicLevel(ion=ion,
                          ionic_fraction=ionic_fraction,
                          number_density=number_density)

    # Prepare to check for the default values when they are not set

    if ionic_fraction is None:
        ionic_fraction = np.nan
    if number_density is None:
        number_density = np.nan * u.m**-3

    assert Particle(ion) == Particle(instance.ionic_symbol)
    assert u.isclose(instance.ionic_fraction, ionic_fraction, equal_nan=True)
    assert u.isclose(instance.number_density, number_density, equal_nan=True)
Beispiel #6
0
def test_ionic_level_attributes(ion, ionic_fraction, number_density):

    instance = IonicLevel(ion=ion,
                          ionic_fraction=ionic_fraction,
                          number_density=number_density)

    # Prepare to check for the default values when they are not set

    if ionic_fraction is None:
        ionic_fraction = np.nan
    if number_density is None:
        number_density = np.nan * u.m**-3

    assert Particle(ion) == Particle(instance.ionic_symbol)
    assert u.isclose(instance.ionic_fraction, ionic_fraction, equal_nan=True)
    assert u.isclose(instance.number_density, number_density, equal_nan=True)
    assert instance.charge_number == charge_number(ion)

    # TODO: remove when IonicLevel.integer_charge is removed
    with pytest.warns(PlasmaPyFutureWarning):
        integer_charge = instance.integer_charge
    assert integer_charge == charge_number(ion)
    def __getitem__(self, *values) -> Union[IonizationState, IonicLevel]:

        errmsg = f"Invalid indexing for IonizationStateCollection instance: {values[0]}"

        one_input = not isinstance(values[0], tuple)
        two_inputs = len(values[0]) == 2

        if not one_input and not two_inputs:
            raise IndexError(errmsg)

        try:
            arg1 = values[0] if one_input else values[0][0]
            int_charge = None if one_input else values[0][1]
            particle = arg1 if arg1 in self.base_particles else particle_symbol(arg1)

            if int_charge is None:
                return IonizationState(
                    particle=particle,
                    ionic_fractions=self.ionic_fractions[particle],
                    T_e=self._pars["T_e"],
                    n_elem=np.sum(self.number_densities[particle]),
                    tol=self.tol,
                )
            else:
                if not isinstance(int_charge, Integral):
                    raise TypeError(
                        f"{int_charge} is not a valid charge for {particle}."
                    )
                elif not 0 <= int_charge <= atomic_number(particle):
                    raise ChargeError(
                        f"{int_charge} is not a valid charge for {particle}."
                    )
                return IonicLevel(
                    ion=particle_symbol(particle, Z=int_charge),
                    ionic_fraction=self.ionic_fractions[particle][int_charge],
                    number_density=self.number_densities[particle][int_charge],
                )
        except Exception as exc:
            raise IndexError(errmsg) from exc