Skip to content

Commit

Permalink
[WIP] Pretty printing (#60)
Browse files Browse the repository at this point in the history
Adds pretty printing for:
- PerturbativeQED model
- Compton process
- Coordinate systems, frames of reference, and phase space definition
- Particle stateful
- PhaseSpacePoint

Essentially, adding similar functionality to
QEDjl-project/QEDbase.jl#61 for the QEDprocesses
types.

I'm using the jldoctests to test, I'm not sure if it's really necessary
to test in a separate test as well. Putting single jldoctests for these
prints in every type definition would clutter the documentation a bit so
I've not done that. If we really want tests for each `show()` we should
probably do it in a test file.

Also, I'm not sure if there's a better way for the print functions than
alternating the `show` for objects and `print` for strings.
Interpolating doesn't work unless we also overload the `print`. (I
*think* it is print, the number of string output related functions in
Julia is confusing)
  • Loading branch information
AntonReinhard authored May 21, 2024
1 parent e84809c commit 0491353
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 11 deletions.
1 change: 1 addition & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
QEDbase = "10e22c08-3ccb-4172-bfcf-7d7aa3d04d93"
QEDprocesses = "46de9c38-1bb3-4547-a1ec-da24d767fdad"
7 changes: 5 additions & 2 deletions src/models/perturbative_qed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ fundamental_interaction_type(::PerturbativeQED) = :electromagnetic
"""
in_phase_space_dimension(proc::AbstractProcessDefinition, ::PerturbativeQED)
Return the number of degrees of freedom to determine the incoming phase space for processes in PerturbativeQED.
!!! note "Convention"
The current implementation only supports the case where two of the incoming particles collide head-on.
"""
function in_phase_space_dimension(proc::AbstractProcessDefinition, ::PerturbativeQED)
return 3 * number_incoming_particles(proc) - 4 - 1
Expand All @@ -21,3 +19,8 @@ end
function out_phase_space_dimension(proc::AbstractProcessDefinition, ::PerturbativeQED)
return 3 * number_outgoing_particles(proc) - 4
end

function Base.show(io::IO, ::PerturbativeQED)
print(io, "perturbative QED")
return nothing
end
13 changes: 13 additions & 0 deletions src/patch_QEDbase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
#
#############

# fix: https://github.com/QEDjl-project/QEDbase.jl/pull/61
Base.show(io::IO, ::Electron) = print(io, "electron")
Base.show(io::IO, ::Positron) = print(io, "positron")
Base.show(io::IO, ::Photon) = print(io, "photon")
Base.show(io::IO, ::Incoming) = print(io, "incoming")
Base.show(io::IO, ::Outgoing) = print(io, "outgoing")
Base.show(io::IO, ::PolX) = print(io, "x-polarized")
Base.show(io::IO, ::PolY) = print(io, "y-polarized")
Base.show(io::IO, ::AllPol) = print(io, "all polarizations")
Base.show(io::IO, ::SpinUp) = print(io, "spin up")
Base.show(io::IO, ::SpinDown) = print(io, "spin down")
Base.show(io::IO, ::AllSpin) = print(io, "all spins")

# fix: https://github.com/QEDjl-project/QEDbase.jl/pull/62
Broadcast.broadcastable(dir::Incoming) = Ref(dir)
Broadcast.broadcastable(dir::Outgoing) = Ref(dir)
Expand Down
107 changes: 104 additions & 3 deletions src/phase_spaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ abstract type AbstractPhasespaceDefinition end
Broadcast.broadcastable(ps_def::AbstractPhasespaceDefinition) = Ref(ps_def)

