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

Processing updates #22

Merged
merged 8 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/LegendDataManagement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ using Printf: @printf
using IntervalSets: AbstractInterval, ClosedInterval, leftendpoint, rightendpoint
using LRUCache: LRU
using ProgressMeter: @showprogress
using PropertyFunctions: PropertyFunction, @pf
using PropertyFunctions: PropertyFunction, @pf, filterby
using StaticStrings: StaticString
using Tables: columns

Expand Down
86 changes: 86 additions & 0 deletions src/dataprod_config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,92 @@
end
end

const _cached_analysis_runs = LRU{UInt, StructVector{@NamedTuple{period::DataPeriod, run::DataRun}}}(maxsize = 10)

"""
analysis_runs(data::LegendData)

Return cross-period analysis runs.
"""
function analysis_runs(data::LegendData)
get!(_cached_analysis_runs, objectid(data)) do
aruns = pydataprod_config(data).analysis_runs
periods_and_runs = [

Check warning on line 157 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L154-L157

Added lines #L154 - L157 were not covered by tests
let period = DataPeriod(string(p))
map(run -> (period = period, run = run), _resolve_partition_runs(data, period, rs))

Check warning on line 159 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L159

Added line #L159 was not covered by tests
end
for (p,rs) in aruns
]
flat_pr = vcat(periods_and_runs...)::Vector{@NamedTuple{period::DataPeriod, run::DataRun}}
StructArray(flat_pr)

Check warning on line 164 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L163-L164

Added lines #L163 - L164 were not covered by tests
end
end
export analysis_runs

"""
oschulz marked this conversation as resolved.
Show resolved Hide resolved
is_analysis_run(data::LegendData, period::DataPeriod, run::DataRun)

Return `true` if `run` is an analysis run for `data` in `period`.
"""
function is_analysis_run(data::LegendData, period::DataPeriodLike, run::DataRunLike)
(period = DataPeriod(period), run = DataRun(run)) in analysis_runs(data)

Check warning on line 175 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L174-L175

Added lines #L174 - L175 were not covered by tests
end
export is_analysis_run


const _cached_runinfo = LRU{Tuple{UInt, DataPeriod, DataRun, DataCategory}, typeof((startkey = FileKey("l200-p02-r006-cal-20221226T200846Z"), livetime = 0.0u"s"))}(maxsize = 30)

"""
runinfo(data::LegendData, runsel::RunSelLike)::NamedTuple

Get the run information for `data` in `runsel`.
"""
function runinfo(data::LegendData, runsel::RunCategorySelLike)::NamedTuple

Check warning on line 187 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L187

Added line #L187 was not covered by tests
# unpack runsel
period_in, run_in, category_in = runsel
period, run, category = DataPeriod(period_in), DataRun(run_in), DataCategory(category_in)
get!(_cached_runinfo, (objectid(data), period, run, category)) do

Check warning on line 191 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L189-L191

Added lines #L189 - L191 were not covered by tests
# check if run, period and category is available
if !haskey(data.metadata.dataprod.runinfo, Symbol(period))
throw(ArgumentError("Invalid period $period"))
elseif !haskey(data.metadata.dataprod.runinfo[Symbol(period)], Symbol(run))
throw(ArgumentError("Invalid run $run in period $period"))
elseif !haskey(data.metadata.dataprod.runinfo[Symbol(period)][Symbol(run)], Symbol(category))
throw(ArgumentError("Invalid category $category in period $period and run $run"))

Check warning on line 198 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L193-L198

Added lines #L193 - L198 were not covered by tests
end
(

Check warning on line 200 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L200

Added line #L200 was not covered by tests
startkey = FileKey(data.name, period, run, category, Timestamp(data.metadata.dataprod.runinfo[Symbol(period)][Symbol(run)][Symbol(category)][:start_key])),
livetime = if haskey(data.metadata.dataprod.runinfo[Symbol(period)][Symbol(run)][Symbol(category)], :livetime_in_s)
Unitful.Quantity(data.metadata.dataprod.runinfo[Symbol(period)][Symbol(run)][Symbol(category)][:livetime_in_s], u"s")

Check warning on line 203 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L203

Added line #L203 was not covered by tests
else
Unitful.Quantity(NaN, u"s")

Check warning on line 205 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L205

Added line #L205 was not covered by tests
end
)
end
end
export runinfo


"""
oschulz marked this conversation as resolved.
Show resolved Hide resolved
start_filekey(data::LegendData, runsel::RunCategorySelLike)

Get the starting filekey for `data` in `period`, `run`, `category`.
"""
function start_filekey(data::LegendData, runsel::RunCategorySelLike)
runinfo(data, runsel).startkey

Check warning on line 219 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L218-L219

Added lines #L218 - L219 were not covered by tests
end
export start_filekey


"""
phy_livetime(data::LegendData, runsel::RunSelLike)

Get the livetime for `data` in physics data taking of `run` in `period`.
"""
function livetime(data::LegendData, runsel::RunCategorySelLike)
runinfo(data, runsel).livetime

