Exemplo n.º 1
0
 def test_eq():
     particle = Particle(
         name="MyParticle",
         pid=123,
         mass=1.2,
         spin=1,
         charge=0,
         isospin=Spin(1, 0),
     )
     assert particle != Particle(
         "MyParticle", pid=123, mass=1.5, width=0.2, spin=1)
     same_particle = deepcopy(particle)
     assert particle is not same_particle
     assert particle == same_particle
     assert hash(particle) == hash(same_particle)
     different_labels = Particle(
         name="Different name, same QNs",
         pid=753,
         mass=1.2,
         spin=1,
         charge=0,
         isospin=Spin(1, 0),
     )
     assert particle == different_labels
     assert hash(particle) == hash(different_labels)
     assert particle.name != different_labels.name
     assert particle.pid != different_labels.pid
Exemplo n.º 2
0
 def test_exceptions():
     with pytest.raises(FrozenInstanceError):
         test_state = Particle(
             "MyParticle",
             123,
             mass=1.2,
             width=0.1,
             spin=1,
             charge=0,
             isospin=Spin(1, 0),
         )
         test_state.charge = 1  # type: ignore
     with pytest.raises(ValueError):
         Particle(
             name="Fails Gell-Mann–Nishijima formula",
             pid=666,
             mass=0.0,
             spin=1,
             charge=0,
             parity=Parity(-1),
             c_parity=Parity(-1),
             g_parity=Parity(-1),
             isospin=Spin(0.0, 0.0),
             charmness=1,
         )
Exemplo n.º 3
0
 def test_hash():
     spin1 = Spin(0.0, 0.0)
     spin2 = Spin(1.5, -0.5)
     assert {spin2, spin1, deepcopy(spin1),
             deepcopy(spin2)} == {
                 spin1,
                 spin2,
             }
Exemplo n.º 4
0
class TestGellmannNishijima:
    @staticmethod
    @pytest.mark.parametrize(
        "state",
        [
            Particle(
                "p1",
                1,
                spin=0.0,
                mass=1,
                charge=1,
                isospin=Spin(1.0, 0.0),
                strangeness=2,
            ),
            Particle(
                "p1",
                1,
                spin=1.0,
                mass=1,
                charge=1,
                isospin=Spin(1.5, 0.5),
                charmness=1,
            ),
            Particle(
                "p1",
                1,
                spin=0.5,
                mass=1,
                charge=1.5,  # type: ignore
                isospin=Spin(1.0, 1.0),
                baryon_number=1,
            ),
        ],
    )
    def test_computations(state: Particle):
        assert GellmannNishijima.compute_charge(state) == state.charge
        assert (GellmannNishijima.compute_isospin_projection(
            charge=state.charge,
            baryon_number=state.baryon_number,
            strangeness=state.strangeness,
            charmness=state.charmness,
            bottomness=state.bottomness,
            topness=state.topness,
        ) == state.isospin.projection  # type: ignore
                )

    @staticmethod
    def test_isospin_none():
        state = Particle("p1", 1, mass=1, spin=0.0, charge=1, isospin=None)
        assert GellmannNishijima.compute_charge(state) is None
Exemplo n.º 5
0
class TestSpin:
    @staticmethod
    def test_init_and_eq():
        isospin = Spin(1.5, -0.5)
        assert isospin == 1.5
        assert float(isospin) == 1.5
        assert isospin.magnitude == 1.5
        assert isospin.projection == -0.5

    @staticmethod
    def test_hash():
        spin1 = Spin(0.0, 0.0)
        spin2 = Spin(1.5, -0.5)
        assert {spin2, spin1, deepcopy(spin1),
                deepcopy(spin2)} == {
                    spin1,
                    spin2,
                }

    @staticmethod
    def test_neg():
        isospin = Spin(1.5, -0.5)
        flipped_spin = -isospin
        assert flipped_spin.magnitude == isospin.magnitude
        assert flipped_spin.projection == -isospin.projection

    @pytest.mark.parametrize("spin", [Spin(2.5, -0.5), Spin(1, 0)])
    def test_repr(self, spin):
        from_repr = eval(repr(spin))  # pylint: disable=eval-used
        assert from_repr == spin

    @pytest.mark.parametrize(
        "magnitude, projection",
        [(0.3, 0.3), (1.0, 0.5), (0.5, 0.0), (-0.5, 0.5)],
    )
    def test_exceptions(self, magnitude, projection):
        with pytest.raises(ValueError):
            print(Spin(magnitude, projection))
