API
Modules
Types and constants
Functions and macros
Juleanita.GeBandgapJuleanita.Ge_Energy_per_eholePairJuleanita.Ge_NumberChargeCarrierJuleanita.V_to_electronsJuleanita._ADC_to_VJuleanita._ADC_to_electronsJuleanita._ADC_to_keVJuleanita._is_valid_datestrJuleanita.apply_qcJuleanita.csv_to_lh5Juleanita.fit_linearityJuleanita.noise_sweepJuleanita.process_ctcJuleanita.process_decaytimeJuleanita.process_dspJuleanita.process_energy_calibrationJuleanita.process_filteroptJuleanita.process_hitJuleanita.process_peak_splitJuleanita.process_peakfitsJuleanita.process_pulser_linearityJuleanita.process_qualitycutsJuleanita.read_csv_metadataJuleanita.read_folder_csv_oscilloscopeJuleanita.rmsJuleanita.simple_dspJuleanita.simple_dsp_pulserJuleanita.simple_dsp_qcJuleanita.sktutek_csv_to_lh5
Documentation
Juleanita.electron_charge — Constantelectron_chargecharge of electron in Coulomb: $e = 1.60217662 10^{-19}$ C
Juleanita.GeBandgap — MethodGeBandgap(T::Real)bandgap energy (eV) of germanium as a function of temperature (K)
\[E_\textrm{gap}(T) = 0.744 - \frac{4.774 \cdot 10^{-4} \cdot T^2}{T + 235}\]
Juleanita.Ge_Energy_per_eholePair — MethodGe_Energy_per_eholePair(T::Real)energy (eV) required to create an electron-hole pair in germanium as a function of temperature (K)
\[E(T) = 2.2 \cdot E_\textrm{gap}(T) + 1.99 \cdot E_\textrm{gap}(T)^{3/2} \cdot \exp(4.75 \cdot \frac{E_\textrm{gap}(T)}{T})\]
Juleanita.Ge_NumberChargeCarrier — MethodGe_NumberChargeCarrier(E::Real, T::Real)number of charge carriers created by an energy E (eV) in germanium at temperature T (K)
Juleanita.V_to_electrons — MethodV_to_electrons(Voltage_V::Real, capacitance_F::Real; gain::Real = 1.0)Convert voltage into a charge in electrons based on the capacitance of the system (could be pulser, detector, or combination).
\[Q[e^{-}] = \frac{V}{\textrm{gain}} \cdot \frac{C_{\textrm{inj}}}{e^{-}}\]
Juleanita._ADC_to_V — Method_ADC_to_V(ADC::Real, dynamicrange_V::Real, bits::Int)Convert ADC-code from digitizer into voltage. The ADC-code is assumed to be in the range [0, 2^bits] corresponding to voltages within the dynamic range.
\[V = \frac{V_{\textrm{dynamic range}}}{2^{\textrm{bits}}} \cdot \textrm{ADC}\]
Inputs:
ADC: ADC-code from digitizerdynamicrange_V: dynamic range of the DAQ in Voltsbits: number of bits of the ADC
Juleanita._ADC_to_electrons — Method_ADC_to_electrons(ADC::Real, capacitance_F::Real; bits::Int = 14, dynamicrange_V::Real = 2.0, gain::Real = 1.0)Convert ADC-code from pulser into injected charge in pulserADCto_electrons
\[Q[e^{-}] = (\frac{V_{\textrm{dynamic range}}}{2^{\textrm{bits}}} \cdot \textrm{ADC}) \cdot \frac{1}{\textrm{gain}} \cdot \frac{C_{\textrm{inj}}}{e^{-}}\]
Inputs:
ADC: ADC-code from digitizercapacitance_F: capacitance of the system (could be pulser, detector, or combination) in Faradbits: number of bits of the ADCdynamicrange_V: dynamic range of the DAQ in Voltsgain: gain of the system
Juleanita._ADC_to_keV — Methodpulser_ADC_to_keV(ADC::Real, capacitance_F::Real; bits::Int = 14, dynamicrange_V::Real = 2.0, gain::Real = 1.0)Convert ADC-code from pulser into injected energy in keV. Inputs:
ADC: ADC-code from digitizercapacitance_F: capacitance of the system (could be pulser, detector, or combination) in Faradbits: number of bits of the DAQdynamicrange_V: dynamic range of the ADC in Voltsgain: gain of the system
Juleanita._is_valid_datestr — Method_is_valid_datestr(timestr_file::String; timezone::String = "PT")check if the time string in the filename is a valid date string
Juleanita.apply_qc — Methodquality cuts based on dsp parametersJuleanita.csv_to_lh5 — Methodcsvtolh5(data::LegendData, period::DataPeriod, run::DataRun, category::DataCategoryLike, channel::ChannelId, csv_folder::String; heading::Int = 17, nwvfmax::Union{Int, Float64, Vector{Int64}} = NaN, nChannels::Int = 2, ti::ClosedInterval{<:Quantity} = 0.0u"µs".. 550.0u"µs")
- converts csv files from oscilloscope to lh5 files
- format of csv file matches the one from an oscilloscope...might be different for other systems
- saves the lh5 files in the raw tier defined in "LEGENDDATACONFIG"
INPUTS:
data::LegendDataLegendData object. You need"LEGEND_DATA_CONFIG"to construct this. this will define later where.lh5files are savedperiod::DataPerioddata period that you want to assign your data torun::DataRundata run that you want to assign your data tocategory::DataCategoryLikedata category that you want to assign your data tochannel::ChannelIdchannel id that you want to assign your data tocsv_folder::Stringfolder where the csv files are locatedcsv_heading::Intnumber of lines to skip in csv filenwvfmax::Union{Int, Float64, Vector{Int64}}number of waveforms to read OR vector of waveforms indices to readnChannels::Intnumber of channels in csv files to read (supports only 1 or 2)ti::ClosedInterval{<:Quantity}time interval to truncate the waveforms towpf::Intwaveforms per files –> number of waveforms to write per.lh5file
Juleanita.fit_linearity — Methodfit_linearity(pol_order::Int, µ::AbstractVector{<:Union{Real,Measurement{<:Real}}}, peaks::AbstractVector{<:Union{Real,Measurement{<:Real}}}; pull_t::Vector{<:NamedTuple}=fill(NamedTuple(), pol_order+1), v_init::Vector = [], uncertainty::Bool=true )Fit the calibration lines with polynomial function of polorder order polorder == 1 -> linear function pol_order == 2 -> quadratic function
Returns
* `result`: NamedTuple with the following fields
* `par`: best-fit parameters
* `gof`: godness of fit
* `report`:Juleanita.noise_sweep — Functionnoise_sweep(filter_type::Symbol, wvfs::ArrayOfRDWaveforms, dsp_config::DSPConfig, τ_pz::Quantity{T}; ft::Quantity{T}= 0.0u"µs", τ_cusp::Quantity{<:AbstractFloat} = 10000000.0u"µs", τ_zac::Quantity{<:AbstractFloat} = 10000000.0u"µs" ) where T<:Real
noise_sweep(filter_type::Symbol, wvfs::ArrayOfRDWaveforms, dsp_config::DSPConfig; kwargs... )Noise sweep function used in DSP filter optimizatio. The goal is to find the optimal rise-time (for a given flat-top time) which minimizes ENC noise. This is an alternative approach to dsp_trap_rt_optimization.
Strategy:
- Shift waveforms to have a common baseline, and deconvolute them with the pole-zero correction (in case τ_pz > 0.0u"µs" )
- Filter waveforms with given rise-time and flat-top time
- Build histogram out of all samples in baseline from all waveforms. Remove bins at the beginning and end of the waveform to avoid edge effects.
- Calculate the RMS of the baseline noise –> ENC noise
Inputs:
filter_type::Symbol: filter type (:trap or :cusp)wvfs::ArrayOfRDWaveforms: raw waveforms to be filtereddsp_config::DSPConfig: DSP configuration object containing relevant parameters:ft,grid_rt,bl_window,flt_length_cusp,flt_length_zacτ_pz::Quantity{T}: pole-zero decay time. If τ_pz = 0.0u"µs" (or none given), no pole-zero correction is applied.
kwargs:
ft::Quantity{T}: fixed flat-top time for optimizationτ_cusp::Quantity{<:AbstractFloat}: cusp decay time; only relevant for cusp filterτ_zac::Quantity{<:AbstractFloat}: cusp decay time; only relevant for zac filter
Juleanita.process_ctc — Methodprocess_ctc(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, ecal_config::PropDict, ctc_config::PropDict;
energy_types::Vector{Symbol} = Symbol.(ctc_config.energy_types), reprocess::Bool = false)
process_ctc(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; kwargs...)Calculate charge-trapping correction: by looking at correlation between drift time and energy. Save correction function to rpars. Inputs:
data::LegendData: LegendData objectperiod::DataPeriod: data periodrun::DataRun: data runcategory::Union{Symbol, DataCategory}: data category, e.g. :calchannel::ChannelId: channel idecal_config::PropDict: energy calibration configuration. If not specified use default from metadatactc_config::PropDict: charge-trapping correction configuration. If not specified use default from metadata
Optional:
energy_types::Vector{Symbol}: energy types to processreprocess::Bool: reprocess the files or notjuleana_logo::Bool: add juleana logo to plots
Juleanita.process_decaytime — Functionprocess_decaytime(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, min_τ::Quantity{T}, max_τ::Quantity{T}, nbins::Int, rel_cut_fit::Real, peak::Symbol, bl_window::ClosedInterval{<:Unitful.Time{<:T}}, tail_window::ClosedInterval{<:Unitful.Time{<:T}}; reprocess::Bool = false) where T <: Real
process_decaytime(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, pz_config::PropDict, bl_window::ClosedInterval{<:Unitful.Time{<:T}}, tail_window::ClosedInterval{<:Unitful.Time{<:T}}; kwargs...) where T <: Real
process_decaytime(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, pz_config::PropDict, dsp_config::DSPConfig; kwargs...)
process_decaytime(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; kwargs...)Goal: calculate decay time used for pole-zero correction Inputs:
data::LegendData: LegendData objectperiod::DataPeriod: data periodrun::DataRun: data runcategory::Union{Symbol, DataCategory}: data category, e.g. :calchannel::ChannelId: channel idmin_τ::Quantity{T}: minimum decay timemax_τ::Quantity{T}: maximum decay timenbins::Int: number of bins for histogramrel_cut_fit::Real: relative cut for truncated gausspeak::Symbol: peak to use for decay time calculation. Can also be :all to use all :raw instead of :jlpeaks tierbl_window::ClosedInterval{<:Unitful.Time{<:T}}: baseline windowtail_window::ClosedInterval{<:Unitful.Time{<:T}}: tail window
Optional:
reprocess::Bool: reprocess the files or notjuleana_logo::Bool: add juleana logo to plots
Juleanita.process_dsp — Functionprocess_dsp(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, dsp_config::DSPConfig, τ_pz::Quantity{<:Real}, pars_filter::PropDict; reprocess::Bool = false )
process_dsp(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId ; kwargs... )Goal:
- run the DSP processing for all raw files in the given period, run, category and channel.
- based on
simple_dspfunction - save the results in the jldsp tier
- if reprocess is false, it will skip the files that are already processed
INPUTS: - data::LegendData LegendData object. You need "LEGEND_DATA_CONFIG" to construct this, e.g. l200 = LegendData(:l200) - period::DataPeriod data period, e.g. DataPeriod(1) - run::DataRun data run, e.g. DataRun(1) - category::Symbol data category, e.g. DataCategory(:cal) - channel::ChannelId channel id, e.g. ChannelId(1) (depending on your data!) - dsp_config::DSPConfig DSP configuration object. If not specified will take default from metadata - τ_pz::Quantity{<:Real} decay time used for pole-zero correction. If not specified will take from rpars.pz - pars_filter::PropDict optimized filter parameters used in DSP. If not specified will take from rpars.fltopt
KWARGS: - reprocess::Bool reprocess the files or not
OUTPUTS: - save the DSP results in the jldsp tier - print the progress - print the completion message
Juleanita.process_energy_calibration — Functionprocess_energy_calibration(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, source::Symbol; reprocess::Bool = true, ecal_config::PropDict = data.metadata.config.energy.energy_config.default, e_types::Vector{<:Symbol} = [:e_trap, :e_cusp, :e_zac])perform energy calibration: take uncalibration energy values from dsp files and calibrate them using calibration sources INPUTS:
- data::LegendData: LegendData object
- period::DataPeriod: data period
- run::DataRun: data run
- category::Union{Symbol, DataCategory}: data category, e.g. :cal
- channel::ChannelId: channel id
- source::Symbol: calibration source. :th228 or :co60 are supported at the moment
OPTIONAL:
- reprocess::Bool: reprocess the files or not
- ecal_config::PropDict: energy calibration configuration. if not specified, it will take the default from metadata
- etypes::Vector{<:Symbol}: energy types to calibrate. default is [:etrap, :ecusp, :ezac]
OUTPUT:
- save the calibration parameters as json files to disk (in generated/par/rpars/ecal/...)
- save the calibration plots to disk (in generated/jlplt/rplt/...)
Juleanita.process_filteropt — Functionprocess_filteropt(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, dsp_config::DSPConfig, τ_pz::Quantity{T}, peak::Symbol; rt_opt_mode::Symbol = :blnoise, reprocess::Bool = false, filter_types::Vector{Symbol} = [:trap, cusp])
process_filteropt(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; kwargs...)Filter optimization for filter_types
- load waveforms from peakfile, shift baseline and pole-zero
- optimize rise-time for minimum baseline noise after filtering
- optimize flat-top time for FWHM of peak
- save results to disk
- sanity plots for rise-time and flat-top time optimization
Inputs:
data::LegendData: LegendData objectperiod::DataPeriod: data periodrun::DataRun: data runcategory::Union{Symbol, DataCategory}: data category, e.g. :calchannel::ChannelId: channel id
Optional:
dsp_config::DSPConfig: DSP configuration object. If not specified will take default from metadataτ_pz::Quantity{T}: pole-zero decay time. If not specified will take default from metadatapeak::Symbol: peak to optimize for (needs existing peakfile!). If not specified will take default from metadatart_opt_mode::Symbol: mode for rise-time optimization (:blnoise or :pickoff) –> two different strategies for optimizationreprocess::Bool: reprocess the files or notfilter_types::Vector{Symbol}: filter types to optimize for
Juleanita.process_hit — Methodprocessing_hit(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; reprocess::Bool = false, e_types::Vector{<:Symbol} = [:e_trap, :e_cusp, :e_zac])- run the hit processing for all dsp files in the given period, run, category and channel.
- apply energy calibration to the dsp energy estimator and save the results in the jlhit tier
- no PSD at the moment, will be added in future
- if reprocess is false, it will skip the files that are already processed
INPUTS:
data::LegendDataLegendData objectperiod::DataPerioddata periodrun::DataRundata runcategory::Union{Symbol, DataCategory}data category, e.g. :calchannel::ChannelIdchannel idreprocess::Boolreprocess the files or note_types::Vector{<:Symbol}energy types to process. default is [:etrap, :ecusp, :e_zac]
OUTPUTS:
- save the hit results in the jlhit tier
Juleanita.process_peak_split — Functionprocess_peak_split(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, ecal_config::PropDict, dsp_config::DSPConfig, qc_config::PropDict; reprocess::Bool = false)
process_peak_split(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; kwargs...)Create peak files containting only waveforms from peaks in the calibration spectrum.
- Read raw data
- Find peaks in the calibration spectrum using rough energy estimate
data_fk.daqenergy - Do simple DSP for peaks only
- apply quality cuts based on simple DSP
- Save waveforms after QC to peak files
inputs:
- data: LegendData object
- period: DataPeriod object
- run: DataRun object
- category: Symbol or DataCategory object, e.g. :cal for calibration
- channel: ChannelId for germanium detector
- ecal_config: PropDict, energy calibration configuration
- dsp_config: DSPConfig, DSP configuration
- qc_config: PropDict, quality cut configuration
keyword arguments:
reprocess: Bool, default is false
Output:
- h_uncals histograms of peaksearch
- peakpos
Also, peak files containting only waveforms from peaks in the calibration spectrum are saved to jlpeaks folder.
Juleanita.process_peakfits — Functionprogress_peakfits(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; reprocess::Bool = true, e_types::Vector{<:Symbol} = [:e_trap, :e_cusp, :e_zac], juleana_logo::Bool = false)
Process the peak fits for the benchtest data.Juleanita.process_pulser_linearity — FunctionJuleanita.process_qualitycuts — Functionprocess_qualitycuts(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; reprocess::Bool = false, qc_config::PropDict = data.metadata.config.qc.qc_config.default)apply quality cuts based on dsp parameters inputs: data: LegendData object period: DataPeriod object run: DataRun object category: Symbol or DataCategory object channel: ChannelId object reprocess: Bool, default false qcconfig: PropDict, default data.metadata.config.qc.qcconfig.default
Juleanita.read_csv_metadata — Methodread_csv_metadata(filepath::String; heading::Int = 17, nChannels::Int = 2, timezone = "PT")read metadata from a csv file (as taken from oscilloscope) input:
- filepath::String: file name
- heading::Int: number of lines (beginning at top) in csv file contain metadata
- nChannels::Int: number of channels in csv file
- timezone::String: timezone to which the timekey in filename refers (standard is PT = Pacific Time –> Berkeley)
Juleanita.read_folder_csv_oscilloscope — Methodread_folder_csv_oscilloscope(csv_folder::String; heading::Int = 17, nwvfmax::Union{Int, Float64, Vector{Int64}} = NaN, nChannels::Int = 2)read folder with csv files from oscilloscope input:
- csv_folder::String: absolute csv folder path
- heading::Int: number of lines to skip
- nwvfmax::Union{Int, Float64, Vector{Int64}}: number of waveforms to read OR vector of waveforms indices to read
- nChannels::Int: number of channels in csv files to read (1 or 2)
Juleanita.rms — Methodrms(x::Vector{T}) where {T <: Real}Calculate the RMS of a vector of real numbers.
Juleanita.simple_dsp — Methodsimple_dsp(data::Q, dsp_config::DSPConfig; τ_pz::Quantity{T} = 0.0u"µs", pars_filter::PropDict) where {Q <: Table, T<:Real}dsp routine which calculates all relevant parameters for the waveform analysis
data::Q: input data, e.g. raw file, peakfiledsp_config::DSPConfig: DSP configuration objectτ_pz::Quantity{T}: pole-zero decay time. If τ_pz = 0.0u"µs" (or none given), no pole-zero correction is applied.pars_filter::PropDict: filter parameters for the different filter types. Use PropDict() to get default values from config.
Juleanita.simple_dsp_pulser — Methodsimple_dsp_pulser(data::Q, dsp_config::DSPConfig; τ_pz::Quantity{T} = 0.0u"µs", pars_filter::PropDict) where {Q <: Table, T<:Real}minimal version of simple_dsp for pulser channel
Juleanita.simple_dsp_qc — Methodminimal version of simple_dsp used to calculate quality cuts with peakfiles
Juleanita.sktutek_csv_to_lh5 — Functionskutek_csv_to_lh5(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId, csv_folder::String; timestep::Quantity = 0.01u"µs")
skutek_csv_to_lh5(data::LegendData, period::DataPeriod, run::DataRun, category::Union{Symbol, DataCategory}, channel::ChannelId; kwargs...)convert csv files from Skutek digitizer "FemtoDAQ Vireo" to lh5 files
- format of csv file matches the one of Skutek digitizer "FemtoDAQ Vireo ...might be different for other systems
inputs:
data::LegendDataLegendData object. You need"LEGEND_DATA_CONFIG"to construct this. this will define later where.lh5files are savedperiod::DataPerioddata period that you want to assign your data torun::DataRundata run that you want to assign your data tocategory::DataCategoryLikedata category that you want to assign your data tochannel::ChannelIdchannel id that you want to assign your data tocsv_folder::Stringfolder where the csv files are located (optinal). if not defined use the default folder
kwargs
timestep::Quantitytime step of the waveforms. default is 0.01µs –> 100 MHz sampling.- chmode::Symbol = :diff
:diffch1 - ch2 is stored asraw/waveform:diffplusch1 - ch2 is stored asraw/waveformAND both channels are stored asraw/waveform_ch1andraw/waveform_ch2(if available in data):singlech1 is stored asraw/waveformand ch2 is stored asraw/waveform_ch2(if available in data):pulserch1 is stored asraw/waveformand ch2 is stored asraw/pulser