Skip to content
Snippets Groups Projects
Commit 1e3df596 authored by Tamas Gal's avatar Tamas Gal :speech_balloon:
Browse files

Merge branch 'add-summaryslice-interval-iterator' into 'main'

Add Summaryslice interval iterator helper

See merge request !40
parents a4ef3d6a 4036df4d
No related branches found
No related tags found
1 merge request!40Add Summaryslice interval iterator helper
......@@ -27,7 +27,7 @@ KM3ioKM3DBExt = "KM3DB"
DocStringExtensions = "0.8, 0.9"
HDF5 = "^0.16.15, ^0.17"
KM3DB = "0.2.2"
KM3NeTTestData = "^0.4.14"
KM3NeTTestData = "^0.4.16"
StaticArrays = "1"
UnROOT = "^0.10.26"
julia = "1"
......
......@@ -12,4 +12,4 @@ PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
[compat]
Documenter = "1"
FHist = "^0.11"
KM3NeTTestData = "^0.4.15"
KM3NeTTestData = "^0.4.16"
......@@ -131,6 +131,7 @@ CHClient
### General tools
```@docs
SummarysliceIntervalIterator
getevent
categorize
nthbitset
......
......@@ -110,8 +110,12 @@ hasshowerfit,
hasshowerpositionfit,
hasshowerprefit,
# Utils
# Tools
MCEventMatcher,
SummarysliceIntervalIterator,
getevent,
# Utils
categorize,
is3dmuon,
is3dshower,
......@@ -120,7 +124,6 @@ isnb,
most_frequent,
nthbitset,
triggered,
getevent,
# Physics and math helpers
CherenkovPhoton,
......
......@@ -113,6 +113,9 @@ struct Summaryslice
header::SummarysliceHeader
frames::Vector{SummaryFrame}
end
function Base.show(io::IO, s::Summaryslice)
print(io, "Summaryslice($(length(s.frames)) frames)")
end
struct SummarysliceContainer
# For performance reasons we use directly the lazy types of UnROOT
# We could also parametrise it.
......
......@@ -58,3 +58,91 @@ function getevent(tree::T, frame_index, trigger_counter) where T<:Union{OnlineTr
end
getevent(tree::OfflineTree, idx) = tree[idx]
getevent(tree::OnlineTree, idx) = tree.events[idx]
"""
An iterator which yields a `Vector{Summaryslice}` containing summaryslices of a given
`time_interval` (in seconds). Useful when analysing summary data with fixed time intervals.
The returned summaryslices are also sorted in time.
# Examples
```
julia> f = ROOTFile("/Volumes/Ultraspeed/Data/Obelix/KM3NeT_00000133_00014728.root")
ROOTFile{OnlineTree (83509 events, 106969 summaryslices)}
julia> sii = SummarysliceIntervalIterator(f, 60)
SummarysliceIntervalIterator (10753.1s, 60s intervals, 180 chunks)
julia> for summaryslices in sii
@show length(summaryslices)
@show summaryslices[1].header
break
end
length(summaryslices) = 440
(summaryslices[1]).header = SummarysliceHeader(133, 14728, 134, UTCExtended(1676246413, 400000000, 0))
```
!!! note
Short time intervals (usually less than a few tens of seconds) will likely return empty
`Vector{Summaryslice}`s in the first few iterations due to a delay in run changes.
Additionally, the number of frames per summaryslice will gradually increase due
to the asynchronous nature of the run transition. See the example below with a time
inteval of 5s.
```julia-repl
julia> sii = SummarysliceIntervalIterator(f, 5)
SummarysliceIntervalIterator (10753.1s, 5s intervals, 2151 chunks)
julia> for summaryslices in sii
n = length(summaryslices)
@show n
n > 0 && break
end
n = 0
n = 0
n = 5
```
"""
struct SummarysliceIntervalIterator
sc::KM3io.SummarysliceContainer
time_interval::Int # [s]
n_chunks::Int
timespan::Float64
indices::Vector{Int}
function SummarysliceIntervalIterator(f::ROOTFile, time_interval)
ss = f.online.summaryslices
sorted_summaryslice_indices = sortperm([sh.frame_index for sh in ss.headers])
timespan = ss.headers[sorted_summaryslice_indices[end]].frame_index / 10
n_chunks = Int(ceil(timespan / time_interval))
new(f.online.summaryslices, time_interval, n_chunks, timespan, sorted_summaryslice_indices)
end
end
function Base.show(io::IO, sii::SummarysliceIntervalIterator)
print(io, "SummarysliceIntervalIterator ($(sii.timespan)s, $(sii.time_interval)s intervals, $(sii.n_chunks) chunks)")
end
Base.eltype(::Type{SummarysliceIntervalIterator}) = Vector{KM3io.Summaryslice}
Base.length(sii::SummarysliceIntervalIterator) = sii.n_chunks
function Base.iterate(sii::SummarysliceIntervalIterator, state=(chunk_idx=1, s_idx=1))
state.chunk_idx > sii.n_chunks && return nothing
out_size = sii.time_interval * 10
out = empty!(Vector{KM3io.Summaryslice}(undef, out_size))
frame_index_upper = state.chunk_idx * sii.time_interval * 10
s_idx = state.s_idx
while s_idx <= length(sii.indices)
idx = sii.indices[s_idx]
summaryslice = sii.sc[idx]
if summaryslice.header.frame_index < frame_index_upper
push!(out, summaryslice)
s_idx += 1
else
break
end
end
return (out, (chunk_idx=state.chunk_idx+1, s_idx=s_idx))
end
......@@ -336,3 +336,25 @@ end
@test π/2 angle(Direction(1.,0,0), Direction(0.,0,1))
@test π angle(Direction(1.,0,0), Direction(-1.,0,0))
end
@testset "SummarysliceIntervalIterator" begin
f = ROOTFile(datapath("online", "summaryslices.root"))
sii = SummarysliceIntervalIterator(f, 2)
suslis = collect(sii)
@test 55 == length(suslis)
@test 0 == length(suslis[1])
@test 1 == length(suslis[2])
@test 2 == length(suslis[3])
@test all(20 .== length.(suslis[4:end-5]))
@test 8 == length(suslis[end-1])
@test 6 == length(suslis[end])
flat_suslis = vcat(suslis...)
frame_indices = [s.header.frame_index for s in flat_suslis]
@test issorted(frame_indices)
@test frame_indices == sort([s.header.frame_index for s in f.online.summaryslices])
close(f)
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment