laddu-physics 0.21.5

Amplitude analysis tools for Rust
Documentation
use crate::quantum::partial_waves::{infer_c_parity, infer_parity};

use super::RuleInput;
use crate::quantum::rules::{RawRuleOutcome, missing};

pub(super) fn parity(input: RuleInput<'_>) -> RawRuleOutcome {
    let Some(parent) = input.parent.parity else {
        return RawRuleOutcome::unknown(missing(&["parent.parity"]), "parent parity is unknown");
    };
    let mut absent = Vec::new();
    if input.daughters.0.parity.is_none() {
        absent.push("daughter_a.parity".to_string());
    }
    if input.daughters.1.parity.is_none() {
        absent.push("daughter_b.parity".to_string());
    }
    if !absent.is_empty() {
        return RawRuleOutcome::unknown(
            absent,
            "final-state parity cannot be inferred because one or both daughter parities are unknown",
        );
    }

    let final_parity =
        infer_parity(input.daughters, input.l).expect("daughter parities were checked above");
    if parent == final_parity {
        RawRuleOutcome::pass(format!(
            "parity is conserved for L = {} with final parity {:?}",
            input.l.value(),
            final_parity,
        ))
    } else {
        RawRuleOutcome::fail(format!(
            "parity is not conserved for L = {}: parent parity is {:?}, final parity is {:?}",
            input.l.value(),
            parent,
            final_parity,
        ))
    }
}

pub(super) fn isospin(input: RuleInput<'_>) -> RawRuleOutcome {
    let Some(parent) = input.parent.isospin else {
        return RawRuleOutcome::unknown(missing(&["parent.isospin"]), "parent isospin is unknown");
    };
    let Some(a) = input.daughters.0.isospin else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_a.isospin"]),
            "first daughter isospin is unknown",
        );
    };
    let Some(b) = input.daughters.1.isospin else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_b.isospin"]),
            "second daughter isospin is unknown",
        );
    };

    if parent.isospin().can_couple_to(a.isospin(), b.isospin()) {
        RawRuleOutcome::pass("daughter isospins can couple to parent isospin")
    } else {
        RawRuleOutcome::fail("daughter isospins cannot couple to parent isospin")
    }
}

pub(super) fn isospin_projection(input: RuleInput<'_>) -> RawRuleOutcome {
    let Some(parent) = input.parent.isospin else {
        return RawRuleOutcome::unknown(missing(&["parent.isospin"]), "parent isospin is unknown");
    };
    let Some(a) = input.daughters.0.isospin else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_a.isospin"]),
            "first daughter isospin is unknown",
        );
    };
    let Some(b) = input.daughters.1.isospin else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_b.isospin"]),
            "second daughter isospin is unknown",
        );
    };
    let Some(parent_projection) = parent.projection else {
        return RawRuleOutcome::unknown(
            missing(&["parent.isospin.projection"]),
            "parent isospin projection is unknown",
        );
    };
    let Some(a_projection) = a.projection else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_a.isospin.projection"]),
            "first daughter isospin projection is unknown",
        );
    };
    let Some(b_projection) = b.projection else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_b.isospin.projection"]),
            "second daughter isospin projection is unknown",
        );
    };

    if parent_projection.doubled() == a_projection.doubled() + b_projection.doubled() {
        RawRuleOutcome::pass("isospin projection is conserved")
    } else {
        RawRuleOutcome::fail("isospin projection is not conserved")
    }
}

pub(super) fn c_parity(input: RuleInput<'_>) -> RawRuleOutcome {
    let Some(parent) = input.parent.c_parity else {
        return RawRuleOutcome::unknown(
            missing(&["parent.c_parity"]),
            "parent C-parity is unknown or not applicable",
        );
    };
    let Some(final_parity) = infer_c_parity(input.daughters, input.l, input.s) else {
        return RawRuleOutcome::unknown(
            missing(&[
                "daughter_a.species",
                "daughter_a.antiparticle_species",
                "daughter_b.species",
                "daughter_b.antiparticle_species",
            ]),
            "final-state C-parity cannot be inferred; this check currently assumes a C-eigenstate particle-antiparticle combination",
        );
    };

    if parent == final_parity {
        RawRuleOutcome::pass(format!(
            "C-parity is conserved with inferred C_final = {:?}; assumes a C-eigenstate particle-antiparticle combination",
            final_parity,
        ))
    } else {
        RawRuleOutcome::fail(format!(
            "C-parity is not conserved: parent C = {:?}, inferred final C = {:?}; assumes a C-eigenstate particle-antiparticle combination",
            parent, final_parity,
        ))
    }
}

pub(super) fn g_parity(input: RuleInput<'_>) -> RawRuleOutcome {
    let Some(parent) = input.parent.g_parity else {
        return RawRuleOutcome::unknown(
            missing(&["parent.g_parity"]),
            "parent G-parity is unknown or not applicable",
        );
    };
    let Some(a) = input.daughters.0.g_parity else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_a.g_parity"]),
            "first daughter G-parity is unknown or not applicable",
        );
    };
    let Some(b) = input.daughters.1.g_parity else {
        return RawRuleOutcome::unknown(
            missing(&["daughter_b.g_parity"]),
            "second daughter G-parity is unknown or not applicable",
        );
    };
    let final_parity = a.value() * b.value();
    if parent.value() == final_parity {
        RawRuleOutcome::pass("G-parity product check passes")
    } else {
        RawRuleOutcome::fail(format!(
            "G-parity product check fails: parent G = {:?}, daughter product = {}",
            parent, final_parity,
        ))
    }
}