Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow automatic grouping of hits based on a group_distance when creating an Event #461

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

fhagemann
Copy link
Collaborator

Following the discussion on #460, this PR provides a method to automatically group hits in subarrays based on their distances, such that charge clouds close to each other can interact, but the interactions between charge clouds far apart can still be neglected.

@apmypb Thanks for taking care of the core implementation of group_points_by_distance using breadth-first search, which was optimized to have little allocations and fast run times.

To stick to the same example as in #460, where two points are 1mm apart, see the results for passing no group_distance (the previous default), group_distance = 0.5mm (where the charge clouds are not grouped) and group_distance = 2mm (where the charge clouds are grouped).

using SolidStateDetectors
using Unitful
using Plots
T = Float32

sim = Simulation{T}(SSD_examples[:InvertedCoax])
simulate!(sim)
pos = [CartesianPoint{T}(0.02,0,0.05), CartesianPoint{T}(0.02,0.0,0.051)]
E = [1u"GeV", 1u"GeV"]
N = 5

@btime evt1 = Event($pos, $E, $N)
evt1 = Event(pos, E, N)
simulate!(evt1, sim, Δt = 1u"ns", max_nsteps = 5000, self_repulsion = true)
p1 = plot(sim.detector)
plot!(p1, evt1.drift_paths)

@btime Event($pos, $E, $N, group_distance = 0.5u"mm")
evt2 = Event(pos, E, N, group_distance = 0.5u"mm")
simulate!(evt2, sim, Δt = 1u"ns", max_nsteps = 5000, self_repulsion = true)
p2 = plot(sim.detector)
plot!(p2, evt2.drift_paths)

@btime Event($pos, $E, $N, group_distance = 2u"mm")
evt3 = Event(pos, E, N, group_distance = 2u"mm")
simulate!(evt3, sim, Δt = 1u"ns", max_nsteps = 5000, self_repulsion = true)
p3 = plot(sim.detector)
plot!(p3, evt3.drift_paths)
    
plot(p1, p2, p3, size = (1500,500), layout = (1,3), legend = false)
  11.870 μs (180 allocations: 7.20 KiB)
  16.472 μs (257 allocations: 10.20 KiB)
  17.873 μs (242 allocations: 9.72 KiB)

image

The grouping results in some extra runtime when creating the Event, but can help saving time when calculating self_repulsion later in the pipeline. If self_repulsion = false, I would still recommend to use the method without group_distance to achieve the previous results and run times.

@fhagemann fhagemann added enhancement Improvement of existing features convenience Improve user-friendliness labels Feb 19, 2025
@fhagemann
Copy link
Collaborator Author

Note: this PR is non-breaking as it defaults to the old implementation

@fhagemann
Copy link
Collaborator Author

The other example from #460 also works:

using SolidStateDetectors
using Unitful
using Plots
T = Float32

sim = Simulation{T}(SSD_examples[:InvertedCoax])
simulate!(sim)

pos = CartesianPoint{T}(0.02,0,0.05)
E = T(1)u"GeV"

evt0 = Event([pos], [E], 50)
simulate!(evt0, sim, Δt = 1u"ns", max_nsteps = 5000, self_repulsion = true)

evt1 = Event([pos, pos], [E/2, E/2], 50)
simulate!(evt1, sim, Δt = 1u"ns", max_nsteps = 5000, self_repulsion = true)

evt2 = Event([pos, pos], [E/2, E/2], 50, group_distance = 1u"mm")
simulate!(evt2, sim, Δt = 1u"ns", max_nsteps = 5000, self_repulsion = true)

plot(evt0.waveforms[1],  label = "One hit")
plot!(evt1.waveforms[1], label = "Two hits, independent")
plot!(evt2.waveforms[1], label = "Two hits, interacting")

image


particle_type::Type{PT} = Gamma, number_of_shells::Int = 2,
radius::Vector{<:Union{<:Real, <:LengthQuantity}} = radius_guess.(T.(to_internal_units.(energies)), particle_type),
group_distance::Union{<:Real, <:LengthQuantity} = NaN
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still not quite convinced by the name group_distance. Maybe this could become something like interaction_distance or max_interaction_distance?
@oschulz any suggestions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
convenience Improve user-friendliness enhancement Improvement of existing features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants