Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gain selection to OSA workflow #230

Merged
merged 37 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3b415a1
Add the possibility to run gain selection for a single date or for a …
marialainez Jun 15, 2023
aba765d
Write a flag file if gain selection finishes successfully
marialainez Jun 16, 2023
e42d9e1
Check if the gain selection finished successfully before starting the…
marialainez Jun 16, 2023
a6ba55e
add necessary imports
marialainez Jun 16, 2023
97e9618
Mistake in the name of the gain selection file
marialainez Jun 20, 2023
0cc7643
Create the flag file using .touch()
marialainez Jun 20, 2023
ac3acf9
Remove unnecessary import
marialainez Jun 20, 2023
2407ae5
add fixture for the gain selection flag file
marialainez Jun 22, 2023
03f68a1
update config.py to the main branch
marialainez Jun 22, 2023
09cf58f
Merge branch main
marialainez Feb 20, 2024
80ed20b
Add start and end time arguments for apply_gain_selection
marialainez Feb 20, 2024
269043e
Add comment to try again later
marialainez Feb 20, 2024
2e82c50
Change name of the directory of the gain selection flag file
marialainez Feb 20, 2024
ed77a8d
Make sure the gain selection flag file exists for the tests
marialainez Feb 21, 2024
1e01368
Make sure the GainSel directory for the date exists for the tests
marialainez Feb 21, 2024
5db8c22
fix tests
marialainez Feb 21, 2024
2619970
fix tests
marialainez Feb 21, 2024
647c6ed
Check if any runs were taken before checking if gain selection finsih…
marialainez Feb 22, 2024
511c92d
Add --no-gainsel option to avoid checking if the gain selection flag …
marialainez Feb 22, 2024
0e464f5
import run_summary_table
marialainez Feb 22, 2024
2bf5f41
Add date as argument of GainSel_flag_file
marialainez Feb 27, 2024
ad33d55
Add date to GainSel_flag_file function in sequencer
marialainez Feb 27, 2024
5f3837b
Use argparser to add the arguments of the script, so that a specific …
marialainez Feb 27, 2024
7590ff3
Create directory before creating gain selection flag file
marialainez Feb 27, 2024
5cb8019
Use date (instead of args.date) in the for loop
marialainez Feb 27, 2024
4cfbe24
Remove unnecessary import
marialainez Feb 27, 2024
cfac411
Use new lstchain script for dates from 20231205
marialainez Feb 27, 2024
57fa22d
Fix mistake
marialainez Feb 27, 2024
eacd04b
Make gain_selection script more informative
marialainez Feb 27, 2024
f2a88c8
Fix undefined name
marialainez Feb 27, 2024
7115e77
Unnecessary f-string
marialainez Feb 27, 2024
e8dc1e2
By default use --no-flatfield-heuristic option
marialainez Feb 27, 2024
73002cc
Use both queues short and long to run the gain selection
marialainez Mar 5, 2024
73a7489
Add option to avoid checking the number of pending jobs in queue
marialainez Mar 5, 2024
f402ff1
Fix name
marialainez Mar 5, 2024
200aa18
Correction
marialainez Mar 5, 2024
e4e6d3d
Add --no-gainsel option also for autocloser
marialainez Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/osa/configs/sequencer.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ HIGH_LEVEL_DIR: %(OSA_DIR)s/HighLevel
LONGTERM_DIR: %(OSA_DIR)s/DL1DataCheck_LongTerm
MERGED_SUMMARY: %(OSA_DIR)s/Catalog/merged_RunSummary.ecsv
SEQUENCER_WEB_DIR: %(OSA_DIR)s/SequencerWeb
GAIN_SELECTION_FLAG_DIR: %(OSA_DIR)s/GainSel

# To be set by the user. Using PROD-ID will overcome the automatic
# fetching of lstchain version. Otherwise leave it empty (and without the colon symbol).
Expand Down Expand Up @@ -138,6 +139,7 @@ WORKFLOWPREFIX: Workflow
GRAPHSUFFIX: .dot
SVGSUFFIX: .svg
end_of_activity: NightFinished.txt
gain_selection_check: GainSelFinished.txt

