Example #1
0
 def test_angles_beam90_reacazi0(self):
     for azi in numpy.linspace(0, 2*pi, 100):
         proj = pytpc.Particle(4, 2, 2, polar=pi/2, azimuth=azi)
         ejec, recoil = rel.elastic_scatter(proj, self.target, pi/2, 0)
         self.assertAlmostEqual(ejec.azimuth, azi, places=3)
         self.assertAlmostEqual(recoil.azimuth, azi, places=3)
         self.assertAlmostEqual(abs(ejec.polar - recoil.polar), pi/2, places=2)
Example #2
0
 def test_azimuth(self):
     for azi in numpy.linspace(0, 2*pi, 20):
         ejec, recoil = rel.elastic_scatter(self.proj, self.target, self.cm_angle, azi)
         self.assertAlmostEqual(ejec.azimuth, azi)
         self.assertAlmostEqual(recoil.azimuth, constrain_angle(azi + pi))
Example #3
0
 def test_polar(self):
     for cm_angle in numpy.linspace(0.01, pi, 20, endpoint=False):
         ejec, recoil = rel.elastic_scatter(self.proj, self.target, cm_angle, self.azi)
         self.assertAlmostEqual(ejec.polar + recoil.polar, pi/2, delta=2.0)
Example #4
0
 def test_energy(self):
     ejec, recoil = rel.elastic_scatter(self.proj, self.target, self.cm_angle, self.azi)
     self.assertAlmostEqual(recoil.energy, 0, places=4)
     self.assertAlmostEqual(ejec.energy, self.proj.energy, places=4)
Example #5
0
 def test_energy_large_angle(self):
     ejec, recoil = rel.elastic_scatter(self.proj, self.target, pi-0.01, self.azi)
     self.assertAlmostEqual(ejec.energy, 0, places=3)
Example #6
0
 def test_energy_equal(self):
     ejec, recoil = rel.elastic_scatter(self.proj, self.target, pi/2, self.azi)
     self.assertAlmostEqual(recoil.energy, ejec.energy)
Example #7
0
def simulate_elastic_scattering_track(proj, target, gas, ef, bf, interact_energy, cm_angle, azimuth):
    """Simulate an elastic scattering event with the given particles and parameters.

    The projectile will be tracked in the detector until it has total energy equal to `interact_energy`. Then, an
    elastic scattering interaction will happen with the provided COM angle and final azimuthal angle.

    Parameters
    ----------
    proj : Particle
        The projectile. It must have non-zero energy.
    target : Particle
        The target. It must have zero energy (at least for now)
    gas : pytpc.gases.Gas or subclass
        The gas in the detector. If it's a subclass, make sure it is compatible with both the target and the
        projectile.
    ef : array-like
        The electric field, in SI units
    bf : array-like
        The magnetic field, in Tesla
    interact_energy : number
        The energy at which to stop tracking the projectile and perform the interaction
    cm_angle : number
        The center-of-momentum angle for the relativistic scattering calculation
    azimuth : number
        The final azimuthal angle of the ejectile particle

    Returns
    -------
    pandas.DataFrame
        The concatenated outputs of the `track` function for each particle

    Raises
    ------
    ValueError
        If the projectile has zero energy
    NotImplementedError
        If the target has nonzero energy. In the future, the code could be changed to allow a moving target particle,
        but it seems unnecessary for now.

    See Also
    --------
    pytpc.relativity.elastic_scatter

    """

    if proj.energy == 0:
        raise ValueError('Projectile must have energy > 0')
    if target.energy > 0.0:
        raise NotImplementedError('Target energy must be zero (for now at least)')

    # Track projectile until the collision
    proj_track = track(proj, gas, ef, bf, interact_energy)
    if not(0 <= proj.position[2] <= 1) or sqrt(proj.position[0]**2 + proj.position[1]**2) > 0.275:
        # The particle left the chamber before interacting
        return proj_track

    reaction_time = proj_track.time.max()

    ejec, recoil = rel.elastic_scatter(proj, target, cm_angle, azimuth)

    ejec_track = track(ejec, gas, ef, bf)
    ejec_track.time += reaction_time
    recoil_track = track(recoil, gas, ef, bf)
    recoil_track.time += reaction_time

    return pd.concat((proj_track, ejec_track, recoil_track), ignore_index=True)