Check warning on line 230 in src/dataprod_config.jl

View check run for this annotation

Codecov / codecov/patch

src/dataprod_config.jl#L229-L230

Added lines #L229 - L230 were not covered by tests
end
export phy_livetime

const _cached_bad_filekeys = LRU{UInt, Set{FileKey}}(maxsize = 10)

Expand Down
28 changes: 25 additions & 3 deletions src/filekey.jl
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,20 @@
end
end

function DataPeriod(s::Symbol)
DataPeriod(string(s))

Check warning on line 161 in src/filekey.jl

View check run for this annotation

Codecov / codecov/patch

src/filekey.jl#L160-L161

Added lines #L160 - L161 were not covered by tests
end

Base.convert(::Type{DataPeriod}, s::AbstractString) = DataPeriod(s)
Base.convert(::Type{DataPeriod}, s::Symbol) = DataPeriod(string(s))

Check warning on line 165 in src/filekey.jl

View check run for this annotation

Codecov / codecov/patch

src/filekey.jl#L165

Added line #L165 was not covered by tests


"""
DataPeriodLike = Union{DataPeriod, Integer, AbstractString}

Anything that can represent a data period, like `DataPeriod(2)` or "p02".
"""
const DataPeriodLike = Union{DataPeriod, AbstractString}
const DataPeriodLike = Union{DataPeriod, Symbol, AbstractString}
export DataPeriodLike


Expand Down Expand Up @@ -210,17 +215,21 @@
end
end

function DataRun(s::Symbol)
DataRun(string(s))

Check warning on line 219 in src/filekey.jl

View check run for this annotation

Codecov / codecov/patch

src/filekey.jl#L218-L219

Added lines #L218 - L219 were not covered by tests
end

Base.convert(::Type{DataRun}, s::AbstractString) = DataRun(s)
Base.convert(::Type{DataRun}, s::Symbol) = DataRun(string(s))

Check warning on line 223 in src/filekey.jl

View check run for this annotation

Codecov / codecov/patch

src/filekey.jl#L223

Added line #L223 was not covered by tests

"""
DataRunLike = Union{DataRun, Integer, AbstractString}

Anything that can represent a data run, like `DataRun(6)` or "r006".
"""
DataRunLike = Union{DataRun, AbstractString}
DataRunLike = Union{DataRun, Symbol, AbstractString}
export DataRunLike


"""
struct DataCategory <: DataSelector

Expand Down Expand Up @@ -274,6 +283,19 @@
export DataCategoryLike


"""
struct RunSelLike = Tuple{<:DataPeriodLike, <:DataRunLike}

Represents a LEGEND run selection.
"""
const RunSelLike = Tuple{<:DataPeriodLike, <:DataRunLike}

"""
struct RunCategorySelLike = Tuple{<:DataPeriodLike, <:DataRunLike}

Represents a LEGEND run selection for a specific `category`.
"""
const RunCategorySelLike = Tuple{<:DataPeriodLike, <:DataRunLike, <:DataCategoryLike}

"""
struct Timestamp <: DataSelector
Expand Down
48 changes: 32 additions & 16 deletions src/legend_data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,19 @@
struct LegendData <: AbstractSetupData
# ToDo: Add setup name
_config::SetupConfig
_name::Symbol
end
export LegendData

get_setup_config(data::LegendData) = getfield(data, :_config)
get_setup_name(data::LegendData) = getfield(data, :_name)

Check warning on line 62 in src/legend_data.jl

View check run for this annotation

Codecov / codecov/patch

src/legend_data.jl#L62

Added line #L62 was not covered by tests

@inline function Base.getproperty(d::LegendData, s::Symbol)
# Include internal fields:
if s == :_config
getfield(d, :_config)
elseif s == :name
getfield(d, :_name)

Check warning on line 69 in src/legend_data.jl

View check run for this annotation

Codecov / codecov/patch

src/legend_data.jl#L69

Added line #L69 was not covered by tests
elseif s == :metadata
AnyProps(data_path(d, "metadata"))
elseif s == :tier
Expand All @@ -87,14 +91,13 @@


function LegendData(setup::Symbol)
LegendData(getproperty(LegendDataConfig().setups, setup))
LegendData(getproperty(LegendDataConfig().setups, setup), setup)
end

Base.@deprecate data_filename(data::LegendData, filekey::FileKey, tier::DataTierLike) data.tier[tier, filekey]
export data_filename



"""
struct LegendDataManagement.LegendTierData

Expand Down Expand Up @@ -215,12 +218,13 @@


"""
channelinfo(data::LegendData, sel::AnyValiditySelection)
channelinfo(data::LegendData, sel::AnyValiditySelection; system::Symbol = :all, only_processable::Bool = false)
channelinfo(data::LegendData, sel::RunCategorySelLike; system::Symbol = :all, only_processable::Bool = false)

