Skip to content

Commit fea0067

Browse files
authored
Merge pull request #239 from cta-observatory/calib_prod_id
Use CALIB_PROD_ID instead of pro to search for calibration files
2 parents b8b0c67 + 04e9548 commit fea0067

File tree

12 files changed

+278
-218
lines changed

12 files changed

+278
-218
lines changed

Diff for: src/osa/configs/options.py

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
nocheck = None
1717
no_dl2 = None
1818
prod_id = None
19-
calib_prod_id = None
2019
dl1_prod_id = None
2120
dl2_prod_id = None
2221
append = None

Diff for: src/osa/configs/sequencer.cfg

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ SEQUENCER_WEB_DIR: %(OSA_DIR)s/SequencerWeb
3232
# To be set by the user. Using PROD-ID will overcome the automatic
3333
# fetching of lstchain version. Otherwise leave it empty (and without the colon symbol).
3434
PROD_ID: v0.1.0
35-
CALIB_PROD_ID: v01
3635
# Change this to produce a different DL1b or DL2 sub-productions.
3736
# Otherwise, keep it empty to use the common PROD-ID
3837
DL1_PROD_ID: tailcut84

Diff for: src/osa/conftest.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from osa.scripts.tests.test_osa_scripts import run_program
2727
from osa.utils.utils import date_to_dir
2828
from datetime import datetime
29+
import lstchain
2930

3031
date = datetime.fromisoformat("2020-01-17")
3132
nightdir = date_to_dir(date)
@@ -68,16 +69,25 @@ def calibration_base_dir(monitoring_dir):
6869
return base_dir
6970

7071

72+
@pytest.fixture(scope="session")
73+
def drive_log(monitoring_dir):
74+
drive_dir = monitoring_dir / "DrivePositioning"
75+
drive_file = drive_dir / "DrivePosition_log_20200117.txt"
76+
drive_dir.mkdir(parents=True, exist_ok=True)
77+
drive_file.touch()
78+
return drive_file
79+
80+
7181
@pytest.fixture(scope="session")
7282
def calibration_dir(calibration_base_dir):
73-
directory = calibration_base_dir / "calibration" / nightdir / "pro"
83+
directory = calibration_base_dir / "calibration" / nightdir / f"v{lstchain.__version__}"
7484
directory.mkdir(parents=True, exist_ok=True)
7585
return directory
7686

7787

7888
@pytest.fixture(scope="session")
7989
def drs4_baseline_dir(calibration_base_dir):
80-
directory = calibration_base_dir / "drs4_baseline" / nightdir / "pro"
90+
directory = calibration_base_dir / "drs4_baseline" / nightdir / f"v{lstchain.__version__}"
8191
directory.mkdir(parents=True, exist_ok=True)
8292
return directory
8393

Diff for: src/osa/paths.py

+97-37
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
"""Handle the paths of the analysis products."""
22

33
import logging
4+
import re
5+
from datetime import datetime
46
from pathlib import Path
57
from typing import List
6-
from datetime import datetime
78

9+
import lstchain
810
from astropy.table import Table
9-
from lstchain.onsite import find_systematics_correction_file, find_time_calibration_file
10-
from lstchain.scripts.onsite.onsite_create_calibration_file import search_filter
11+
from lstchain.onsite import (find_systematics_correction_file,
12+
find_time_calibration_file)
13+
from lstchain.scripts.onsite.onsite_create_calibration_file import \
14+
search_filter
1115

1216
from osa.configs import options
13-
from osa.configs.config import DEFAULT_CFG
14-
from osa.configs.config import cfg
17+
from osa.configs.config import DEFAULT_CFG, cfg
1518
from osa.configs.datamodel import Sequence
1619
from osa.utils import utils
1720
from osa.utils.logging import myLogger
1821

1922
log = myLogger(logging.getLogger(__name__))
2023

