roc-film 1.13.5__py3-none-any.whl → 1.14.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- roc/__init__.py +2 -1
- roc/film/__init__.py +2 -2
- roc/film/commands.py +372 -323
- roc/film/config/__init__.py +0 -1
- roc/film/constants.py +101 -65
- roc/film/descriptor.json +127 -96
- roc/film/exceptions.py +28 -27
- roc/film/tasks/__init__.py +16 -16
- roc/film/tasks/cat_solo_hk.py +86 -74
- roc/film/tasks/cdf_postpro.py +438 -309
- roc/film/tasks/check_dds.py +39 -45
- roc/film/tasks/db_to_anc_bia_sweep_table.py +381 -0
- roc/film/tasks/dds_to_l0.py +232 -180
- roc/film/tasks/export_solo_coord.py +147 -0
- roc/film/tasks/file_handler.py +91 -75
- roc/film/tasks/l0_to_hk.py +117 -103
- roc/film/tasks/l0_to_l1_bia_current.py +38 -30
- roc/film/tasks/l0_to_l1_bia_sweep.py +417 -329
- roc/film/tasks/l0_to_l1_sbm.py +250 -208
- roc/film/tasks/l0_to_l1_surv.py +185 -130
- roc/film/tasks/make_daily_tm.py +40 -37
- roc/film/tasks/merge_tcreport.py +77 -71
- roc/film/tasks/merge_tmraw.py +101 -88
- roc/film/tasks/parse_dds_xml.py +21 -20
- roc/film/tasks/set_l0_utc.py +51 -49
- roc/film/tests/cdf_compare.py +565 -0
- roc/film/tests/hdf5_compare.py +84 -62
- roc/film/tests/test_dds_to_l0.py +93 -51
- roc/film/tests/test_dds_to_tc.py +8 -11
- roc/film/tests/test_dds_to_tm.py +8 -10
- roc/film/tests/test_film.py +161 -116
- roc/film/tests/test_l0_to_hk.py +64 -36
- roc/film/tests/test_l0_to_l1_bia.py +10 -14
- roc/film/tests/test_l0_to_l1_sbm.py +14 -19
- roc/film/tests/test_l0_to_l1_surv.py +68 -41
- roc/film/tests/test_metadata.py +21 -20
- roc/film/tests/tests.py +743 -396
- roc/film/tools/__init__.py +5 -5
- roc/film/tools/dataset_tasks.py +34 -2
- roc/film/tools/file_helpers.py +390 -269
- roc/film/tools/l0.py +402 -324
- roc/film/tools/metadata.py +147 -127
- roc/film/tools/skeleton.py +12 -17
- roc/film/tools/tools.py +109 -92
- roc/film/tools/xlsx2skt.py +161 -139
- {roc_film-1.13.5.dist-info → roc_film-1.14.0.dist-info}/LICENSE +127 -125
- roc_film-1.14.0.dist-info/METADATA +60 -0
- roc_film-1.14.0.dist-info/RECORD +50 -0
- {roc_film-1.13.5.dist-info → roc_film-1.14.0.dist-info}/WHEEL +1 -1
- roc/film/tasks/l0_to_anc_bia_sweep_table.py +0 -348
- roc_film-1.13.5.dist-info/METADATA +0 -120
- roc_film-1.13.5.dist-info/RECORD +0 -48
roc/film/tasks/parse_dds_xml.py
CHANGED
@@ -13,61 +13,62 @@ from poppy.core.target import FileTarget, PyObjectTarget
|
|
13
13
|
|
14
14
|
from edds_process.response import xml_to_dict
|
15
15
|
|
16
|
-
__all__ = [
|
16
|
+
__all__ = ["ParseDdsXml"]
|
17
|
+
|
17
18
|
|
18
19
|
class ParseDdsXml(Task):
|
19
20
|
"""
|
20
21
|
Task to parse an input DDS TmRaw XML file
|
21
22
|
and return content as a dictionary.
|
22
23
|
"""
|
23
|
-
|
24
|
-
|
24
|
+
|
25
|
+
plugin_name = "roc.film"
|
26
|
+
name = "parse_dds_xml"
|
25
27
|
|
26
28
|
def add_targets(self):
|
27
|
-
self.add_input(
|
28
|
-
|
29
|
-
|
30
|
-
self.add_output(identifier=
|
31
|
-
target_class=PyObjectTarget)
|
29
|
+
self.add_input(
|
30
|
+
identifier="dds_xml", filepath=self.get_dds_xml(), target_class=FileTarget
|
31
|
+
)
|
32
|
+
self.add_output(identifier="dds_data", target_class=PyObjectTarget)
|
32
33
|
|
33
34
|
def get_dds_xml(self):
|
34
|
-
return self.pipeline.get(
|
35
|
+
return self.pipeline.get("dds_xml", default=[])
|
35
36
|
|
36
37
|
def setup_inputs(self):
|
37
|
-
|
38
38
|
# Get input DDS XML file
|
39
39
|
dds_file = None
|
40
40
|
try:
|
41
|
-
dds_file = self.inputs[
|
41
|
+
dds_file = self.inputs["dds_xml"].filepath
|
42
42
|
if not os.path.isfile(dds_file):
|
43
43
|
raise FileNotFoundError
|
44
|
-
except:
|
45
|
-
logger.exception(f"Cannot load input DDS XML file
|
44
|
+
except Exception as e:
|
45
|
+
logger.exception(f"Cannot load input DDS XML file {dds_file}:\n{e}")
|
46
46
|
return False
|
47
47
|
else:
|
48
48
|
self.dds_file = dds_file
|
49
49
|
|
50
50
|
# Get/create list of well processed DDS files
|
51
51
|
self.processed_dds_files = self.pipeline.get(
|
52
|
-
|
52
|
+
"processed_dds_files", default=[], create=True
|
53
|
+
)
|
53
54
|
# Get/create list of failed DDS files
|
54
55
|
self.failed_dds_files = self.pipeline.get(
|
55
|
-
|
56
|
+
"failed_dds_files", default=[], create=True
|
57
|
+
)
|
56
58
|
|
57
59
|
return True
|
58
60
|
|
59
61
|
def run(self):
|
60
|
-
|
61
62
|
if not self.setup_inputs():
|
62
63
|
return
|
63
64
|
|
64
65
|
try:
|
65
|
-
logger.info(f
|
66
|
+
logger.info(f"Parsing {self.dds_file}...")
|
66
67
|
dds_data = xml_to_dict(self.dds_file)
|
67
|
-
except:
|
68
|
-
logger.exception(f"Cannot parse input DDS XML file
|
68
|
+
except Exception as e:
|
69
|
+
logger.exception(f"Cannot parse input DDS XML file {self.dds_file}:\n{e}")
|
69
70
|
self.failed_dds_files.append(self.dds_file)
|
70
71
|
return
|
71
72
|
else:
|
72
|
-
self.outputs[
|
73
|
+
self.outputs["dds_data"].value = dds_data
|
73
74
|
self.processed_dds_files.append(self.dds_file)
|
roc/film/tasks/set_l0_utc.py
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
|
4
4
|
"""Contains task to set the utc_time values of L0 TM/TC packets."""
|
5
5
|
|
6
|
-
|
7
6
|
import os
|
8
7
|
import shutil
|
9
8
|
from datetime import datetime
|
@@ -18,29 +17,30 @@ from roc.film import TIME_ISO_STRFORMAT
|
|
18
17
|
from roc.film.tools.file_helpers import get_output_dir
|
19
18
|
from roc.film.tools.l0 import L0
|
20
19
|
|
21
|
-
__all__ = [
|
20
|
+
__all__ = ["SetL0Utc"]
|
21
|
+
|
22
22
|
|
23
23
|
class SetL0Utc(Task):
|
24
24
|
"""
|
25
25
|
Set the UTC times of the input L0 file using SolO SPICE kernels.
|
26
26
|
"""
|
27
|
-
|
28
|
-
|
27
|
+
|
28
|
+
plugin_name = "roc.film"
|
29
|
+
name = "set_l0_utc"
|
29
30
|
|
30
31
|
def add_targets(self):
|
31
|
-
self.add_input(
|
32
|
-
|
33
|
-
|
34
|
-
self.add_output(target_class=FileTarget,
|
35
|
-
identifier='l0_file')
|
32
|
+
self.add_input(
|
33
|
+
target_class=FileTarget, identifier="l0_file", filepath=self.get_l0_file()
|
34
|
+
)
|
35
|
+
self.add_output(target_class=FileTarget, identifier="l0_file")
|
36
36
|
|
37
37
|
def get_l0_file(self):
|
38
|
-
return self.pipeline.get(
|
38
|
+
return self.pipeline.get("l0_file", default=[None])[0]
|
39
39
|
|
40
40
|
def setup_inputs(self):
|
41
|
-
self.l0_file = self.inputs[
|
41
|
+
self.l0_file = self.inputs["l0_file"].filepath
|
42
42
|
if not os.path.isfile(self.l0_file):
|
43
|
-
logger.error(f
|
43
|
+
logger.error(f"Input file {self.l0_file} not found!")
|
44
44
|
return False
|
45
45
|
|
46
46
|
# Get time instance
|
@@ -48,49 +48,47 @@ class SetL0Utc(Task):
|
|
48
48
|
|
49
49
|
# Pass input arguments for the Time instance
|
50
50
|
self.time.kernel_date = self.pipeline.get(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
self.time.no_spice = self.pipeline.get(
|
55
|
-
'no_spice', default=False, args=True)
|
51
|
+
"kernel_date", default=None, args=True
|
52
|
+
)
|
53
|
+
self.time.predictive = self.pipeline.get("predictive", default=True, args=True)
|
54
|
+
self.time.no_spice = self.pipeline.get("no_spice", default=False, args=True)
|
56
55
|
|
57
56
|
# Get/create list of well processed L0 files
|
58
57
|
self.processed_files = self.pipeline.get(
|
59
|
-
|
58
|
+
"processed_files", default=[], create=True
|
59
|
+
)
|
60
60
|
# Get/create list of failed DDS files
|
61
|
-
self.failed_files = self.pipeline.get(
|
62
|
-
'failed_files', default=[], create=True)
|
61
|
+
self.failed_files = self.pipeline.get("failed_files", default=[], create=True)
|
63
62
|
|
64
63
|
# If output directory not found, create it
|
65
64
|
self.output_dir = get_output_dir(self.pipeline)
|
66
65
|
if not os.path.isdir(self.output_dir):
|
67
|
-
logger.debug(f
|
66
|
+
logger.debug(f"Making {self.output_dir}...")
|
68
67
|
os.makedirs(self.output_dir)
|
69
68
|
|
70
69
|
return True
|
71
70
|
|
72
71
|
def run(self):
|
73
|
-
|
74
72
|
# Load/Initialize task inputs
|
75
73
|
if not self.setup_inputs():
|
76
74
|
return
|
77
75
|
|
78
76
|
# Make a copy of the input L0 file
|
79
|
-
l0_copy = os.path.join(self.output_dir,
|
80
|
-
os.path.basename(self.l0_file))
|
77
|
+
l0_copy = os.path.join(self.output_dir, os.path.basename(self.l0_file))
|
81
78
|
shutil.copyfile(self.l0_file, l0_copy)
|
82
79
|
|
83
80
|
if not self._set_utc_time(l0_copy):
|
84
|
-
logger.info(
|
85
|
-
|
81
|
+
logger.info(
|
82
|
+
f"{self.l0_file} does not need to be updated "
|
83
|
+
f"(delete copy in {self.output_dir})"
|
84
|
+
)
|
86
85
|
os.remove(l0_copy)
|
87
86
|
else:
|
88
|
-
logger.debug(
|
87
|
+
logger.debug("Make sure to have sorted/unique utc time values")
|
89
88
|
L0.order_by_utc(l0_copy, unique=True, update_time_minmax=True)
|
90
|
-
logger.info(f
|
89
|
+
logger.info(f"{l0_copy} updated")
|
91
90
|
|
92
91
|
def _set_utc_time(self, l0_file):
|
93
|
-
|
94
92
|
# Flag to indicate if the L0 file content has been changed at the end
|
95
93
|
# (or if the L0 already uses the latest SPICE kernels to compute time).
|
96
94
|
# If has_changed = False, then do not need to update the L0, if True then
|
@@ -98,62 +96,66 @@ class SetL0Utc(Task):
|
|
98
96
|
has_changed = False
|
99
97
|
|
100
98
|
# SPICE SCLK kernel name prefix
|
101
|
-
sclk_prefix =
|
99
|
+
sclk_prefix = "solo_ANC_soc-sclk"
|
102
100
|
|
103
101
|
# Get loaded SPICE kernels
|
104
102
|
loaded_kernel_list = self.time.spice.kall()
|
105
103
|
if not loaded_kernel_list:
|
106
|
-
logger.warning(
|
104
|
+
logger.warning("No SPICE kernel loaded, exiting")
|
107
105
|
return has_changed
|
108
106
|
else:
|
109
107
|
# Keep only SCLK kernels
|
110
|
-
loaded_sclk_list = [
|
111
|
-
|
112
|
-
|
108
|
+
loaded_sclk_list = [
|
109
|
+
kfile for kfile in loaded_kernel_list.keys() if sclk_prefix in kfile
|
110
|
+
]
|
113
111
|
loaded_sclk_num = len(loaded_sclk_list)
|
114
112
|
if loaded_sclk_num == 0:
|
115
|
-
logger.warning(
|
113
|
+
logger.warning("No SPICE SCLK kernel loaded, exiting")
|
116
114
|
return has_changed
|
117
115
|
else:
|
118
116
|
# Get loaded SCLK (latest)
|
119
117
|
loaded_sclk = os.path.basename(loaded_sclk_list[-1])
|
120
118
|
|
121
119
|
# Open L0 file
|
122
|
-
with h5py.File(l0_file,
|
123
|
-
|
120
|
+
with h5py.File(l0_file, "a") as l0:
|
124
121
|
# Check if utc time values need to be updated
|
125
122
|
# To achieve it, re-compute UTC times with loaded kernels
|
126
123
|
# and compare with current values in the L0
|
127
|
-
cat =
|
124
|
+
cat = "TM"
|
128
125
|
if cat in l0.keys():
|
129
126
|
# Loop over each TM packet in L0
|
130
127
|
for packet_name in l0[cat].keys():
|
131
128
|
# Get packet UTC times
|
132
|
-
utc_time = [
|
133
|
-
|
129
|
+
utc_time = [
|
130
|
+
datetime.strptime(current_time[:-4] + "Z", TIME_ISO_STRFORMAT)
|
131
|
+
for current_time in l0[cat][packet_name]["utc_time"][()]
|
132
|
+
]
|
134
133
|
|
135
134
|
# Compute UTC times with current SPICE kernels from
|
136
135
|
# array of time in packet data_field_header
|
137
|
-
new_utc_time = self.time.obt_to_utc(
|
138
|
-
|
139
|
-
|
136
|
+
new_utc_time = self.time.obt_to_utc(
|
137
|
+
(l0[cat][packet_name]["data_field_header"]["time"][()])[:, :2],
|
138
|
+
to_datetime=True,
|
139
|
+
)
|
140
140
|
try:
|
141
141
|
# Compare current L0 utc time values with new ones
|
142
142
|
assert utc_time == new_utc_time
|
143
143
|
except AssertionError:
|
144
144
|
# If not equal, then update L0 UTC Times with loaded
|
145
145
|
# SCLK kernel
|
146
|
-
l0[cat][packet_name][
|
147
|
-
logger.debug(
|
148
|
-
|
146
|
+
l0[cat][packet_name]["utc_time"][...] = new_utc_time
|
147
|
+
logger.debug(
|
148
|
+
f"UTC time values updated for {packet_name} in {l0_file}"
|
149
|
+
)
|
149
150
|
has_changed = True
|
150
151
|
else:
|
151
|
-
logger.debug(
|
152
|
-
|
152
|
+
logger.debug(
|
153
|
+
f"Same UTC time values found for {packet_name} in {l0_file}"
|
154
|
+
)
|
153
155
|
|
154
156
|
# If UTC times have been updated, set the new SCLK filename
|
155
157
|
# in the SPICE_KERNELS attribute
|
156
158
|
if has_changed:
|
157
|
-
l0.attrs[
|
159
|
+
l0.attrs["SPICE_KERNELS"] = loaded_sclk
|
158
160
|
|
159
161
|
return has_changed
|