"""
PhasespaceDefinition(coord_sys::AbstractCoordinateSystem, frame::AbstractFrameOfReference)
Convenient type to dispatch on coordiante systems and frames of reference.
Expand All @@ -54,6 +53,29 @@ struct PhasespaceDefinition{CS<:AbstractCoordinateSystem,F<:AbstractFrameOfRefer
frame::F
end

function Base.show(io::IO, ::SphericalCoordinateSystem)
print(io, "spherical coordinates")
return nothing
end
function Base.show(io::IO, ::CenterOfMomentumFrame)
print(io, "center-of-momentum frame")
return nothing
end
function Base.show(io::IO, ::ElectronRestFrame)
print(io, "electron rest frame")
return nothing
end
function Base.show(io::IO, m::MIME"text/plain", ps_def::PhasespaceDefinition)
println(io, "PhasespaceDefinition")
println(io, " coordinate system: $(ps_def.coord_sys)")
println(io, " frame: $(ps_def.frame)")
return nothing
end
function Base.show(io::IO, ps_def::PhasespaceDefinition)
print(io, "$(ps_def.coord_sys) in $(ps_def.frame)")
return nothing
end

# abstract type for generic phase spaces
#
# Currently, elements can be either four-momenta, or real numbers,
Expand Down Expand Up @@ -117,11 +139,25 @@ Representation of a particle with a state. It has four fields:
- `dir::ParticleDirection`: The direction of the particle, `QEDbase.Incoming()` or `QEDbase.Outgoing()`.
- `species::AbstractParticleType`: The species of the particle, `QEDbase.Electron()`, `QEDbase.Positron()` etc.
- `mom::AbstractFourMomentum`: The momentum of the particle.
- `spin_or_pol::AbstractSpinOrPolarization`: The spin or polarization of the particle, `QEDbase.SpinUp()`, `QEDbase.PolX() etc. Can only use spins with fermions and polarizations with bosons.
- `spin_or_pol::AbstractSpinOrPolarization`: The spin or polarization of the particle, `QEDbase.SpinUp()`, `QEDbase.PolX() etc. Can only use spins with fermions and polarizations with bosons. `AllSpin` or `AllPol` by default.
Overloads for `QEDbase.is_fermion`, `QEDbase.is_boson`, `QEDbase.is_particle`, `QEDbase.is_anti_particle`, `QEDbase.is_incoming`, `QEDbase.is_outgoing`, `QEDbase.mass`, and `QEDbase.charge` are provided, delegating the call to the correct field and thus implementing the `QEDbase.AbstractParticle` interface.
The legality of the combination of `species` and `spin_or_pol` is checked on construction. If, for example, the construction of an `Electron()` with a polarization is attempted, an [`InvalidInputError`](@ref) is thrown.
```jldoctest
julia> using QEDbase; using QEDprocesses
julia> ParticleStateful(Incoming(), Electron(), SFourMomentum(1, 0, 0, 0))
ParticleStateful: incoming electron
spin: all spins
momentum: [1.0, 0.0, 0.0, 0.0]
julia> ParticleStateful(Outgoing(), Photon(), SFourMomentum(1, 0, 0, 0), PolX())
ParticleStateful: outgoing photon
polarization: x-polarized
momentum: [1.0, 0.0, 0.0, 0.0]
```
"""
struct ParticleStateful{ElType<:AbstractFourMomentum} <: AbstractParticle
dir::ParticleDirection
Expand Down Expand Up @@ -167,12 +203,57 @@ momentum(part::ParticleStateful) = part.mom
particle.spin_or_pol
@inline polarization(particle::ParticleStateful) = _polarization(particle.species, particle)

function Base.show(io::IO, particle::ParticleStateful)
print(
io, "$(particle.dir) $(particle.species) ($(particle.spin_or_pol)): $(particle.mom)"
)
return nothing
end

function Base.show(io::IO, m::MIME"text/plain", particle::ParticleStateful)
println(io, "ParticleStateful: $(particle.dir) $(particle.species)")
println(
io,
" $(particle.spin_or_pol isa AbstractSpin ? "spin" : "polarization"): $(particle.spin_or_pol)",
)
println(io, " momentum: $(particle.mom)")
return nothing
end

