#![allow(clippy::missing_errors_doc)]
pub mod amplitude;
pub mod angular;
pub mod cross_section;
pub mod data;
pub mod error;
pub mod expr;
#[cfg(feature = "fit")]
pub mod fit;
#[cfg(feature = "generation")]
pub mod generation;
pub mod histogram;
#[cfg(feature = "likelihood")]
pub mod likelihood;
pub mod math;
pub mod model;
pub mod particle;
pub mod quantum;
pub mod query;
pub mod runtime;
pub mod topology;
pub use laddu_fit::ganesh::python::ganesh;
#[macro_export]
macro_rules! laddu_python_module {
($name:ident, $backend:expr $(, $initializer:item)?) => {
#[pyo3::pymodule(gil_used = false)]
#[doc = "laddu's native Python analysis API."]
pub mod $name {
use pyo3::prelude::*;
#[pymodule_export]
use $crate::python::ganesh;
#[pymodule_export]
use $crate::python::amplitude::{
amplitudes, blatt_weisskopf_barriers, breit_wigner, f_vector, k_matrix, kopf_pi1,
kopf_rho, p_vector, relativistic_breit_wigner,
relativistic_breit_wigner_custom,
};
#[pymodule_export]
use $crate::python::angular::{
PyVec3 as Vec3, PyVec4 as Vec4, PyWignerD as WignerD, clebsch_gordan
};
#[pymodule_export]
use $crate::python::cross_section::{
PyAxis as Axis, PyBinnedEstimate as BinnedEstimate,
PyCrossSection as CrossSection,
PyDifferentialCrossSection as DifferentialCrossSection, PyEnsemble as Ensemble,
PyEstimate as Estimate,
};
#[pymodule_export]
use $crate::python::data::{
PyBinDataset as BinnedDataset, PyDataset as Dataset,
PyParquetSink as ParquetSink, PyParquetSource as ParquetSource,
PyRootSink as RootSink, PyRootSource as RootSource, read_parquet, read_root,
};
#[pymodule_export]
use $crate::python::error::LadduError;
#[pymodule_export]
use $crate::python::expr::{
PyExpr as Expr, acos, atan2, cis, complex, dot, matmul, matrix, matvec, parameter,
polar_complex, scalar, solve, vector,
};
#[pymodule_export]
use $crate::python::generation::{
PyGenerationReport as GenerationReport, PyGenerator as Generator,
PyInitialMomentum as InitialMomentum, PyMassProposal as MassProposal,
PyVertexProposal as VertexProposal,
};
#[pymodule_export]
use $crate::python::histogram::PyHistogram as Histogram;
#[pymodule_export]
use $crate::python::likelihood::{
PyCrossSectionIntegrals as CrossSectionIntegrals,
PyExtendedNll as ExtendedNLL, PyLassoPenalty as LassoPenalty,
PyLikelihood as Likelihood, PyLikelihoodProjection as LikelihoodProjection,
PyNll as NLL, PyRidgePenalty as RidgePenalty,
};
#[pymodule_export]
use $crate::python::math::{
PyBarrierKind as BarrierKind, PySheet as Sheet, blatt_weisskopf,
blatt_weisskopf_custom, chew_mandelstam, q, rho, spherical_harmonic,
};
#[pymodule_export]
use $crate::python::model::PyModel as Model;
#[pymodule_export]
use $crate::python::particle::{PyParticle as Particle, particles};
#[pymodule_export]
use $crate::python::quantum::{
PyAllowedPartialWave as AllowedPartialWave, PyIsospin as Isospin, PyJ as J,
PyL as L, PyM as M, PyMandelstamChannel as MandelstamChannel,
PyPartialWave as PartialWave, PyParity as Parity, PyRuleCheck as RuleCheck,
PyRuleReport as RuleReport, PyRuleSet as RuleSet, PyS as S,
PySelectionRules as SelectionRules, PyStatistics as Statistics,
};
#[pymodule_export]
use $crate::python::query::{PyBin as Bin, PyPredicate as Predicate};
#[pymodule_export]
use $crate::python::runtime::{
PyExecution as Execution, PyMemoryBudget as MemoryBudget,
PyMemoryPlan as MemoryPlan, PyMemoryResource as MemoryResource,
PyMemoryState as MemoryState, capabilities, gpu
};
#[pymodule_export]
use $crate::python::topology::{
PyChannel as Channel, PyEdge as Edge, PyVertex as Vertex,
PyVertexFrame as VertexFrame,
};
#[pyfunction]
fn backend() -> &'static str {
$backend
}
$($initializer)?
}
};
}
laddu_python_module!(
api,
if cfg!(feature = "mpi") {
"mpi"
} else {
"local"
}
);
#[cfg(test)]
mod tests {
use pyo3::prelude::*;
#[test]
fn python_module_exports_the_analysis_spine() {
Python::initialize();
Python::attach(|py| {
let module = pyo3::wrap_pymodule!(super::api)(py);
for name in [
"Expr",
"Particle",
"Channel",
"VertexFrame",
"Vec3",
"Vec4",
"J",
"L",
"S",
"M",
"Parity",
"Dataset",
"Axis",
"Ensemble",
"Estimate",
"CrossSection",
"BinnedEstimate",
"DifferentialCrossSection",
"Execution",
"Model",
"Likelihood",
"CrossSectionIntegrals",
"LikelihoodProjection",
"Generator",
"ganesh",
"clebsch_gordan",
"WignerD",
] {
assert!(
module.getattr(py, name).is_ok(),
"missing Python export {name}"
);
}
assert!(module.getattr(py, "particles").is_ok());
assert!(module.getattr(py, "gpu").is_ok());
assert!(module.getattr(py, "ganesh").is_ok());
let cross_sections = module.getattr(py, "CrossSectionIntegrals").unwrap();
for method in [
"accepted_integral",
"generated_integral",
"acceptance",
"full_accepted_integral",
"acceptance_corrected_yield",
"cross_section",
] {
assert!(
cross_sections.getattr(py, method).is_ok(),
"missing CrossSectionIntegrals.{method}"
);
}
let projection = module.getattr(py, "LikelihoodProjection").unwrap();
for method in [
"accepted_integral",
"generated_integral",
"acceptance",
"full_accepted_integral",
"acceptance_corrected_yield",
"cross_section",
"intensities",
"weights",
] {
assert!(
projection.getattr(py, method).is_ok(),
"missing LikelihoodProjection.{method}"
);
}
let cross_section = module.getattr(py, "CrossSection").unwrap();
for method in [
"total",
"acceptance",
"corrected_yield",
"differential",
"combine",
] {
assert!(
cross_section.getattr(py, method).is_ok(),
"missing CrossSection.{method}"
);
}
let ensemble = module.getattr(py, "Ensemble").unwrap();
for method in ["from_arrays", "from_mcmc"] {
assert!(
ensemble.getattr(py, method).is_ok(),
"missing Ensemble.{method}"
);
}
});
}
}