Extensions

Plots extension

LegendDataManagment provides an extension for Plots. This makes it possible to directly plot LEGEND data via the plot function. The extension is automatically loaded when both packages are loaded. You can plot a parameter overview as a 2D plot over a set of detectors (requires a $LEGEND_DATA_CONFIG environment variable pointing to a legend data-config file):

using LegendDataManagement, Plots

l200 = LegendData(:l200)

filekey = FileKey("l200-p03-r000-cal-20230311T235840Z")

pars = l200.par.ppars.ecal(filekey)
properties = [:e_cusp_ctc, :fwhm, :qbb];

chinfo = channelinfo(l200, filekey; system = :geds, only_processable = true)

plot(chinfo, pars, properties, verbose = true, color = 1, markershape = :o, calculate_mean = true)

The plot recipe takes three arguments:

  • chinfo: the channel info with all detectors to be plotted on the x-axis
  • pars: a PropDict that has the detector IDs as keys and parameters as values
  • properties: an array of Symbols to access the data that should be plotted

(if no properties are provided, the PropDict pars is expected to just contain the data to be plotted as values)

There are also keyword arguments:

  • calculate_mean: If set to true, then the mean values are included in the legend labels. For values with uncertainties, the mean values are calculated as weighted means.
  • verbose: some output when the plot is generated, e.g. if values for (some) detectors are missing

A 3D plot is WIP.

In addition, you can plot an event display of the raw waveforms:

using Unitful, LegendDataManagement, Plots

l200 = LegendData(:l200)

ts = 1.6785791257987175e9u"s"

ch = ChannelId(1104000)

plot(l200, ts, ch)
  • plot_tier: The data tier to be plotted. Default is DataTier(:raw).
  • plot_waveform: All waveforms to be plotted from the data. Default is [:waveform_presummed] which plots the presummed waveform.
  • show_unixtime: If set to true, use unix time instead of the datetime in the title. Default is false.

If the channel is not given, the recipe automtically searches for the correct event in the data.

ts = 1.6785791257987175e9u"s"

plot(l200, ts)

In case of a cal event, only the HPGe channel with that event is plotted. In case of a phy event, all waveforms of the full HPGe and SiPM systems are plotted. The following additional keywords arguments can be set (the plot_waveform kwarg is replaced by the system kwarg here):

  • system: The system and the waveforms to be plotted for each system. Default is Dict{Symbol, Vector{Symbol}}([:geds, :spms] .=> [[:waveform_presummed], [:waveform_bit_drop]])
  • only_processable: If set to true, only processable channels are plotted. Default is true.

LegendHDF5IO extension

LegendDataManagment provides an extension for LegendHDF5IO. This makes it possible to directly load LEGEND data from HDF5 files via the read_ldata function. The extension is automatically loaded when both packages are loaded. Example (requires a $LEGEND_DATA_CONFIG environment variable pointing to a legend data-config file):

using LegendDataManagement, LegendHDF5IO
l200 = LegendData(:l200)
filekeys = search_disk(FileKey, l200.tier[:jldsp, :cal, :p03, :r000])

chinfo = channelinfo(l200, (:p03, :r000, :cal); system=:geds, only_processable=true)

ch = chinfo[1].channel

dsp = read_ldata(l200, :jldsp, first(filekeys), ch)
dsp = read_ldata(l200, :jldsp, :cal, :p03, :r000, ch)
dsp = read_ldata((:e_cusp, :e_trap, :blmean, :blslope), l200, :jldsp, :cal, :p03, :r000, ch)

read_ldata automitcally loads LEGEND data for a specific DataTier and data selection like e.g. a FileKey or a run-selection based for a given ChannelId. The search_disk function allows the user to search for available DataTier and FileKey on disk. The first argument can be either a selection of keys in form of a NTuple of Symbol or a PropertyFunction which will be applied during loading. It is also possible to load whole a DataPartition or DataPeriod for a given ChannelId ch:

dsp = read_ldata(l200, :jldsp, :cal, DataPartition(1), ch)
dsp = read_ldata(l200, :jldsp, :cal, DataPeriod(3), ch)

In additon, it is possible to load a random selection of n_evts events randomly selected from each loaded file:

dsp = read_ldata(l200, :jldsp, :cal, :p03, :r000, ch; n_evts=1000)

For simplicity, the ch can also be given as a DetectorID which will be converted internally to a ChannelId:

det = chinfo[1].detector
dsp = read_ldata(l200, :jldsp, :cal, :p03, :r000, det)

In case, a ChannelId is missing in a file, the function will throw an ArgumentError. To avoid this and return nothing instead, you can use the ignore_missing keyword argument.

SolidStateDetectors extension

LegendDataManagment provides an extension for SolidStateDetectors. This makes it possible to create SolidStateDetector and Simulation instances from LEGEND metadata.

Example (requires a $LEGEND_DATA_CONFIG environment variable pointing to a legend data-config file):

using LegendDataManagement, SolidStateDetectors, Plots
det = SolidStateDetector(LegendData(:l200), :V99000A)
plot(det)

A detector can also be constructed using the filename of the LEGEND metadata detector-datasheet JSON file (no $LEGEND_DATA_CONFIG required):

det = SolidStateDetector(LegendData, "V99000A.json")

In addition, when creating a Simulation, all simulation functions in SolidStateDetectors.jl can be applied. As usual, all fields stored in the Simulation can be written and read using LegendHDF5IO:

using LegendDataManagement
using SolidStateDetectors

sim = Simulation(LegendData, "V99000A.json")
simulate!(sim) # calculate electric field and weighting potentials

using LegendHDF5IO
ssd_write("V99000A.lh5", sim)
sim_in = ssd_read("V99000A.lh5", Simulation)

The following code will generate an overview plot of every 5th LEGEND detector (requires the actual LEGEND metadata instead of the metadata in legend-testdata):

using LegendDataManagement, SolidStateDetectors, Plots
l200 = LegendData(:l200)
detnames = propertynames(l200.metadata.hardware.detectors.germanium.diodes)
plot(
    plot.(SolidStateDetector.(Ref(l200), detnames[1:5:120]))...,
    layout = (3,8), lw = 0.05, legend = false, grid = false, showaxis = false,
    xlims = (-0.05,0.05), ylims = (-0.05,0.05), zlims = (0,0.1), size = (4000,1500)
)