Skip to content

Commit 309968b

Browse files
committed
Merge branch 'catB_option1' into dl2_production
2 parents e6ea503 + 412eb7e commit 309968b

17 files changed

+469
-61
lines changed

Diff for: pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ reprocess_longterm = "osa.scripts.reprocess_longterm:main"
7676
gain_selection = "osa.scripts.gain_selection:main"
7777
update_source_catalog = "osa.scripts.update_source_catalog:main"
7878
gainsel_webmaker = "osa.scripts.gainsel_webmaker:main"
79+
sequencer_catB_tailcuts = "osa.scripts.sequencer_catB_tailcuts:main"
7980

8081
[tool.setuptools.packages.find]
8182
where = ["src"]

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

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
warning = None
1616
nocheck = None
1717
no_dl2 = None
18+
no_dl1ab = None
19+
no_gainsel = None
1820
prod_id = None
1921
dl1_prod_id = None
2022
dl2_prod_id = None

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

+9-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ RUN_SUMMARY_DIR: %(MONITORING)s/RunSummary
1515
RUN_CATALOG: %(MONITORING)s/RunCatalog
1616
PEDESTAL_FINDER_DIR: %(BASE)s/auxiliary/PedestalFinder
1717
ANALYSIS_DIR: %(BASE)s/running_analysis
18-
CALIB_BASE_DIR: %(MONITORING)s/PixelCalibration/Cat-A
19-
CALIB_DIR: %(CALIB_BASE_DIR)s/calibration
20-
PEDESTAL_DIR: %(CALIB_BASE_DIR)s/drs4_baseline
18+
CALIB_BASE_DIR: %(MONITORING)s/PixelCalibration
19+
CAT_A_CALIB_BASE: %(CALIB_BASE_DIR)s/Cat-A
20+
CAT_A_CALIB_DIR: %(CAT_A_CALIB_BASE)s/calibration
21+
CAT_A_PEDESTAL_DIR: %(CAT_A_CALIB_BASE)s/drs4_baseline
22+
CAT_B_CALIB_BASE: %(CALIB_BASE_DIR)s/Cat-B
2123
DL1_DIR: %(BASE)s/DL1
2224
DL1AB_DIR: %(BASE)s/DL1
2325
DL2_DIR: %(BASE)s/DL2
@@ -46,18 +48,22 @@ DL2_PROD_ID: model2
4648
#charge_calibration: onsite_create_calibration_file
4749
drs4_baseline: lstcam_calib_onsite_create_drs4_pedestal_file
4850
charge_calibration: lstcam_calib_onsite_create_calibration_file
51+
catB_calibration: onsite_create_cat_B_calibration_file
4952
use_ff_heuristic_id: False
5053

5154
# Data processing steps in datasequence script
5255
r0_to_dl1: lstchain_data_r0_to_dl1
5356
dl1ab: lstchain_dl1ab
5457
check_dl1: lstchain_check_dl1
5558
dl1_to_dl2: lstchain_dl1_to_dl2
59+
tailcuts_finder: lstchain_find_tailcuts
5660

5761
# To be set by the user
5862
dl1a_config: /software/lstchain/data/lstchain_standard_config.json
5963
store_image_dl1ab: True
6064
merge_dl1_datacheck: True
65+
apply_catB_calibration: True
66+
apply_standard_dl1b_config: False
6167
use_ff_heuristic_gain_selection: False
6268
dl1b_config: /software/lstchain/data/lstchain_standard_config.json
6369
dl2_config: /software/lstchain/data/lstchain_standard_config.json

Diff for: src/osa/conftest.py

