#! /usr/bin/env python
###############################################################################
import re
import urllib.request
from km3dq_common.common_library import create_ttree_from_qaqc
from km3dq_common.config_library import configure_dataquality_tag
from km3dq_common.config_library import configure_defect
from km3dq_common.lw_db_defect_library import decode_defect_diag_byte
###############################################################################
[docs]
def get_unsignedoff_runs(det, dq_tag_name="default"):
"""
Return the unsignedoff PHYS runs based on the defect files stored on SFTP
("signoff" defect type)
=== Arguments ===
- det : detector name - [string] - Ex: "D0ARCA021", "D0ORCA018"...
- dq_tag_name : data quality tag name - [string] - Ex: "default", "neutrino2024"
=== Output ===
- Dictionnary with def_[defect] as keys and a value for each affected run.
This value will be decoded by the decode_defect_diag_byte function.
Ex: {'def_daq': {}, 'def_operation': {16501: 1, 16503: 2}...}
"""
# The DQ tag is needed as the signoff depends on the QAQC file that
# depends itself on the DQ tag
dq_tag = configure_dataquality_tag(dq_tag_name)
defects0 = configure_defect()
if "ORCA" in det:
site = "ORCA"
else:
site = "ARCA"
(n1, _) = create_ttree_from_qaqc(det, ["run"], "qaqc_sftp", dq_tag)
re_line = re.compile(r"\s*([0-9]+)\s*\|.*")
res = {}
# Initialize the output for all runs as not yet signed off
for _, irun in n1.iterrows(): # One entry per run
res[irun["run"]] = []
for i_diag in defects0["bit"]["signoff"].keys():
res[irun["run"]].append(i_diag)
# Now scan the defect files and removed the run signed off
for i_diag in defects0["bit"]["signoff"].keys():
lines = []
defect_url = (
"https://sftp.km3net.de/data/km3dq_lw_db/"
f"{site}/{det}/Defects/{dq_tag['def_tag']}/"
f"signoff_{i_diag}.txt"
)
try:
with urllib.request.urlopen(defect_url) as def_file:
tmp = (def_file.read()).split(b"\n")
for i_line in tmp:
if i_line != "":
lines.append(i_line.decode("utf-8"))
except urllib.error.URLError:
# No defect file found
continue
for i_line in lines:
r_m = re_line.match(i_line)
if r_m is not None:
run_nb = int(r_m.group(1))
# Run signed off not (yet?) in QAQC
if run_nb not in res.keys():
continue
signoff_nature_bit = 1 << defects0["bit"]["signoff"][i_diag]
signoff_nature = decode_defect_diag_byte(signoff_nature_bit, "signoff")
for i_nature in signoff_nature.split(" / "):
if i_nature != "":
res[run_nb].remove(i_nature)
if len(res[run_nb]) == 0:
res.pop(run_nb)
return res