psboard-qaqc-analysis/slavelog_parser.jl

207 lines
5.2 KiB
Julia
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

HEADER_QSPIP_START = "=============== Test QAPIp Start ==============="
HEADER_POWER_START = "=============== Test Power Start ==============="
HEADER_ASDTP_START = "=============== Test ASDTP Start ==============="
HEADER_RECOV_START = "=============== Test Recov Start ==============="
HEADER_STARTS = [HEADER_QSPIP_START, HEADER_POWER_START, HEADER_ASDTP_START, HEADER_RECOV_START]
@enum SlaveLogSection begin
MODE_NONE
MODE_QSPIP
MODE_POWER
MODE_ASDTP
MODE_RECOV
end
"""
Extract info from slave log filename.
"""
function get_psbid_runid_from_filename(filename::AbstractString)::Tuple{Int64,Int64,Bool}
main, _ext = splitext(filename)
parts = split(main, '_')
psbid = parse(Int64, parts[1])
runid = parse(Int64, parts[2])
islongrun = if length(parts) == 3
true
else
false
end
(psbid, runid, islongrun)
end
function is_valid_slavelog(filename::AbstractString)::Bool
error("not yet implemented")
end
"""
detect_mode_start(line::AbstractString)
Detect [`SlaveLogSection`](@ref) from section starting header line.
If the line doesn't match any section, returns `nothing`.
"""
function detect_mode_start(line::AbstractString)
if line == HEADER_QSPIP_START
MODE_QSPIP
elseif line == HEADER_POWER_START
MODE_POWER
elseif line == HEADER_ASDTP_START
MODE_ASDTP
elseif line == HEADER_RECOV_START
MODE_RECOV
else
nothing
end
end
"""
detect_mode_start!(mode::SlaveLogSection, line::AbstractString)
Detect mode from the `line` and update `mode`.
"""
function detect_mode_start(mode::SlaveLogSection, line::AbstractString)
newmode = detect_mode_start(line)
if !isnothing(newmode)
mode = newmode
end
mode
end
"""
parse_qspip_section(lines::Base.Iterators.Stateful)
Parse QSPIp section of given stateful iterator of log.
# Args
- `lines`: Stateful iterator of slave log file lines
"""
function parse_qspip_section!(lines::Base.Iterators.Stateful)
# TODO
nothing
end
"""
parse_power_section(lines::Base.Iterators.Stateful)
Parse Power section of given stateful iterator of log.
# Args
- `lines`: Stateful iterator of slave log file lines
"""
function parse_power_section!(lines::Base.Iterators.Stateful)
# TODO
nothing
end
"""
Measurement result for asic in asdtp test.
"""
struct AsdtpMeasurement
before::Float64
current::Float64
next::Float64
end
function Base.parse(::Type{AsdtpMeasurement}, s::AbstractString)
v = split(s, ':')
@assert length(v) == 3
AsdtpMeasurement(
parse(Float64, v[1]),
parse(Float64, v[2]),
parse(Float64, v[3]),
)
end
"""
parse_asdtp_section(lines::Base.Iterators.Stateful)
Parse ASDTP section of given stateful iterator of log.
# Args
- `lines`: Stateful iterator of slave log file lines
"""
function parse_asdtp_section!(lines::Base.Iterators.Stateful)
line_count = 0
line = popfirst!(lines)
line_count += 1
results = map(_ -> AsdtpMeasurement[], 1:8)
for asic_id in 1:8
header_line = "----PP$(asic_id)----"
while line != header_line
line = popfirst!(lines)
line_count += 1
end
for _ in 1:32
line = popfirst!(lines)
line_count += 1
mes = parse(AsdtpMeasurement, line)
push!(results[asic_id], mes)
end
end
@assert length(results[1]) == 32 "unexpected length: $(length(results[1]))"
return results
end
"""
parse_qspip_section(lines::Base.Iterators.Stateful)
Parse Recov section of given stateful iterator of log.
# Args
- `lines`: Stateful iterator of slave log file lines
"""
function parse_recov_section!(lines::Base.Iterators.Stateful)
# TODO
nothing
end
function parse_slavelog_file(filename::AbstractString)
lines_iter = Iterators.Stateful(eachline(filename))
asdtp_results = Any[]
mode::SlaveLogSection = MODE_NONE
# main loop
while !isempty(lines_iter)
# each sections
if mode == MODE_NONE
line = popfirst!(lines_iter)
mode = detect_mode_start(mode, line)
elseif mode == MODE_QSPIP
parse_qspip_section!(lines_iter)
mode = MODE_NONE
elseif mode == MODE_POWER
parse_power_section!(lines_iter)
mode = MODE_NONE
elseif mode == MODE_ASDTP
result = parse_asdtp_section!(lines_iter)
push!(asdtp_results, result)
mode = MODE_NONE
elseif mode == MODE_RECOV
parse_recov_section!(lines_iter)
mode = MODE_NONE
end
end
@info "Finished"
return asdtp_results
end
function eff99_count_map(asdtp_results)
# try(100) × channel(8) × channel(32)
@assert length(asdtp_results) == 100
@assert length(asdtp_results[begin]) == 8
@assert length(asdtp_results[begin][begin]) == 32
map(1:8) do i_asic
map(1:32) do i_channel
sum(1:100) do i_try
asdtp_results[i_try][i_asic][i_channel] != AsdtpMeasurement(0, 1, 0)
end
end
end
end
map(eachrow(filter(:position => ==("B-0-1"), df))) do row
readdir("slavelogs/") |>
filter(startswith("$(row.motherboard_id)_")) |>
filter(contains("longrun"))
end |> Iterators.flatten