+53
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,56 @@ def gain_selection_flag_file(osa_dir):
596596
file = GainSel_dir / "GainSelFinished.txt"
597597
file.touch()
598598
return file
599+
600+
601+
@pytest.fixture(scope="session")
602+
def catB_closed_file(running_analysis_dir):
603+
604+
catB_closed_file = running_analysis_dir / "catB_00003.closed"
605+
catB_closed_file.touch()
606+
return catB_closed_file
607+
608+
609+
@pytest.fixture(scope="session")
610+
def catB_calib_base_dir(monitoring_dir):
611+
612+
catB_calib_base_dir = monitoring_dir / "PixelCalibration" / "Cat-B"
613+
catB_calib_base_dir.mkdir(parents=True, exist_ok=True)
614+
return catB_calib_base_dir
615+
616+
617+
@pytest.fixture(scope="session")
618+
def catB_calibration_file(catB_calib_dir):
619+
620+
catB_calib_dir = catB_calib_base_dir / "calibration" / nightdir / prod_id
621+
catB_calib_file = catB_calib_dir / "cat_B_calibration_filters_52.Run00003.h5"
622+
catB_calib_file.touch()
623+
return catB_calib_file
624+
625+
626+
@pytest.fixture(scope="session")
627+
def dl1b_config_file(running_analysis_dir):
628+
config_information = dedent(
629+
"""\
630+
{
631+
"tailcuts_clean_with_pedestal_threshold": {
632+
"picture_thresh": 8,
633+
"boundary_thresh": 4,
634+
"sigma": 2.5,
635+
"keep_isolated_pixels": false,
636+
"min_number_picture_neighbors": 2,
637+
"use_only_main_island": false,
638+
"delta_time": 2
639+
},
640+
"dynamic_cleaning": {
641+
"apply": true,
642+
"threshold": 267,
643+
"fraction_cleaning_intensity": 0.03
644+
}
645+
}"""
646+
)
647+
config_file = running_analysis_dir / "dl1ab_Run00003.json"
648+
config_file.touch()
649+
config_file.write_text(config_information)
650+
return config_file
651+

Diff for: src/osa/job.py

+18
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ def are_all_jobs_correctly_finished(sequence_list):
9999
analysis_directory = Path(options.directory)
100100
for sequence in sequence_list:
101101
history_files_list = analysis_directory.rglob(f"*{sequence.seq}*.history")
102+
103+
if not options.test:
104+
try:
105+
next(history_files_list)
106+
except StopIteration:
107+
log.info("no history files found")
108+
flag = False
109+
102110
for history_file in history_files_list:
103111
# TODO: s.history should be SubRunObj attribute not RunObj
104112
# s.history only working for CALIBRATION sequence (run-wise), since it is
@@ -115,6 +123,12 @@ def are_all_jobs_correctly_finished(sequence_list):
115123
f"finished up to DL1ab, but --no-dl2 option selected"
116124
)
117125
continue
126+
if out == 3 and options.no_dl1ab:
127+
log.debug(
128+
f"Job {sequence.seq} ({sequence.type}) correctly "
129+
f"finished up to DL1A, but --no-dl1ab option selected"
130+
)
131+
continue
118132