Exemplo n.º 6
0
def test_particle():
    state = Particle(
        "MyParticle",
        pid=123,
        mass=2.5,
        width=0.3,
        spin=1.5,
        isospin=Spin(1.0, -1.0),
        charge=-1,
    )
    converted_dict = io._xml.object_to_dict(state)
    quantum_numbers = converted_dict["QuantumNumber"]
    spin_dict = quantum_numbers[0]
    charge_dict = quantum_numbers[1]
    assert spin_dict["Value"] == 1.5
    assert charge_dict["Value"] == -1
Exemplo n.º 7
0
def build_spin(definition: Union[dict, float, int, str]) -> Spin:
    def check_missing_projection(magnitude: float) -> None:
        if magnitude != 0.0:
            raise ValueError(
                "Can only have a spin without projection if magnitude = 0")

    if isinstance(definition, (float, int)):
        magnitude = float(definition)
        check_missing_projection(magnitude)
        projection = 0.0
    elif not isinstance(definition, dict):
        raise ValueError(f"Cannot create Spin from definition {definition}")
    else:
        magnitude = float(definition["Value"])
        if "Projection" not in definition:
            check_missing_projection(magnitude)
        projection = definition.get("Projection", 0.0)
    return Spin(magnitude, projection)
Exemplo n.º 8
0
def __create_two_body_decay_spin_data(
    in_spin: Optional[Spin] = None,
    out_spin1: Optional[Spin] = None,
    out_spin2: Optional[Spin] = None,
    angular_momentum: Optional[Spin] = None,
    coupled_spin: Optional[Spin] = None,
) -> _SpinRuleInputType:
    spin_zero = Spin(0, 0)
    if in_spin is None:
        in_spin = spin_zero
    if out_spin1 is None:
        out_spin1 = spin_zero
    if out_spin2 is None:
        out_spin2 = spin_zero
    if angular_momentum is None:
        angular_momentum = spin_zero
    if coupled_spin is None:
        coupled_spin = spin_zero
    return (
        [
            SpinEdgeInput(
                EdgeQuantumNumbers.spin_magnitude(in_spin.magnitude),
                EdgeQuantumNumbers.spin_projection(in_spin.projection),
            )
        ],
        [
            SpinEdgeInput(
                EdgeQuantumNumbers.spin_magnitude(out_spin1.magnitude),
                EdgeQuantumNumbers.spin_projection(out_spin1.projection),
            ),
            SpinEdgeInput(
                EdgeQuantumNumbers.spin_magnitude(out_spin2.magnitude),
                EdgeQuantumNumbers.spin_projection(out_spin2.projection),
            ),
        ],
        SpinNodeInput(
            NodeQuantumNumbers.l_magnitude(angular_momentum.magnitude),
            NodeQuantumNumbers.l_projection(angular_momentum.projection),
            NodeQuantumNumbers.s_magnitude(coupled_spin.magnitude),
            NodeQuantumNumbers.s_projection(coupled_spin.projection),
        ),
    )
Exemplo n.º 9
0
 def test_exceptions(self, magnitude, projection):
     with pytest.raises(ValueError):
         print(Spin(magnitude, projection))
Exemplo n.º 10
0
def build_spin(definition: dict) -> Spin:
    magnitude = definition["Value"]
    projection = definition.get("Projection", 0.0)
    return Spin(magnitude, projection)
Exemplo n.º 11
0
            ),
        ],
        SpinNodeInput(
            NodeQuantumNumbers.l_magnitude(angular_momentum.magnitude),
            NodeQuantumNumbers.l_projection(angular_momentum.projection),
            NodeQuantumNumbers.s_magnitude(coupled_spin.magnitude),
            NodeQuantumNumbers.s_projection(coupled_spin.projection),
        ),
    )