Get all channel information for the given [`LegendData`](@ref) and
[`ValiditySelection`](@ref).
"""
function channelinfo(data::LegendData, sel::AnyValiditySelection)
function channelinfo(data::LegendData, sel::AnyValiditySelection; system::Symbol = :all, only_processable::Bool = false)
chmap = data.metadata(sel).hardware.configuration.channelmaps
dpcfg = data.metadata(sel).dataprod.config.analysis

Expand Down Expand Up @@ -249,9 +253,11 @@
channel::ChannelId = ChannelId(fcid >= 0 ? fcid : rawid)

detector::DetectorId = DetectorId(k)
system::Symbol = Symbol(chmap[k].system)
local system::Symbol = Symbol(chmap[k].system)
processable::Bool = get(dpcfg[k], :processable, false)
usability::Symbol = Symbol(get(dpcfg[k], :usability, :unkown))
is_blinded::Bool = get(dpcfg[k], :is_blinded, false)
aoe_status::Symbol = Symbol(get(get(dpcfg[k], :psd_status, PropDict()), Symbol("A/E"), :unkown))

location::Symbol, detstring::Int, position::Union{Int,Symbol}, fiber::StaticString{8} = _convert_location(chmap[k].location)

Expand All @@ -263,26 +269,37 @@
hvch::Int = get(chmap[k].voltage, :channel, -1)

return (;
detector, channel, fcid, rawid, system, processable, usability,
detector, channel, fcid, rawid, system, processable, usability, is_blinded, aoe_status,
location, detstring, fiber, position, cc4, cc4ch, daqcrate, daqcard, hvcard, hvch
)
end

StructArray(make_row.(channel_keys))
chinfo = StructArray(make_row.(channel_keys))
if !(system == :all)
chinfo = chinfo |> filterby(@pf $system .== system)

Check warning on line 279 in src/legend_data.jl

View check run for this annotation

Codecov / codecov/patch

src/legend_data.jl#L279

Added line #L279 was not covered by tests
end
if only_processable
chinfo = chinfo |> filterby(@pf $processable .== true)

Check warning on line 282 in src/legend_data.jl

View check run for this annotation

Codecov / codecov/patch

src/legend_data.jl#L282

Added line #L282 was not covered by tests
end
return chinfo
end
export channelinfo

function channelinfo(data::LegendData, sel::RunCategorySelLike; kwargs...)
channelinfo(data, start_filekey(data, sel); kwargs...)

Check warning on line 289 in src/legend_data.jl

View check run for this annotation

Codecov / codecov/patch

src/legend_data.jl#L288-L289

Added lines #L288 - L289 were not covered by tests
end


"""
channelinfo(data::LegendData, sel::AnyValiditySelection, channel::ChannelId)
channelinfo(data::LegendData, sel::AnyValiditySelection, detector::DetectorId)
channelinfo(data::LegendData, sel::AnyValiditySelection, channel::ChannelIdLike)
channelinfo(data::LegendData, sel::AnyValiditySelection, detector::DetectorIdLike)

Get channel information validitiy selection and [`DetectorId`](@ref) resp.
[`ChannelId`](@ref).
"""
function channelinfo(data::LegendData, sel::AnyValiditySelection, channel::ChannelId)
chinfo = channelinfo(data, sel)
idxs = findall(x -> ChannelId(x) == channel, chinfo.channel)
function channelinfo(data::LegendData, sel::AnyValiditySelection, channel::ChannelIdLike; kwargs...)
chinfo = channelinfo(data, sel; kwargs...)
idxs = findall(x -> ChannelId(x) == ChannelId(channel), chinfo.channel)

Check warning on line 302 in src/legend_data.jl

View check run for this annotation

Codecov / codecov/patch

src/legend_data.jl#L300-L302

Added lines #L300 - L302 were not covered by tests
if isempty(idxs)
throw(ArgumentError("No channel information found for channel $channel"))
elseif length(idxs) > 1
Expand All @@ -292,9 +309,9 @@
end
end

function channelinfo(data::LegendData, sel::AnyValiditySelection, detector::DetectorId)
chinfo = channelinfo(data, sel)
idxs = findall(x -> DetectorId(x) == detector, chinfo.detector)
function channelinfo(data::LegendData, sel::AnyValiditySelection, detector::DetectorIdLike; kwargs...)
chinfo = channelinfo(data, sel; kwargs...)
idxs = findall(x -> DetectorId(x) == DetectorId(detector), chinfo.detector)

Check warning on line 314 in src/legend_data.jl

View check run for this annotation

Codecov / codecov/patch

src/legend_data.jl#L312-L314

Added lines #L312 - L314 were not covered by tests
if isempty(idxs)
throw(ArgumentError("No channel information found for detector $detector"))
elseif length(idxs) > 1
Expand All @@ -305,7 +322,6 @@
end



function channel_info(data::LegendData, sel::AnyValiditySelection)
Base.depwarn(
"`channel_info(data::LegendData, sel::AnyValiditySelection)` is deprecated, use `channelinfo(data, sel)` instead (note: output format differs).",
Expand Down
Loading