[OUTPUT]
# REPORTWIDTH is the width in characters of the heading frame for the output
Expand Down
25 changes: 22 additions & 3 deletions src/osa/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ def monitoring_dir(base_test_dir):
return monitoring_dir


@pytest.fixture(scope="session")
def osa_dir(base_test_dir):
osa_dir = base_test_dir / "OSA"
osa_dir.mkdir(parents=True, exist_ok=True)
return osa_dir


@pytest.fixture(scope="session")
def run_summary_dir(monitoring_dir):
summary_dir = monitoring_dir / "RunSummary"
Expand Down Expand Up @@ -436,6 +443,8 @@ def sequence_file_list(
drs4_time_calibration_files,
systematic_correction_files,
r0_data,
gain_selection_flag_file,
merged_run_summary,
):
for r0_file in r0_data:
assert r0_file.exists()
Expand All @@ -448,6 +457,8 @@ def sequence_file_list(

assert run_summary_file.exists()
assert run_catalog.exists()
assert gain_selection_flag_file.exists()
assert merged_run_summary.exists()

run_program("sequencer", "-d", "2020-01-17", "--no-submit", "-t", "LST1")
# First sequence in the list corresponds to the calibration run 1809
Expand Down Expand Up @@ -548,11 +559,9 @@ def run_catalog(run_catalog_dir):


@pytest.fixture(scope="session")
def database(base_test_dir):
def database(osa_dir):
import sqlite3

osa_dir = base_test_dir / "OSA"
osa_dir.mkdir(parents=True, exist_ok=True)
db_file = osa_dir / "osa.db"
with sqlite3.connect(db_file) as connection:
cursor = connection.cursor()
Expand All @@ -562,3 +571,13 @@ def database(base_test_dir):
)
cursor.connection.commit()
yield cursor


@pytest.fixture(scope="session")
def gain_selection_flag_file(osa_dir):

GainSel_dir = osa_dir / "GainSel" / "20200117"
GainSel_dir.mkdir(parents=True, exist_ok=True)
file = GainSel_dir / "GainSelFinished.txt"
file.touch()
return file
113 changes: 71 additions & 42 deletions src/osa/scripts/gain_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
from lstchain.paths import run_info_from_filename, parse_r0_filename

from osa.scripts.reprocessing import get_list_of_dates, check_job_status_and_wait
from osa.utils.utils import wait_for_daytime
from osa.utils.utils import wait_for_daytime, date_to_dir
from osa.utils.logging import myLogger
from osa.job import get_sacct_output, FORMAT_SLURM
from osa.configs import options
from osa.configs.config import cfg

log = myLogger(logging.getLogger(__name__))

Expand Down Expand Up @@ -150,6 +152,20 @@
return StringIO(sp.check_output(sacct_cmd).decode())


def GainSel_flag_file() -> Path:
filename = cfg.get("LSTOSA", "gain_selection_check")
date = date_to_dir(options.date)
GainSel_dir = Path(cfg.get(options.tel_id, "GAIN_SELECTION_FLAG_DIR"))
flagfile = GainSel_dir / date / filename
return flagfile.resolve()


def GainSel_finished() -> bool:
"""Check if gain selection finished successfully."""
flagfile = GainSel_flag_file()
return flagfile.exists()


def check_failed_jobs(date: str, output_basedir: Path = None):
"""Search for failed jobs in the log directory."""
failed_jobs = []
Expand All @@ -165,51 +181,56 @@
log.warning(f"Job {job} did not finish successfully")
failed_jobs.append(job)

if not failed_jobs:
log.info(f"{date}: all jobs finished successfully")
else:
if failed_jobs:

Check warning on line 184 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L184

Added line #L184 was not covered by tests
log.warning(f"{date}: some jobs did not finish successfully")

else:
log.info(f"{date}: all jobs finished successfully")

Check warning on line 188 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L188

Added line #L188 was not covered by tests

