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
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)
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)
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)
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