@pytest.mark.parametrize(
    "rule_input, expected",
    [(
        __create_two_body_decay_spin_data(
            angular_momentum=Spin(ang_mom_mag, 0)),
        expected,
    ) for ang_mom_mag, expected in [
        (0, True),
        (1, False),
        (2, False),
        (3, False),
    ]] + [(
        __create_two_body_decay_spin_data(in_spin=Spin(spin_mag, 0),
                                          angular_momentum=Spin(spin_mag, 0)),
        expected,
    ) for spin_mag, expected in zip([0, 1, 2], [True] * 3)] + [(
        __create_two_body_decay_spin_data(
            in_spin=Spin(spin_mag, 0),
            out_spin1=Spin(1, -1),
            out_spin2=Spin(1, 1),
Exemplo n.º 12
0
 def test_init_and_eq():
     isospin = Spin(1.5, -0.5)
     assert isospin == 1.5
     assert float(isospin) == 1.5
     assert isospin.magnitude == 1.5
     assert isospin.projection == -0.5
Exemplo n.º 13
0
def __create_isospin(pdg_particle: PdgDatabase) -> Optional[Spin]:
    if pdg_particle.I is None:
        return None
    magnitude = pdg_particle.I
    projection = __compute_isospin_projection(pdg_particle)
    return Spin(magnitude, projection)
Exemplo n.º 14
0
    def wrapper(  # pylint: disable=too-many-locals
            self: Any, graph: StateTransitionGraph[ParticleWithSpin],
            node_id: int) -> DecayNode:
        amplitude = decay_generate_function(self, graph, node_id)
        if isinstance(amplitude, HelicityDecay):
            helicity_decay = amplitude
        else:
            raise TypeError(
                f"Can only decorate with return value {HelicityDecay.__name__}"
            )

        node_props = graph.get_node_props(node_id)
        ang_mom = __get_angular_momentum(node_props)
        if ang_mom.projection != 0.0:
            raise ValueError(f"Projection of L is non-zero!: {ang_mom}")

        spin = __get_coupled_spin(node_props)
        if not isinstance(spin, Spin):
            raise ValueError(
                f"{spin.__class__.__name__} is not of type {Spin.__name__}")

        in_edge_ids = graph.get_edge_ids_ingoing_to_node(node_id)

        parent_spin = Spin(
            graph.get_edge_props(in_edge_ids[0])[0].spin,
            graph.get_edge_props(in_edge_ids[0])[1],
        )

        daughter_spins: List[Spin] = []

        for out_edge_id in graph.get_edge_ids_outgoing_from_node(node_id):
            daughter_spin = Spin(
                graph.get_edge_props(out_edge_id)[0].spin,
                graph.get_edge_props(out_edge_id)[1],
            )
            if daughter_spin is not None and isinstance(daughter_spin, Spin):
                daughter_spins.append(daughter_spin)

        decay_particle_lambda = (daughter_spins[0].projection -
                                 daughter_spins[1].projection)

        cg_ls = ClebschGordan(
            j_1=ang_mom.magnitude,
            m_1=ang_mom.projection,
            j_2=spin.magnitude,
            m_2=decay_particle_lambda,
            J=parent_spin.magnitude,
            M=decay_particle_lambda,
        )
        cg_ss = ClebschGordan(
            j_1=daughter_spins[0].magnitude,
            m_1=daughter_spins[0].projection,
            j_2=daughter_spins[1].magnitude,
            m_2=-daughter_spins[1].projection,
            J=spin.magnitude,
            M=decay_particle_lambda,
        )

        return CanonicalDecay(
            decaying_particle=helicity_decay.decaying_particle,
            decay_products=helicity_decay.decay_products,
            recoil_system=helicity_decay.recoil_system,
            l_s=cg_ls,
            s2s3=cg_ss,
        )
Exemplo n.º 15
0
def __get_coupled_spin(node_props: InteractionProperties) -> Spin:
    s_mag = node_props.s_magnitude
    s_proj = node_props.s_projection
    if s_mag is None or s_proj is None:
        raise TypeError("Coupled spin S not defined!")
    return Spin(s_mag, s_proj)
Exemplo n.º 16
0
def __get_angular_momentum(node_props: InteractionProperties) -> Spin:
    l_mag = node_props.l_magnitude
    l_proj = node_props.l_projection
    if l_mag is None or l_proj is None:
        raise TypeError("Angular momentum L not defined!")
    return Spin(l_mag, l_proj)
Exemplo n.º 17
0
    isospin_conservation,
    spin_conservation,
)

from .test_spin import __create_two_body_decay_spin_data

_SpinRuleInputType = Tuple[List[SpinEdgeInput], List[SpinEdgeInput],
                           SpinNodeInput]


@pytest.mark.parametrize(
    "rule_input, expected",
    [
        (
            __create_two_body_decay_spin_data(
                Spin(1, 0),
                Spin(1, 0),
                Spin(1, 0),
                Spin(1, 0),
                Spin(0, 0),
            ),
            True,
        ),
        (
            __create_two_body_decay_spin_data(
                Spin(1, 0),
                Spin(1, 0),
                Spin(1, 0),
                Spin(1, 0),
                Spin(1, 0),
            ),
Exemplo n.º 18
0
 def test_neg():
     isospin = Spin(1.5, -0.5)
     flipped_spin = -isospin
     assert flipped_spin.magnitude == isospin.magnitude
     assert flipped_spin.projection == -isospin.projection