run_summary_dir = Path("/fefs/aswg/data/real/monitoring/RunSummary")
run_summary_file = run_summary_dir / f"RunSummary_{date}.ecsv"
summary_table = Table.read(run_summary_file)
runs = summary_table["run_id"]
missing_runs = []

r0_files = glob.glob(f"/fefs/aswg/data/real/R0/{date}/LST-1.?.Run?????.????.fits.fz")
r0g_files = glob.glob(f"/fefs/aswg/data/real/R0G/{date}/LST-1.?.Run?????.????.fits.fz")
all_r0_runs = [parse_r0_filename(i).run for i in r0_files]
all_r0g_runs = [parse_r0_filename(i).run for i in r0g_files]

for run in all_r0_runs:
if run not in runs:
if run not in all_r0g_runs:
missing_runs.append(run)

missing_runs.sort()
if missing_runs:
log.info(
f"Some runs are missing. Copying R0 files of runs {pd.Series(missing_runs).unique()} "
f"directly to /fefs/aswg/data/real/R0G/{date}"
)

for run in missing_runs:
output_dir = Path(f"/fefs/aswg/data/real/R0G/{date}/")
files = glob.glob(f"/fefs/aswg/data/real/R0/{date}/LST-1.?.Run{run:05d}.????.fits.fz")
for file in files:
sp.run(["cp", file, output_dir])

run_summary_dir = Path("/fefs/aswg/data/real/monitoring/RunSummary")
run_summary_file = run_summary_dir / f"RunSummary_{date}.ecsv"
summary_table = Table.read(run_summary_file)
runs = summary_table["run_id"]
missing_runs = []

Check warning on line 195 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L191-L195

Added lines #L191 - L195 were not covered by tests

r0_files = glob.glob(f"/fefs/aswg/data/real/R0/{date}/LST-1.?.Run?????.????.fits.fz")
r0g_files = glob.glob(f"/fefs/aswg/data/real/R0G/{date}/LST-1.?.Run?????.????.fits.fz")
all_r0_runs = [parse_r0_filename(i).run for i in r0_files]
all_r0g_runs = [parse_r0_filename(i).run for i in r0g_files]

Check warning on line 200 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L197-L200

Added lines #L197 - L200 were not covered by tests

for run in all_r0_runs:
if run not in runs:
if run not in all_r0g_runs:
missing_runs.append(run)

Check warning on line 205 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L202-L205

Added lines #L202 - L205 were not covered by tests

missing_runs.sort()
if missing_runs:
log.info(

Check warning on line 209 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L207-L209

Added lines #L207 - L209 were not covered by tests
f"Some runs are missing. Copying R0 files of runs {pd.Series(missing_runs).unique()} "
f"directly to /fefs/aswg/data/real/R0G/{date}"
)

for run in missing_runs:
output_dir = Path(f"/fefs/aswg/data/real/R0G/{date}/")
files = glob.glob(f"/fefs/aswg/data/real/R0/{date}/LST-1.?.Run{run:05d}.????.fits.fz")
for file in files:
sp.run(["cp", file, output_dir])

Check warning on line 218 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L214-L218

Added lines #L214 - L218 were not covered by tests

flagfile = GainSel_flag_file()
flagfile.touch()

Check warning on line 221 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L220-L221

Added lines #L220 - L221 were not covered by tests


