mirror of
https://gitlab.cern.ch/wotsubo/psboard-qaqc-analysis.git
synced 2024-12-05 05:21:06 +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