2124
__all__ = [
22-
"get_calibration_file",
23-
"get_drs4_pedestal_file",
25+
"get_calibration_filename",
26+
"get_drs4_pedestal_filename",
2427
"pedestal_ids_file_exists",
2528
"get_run_date",
2629
"drs4_pedestal_exists",
@@ -40,6 +43,8 @@
4043

4144

4245
DATACHECK_WEB_BASEDIR = Path(cfg.get("WEBSERVER", "DATACHECK"))
46+
CALIB_BASEDIR = Path(cfg.get("LST1", "CALIB_DIR"))
47+
DRS4_PEDESTAL_BASEDIR = Path(cfg.get("LST1", "PEDESTAL_DIR"))
4348

4449

4550
def analysis_path(tel) -> Path:
@@ -86,18 +91,25 @@ def get_run_date(run_id: int) -> datetime:
8691
return datetime.strptime(date_string, "%Y-%m-%d")
8792

8893

89-
def get_drs4_pedestal_file(run_id: int) -> Path:
94+
def get_drs4_pedestal_filename(run_id: int, prod_id: str) -> Path:
9095
"""
9196
Return the drs4 pedestal file corresponding to a given run id
9297
regardless of the date when the run was taken.
9398
"""
94-
drs4_pedestal_dir = Path(cfg.get("LST1", "PEDESTAL_DIR"))
99+
if drs4_pedestal_exists(run_id, prod_id):
100+
files = search_drs4_files(run_id, prod_id)
101+
return files[-1] # Get the latest production among the major lstchain version
102+
95103
date = utils.date_to_dir(get_run_date(run_id))
96-
file = drs4_pedestal_dir / date / f"pro/drs4_pedestal.Run{run_id:05d}.0000.h5"
97-
return file.resolve()
104+
return (
105+
DRS4_PEDESTAL_BASEDIR
106+
/ date
107+
/ f"v{lstchain.__version__}/drs4_pedestal.Run{run_id:05d}.0000.h5"
108+
).resolve()
98109

99110

100-
def get_calibration_file(run_id: int) -> Path:
111+
def get_calibration_filename(run_id: int, prod_id: str) -> Path:
112+
# sourcery skip: remove-unnecessary-cast
101113
"""
102114
Return the calibration file corresponding to a given run_id.
103115
@@ -109,14 +121,18 @@ def get_calibration_file(run_id: int) -> Path:
109121
Notes
110122
-----
111123
The file path will be built regardless of the date when the run was taken.
112-
We follow the naming convention of the calibration files produced by the lstchain script
113-
which depends on the filter wheels position. Therefore, we need to try to fetch the filter
114-
position from the CaCo database. If the filter position is not found, we assume the default
115-
filter position 5-2. Filter information is not available in the database for runs taken before
124+
We follow the naming convention of the calibration files produced by the
125+
lstchain script which depends on the filter wheels position. Therefore, we
126+
need to try to fetch the filter position from the CaCo database. If the
127+
filter position is not found, we assume the default filter position 5-2.
128+
Filter information is not available in the database for runs taken before
116129
mid 2021 approx.
117130
"""
118131

119-
calib_dir = Path(cfg.get("LST1", "CALIB_DIR"))
132+
if calibration_file_exists(run_id, prod_id):
133+
files = search_calibration_files(run_id, prod_id)
134+
return files[-1] # Get the latest production among the major lstchain version
135+
120136
date = utils.date_to_dir(get_run_date(run_id))
121137

122138
if options.test: # Run tests avoiding the access to the database
@@ -131,8 +147,11 @@ def get_calibration_file(run_id: int) -> Path:
131147
log.warning("No filter information found in database. Assuming positions 52.")
132148
options.filters = 52
133149

134-
file = calib_dir / date / f"pro/calibration_filters_{options.filters}.Run{run_id:05d}.0000.h5"
135-
return file.resolve()
150+
return (
151+
CALIB_BASEDIR
152+
/ date
153+
/ f"v{lstchain.__version__}/calibration_filters_{options.filters}.Run{run_id:05d}.0000.h5"
154+
).resolve()
136155

137156

138157
def pedestal_ids_file_exists(run_id: int) -> bool:
@@ -142,16 +161,51 @@ def pedestal_ids_file_exists(run_id: int) -> bool:
142161
return bool(file_list)
143162

144163

145-
def drs4_pedestal_exists(run_id: int) -> bool:
164+
def drs4_pedestal_exists(run_id: int, prod_id: str) -> bool:
146165
"""Return true if drs4 pedestal file was already produced."""
147-
file = get_drs4_pedestal_file(run_id)
148-
return file.exists()
166+
files = search_drs4_files(run_id, prod_id)
167+
168+
return len(files) != 0
149169

150170

151-
def calibration_file_exists(run_id: int) -> bool:
171+
def calibration_file_exists(run_id: int, prod_id: str) -> bool:
152172
"""Return true if calibration file was already produced."""
153-
file = get_calibration_file(run_id)
154-
return file.exists()
173+
files = search_calibration_files(run_id, prod_id)
174+
175+
return len(files) != 0
176+
177+
178+
def search_drs4_files(run_id: int, prod_id: str) -> list:
179+
"""
180+
Find DRS4 baseline correction files corresponding to a run ID
181+
and major lstchain production version
182+
"""
183+
date = utils.date_to_dir(get_run_date(run_id))
184+
version = get_major_version(prod_id)
185+
drs4_dir = DRS4_PEDESTAL_BASEDIR / date
186+
return sorted(
187+
drs4_dir.glob(f"{version}*/drs4_pedestal.Run{run_id:05d}.0000.h5")
188+
)
189+
190+
191+
def get_major_version(prod_id):
192+
"""Given a version as vX.Y.Z return vX.Y"""
193+
# First check that the given version is in the correct format
194+
if prod_id.startswith("v") and len(prod_id.split(".")) >= 2:
195+
return re.search(r"\D\d+\.\d+", prod_id)[0]
196+
197+
raise ValueError("Format of the version is not in the form vW.X.Y.Z")
198+
199+
200+
def search_calibration_files(run_id: int, prod_id: str) -> list:
201+
"""
202+
Search charge calibration files corresponding to a run ID and major lstchain production version
203+
"""
204+
date = utils.date_to_dir(get_run_date(run_id))
205+
version = get_major_version(prod_id)
206+
return sorted(
207+
(CALIB_BASEDIR / date).glob(f"{version}*/calibration_filters_*.Run{run_id:05d}.0000.h5")
208+
)
155209

156210

157211
def get_drive_file(date: str) -> Path:
@@ -180,11 +234,16 @@ def sequence_calibration_files(sequence_list: List[Sequence]) -> None:
180234
"""Build names of the calibration files for each sequence in the list."""
181235
flat_date = utils.date_to_dir(options.date)
182236
base_dir = Path(cfg.get("LST1", "BASE"))
237+
prod_id = options.prod_id
183238

184239
for sequence in sequence_list:
185240
# Assign the calibration files to the sequence object
186-
sequence.drs4_file = get_drs4_pedestal_file(sequence.drs4_run)
187-
sequence.calibration_file = get_calibration_file(sequence.pedcal_run)
241+
sequence.drs4_file = get_drs4_pedestal_filename(
242+
sequence.drs4_run, prod_id
243+
)
244+
sequence.calibration_file = get_calibration_filename(
245+
sequence.pedcal_run, prod_id
246+
)
188247
sequence.time_calibration_file = find_time_calibration_file(
189248
"pro", sequence.pedcal_run, base_dir=base_dir
190249
)
@@ -235,10 +294,7 @@ def destination_dir(concept: str, create_dir: bool = True) -> Path:
235294
directory = Path(cfg.get(options.tel_id, "DL1_DIR")) / nightdir / options.prod_id / "muons"
236295
elif concept == "INTERLEAVED":
237296
directory = (
238-
Path(cfg.get(options.tel_id, "DL1_DIR"))
239-
/ nightdir
240-
/ options.prod_id
241-
/ "interleaved"
297+
Path(cfg.get(options.tel_id, "DL1_DIR")) / nightdir / options.prod_id / "interleaved"
242298
)
243299
elif concept == "DATACHECK":
244300
directory = (
@@ -257,17 +313,21 @@ def destination_dir(concept: str, create_dir: bool = True) -> Path:
257313
)
258314
elif concept in {"DL2", "DL3"}:
259315
directory = (
260-
Path(cfg.get(options.tel_id, concept + "_DIR"))
261-
/ nightdir
316+
(Path(cfg.get(options.tel_id, f"{concept}_DIR")) / nightdir)
262317
/ options.prod_id
263-
/ options.dl2_prod_id
264-
)
318+
) / options.dl2_prod_id
265319
elif concept in {"PEDESTAL", "CALIB", "TIMECALIB"}:
266320
directory = (
267-
Path(cfg.get(options.tel_id, concept + "_DIR")) / nightdir / options.calib_prod_id
321+
Path(cfg.get(options.tel_id, f"{concept}_DIR"))
322+
/ nightdir
323+
/ options.prod_id
268324
)
269325
elif concept == "HIGH_LEVEL":
270-
directory = Path(cfg.get(options.tel_id, concept + "_DIR")) / nightdir / options.prod_id
326+
directory = (
327+
Path(cfg.get(options.tel_id, f"{concept}_DIR"))
328+
/ nightdir
329+
/ options.prod_id
330+
)
271331
else:
272332
log.warning(f"Concept {concept} not known")
273333
directory = None

0 commit comments

Comments
 (0)