@click.command()
@click.option("--check", is_flag=True, default=False, help="Check for failed jobs.")
@click.argument("dates-file", type=click.Path(exists=True, path_type=Path))
@click.argument("output-basedir", type=click.Path(path_type=Path))
@click.option("-d", "--date", type=str)
@click.option("-l", "--dates-file", type=click.Path(exists=True, path_type=Path))
@click.option("-o", "--output-basedir", type=click.Path(path_type=Path))
@click.option("-s", "--start-time", type=int, default=10, help="Time to (re)start gain selection in HH format.")
@click.option("-e", "--end-time", type=int, default=18, help="Time to stop gain selection in HH format.")
def main(
dates_file: Path = None,
date: str = None,
dates_file: Path = None,
output_basedir: Path = None,
check: bool = False,
start_time: int = 10,
Expand All @@ -222,15 +243,23 @@
"""
log.setLevel(logging.INFO)

list_of_dates = get_list_of_dates(dates_file)

if check:
for date in list_of_dates:
if date:
if check:

Check warning on line 247 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L246-L247

Added lines #L246 - L247 were not covered by tests
check_failed_jobs(date, output_basedir)
else:
for date in list_of_dates:
else:
apply_gain_selection(date, start_time, end_time, output_basedir)
log.info("Done! No more dates to process.")


elif dates_file:
list_of_dates = get_list_of_dates(dates_file)

Check warning on line 254 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L253-L254

Added lines #L253 - L254 were not covered by tests

if check:
for date in list_of_dates:
check_failed_jobs(date, output_basedir)

Check warning on line 258 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L256-L258

Added lines #L256 - L258 were not covered by tests
else:
for date in list_of_dates:
apply_gain_selection(date, start_time, end_time, output_basedir)
log.info("Done! No more dates to process.")

Check warning on line 262 in src/osa/scripts/gain_selection.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/gain_selection.py#L260-L262

Added lines #L260 - L262 were not covered by tests


if __name__ == "__main__":
Expand Down
15 changes: 15 additions & 0 deletions src/osa/scripts/sequencer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import logging
import os
import sys
from decimal import Decimal

from osa import osadb
Expand All @@ -22,12 +23,14 @@
run_squeue,
)
from osa.nightsummary.extract import build_sequences
from osa.nightsummary.nightsummary import run_summary_table
from osa.paths import analysis_path
from osa.report import start
from osa.utils.cliopts import sequencer_cli_parsing
from osa.utils.logging import myLogger
from osa.utils.utils import is_day_closed, gettag, date_to_iso
from osa.veto import get_closed_list, get_veto_list
from osa.scripts.gain_selection import GainSel_finished

__all__ = [
"single_process",
Expand Down Expand Up @@ -90,6 +93,18 @@
if not options.simulate:
os.makedirs(options.log_directory, exist_ok=True)

summary_table = run_summary_table(options.date)
if len(summary_table) == 0:
log.warning("No runs found for this date. Nothing to do. Exiting.")
sys.exit(0)
morcuended marked this conversation as resolved.
Show resolved Hide resolved

if not options.no_gainsel and not GainSel_finished():
log.info(

Check warning on line 102 in src/osa/scripts/sequencer.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/sequencer.py#L102

Added line #L102 was not covered by tests
f"Gain selection did not finish successfully for date {options.date}."
"Try again later, once gain selection has finished."
)
sys.exit()

Check warning on line 106 in src/osa/scripts/sequencer.py

View check run for this annotation

Codecov / codecov/patch

src/osa/scripts/sequencer.py#L106

Added line #L106 was not covered by tests

if is_day_closed():
log.info(f"Date {date_to_iso(options.date)} is already closed for {options.tel_id}")
return sequence_list
Expand Down
2 changes: 2 additions & 0 deletions src/osa/scripts/tests/test_osa_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ def test_simulated_sequencer(
run_catalog,
r0_data,
merged_run_summary,
gain_selection_flag_file,
):
assert run_summary_file.exists()
assert run_catalog.exists()
assert gain_selection_flag_file.exists()

for r0_file in r0_data:
assert r0_file.exists()
Expand Down
7 changes: 7 additions & 0 deletions src/osa/utils/cliopts.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ def sequencer_argparser():
default=False,
help="Do not produce DL2 files (default False)",
)
parser.add_argument(
"--no-gainsel",
action="store_true",
default=False,
help="Do not check if the gain selection finished correctly (default False)",
)
parser.add_argument(
"tel_id",
choices=["ST", "LST1", "LST2", "all"],
Expand All @@ -292,6 +298,7 @@ def sequencer_cli_parsing():
options.no_submit = opts.no_submit
options.no_calib = opts.no_calib
options.no_dl2 = opts.no_dl2
options.no_gainsel = opts.no_gainsel

log.debug(f"the options are {opts}")

Expand Down
Loading