mirror of
https://gitlab.cern.ch/wotsubo/psboard-qaqc-analysis.git
synced 2024-12-04 13:01:05 +09:00
init: partial slave log parser
This commit is contained in:
commit
07971df5e4
4 changed files with 278 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
./slavelogs/
|
||||
./ps_all.csv
|
||||
./masterlogs/
|
68
analysis.jl
Normal file
68
analysis.jl
Normal file
|
@ -0,0 +1,68 @@
|
|||
using CSV
|
||||
using DataFrames
|
||||
using GLMakie
|
||||
|
||||
"""
|
||||
mapping to unique numbers
|
||||
"""
|
||||
function unique_num(v)
|
||||
uniques = unique(v)
|
||||
mapping = Dict(uniques .=> eachindex(uniques))
|
||||
map(v) do x
|
||||
mapping[x]
|
||||
end
|
||||
end
|
||||
|
||||
df = CSV.read("ps_all.csv", DataFrame)
|
||||
dropmissing!(df, :position)
|
||||
|
||||
gdf = groupby(df, :position)
|
||||
|
||||
df_stacked = let
|
||||
preheaders = [:qspip, :recov, :power, :clock]
|
||||
postheaders = map(preheaders) do sym
|
||||
Symbol("n" * string(sym))
|
||||
end
|
||||
df = combine(
|
||||
gdf,
|
||||
preheaders .=> (v -> count(v .!= 1)) .=> postheaders,
|
||||
)
|
||||
|
||||
stack(df, postheaders)
|
||||
end
|
||||
|
||||
transform!(
|
||||
df_stacked,
|
||||
:position => unique_num => :position_id,
|
||||
)
|
||||
transform!(
|
||||
df_stacked,
|
||||
:variable => unique_num => :variable_id,
|
||||
)
|
||||
|
||||
colors = Makie.wong_colors()
|
||||
fig = Figure()
|
||||
ax = Axis(
|
||||
fig[1, 1],
|
||||
title = "failed ones",
|
||||
xlabel = "position",
|
||||
xticks = (df_stacked.position_id, df_stacked.position),
|
||||
xticklabelrotation = π / 3,
|
||||
ylabel = "counts",
|
||||
)
|
||||
barplot!(
|
||||
ax,
|
||||
df_stacked.position_id,
|
||||
df_stacked.value,
|
||||
stack = df_stacked.variable_id,
|
||||
color = colors[df_stacked.variable_id |> collect],
|
||||
)
|
||||
|
||||
Legend(
|
||||
fig[1, 2],
|
||||
[PolyElement(polycolor = colors[i]) for i in df_stacked.variable_id |> unique],
|
||||
df_stacked.variable |> unique,
|
||||
"entries",
|
||||
)
|
||||
|
||||
save("failed_reasons.png", fig)
|
BIN
failed_reasons.png
Normal file
BIN
failed_reasons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
207
slavelog_parser.jl
Normal file
207
slavelog_parser.jl
Normal file
|
@ -0,0 +1,207 @@
|
|||
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
|
Loading…
Reference in a new issue