119133
log.warning(
120134
f"Job {sequence.seq} (run {sequence.run}) not correctly finished [level {out}]"
@@ -221,6 +235,8 @@ def historylevel(history_file: Path, data_type: str):
221235
# Data sequence
222236
elif program == cfg.get("lstchain", "r0_to_dl1"):
223237
level = 3 if exit_status == 0 else 4
238+
#elif program == cfg.get("lstchain", "catB_calibration"):
239+
# level = 3 if exit_status == 0 else 4
224240
elif program == cfg.get("lstchain", "dl1ab"):
225241
if (exit_status == 0) and (prod_id == options.dl1_prod_id):
226242
log.debug(f"DL1ab prod ID: {options.dl1_prod_id} already produced")
@@ -431,6 +447,8 @@ def data_sequence_job_template(sequence):
431447
commandargs.extend(("--config", f"{Path(options.configfile).resolve()}"))
432448
if sequence.type == "DATA" and options.no_dl2:
433449
commandargs.append("--no-dl2")
450+
if sequence.type == "DATA" and options.no_dl1ab:
451+
commandargs.append("--no-dl1ab")
434452

435453
commandargs.extend(
436454
(

Diff for: src/osa/paths.py

+38-17
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
from typing import List
88
import subprocess
99
import time
10-
10+
import json
1111
import lstchain
1212
from astropy.table import Table
1313
from lstchain.onsite import (find_systematics_correction_file,
14-
find_time_calibration_file,
15-
find_filter_wheels)
14+
find_time_calibration_file)
1615

1716
from osa.configs import options
1817
from osa.configs.config import DEFAULT_CFG, cfg
@@ -45,8 +44,8 @@
4544

4645

4746
DATACHECK_WEB_BASEDIR = Path(cfg.get("WEBSERVER", "DATACHECK"))
48-
CALIB_BASEDIR = Path(cfg.get("LST1", "CALIB_DIR"))
49-
DRS4_PEDESTAL_BASEDIR = Path(cfg.get("LST1", "PEDESTAL_DIR"))
47+
CALIB_BASEDIR = Path(cfg.get("LST1", "CAT_A_CALIB_DIR"))
48+
DRS4_PEDESTAL_BASEDIR = Path(cfg.get("LST1", "CAT_A_PEDESTAL_DIR"))
5049

5150

5251
def analysis_path(tel) -> Path:
@@ -136,18 +135,7 @@ def get_calibration_filename(run_id: int, prod_id: str) -> Path:
136135
return files[-1] # Get the latest production among the major lstchain version
137136

138137
date = utils.date_to_dir(get_run_date(run_id))
139-
140-
if options.test: # Run tests avoiding the access to the database
141-
options.filters = 52
142-
143-
else:
144-
mongodb = cfg.get("database", "caco_db")
145-
try:
146-
# Cast run_id to int to avoid problems with numpy int64 encoding in MongoDB
147-
options.filters = find_filter_wheels(int(run_id), mongodb)
148-
except IOError:
149-
log.warning("No filter information found in database. Assuming positions 52.")
150-
options.filters = 52
138+
options.filters = utils.get_calib_filters(run_id)
151139

152140
return (
153141
CALIB_BASEDIR
@@ -156,6 +144,15 @@ def get_calibration_filename(run_id: int, prod_id: str) -> Path:
156144
).resolve()
157145

158146

147+
def get_catB_calibration_filename(run_id: int) -> Path:
148+
"""Return the Category-B calibration filename of a given run."""
149+
date = utils.date_to_dir(options.date)
150+
calib_prod_id = utils.get_lstchain_version()
151+
catB_calib_dir = Path(cfg.get("LST1", "CAT_B_CALIB_BASE")) / "calibration" / date / calib_prod_id
152+
filters = utils.get_calib_filters(run_id)
153+
return catB_calib_dir / f"cat_B_calibration_filters_{filters}.Run{run_id:05d}.h5"
154+
155+
159156
def pedestal_ids_file_exists(run_id: int) -> bool:
160157
"""Look for the files with pedestal interleaved event identification."""
161158
pedestal_ids_dir = Path(cfg.get("LST1", "PEDESTAL_FINDER_DIR"))
@@ -405,3 +402,27 @@ def dl1_datacheck_longterm_file_exits() -> bool:
405402
longterm_file = longterm_dir / options.prod_id / nightdir / f"DL1_datacheck_{nightdir}.h5"
406403
return longterm_file.exists()
407404

405+
406+
def catB_closed_file_exists(run_id: int) -> bool:
407+
catB_closed_file = Path(options.directory) / f"catB_{run_id:05d}.closed"
408+
return catB_closed_file.exists()
409+
410+
411+
def catB_calibration_file_exists(run_id: int) -> bool:
412+
catB_calib_base_dir = Path(cfg.get("LST1","CAT_B_CALIB_BASE"))
413+
prod_id = utils.get_lstchain_version()
414+
night_dir = utils.date_to_dir(options.date)
415+
filters = utils.get_calib_filters(run_id)
416+
catB_calib_dir = catB_calib_base_dir / "calibration" / night_dir / prod_id
417+
catB_calib_file = catB_calib_dir / f"cat_B_calibration_filters_{filters}.Run{run_id:05d}.h5"
418+
return catB_calib_file.exists()
419+
420+
421+
def get_dl1_prod_id(config_filename):
422+
with open(config_filename) as json_file:
423+
data = json.load(json_file)
424+
425+
picture_thresh = data["tailcuts_clean_with_pedestal_threshold"]["picture_thresh"]
426+
boundary_thresh = data["tailcuts_clean_with_pedestal_threshold"]["boundary_thresh"]
427+
428+
return f"tailcut{picture_thresh}{boundary_thresh}"

Diff for: src/osa/provenance/capture.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
PROV_PREFIX = provconfig["PREFIX"]
5454
SUPPORTED_HASH_METHOD = ["md5"]
5555
SUPPORTED_HASH_BUFFER = ["content", "path"]
56-
REDUCTION_TASKS = ["r0_to_dl1", "dl1ab", "dl1_datacheck", "dl1_to_dl2"]
56+
REDUCTION_TASKS = ["r0_to_dl1", "catB_calibration", "dl1ab", "dl1_datacheck", "dl1_to_dl2"]
5757

5858
# global variables
5959
traced_entities = {}

Diff for: src/osa/provenance/config/definition.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@ activities:
200200
# filepath: /fefs/aswg/data/real/DL1/20200218/v0.4.3_v00/
201201
# size: 128
202202

203+
catB_calibration:
204+
description:
205+
"Create Cat-B calibration file for an observation run"
206+
parameters:
207+
usage:
208+
generation:
209+
203210
dl1ab:
204211
description:
205212
"Create DL1AB files for an observation run"

Diff for: src/osa/provenance/utils.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
__all__ = ["parse_variables", "get_log_config"]
1212

13-
REDUCTION_TASKS = ["r0_to_dl1", "dl1ab", "dl1_datacheck", "dl1_to_dl2"]
13+
REDUCTION_TASKS = ["r0_to_dl1", "catB_calibration", "dl1ab", "dl1_datacheck", "dl1_to_dl2"]
1414

1515

1616
def parse_variables(class_instance):
@@ -43,8 +43,8 @@ def parse_variables(class_instance):
4343
rf_models_directory = Path(cfg.get("LST1", "RF_MODELS"))
4444
dl1_dir = Path(cfg.get("LST1", "DL1_DIR"))
4545
dl2_dir = Path(cfg.get("LST1", "DL2_DIR"))
46-
calib_dir = Path(cfg.get("LST1", "CALIB_DIR"))
47-
pedestal_dir = Path(cfg.get("LST1", "PEDESTAL_DIR"))
46+
calib_dir = Path(cfg.get("LST1", "CAT_A_CALIB_DIR"))
47+
pedestal_dir = Path(cfg.get("LST1", "CAT_A_PEDESTAL_DIR"))
4848

4949
class_instance.SoftwareVersion = get_lstchain_version()
5050
class_instance.ProcessingConfigFile = str(options.configfile)
@@ -133,6 +133,9 @@ def parse_variables(class_instance):
133133
class_instance.InterleavedPedestalEventsFile = None
134134
if class_instance.args[6] is not None:
135135
class_instance.InterleavedPedestalEventsFile = str(Path(class_instance.args[6]))
136+
137+
if class_instance.__name__ == "catB_calibration":
138+
class_instance.ObservationRun = class_instance.args[0].split(".")[0]
136139

137140
if class_instance.__name__ == "dl1ab":
138141
# run_str [0] 02006.0000

Diff for: src/osa/scripts/calibration_pipeline.py

+4
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,27 @@ def is_calibration_produced(drs4_pedestal_run_id: int, pedcal_run_id: int) -> bo
4444
def drs4_pedestal_command(drs4_pedestal_run_id: int) -> list:
4545
"""Build the create_drs4_pedestal command."""
4646
base_dir = Path(cfg.get("LST1", "BASE")).resolve()
47+
r0_dir = Path(cfg.get("LST1", "R0_DIR")).resolve()
4748
command = cfg.get("lstchain", "drs4_baseline")
4849
return [
4950
command,
5051
"-r", str(drs4_pedestal_run_id),
5152
"-b", base_dir,
53+
f"--r0-dir={r0_dir}",
5254
"--no-progress",
5355
]
5456

5557
def calibration_file_command(drs4_pedestal_run_id: int, pedcal_run_id: int) -> list:
5658
"""Build the create_calibration_file command."""
5759
base_dir = Path(cfg.get("LST1", "BASE")).resolve()
60+
r0_dir = Path(cfg.get("LST1", "R0_DIR")).resolve()
5861
command = cfg.get("lstchain", "charge_calibration")
5962
cmd = [
6063
command,
6164
"-p", str(drs4_pedestal_run_id),
6265
"-r", str(pedcal_run_id),
6366
"-b", base_dir,
67+
f"--r0-dir={r0_dir}",
6468
]
6569
# In case of problems with trigger tagging:
6670
if cfg.getboolean("lstchain", "use_ff_heuristic_id"):

0 commit comments

Comments
 (0)