Tracking_Apollonius.jl Documentation
Introduction
From an original idea of Wilfrid Dasilva : study track Finding using Apollonius 2D (3D) and compressed sensing method The description of this method is descibed here: GPU-accelerated Interval Arithmetic to solve the Apollonius Problem applied to a Stereo Drift Chamber.
Divide And Conqueer algorithm (Used by this version)

- For each iteration there are two grids (also named accumulator):
One for solution with pz>0 and one for pz<0 (𝛌=pz/pt) The grid with maximum of votes gives the sign of pz
- For the two last iterations the Apollonius function returns ± 1 or ± 2 and the information for each hit is stored in the accumulator.The sign is for a solution with left(-) or right(+) drift
1 for the solution found with first turn 2 for the second turn
For an ideal event the two votes 1 for turn1 and 2 for turn2 are in the same cells. Meaning differences between the two helix turns produce some inefficiencies.
The Apollonius results (Xc, Yc, R, Z0) of the helix are given by the cells with the maximum of votes at the third iteration.
Example
A GitLab project using Tracking_Apollonius can be found here
Types
Tracking_Apollonius.AbstractTrackHits — TypeAbstractTrackHitsSupertype for CDC hits events which can be used by Apollonius. getdrifts(hits::AbstractTrackHits), numberofhits(hits::AbstractTrackHits) and wireproporties functions has to be implemented for all child types of it.
Tracking_Apollonius.Accumulator — TypeAccumulator{T, I} <: AbstractAccumulator where {T<:AbstractFloat, I<:Signed}(
grid::ApolloniusGrid{T}
votes::Vector{I}
pivot::Vector{T}
λpositif::Bool
hitsfound::Vector{Bool}
vcellsfoundperhit::Vector{Vector{Int8}})The accumulator to store results of Apollonius functions.
grid: a vector of IntervalBox used as input of the Apollonius functions.votes: a vote is equal to one when the return of Apollonius functions is not equal to 0. the sum for all hits is stored for each IntervalBox.pivot: a parameter used by Apollonius functionsλpositifis true when lambda=1, false for lambda=-1. lambda is used as input of Apollonius functionshitsfound: each element corresponds to a hit. its value is false if no vote found for this given hitvcellsfoundperhit: for each hit found gives a vector of results in all IntervalBoxes
Tracking_Apollonius.WireProperty — TypeWireProperty{T} where {T<:AbstractFloat}(
vstart::Vector{T}
vend::Vector{T}
tanStereoAngle::T
phisLine::T)Proporty of a wire used by Apollonius
vstart: x,y,z of the wire in the projection plane define byzprojvend: ending x,y,z of the wiretanStereoAngle: tangent of the stereo anglephisLine: phi of the wire in the projection plane.
Tracking_Apollonius.CDChitsICEDUST — TypeCDChitsICEDUST{T<:AbstractFloat} <: AbstractTrackHits(
xstarts::Vector{T}
ystarts::Vector{T}
zstarts::Vector{T}
xends::Vector{T}
yends::Vector{T}
zends::Vector{T}
drifts::Vector{T})A hit is defied by the drift distance to a wire position. Each element of the Vectors corresponds to one hit (number of hits = vector length)
xstarts: starting x position of the wiresystarts: starting y position of the wireszstarts: starting z position of the wiresxends: ending x position of the wiresyends: ending y position of the wireszends: ending z position of the wiresdrifts: drift distance of hit from the wires
Tracking_Apollonius.ApolloniusEvent — TypeApolloniusEvent <: AbstractApolloniusEvent
eventnumber::Int
accumulators::Tuple{Accumulator, Accumulator}An instance of ApolloniusEvent is the results returned by runApollonius for each iteration.
eventnumber: the event numberaccumulators: ATuplethe first accumulator is forλpositif == trueand the second one forλpositif == false
Initialization Function
Tracking_Apollonius.init_apollonius — Functioninit_apollonius()Tracking_Apollonius.parameters is used to initialize and configure Tracking_Apollonius
Do not modify Tracking_Apollonius.parameters after init_apollonius has been called or call it again.
Return 0 if no error.
Description of keys in Tracking_Apollonius.parameters (distance is mm):
Tracking_Apollonius_version: gives the version ofTracking_Apolloniusused (pkgversion(Tracking_Apollonius)),precision: has to beFloat32(default) orFloat64to use GPU in single or double precision,vote_min_iter: for each iteration a value is given to define the number of minimum of votes in a cell of the accumulator.zProj: Position on the Z axis of the plane of projection (expert),intervals_init: domain of the possible values of the helix (Xc, Yc, Z0, E),subdivisions: for each iteration defines the number of cells (defines the cell sizes).,iterations: number of iterations,thresholds_iter: at each iteration, a set of thresholds is defined.
The highest value is used to select cells to create the grid for the next iteration. A set of hits found correspond to a threshold (each threshold is associated to a probability to be a hit of signal). A hit is found when it belongs to a cell with a number of votes > MAX(votes)-threshold,
hasCellsPerHit_iter: at each iteration, if true for each hit the accumulator stores the cell index where a solution is found,divideandconquer: if true, divide and conqueer method is used (no other method is implemanted for this version),magneticField: value of the uniform magnetic field in Tesla (oriented in the Z axis),pivot: pivot value in the x,y plane (expert),threshold_results: Apollonius circle values are obtained with the cells having a number of votes > MAX(votes)-threshold_results,virtual_drift=> to remove cells having a solution for|Xc| < virtual_drift_vec[1]and|Yc| < virtual_drift_vec[2],EeAMean: middle of the interval in energy (in MeV),deltaE: radius of the interval in energy (in MeV),nturn_iter: for each iteration, maximum number of turns used by the Apollonius function,useValidDomain: boolean values for each iteration. If trueevent_ValidDomainfunction is used to define the grid domain of the accumulor (expert),n_xyR_iter: for each iteration, number of cells kept around the maximum of votes used byevent_ValidDomainfunction (expert),
Default values:
"Tracking_Apollonius_version" => pkgversion(Tracking_Apollonius),
"precision" => Float32,
"vote_min_iter" => [15,15,15,7],
"zProj" => 0.0,
"intervals_init" => [[-504.0, 504.0], [-504.0, 504.0], [87.0, 375.0], [-510.0, 490.0]], #CDC coordinates (wires positions)
"subdivisions" => [
(ncellsX = 63, ncellsY = 63, ncellsR = 18, ncellsZ = 25, ncellsE = 1),
(ncellsX=4, ncellsY=4, ncellsR=4, ncellsZ=2, ncellsE=1),
(ncellsX=4, ncellsY=4, ncellsR=4, ncellsZ=2, ncellsE=1),
(ncellsX=4, ncellsY=4, ncellsR=4, ncellsZ=4, ncellsE=1)
],
"iterations" => 4,
"thresholds_iter" => [15,20,20,10],
"hasCellsPerHit_iter" => [false, false, true, true],
"divideandconquer" => true,
"magneticField" => 1.0,
"pivot" => [0.0, 0.0],
"threshold_results" => 1,
"virtual_drift" => [-100. 100],
"EeAMean" => 104.97,
"deltaE" => 0.00001,
"nturn_iter" => [1,2,2,2],
"n_xyR_iter" => [4,4,4,4],
"useValidDomain" => [false, false, false, true]Examples
julia> Tracking_Apollonius.parameters["magneticField"]=0.98
0.98
julia> init_apollonius()
Start init_apollonius
Precision: Float32
Magnetic Field: 0.98 Tesla
zProj: 0.0
Grid Init:
[-504f0, 504f0] × [-504f0, 504f0] × [87f0, 375f0] × [-510f0, 490f0] × [104.969f0, 104.971f0]
(ncellsX = 63, ncellsY = 63, ncellsR = 18, ncellsZ = 25, ncellsE = 1)
(ncellsX = 4, ncellsY = 4, ncellsR = 4, ncellsZ = 2, ncellsE = 1)
(ncellsX = 4, ncellsY = 4, ncellsR = 4, ncellsZ = 2, ncellsE = 1)
(ncellsX = 4, ncellsY = 4, ncellsR = 4, ncellsZ = 4, ncellsE = 1)
CUDA runtime 12.6, artifact installation
CUDA driver 12.9
NVIDIA driver 575.57.8
CUDA libraries:
- CUBLAS: 12.6.4
- CURAND: 10.3.7
- CUFFT: 11.3.0
- CUSOLVER: 11.7.1
- CUSPARSE: 12.5.4
- CUPTI: 2024.3.2 (API 24.0.0)
- NVML: 12.0.0+575.57.8
Julia packages:
- CUDA: 5.5.1
- CUDA_Driver_jll: 0.10.4+0
- CUDA_Runtime_jll: 0.15.5+0
Toolchain:
- Julia: 1.10.10
- LLVM: 15.0.7
Preferences:
- CUDA_Runtime_jll.version: 12.6
1 device:
0: Tesla V100-PCIE-32GB (sm_70, 31.729 GiB / 32.000 GiB available)
cu_array length: 1786050
cu_array constraint length: 551350
Dict{String, Any}("magneticField" => 0.98, "nturn_iter" => [1, 2, 2, 2], "zProj" => 0.0f0, "EeAMean" => 104.97, "hasCellsPerHit_iter" => Bool[0, 0, 1, 1], "virtual_drift" => [-100.0 100.0], "precision" => Float32, "thresholds_iter" => [15, 20, 20, 10], "Tracking_Apollonius_version" => v"1.5.2", "vote_min_iter" => Int16[15, 15, 15, 7], "iterations" => 4, "pivot" => Float32[0.0, 0.0], "versioninfo" => "CUDA runtime 12.6, artifact installation
CUDA driver 12.9
NVIDIA driver 575.57.8
CUDA libraries:
- CUBLAS: 12.6.4
- CURAND: 10.3.7
- CUFFT: 11.3.0
- CUSOLVER: 11.7.1
- CUSPARSE: 12.5.4
- CUPTI: 2024.3.2 (API 24.0.0)
- NVML: 12.0.0+575.57.8
Julia packages:
- CUDA: 5.5.1
- CUDA_Driver_jll: 0.10.4+0
- CUDA_Runtime_jll: 0.15.5+0
Toolchain:
- Julia: 1.10.10
- LLVM: 15.0.7
Preferences:
- CUDA_Runtime_jll.version: 12.6
1 device:
0: Tesla V100-PCIE-32GB (sm_70, 31.729 GiB / 32.000 GiB available)
", "n_xyR_iter" => [4, 4, 4, 4], "divideandconquer" => true, "deltaE" => 1.0e-5, "threshold_results" => 1, "intervals_init" => [[-504.0, 504.0], [-504.0, 504.0], [87.0, 375.0], [-510.0, 490.0]], "subdivisions" => @NamedTuple{ncellsX::Int64, ncellsY::Int64, ncellsR::Int64, ncellsZ::Int64, ncellsE::Int64}[(ncellsX = 63, ncellsY = 63, ncellsR = 18, ncellsZ = 25, ncellsE = 1), (ncellsX = 4, ncellsY = 4, ncellsR = 4, ncellsZ = 2, ncellsE = 1), (ncellsX = 4, ncellsY = 4, ncellsR = 4, ncellsZ = 2, ncellsE = 1), (ncellsX = 4, ncellsY = 4, ncellsR = 4, ncellsZ = 4, ncellsE = 1)], "useValidDomain" => Bool[0, 0, 0, 1])
End init_apollonius
0Running Function
Tracking_Apollonius.runApollonius — FunctionrunApollonius(hits::AbstractTrackHits, eventNumber::Int; cudatime::Bool=false)::Vector{ApolloniusEvent}Return a Vector of ApolloniusEvent corresponding to each iteration from 1 to parameters["iterations"]
eventNumberto identify the eventhitsare the hits of the event- @CUDA.time is used if
cudatimeis true.
runApollonius(hits::AbstractTrackHits, hitsselected::Vector{Bool}, eventNumber::Int; cudatime::Bool=false)::Vector{ApolloniusEvent}Return a Vector of ApolloniusEvent corresponding to each iteration from 1 to parameters["iterations"]
eventNumberis to identify the eventhitsare the hits of the event- use only a selection of hits at the first iteration given by
hitsselected - @CUDA.time is used if
cudatimeis true.
Tracking_Apollonius.geteventnumber — Functiongeteventnumber(event::ApolloniusEvent)Return the event number stored in event
Results Functions
Tracking_Apollonius.apolloniusresults — Functionapolloniusresults(alliterations::Vector{ApolloniusEvent}; threshold::Int=parameters["threshold_results"])::Vector{Float32}
The elements of the vector returned are described below:[1]: xc[2]: yc[3]: R[4]: Z0[5]: RMS xc[6]: RMS yc[7]: RMS R[8]: RMs Z0[9]: Vote Max[10]: Number of cells used in the accumulator accu[11]: Sign of Pz[12]: iteration[13]: Number of hits[14 to 14 + Number of hits -1]: Probability for each hit to belong to the track signal (hits found for a given threshold)[14 + Number of hits to end]: sign of drifts (if 0.0 the sign is undetermined)
Tracking_Apollonius.results_turn — Functionresults_turn(event_iter::Vector{<:AbstractApolloniusEvent}, iter::Int) @NamedTuple{hsp_turn::Vector{Vector{Float32}}, results_turn::Vector{Vector{Float32}}, accu_turn::Vector{Accumulator}}As input uses the iteration iter of event_iter.
Return a NamedTuple:
hsp_turn, a vector vector of probabilty for each hit to belong to the turn iturn equal to the index in hsp_turnresults_turnis the return value ofresultsfor each turnaccu_turn, a vector of accumulators for each turn
Tracking_Apollonius.hspIndicator — FunctionhspIndicator(event_iter::Vector{<:AbstractApolloniusEvent}, iter::Int)::Vector{Float32}For each hit, return in a Vector the probability to be a hit produced by a signal at the iteration iter. In input all iterations are given with event_iter All cells having a value between a maxvalue and maxvalue-parameters["thresholds_iter"][iter] (excluded) are used.
hspIndicator(accu::AbstractAccumulator; threshold::Int)::Vector{Float32}For each hit, return in a Vector the probability to be a hit produced by a signal using the accumulator accu. All cells having a value between a maxvalue and maxvalue-threshold(excluded) are used.
Tracking_Apollonius.gethits_sign_indicator — Functiongethits_sign_indicator(accu::Accumulator)::Vector{Float32}Return for accu the Vector{Float32} where each element is the probability to have a positive drift sign (>0) or a negative drift sign (<0)
Tracking_Apollonius.gethits_turn_indicator — Functiongethits_turn_indicator(accu::Accumulator, iturn::Int) @NamedTuple{hits_turn_indicator::Vector{Float32}, accu_turn::Accumulator{Float32, Int16}}Return a NamedTuple:
hits_turn_indicator, a vector of probabilty for each hit to belong to the turn iturnaccu_turn, the accumulator for hits having aniturnApollonius solution.
Tracking_Apollonius.driftSignIndicator — FunctiondriftSignIndicator(event::AbstractApolloniusEvent)For each hit, return in a Vector the signed probability of the the drift sign using the λsigned accumulator
Tracking_Apollonius.results — Functionresults(accu::A; threshold::Int)::Vector{AbstractFloat} where {A<:AbstractAccumulator}return a vector of values in the referential of hits Cells of the accumulator accu with a value greater than maxvalue-threshold are used.
[1]: xc[2]: yc[3]: R[4]: Z0[5]: RMS xc[6]: RMS yc[7]: RMS R[8]: RMs Z0[9]: Vote Max[10]: Number of cells used in the accumulator accu
Tracking_Apollonius.results_λsigned — Functionresults_λsigned(event::AbstractApolloniusEvent; threshold::Int) = results(accu_λsigned(event); threshold)Return the results for the λ sign having the highest probability to be correct ( see function results )
Tracking_Apollonius.results_λpositif — Functionresults_λpositif(event::ApolloniusEvent; threshold::Int)Return the results for the positive λ value ( see function results )
Tracking_Apollonius.results_λnegatif — Functionresults_λnegatif(event::ApolloniusEvent; threshold::Int)Return the results for the negative λ value ( see function results )
Accumulator Functions
Tracking_Apollonius.accu_λsigned — Functionaccu_λsigned(event::ApolloniusEvent)Return the accumulator having the highest probabilty to have the correct λ sign
Tracking_Apollonius.accu_λpositif — Functionaccu_λpositif(event:ApolloniusEvent)Return the accumulator with the positive λ value of the event
Tracking_Apollonius.accu_λnegatif — Functionaccu_λnegatif(event::ApolloniusEvent)Return the accumulator with the negative value of λ of the event
Tracking_Apollonius.isλpositif — Functionisλpositif(accu::Accumulator)Return false if accu is λ negatif or true if accu is λ positif
Tracking_Apollonius.gethitsfound — Functiongethitsfound(accu::Accumulator)Return for accu the Vector{Bool} where each element corresponds to each hit. The value is true if the hit is found as belonging to the signal
gethitsfound(accu::Accumulator, threshold::Int)::Vector{Bool}Return for each hit true if the hit is found in cells of the accumulator accu having a value greater maxvlue-threshold and false for the other case.
Tracking_Apollonius.accumulatorsigned — Functionaccumulatorsigned(accu1::T, accu2::T)::T where {T<:AbstractAccumulator}Return the accumulator (accu1 or accu2) having the highest probabilty to have the correct sign of λ
Tracking_Apollonius.getvotes — Functiongetvotes(accu::Accumulator)Return the votes of accu
Tracking_Apollonius.getgrid — Functiongetgrid(accu::Accumulator)Return the grid of accu
Hits Function
Tracking_Apollonius.numberofhits — Functionnumberofhits(hits::AbstractTrackHits) Return the number of hits which are in hits
Tracking_Apollonius.wireproporties — Functionwireproporties(hits::CDChitsICEDUST)::Vector{WireProperty}for each hit in hits of type CDChitsICEDUST return a vector WireProperty
Other functions
Tracking_Apollonius.turn_rec — Functionturn_rec(hsp_turn::Vector{Vector{Float32}})::Vector{Int8}Tools to get the turn number of each hits
Tracking_Apollonius.event_ValidDomain — Functionevent_ValidDomain(event::ApolloniusEvent, iter::Int)::ApolloniusEventReturn an ApolloniusEvent keeping cells around the maximum values in accumulators in valid domain.
Tracking_Apollonius.get_reconstructed_center_circle — Functionget_reconstructed_center_circle(hits::AbstractTrackHits, event::AbstractApolloniusEvent; threshold::Int)::Vector{NamedTuple{(:center, :signedDrift, :d2), Tuple{Tuple{Float32, Float32}, Float32, Float32}}}
return for each hits of the event the projected center coordinates with the signed drift and the power 2 of the distance between the Apollonius circle
and the circle of the hits (radius=drift).Test
To test Tracking_Apollonius on a machine with GPU installed, do:
julia> using Tracking_Apollonius
julia> include(joinpath(dirname(pathof(Tracking_Apollonius)),"../test","runtests_gpu.jl"))Both single and double precision are tested.
Index
Tracking_Apollonius.AbstractTrackHitsTracking_Apollonius.AccumulatorTracking_Apollonius.ApolloniusEventTracking_Apollonius.CDChitsICEDUSTTracking_Apollonius.WirePropertyTracking_Apollonius.accu_λnegatifTracking_Apollonius.accu_λpositifTracking_Apollonius.accu_λsignedTracking_Apollonius.accumulatorsignedTracking_Apollonius.apolloniusresultsTracking_Apollonius.driftSignIndicatorTracking_Apollonius.event_ValidDomainTracking_Apollonius.get_reconstructed_center_circleTracking_Apollonius.geteventnumberTracking_Apollonius.getgridTracking_Apollonius.gethits_sign_indicatorTracking_Apollonius.gethits_turn_indicatorTracking_Apollonius.gethitsfoundTracking_Apollonius.getvotesTracking_Apollonius.hspIndicatorTracking_Apollonius.init_apolloniusTracking_Apollonius.isλpositifTracking_Apollonius.numberofhitsTracking_Apollonius.resultsTracking_Apollonius.results_turnTracking_Apollonius.results_λnegatifTracking_Apollonius.results_λpositifTracking_Apollonius.results_λsignedTracking_Apollonius.runApolloniusTracking_Apollonius.turn_recTracking_Apollonius.wireproporties