"""
PhaseSpacePoint
Representation of a point in the phase space of a process. Contains the process ([`AbstractProcessDefinition`](@ref)), the model ([`AbstractModelDefinition`](@ref)), the phase space definition ([`AbstractPhasespaceDefinition`]), and stateful incoming and outgoing particles ([`ParticleStateful`](@ref)).
The legality of the combination of the given process and the incoming and outgoing particles is checked on construction. If the numbers of particles mismatch, the types of particles mismatch (note that order is important), or incoming particles have an `Outgoing` direction, an error is thrown.
```jldoctest
julia> using QEDprocesses; using QEDbase
julia> PhaseSpacePoint(
Compton(),
PerturbativeQED(),
PhasespaceDefinition(SphericalCoordinateSystem(), ElectronRestFrame()),
[
ParticleStateful(Incoming(), Electron(), SFourMomentum(1, 0, 0, 0)),
ParticleStateful(Incoming(), Photon(), SFourMomentum(1, 0, 0, 0))
],
[
ParticleStateful(Outgoing(), Electron(), SFourMomentum(1, 0, 0, 0)),
ParticleStateful(Outgoing(), Photon(), SFourMomentum(1, 0, 0, 0))
]
)
PhaseSpacePoint:
process: one-photon Compton scattering
model: perturbative QED
phasespace definition: spherical coordinates in electron rest frame
incoming particles:
-> incoming electron (all spins): [1.0, 0.0, 0.0, 0.0]
-> incoming photon (all polarizations): [1.0, 0.0, 0.0, 0.0]
outgoing particles:
-> outgoing electron (all spins): [1.0, 0.0, 0.0, 0.0]
-> outgoing photon (all polarizations): [1.0, 0.0, 0.0, 0.0]
```
"""
struct PhaseSpacePoint{
PROC<:AbstractProcessDefinition,
Expand Down Expand Up @@ -269,7 +350,6 @@ function momentum(psp::PhaseSpacePoint, dir::ParticleDirection, n::Int)
end

"""
generate_phase_space(
proc::AbstractProcessDefinition,
model::AbstractModelDefinition,
Expand Down Expand Up @@ -307,3 +387,24 @@ function generate_phase_space(

return PhaseSpacePoint(proc, model, ps_def, in_parts, out_parts)
end

function Base.show(io::IO, psp::PhaseSpacePoint)
print(io, "PhaseSpacePoint of $(psp.proc)")
return nothing
end

function Base.show(io::IO, ::MIME"text/plain", psp::PhaseSpacePoint)
println(io, "PhaseSpacePoint:")
println(io, " process: $(psp.proc)")
println(io, " model: $(psp.model)")
println(io, " phasespace definition: $(psp.ps_def)")
println(io, " incoming particles:")
for p in psp.in_particles
println(io, " -> $(p)")
end
println(io, " outgoing particles:")
for p in psp.out_particles
println(io, " -> $(p)")
end
return nothing
end
15 changes: 12 additions & 3 deletions src/processes/one_photon_compton/process.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
"""
Compton(
in_spin [= AllSpin()]
in_pol [= AllPol()]
out_spin [= AllSpin()]
out_pol [= AllPol()]
)
)
"""
struct Compton{InElectronSpin,InPhotonPol,OutElectronSpin,OutPhotonPol} <:
AbstractProcessDefinition where {
Expand Down Expand Up @@ -59,3 +57,14 @@ end
function _spin_or_pol(process::Compton, ::Photon, ::Outgoing)
return process.out_pol
end

function Base.show(io::IO, ::Compton)
print(io, "one-photon Compton scattering")
return nothing
end
function Base.show(io::IO, ::MIME"text/plain", proc::Compton)
println(io, "one-photon Compton scattering")
println(io, " incoming: electron ($(proc.in_spin)), photon ($(proc.in_pol))")
println(io, " outgoing: electron ($(proc.out_spin)), photon ($(proc.out_pol))")
return nothing
end
49 changes: 46 additions & 3 deletions test/phase_spaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ TESTMODEL = TestImplementation.TestModel()
TESTPSDEF = TestImplementation.TestPhasespaceDef()

RNG = Random.MersenneTwister(727)
BUF = IOBuffer()

@testset "broadcast" begin
test_func(ps_def) = ps_def
Expand Down Expand Up @@ -40,7 +41,6 @@ end
@test charge(particle_stateful) == charge(species)

# accessors

@test particle_stateful.dir == dir
@test particle_direction(particle_stateful) == particle_stateful.dir
@test particle_stateful.species == species
Expand All @@ -54,6 +54,14 @@ end
@test polarization(particle_stateful) == spin_or_pol
@test_throws MethodError spin(particle_stateful)
end

# printing
print(BUF, particle_stateful)
@test String(take!(BUF)) == "$(dir) $(species) ($(spin_or_pol)): $(mom)"

show(BUF, MIME"text/plain"(), particle_stateful)
@test String(take!(BUF)) ==
"ParticleStateful: $(dir) $(species)\n $(spin_or_pol isa AbstractSpin ? "spin" : "polarization"): $(spin_or_pol)\n momentum: $(mom)\n"
else
if (VERSION >= v"1.8")
# julia versions before 1.8 did not have support for regex matching in @test_throws
Expand Down Expand Up @@ -94,6 +102,15 @@ end
process, model, phasespace_def, in_particles_valid, out_particles_valid
)

print(BUF, psp)
@test String(take!(BUF)) == "PhaseSpacePoint of $(process)"

show(BUF, MIME"text/plain"(), psp)
@test match(
r"PhaseSpacePoint:\n process: (.*)TestProcess(.*)\n model: (.*)TestModel(.*)\n phasespace definition: (.*)TestPhasespaceDef(.*)\n incoming particles:\n -> incoming electron \(all spins\): (.*)\n -> incoming photon \(all polarizations\): (.*)\n outgoing particles:\n -> outgoing electron \(all spins\): (.*)\n -> outgoing photon \(all polarizations\): (.*)\n",
String(take!(BUF)),
) isa RegexMatch

@testset "Accessor" begin
@test momentum(psp, Incoming(), 1) == in_el.mom
@test momentum(psp, Incoming(), 2) == in_ph.mom
Expand All @@ -117,11 +134,11 @@ end
process, model, phasespace_def, in_particles_valid, out_particles_invalid
)

@test_throws r"process given particle species \((.*)Electron\(\)\) does not match stateful particle species \((.*)Photon\(\)\)" PhaseSpacePoint(
@test_throws r"process given particle species \(electron\) does not match stateful particle species \(photon\)" PhaseSpacePoint(
process, model, phasespace_def, SVector(in_ph, in_el), out_particles_valid
)

@test_throws r"process given particle species \((.*)Electron\(\)\) does not match stateful particle species \((.*)Photon\(\)\)" PhaseSpacePoint(
@test_throws r"process given particle species \(electron\) does not match stateful particle species \(photon\)" PhaseSpacePoint(
process, model, phasespace_def, in_particles_valid, SVector(out_ph, out_el)
)
end
Expand Down Expand Up @@ -168,3 +185,29 @@ end
@test test_psp[Outgoing(), 2] == out_ph
end
end

@testset "Coordinate System" begin
@testset "Pretty printing" begin
print(BUF, SphericalCoordinateSystem())
@test String(take!(BUF)) == "spherical coordinates"
end
end
@testset "Reference Frame" begin
@testset "Pretty printing" begin
print(BUF, ElectronRestFrame())
@test String(take!(BUF)) == "electron rest frame"
print(BUF, CenterOfMomentumFrame())
@test String(take!(BUF)) == "center-of-momentum frame"
end
end

@testset "Phasespace Definition" for (coord_sys, frame) in Iterators.product(
[SphericalCoordinateSystem()], [ElectronRestFrame(), CenterOfMomentumFrame()]
)
ps_def = PhasespaceDefinition(coord_sys, frame)

@testset "Pretty printing" begin
print(BUF, ps_def)
@test String(take!(BUF)) == "$coord_sys in $frame"
end
end
9 changes: 9 additions & 0 deletions test/processes/one_photon_compton/perturbative.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ const OMEGAS = (1e-6 * rand(RNG), 1e-3 * rand(RNG), rand(RNG), 1e3 * rand(RNG))
const COS_THETAS = [-1.0, 2 * rand(RNG) - 1, 0.0, 1.0]
const PHIS = [0, 2 * pi, rand(RNG) * 2 * pi]

@testset "pretty-printing" begin
buf = IOBuffer()
print(buf, MODEL)
@test String(take!(buf)) == "perturbative QED"

show(buf, MIME"text/plain"(), MODEL)
@test String(take!(buf)) == "perturbative QED"
end

@testset "perturbative kinematics" begin
PROC = Compton()
@testset "momentum generation" begin
Expand Down
Loading

0 comments on commit 0491353

Please sign in to comment.