spectre-core 0.0.12__py3-none-any.whl → 0.0.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spectre_core/_file_io/__init__.py +1 -3
- spectre_core/_file_io/file_handlers.py +163 -58
- spectre_core/batches/__init__.py +10 -11
- spectre_core/batches/_base.py +170 -78
- spectre_core/batches/_batches.py +149 -99
- spectre_core/batches/_factory.py +56 -14
- spectre_core/batches/_register.py +23 -8
- spectre_core/batches/plugins/_batch_keys.py +16 -0
- spectre_core/batches/plugins/_callisto.py +183 -0
- spectre_core/batches/plugins/_iq_stream.py +354 -0
- spectre_core/capture_configs/__init__.py +17 -13
- spectre_core/capture_configs/_capture_config.py +93 -34
- spectre_core/capture_configs/_capture_modes.py +22 -0
- spectre_core/capture_configs/_capture_templates.py +207 -122
- spectre_core/capture_configs/_parameters.py +115 -42
- spectre_core/capture_configs/_pconstraints.py +86 -35
- spectre_core/capture_configs/_pnames.py +49 -0
- spectre_core/capture_configs/_ptemplates.py +389 -346
- spectre_core/capture_configs/_pvalidators.py +117 -73
- spectre_core/config/__init__.py +6 -8
- spectre_core/config/_paths.py +65 -25
- spectre_core/config/_time_formats.py +15 -10
- spectre_core/exceptions.py +2 -4
- spectre_core/jobs/__init__.py +14 -0
- spectre_core/jobs/_jobs.py +111 -0
- spectre_core/jobs/_workers.py +171 -0
- spectre_core/logs/__init__.py +17 -0
- spectre_core/logs/_configure.py +67 -0
- spectre_core/logs/_decorators.py +33 -0
- spectre_core/logs/_logs.py +228 -0
- spectre_core/logs/_process_types.py +14 -0
- spectre_core/plotting/__init__.py +4 -2
- spectre_core/plotting/_base.py +204 -102
- spectre_core/plotting/_format.py +17 -4
- spectre_core/plotting/_panel_names.py +18 -0
- spectre_core/plotting/_panel_stack.py +167 -53
- spectre_core/plotting/_panels.py +341 -141
- spectre_core/post_processing/__init__.py +8 -6
- spectre_core/post_processing/_base.py +70 -44
- spectre_core/post_processing/_factory.py +42 -12
- spectre_core/post_processing/_post_processor.py +24 -26
- spectre_core/post_processing/_register.py +22 -6
- spectre_core/post_processing/plugins/_event_handler_keys.py +16 -0
- spectre_core/post_processing/plugins/_fixed_center_frequency.py +129 -0
- spectre_core/post_processing/{library → plugins}/_swept_center_frequency.py +215 -143
- spectre_core/py.typed +0 -0
- spectre_core/receivers/__init__.py +10 -7
- spectre_core/receivers/_base.py +220 -69
- spectre_core/receivers/_factory.py +53 -7
- spectre_core/receivers/_register.py +30 -9
- spectre_core/receivers/_spec_names.py +26 -15
- spectre_core/receivers/plugins/__init__.py +0 -0
- spectre_core/receivers/plugins/_receiver_names.py +16 -0
- spectre_core/receivers/plugins/_rsp1a.py +59 -0
- spectre_core/receivers/plugins/_rspduo.py +67 -0
- spectre_core/receivers/plugins/_sdrplay_receiver.py +190 -0
- spectre_core/receivers/plugins/_test.py +218 -0
- spectre_core/receivers/plugins/gr/_base.py +80 -0
- spectre_core/receivers/{gr → plugins/gr}/_rsp1a.py +42 -52
- spectre_core/receivers/{gr → plugins/gr}/_rspduo.py +61 -74
- spectre_core/receivers/{gr → plugins/gr}/_test.py +33 -31
- spectre_core/spectrograms/__init__.py +5 -3
- spectre_core/spectrograms/_analytical.py +121 -66
- spectre_core/spectrograms/_array_operations.py +103 -36
- spectre_core/spectrograms/_spectrogram.py +380 -207
- spectre_core/spectrograms/_transform.py +197 -169
- spectre_core/wgetting/__init__.py +4 -2
- spectre_core/wgetting/_callisto.py +173 -118
- {spectre_core-0.0.12.dist-info → spectre_core-0.0.13.dist-info}/METADATA +14 -7
- spectre_core-0.0.13.dist-info/RECORD +75 -0
- {spectre_core-0.0.12.dist-info → spectre_core-0.0.13.dist-info}/WHEEL +1 -1
- spectre_core/batches/library/_callisto.py +0 -96
- spectre_core/batches/library/_fixed_center_frequency.py +0 -133
- spectre_core/batches/library/_swept_center_frequency.py +0 -105
- spectre_core/logging/__init__.py +0 -11
- spectre_core/logging/_configure.py +0 -35
- spectre_core/logging/_decorators.py +0 -19
- spectre_core/logging/_log_handlers.py +0 -176
- spectre_core/post_processing/library/_fixed_center_frequency.py +0 -114
- spectre_core/receivers/gr/_base.py +0 -33
- spectre_core/receivers/library/_rsp1a.py +0 -61
- spectre_core/receivers/library/_rspduo.py +0 -69
- spectre_core/receivers/library/_sdrplay_receiver.py +0 -185
- spectre_core/receivers/library/_test.py +0 -221
- spectre_core-0.0.12.dist-info/RECORD +0 -64
- /spectre_core/receivers/{gr → plugins/gr}/__init__.py +0 -0
- {spectre_core-0.0.12.dist-info → spectre_core-0.0.13.dist-info}/LICENSE +0 -0
- {spectre_core-0.0.12.dist-info → spectre_core-0.0.13.dist-info}/top_level.txt +0 -0
@@ -7,145 +7,200 @@ import subprocess
|
|
7
7
|
import shutil
|
8
8
|
import gzip
|
9
9
|
from datetime import datetime
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
"
|
17
|
-
"ALASKA-
|
18
|
-
"
|
19
|
-
"
|
20
|
-
"
|
21
|
-
"
|
22
|
-
"AUSTRIA-
|
23
|
-
"AUSTRIA-
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"
|
31
|
-
"
|
32
|
-
"
|
33
|
-
"
|
34
|
-
"
|
35
|
-
"
|
36
|
-
"
|
37
|
-
"
|
38
|
-
"
|
39
|
-
"INDIA-
|
40
|
-
"
|
41
|
-
"
|
42
|
-
"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"MEXICO-
|
46
|
-
"
|
47
|
-
"
|
48
|
-
"
|
49
|
-
"
|
50
|
-
"
|
51
|
-
"
|
52
|
-
"NORWAY-
|
53
|
-
"
|
54
|
-
"
|
55
|
-
"
|
56
|
-
"
|
57
|
-
"
|
58
|
-
"
|
59
|
-
"
|
60
|
-
"SWISS-
|
61
|
-
"SWISS-
|
62
|
-
"SWISS-
|
63
|
-
"
|
64
|
-
"
|
65
|
-
"
|
66
|
-
"
|
67
|
-
"
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
10
|
+
|
11
|
+
from spectre_core.config import get_spectre_data_dir_path, get_batches_dir_path, TimeFormat
|
12
|
+
|
13
|
+
from enum import Enum
|
14
|
+
|
15
|
+
class CallistoInstrumentCode(Enum):
|
16
|
+
"""e-Callisto network station codes."""
|
17
|
+
ALASKA_ANCHORAGE = "ALASKA-ANCHORAGE"
|
18
|
+
ALASKA_COHOE = "ALASKA-COHOE"
|
19
|
+
ALASKA_HAARP = "ALASKA-HAARP"
|
20
|
+
ALGERIA_CRAAG = "ALGERIA-CRAAG"
|
21
|
+
ALMATY = "ALMATY"
|
22
|
+
AUSTRIA_KRUMBACH = "AUSTRIA-Krumbach"
|
23
|
+
AUSTRIA_MICHELBACH = "AUSTRIA-MICHELBACH"
|
24
|
+
AUSTRIA_OE3FLB = "AUSTRIA-OE3FLB"
|
25
|
+
AUSTRIA_UNIGRAZ = "AUSTRIA-UNIGRAZ"
|
26
|
+
AUSTRALIA_ASSA = "Australia-ASSA"
|
27
|
+
BIR = "BIR"
|
28
|
+
CROATIA_VISNJAN = "Croatia-Visnjan"
|
29
|
+
DENMARK = "DENMARK"
|
30
|
+
EGYPT_ALEXANDRIA = "EGYPT-Alexandria"
|
31
|
+
EGYPT_SPACEAGENCY = "EGYPT-SpaceAgency"
|
32
|
+
FINLAND_SIUNTIO = "FINLAND-Siuntio"
|
33
|
+
FINLAND_KEMPELE = "Finland-Kempele"
|
34
|
+
GERMANY_DLR = "GERMANY-DLR"
|
35
|
+
GLASGOW = "GLASGOW"
|
36
|
+
GREENLAND = "GREENLAND"
|
37
|
+
HUMAIN = "HUMAIN"
|
38
|
+
HURBANOVO = "HURBANOVO"
|
39
|
+
INDIA_GAURI = "INDIA-GAURI"
|
40
|
+
INDIA_OOTY = "INDIA-OOTY"
|
41
|
+
INDIA_UDAIPUR = "INDIA-UDAIPUR"
|
42
|
+
JAPAN_IBARAKI = "JAPAN-IBARAKI"
|
43
|
+
KASI = "KASI"
|
44
|
+
MEXART = "MEXART"
|
45
|
+
MEXICO_FCFM_UANL = "MEXICO-FCFM-UANL"
|
46
|
+
MEXICO_LANCE_A = "MEXICO-LANCE-A"
|
47
|
+
MEXICO_LANCE_B = "MEXICO-LANCE-B"
|
48
|
+
MONGOLIA_UB = "MONGOLIA-UB"
|
49
|
+
MRO = "MRO"
|
50
|
+
MRT3 = "MRT3"
|
51
|
+
MALAYSIA_BANTING = "Malaysia-Banting"
|
52
|
+
NORWAY_EGERSUND = "NORWAY-EGERSUND"
|
53
|
+
NORWAY_NY_AALESUND = "NORWAY-NY-AALESUND"
|
54
|
+
NORWAY_RANDABERG = "NORWAY-RANDABERG"
|
55
|
+
POLAND_GROTNIKI = "POLAND-Grotniki"
|
56
|
+
ROMANIA = "ROMANIA"
|
57
|
+
ROSWELL_NM = "ROSWELL-NM"
|
58
|
+
SPAIN_PERALEJOS = "SPAIN-PERALEJOS"
|
59
|
+
SSRT = "SSRT"
|
60
|
+
SWISS_HB9SCT = "SWISS-HB9SCT"
|
61
|
+
SWISS_HEITERSWIL = "SWISS-HEITERSWIL"
|
62
|
+
SWISS_IRSOL = "SWISS-IRSOL"
|
63
|
+
SWISS_LANDSCHLACHT = "SWISS-Landschlacht"
|
64
|
+
SWISS_MUHEN = "SWISS-MUHEN"
|
65
|
+
TRIEST = "TRIEST"
|
66
|
+
TURKEY = "TURKEY"
|
67
|
+
UNAM = "UNAM"
|
68
|
+
URUGUAY = "URUGUAY"
|
69
|
+
USA_BOSTON = "USA-BOSTON"
|
70
|
+
|
71
|
+
|
72
|
+
def _get_batch_name(
|
73
|
+
station: str,
|
74
|
+
date: str,
|
75
|
+
time: str,
|
76
|
+
code: str
|
77
|
+
) -> str:
|
78
|
+
"""
|
79
|
+
Create a standardised batch file name for a `spectre` batch file.
|
80
|
+
|
81
|
+
:param station: Station name.
|
82
|
+
:param date: Observation date in 'YYYYMMDD' format.
|
83
|
+
:param time: Observation time in 'HHMMSS' format.
|
84
|
+
:param code: Numeric instrument code.
|
85
|
+
:return: Formatted batch file name.
|
86
|
+
"""
|
87
|
+
dt = datetime.strptime(f"{date}T{time}", "%Y%m%dT%H%M%S")
|
88
|
+
formatted_time = dt.strftime(TimeFormat.DATETIME)
|
89
|
+
return f"{formatted_time}_callisto-{station.lower()}-{code}.fits"
|
90
|
+
|
91
|
+
|
92
|
+
def _get_batch_components(
|
93
|
+
gz_path: str
|
94
|
+
) -> list[str]:
|
95
|
+
"""
|
96
|
+
Extract station, date, time, and instrument code from the `.fit.gz` file name.
|
97
|
+
|
98
|
+
:param gz_path: Path to the `.fit.gz` file.
|
99
|
+
:return: List of [station, date, time, instrument_code].
|
100
|
+
:raises ValueError: If file format is invalid.
|
101
|
+
"""
|
80
102
|
file_name = os.path.basename(gz_path)
|
81
103
|
if not file_name.endswith(".fit.gz"):
|
82
|
-
raise ValueError(f"
|
83
|
-
|
104
|
+
raise ValueError(f"Invalid file extension: {file_name}. Expected .fit.gz")
|
84
105
|
file_base_name = file_name.rstrip(".fit.gz")
|
85
106
|
parts = file_base_name.split('_')
|
86
107
|
if len(parts) != 4:
|
87
|
-
raise ValueError("
|
88
|
-
|
108
|
+
raise ValueError("Invalid file name format. Expected '[station]_[date]_[time]_[code].fit.gz'")
|
89
109
|
return parts
|
90
110
|
|
91
111
|
|
92
|
-
def _get_batch_path(
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
112
|
+
def _get_batch_path(
|
113
|
+
gz_path: str
|
114
|
+
) -> str:
|
115
|
+
"""
|
116
|
+
Generate the full path for the `spectre` batch file.
|
117
|
+
|
118
|
+
:param gz_path: Path to the raw `.fit.gz` file.
|
119
|
+
:return: Path to the corresponding batch file.
|
120
|
+
"""
|
121
|
+
station, date, time, code = _get_batch_components(gz_path)
|
122
|
+
batch_name = _get_batch_name(station, date, time, code)
|
123
|
+
batch_start_time = batch_name.split("_")[0]
|
124
|
+
dt = datetime.strptime(batch_start_time, TimeFormat.DATETIME)
|
125
|
+
batch_dir = get_batches_dir_path(year=dt.year, month=dt.month, day=dt.day)
|
126
|
+
os.makedirs(batch_dir, exist_ok=True)
|
127
|
+
return os.path.join(batch_dir, batch_name)
|
128
|
+
|
129
|
+
|
130
|
+
def _unzip_file_to_batches(
|
131
|
+
gz_path: str
|
132
|
+
) -> None:
|
133
|
+
"""
|
134
|
+
Decompress a `.fit.gz` file and save it as a `.fits` batch file.
|
135
|
+
|
136
|
+
:param gz_path: Path to the `.fit.gz` file.
|
137
|
+
"""
|
106
138
|
fits_path = _get_batch_path(gz_path)
|
107
|
-
with gzip.open(gz_path,
|
139
|
+
with gzip.open(gz_path, "rb") as f_in, open(fits_path, "wb") as f_out:
|
108
140
|
shutil.copyfileobj(f_in, f_out)
|
109
141
|
|
110
142
|
|
111
|
-
def _unzip_to_batches(
|
112
|
-
|
113
|
-
|
143
|
+
def _unzip_to_batches(
|
144
|
+
tmp_dir: str
|
145
|
+
) -> None:
|
146
|
+
"""
|
147
|
+
Decompress all `.gz` files in a temporary directory and save them as `spectre`
|
148
|
+
batch files.
|
149
|
+
|
150
|
+
:param tmp_dir: Path to the temporary directory containing `.gz` files.
|
151
|
+
"""
|
152
|
+
for entry in os.scandir(tmp_dir):
|
153
|
+
if entry.is_file() and entry.name.endswith(".gz"):
|
114
154
|
_unzip_file_to_batches(entry.path)
|
115
155
|
os.remove(entry.path)
|
116
156
|
|
117
157
|
|
118
|
-
def _wget_callisto_data(
|
119
|
-
|
120
|
-
|
121
|
-
|
158
|
+
def _wget_callisto_data(
|
159
|
+
instrument_code: str,
|
160
|
+
year: int,
|
161
|
+
month: int,
|
162
|
+
day: int,
|
163
|
+
tmp_dir: str
|
164
|
+
) -> None:
|
165
|
+
"""
|
166
|
+
Download raw `.fit.gz` files from the e-Callisto network using `wget`.
|
167
|
+
|
168
|
+
:param instrument_code: Instrument code for filtering files.
|
169
|
+
:param year: Observation year.
|
170
|
+
:param month: Observation month.
|
171
|
+
:param day: Observation day.
|
172
|
+
:param tmp_dir: Path to the temporary directory for downloads.
|
173
|
+
"""
|
122
174
|
date_str = f"{year:04d}/{month:02d}/{day:02d}"
|
123
175
|
base_url = f"http://soleil.i4ds.ch/solarradio/data/2002-20yy_Callisto/{date_str}/"
|
124
176
|
command = [
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
'-P', _temp_dir,
|
129
|
-
base_url
|
177
|
+
"wget", "-r", "-l1", "-nd", "-np",
|
178
|
+
"-R", ".tmp", "-A", f"{instrument_code}*.fit.gz",
|
179
|
+
"-P", tmp_dir, base_url
|
130
180
|
]
|
131
181
|
subprocess.run(command, check=True)
|
132
182
|
|
133
183
|
|
134
|
-
def download_callisto_data(
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
184
|
+
def download_callisto_data(
|
185
|
+
instrument_code: CallistoInstrumentCode,
|
186
|
+
year: int,
|
187
|
+
month: int,
|
188
|
+
day: int
|
189
|
+
) -> None:
|
190
|
+
"""
|
191
|
+
Download and decompress e-Callisto FITS files, saving them as `spectre` batch files.
|
192
|
+
|
193
|
+
:param instrument_code: e-Callisto station instrument code.
|
194
|
+
:param year: Year of the observation.
|
195
|
+
:param month: Month of the observation.
|
196
|
+
:param day: Day of the observation.
|
197
|
+
"""
|
198
|
+
tmp_dir = os.path.join(get_spectre_data_dir_path(), "tmp")
|
199
|
+
# if there are any residual files in the temporary directory, remove them.
|
200
|
+
if os.path.exists(tmp_dir):
|
201
|
+
shutil.rmtree(tmp_dir)
|
202
|
+
os.makedirs(tmp_dir, exist_ok=True)
|
142
203
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
if instrument_code not in CALLISTO_INSTRUMENT_CODES:
|
147
|
-
raise ValueError(f"No match found for '{instrument_code}'. Expected one of {CALLISTO_INSTRUMENT_CODES}")
|
148
|
-
|
149
|
-
_wget_callisto_data(instrument_code, year, month, day)
|
150
|
-
_unzip_to_batches()
|
151
|
-
shutil.rmtree(_temp_dir)
|
204
|
+
_wget_callisto_data(instrument_code.value, year, month, day, tmp_dir)
|
205
|
+
_unzip_to_batches(tmp_dir)
|
206
|
+
shutil.rmtree(tmp_dir)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: spectre-core
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.13
|
4
4
|
Summary: The core Python package used by the spectre program.
|
5
5
|
Maintainer-email: Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -691,6 +691,7 @@ Requires-Dist: scipy==1.12.0
|
|
691
691
|
Requires-Dist: astropy==6.0.1
|
692
692
|
Requires-Dist: matplotlib==3.5.0
|
693
693
|
Requires-Dist: watchdog==4.0.0
|
694
|
+
Requires-Dist: mypy==1.14.1
|
694
695
|
|
695
696
|
# spectre-core
|
696
697
|
|
@@ -698,18 +699,24 @@ Requires-Dist: watchdog==4.0.0
|
|
698
699
|
|
699
700
|
:loudspeaker: **This project is under active development. Contributors welcome.** :loudspeaker:
|
700
701
|
|
701
|
-
```spectre-core``` provides
|
702
|
+
```spectre-core``` provides an extensible, receiver-agnostic toolkit for generating radio spectrograms in real-time. It is the core Python package used by the [`spectre`](https://github.com/jcfitzpatrick12/spectre.git) program.
|
702
703
|
|
703
704
|
|
704
705
|
## Installation
|
705
|
-
|
706
|
-
```
|
706
|
+
Simply call:
|
707
|
+
```bash
|
708
|
+
pip install spectre-core
|
709
|
+
```
|
707
710
|
|
708
711
|
Alternatively, you can clone the repository in your preferred directory:
|
709
|
-
```
|
712
|
+
```bash
|
713
|
+
git clone https://github.com/jcfitzpatrick12/spectre-core.git && cd spectre-core
|
714
|
+
```
|
710
715
|
|
711
716
|
Then run:
|
712
|
-
```
|
717
|
+
```
|
718
|
+
pip install -e .
|
719
|
+
```
|
713
720
|
|
714
721
|
|
715
722
|
## Contributing
|
@@ -0,0 +1,75 @@
|
|
1
|
+
spectre_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
spectre_core/exceptions.py,sha256=ccr-n88W0c_DKcsKMAe09QHX1iG2LUEqOMYHcGB-_do,451
|
3
|
+
spectre_core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
spectre_core/_file_io/__init__.py,sha256=RZAtX8pFtdtTlxoxxttxJf1Wcg8lDFXgKMe1rcgaFP8,351
|
5
|
+
spectre_core/_file_io/file_handlers.py,sha256=dJ3rMcTGbNnEXbYZgVoaos4p6qKGs-rWNeY8nmluQCQ,6402
|
6
|
+
spectre_core/batches/__init__.py,sha256=nEEGLB9TnCKrP1VHQxYlU6U5MBt_4CHBcrRDnB-9GIU,685
|
7
|
+
spectre_core/batches/_base.py,sha256=KI3f5ZDKC_HrLtMDqqXiVLOF5InAQnk5QkyUuCXyAGI,7237
|
8
|
+
spectre_core/batches/_batches.py,sha256=CrfCjEhBO16SVfKbAvpxRsl0cjBxkiVOCSXegCuG0JM,7877
|
9
|
+
spectre_core/batches/_factory.py,sha256=ApshWhbhZ-CSoQBrlcYaC5W5p_w_v4pxOdOdlrF7YIA,2277
|
10
|
+
spectre_core/batches/_register.py,sha256=dSQC8KXj_jG8EiPwmKPdV0HSSalIZLaWt-8E29sczJM,1085
|
11
|
+
spectre_core/batches/plugins/_batch_keys.py,sha256=8v0KE1n0NAQX0i9SwwB4Lgkct7Q_jna-H5S0Gs6p1qg,544
|
12
|
+
spectre_core/batches/plugins/_callisto.py,sha256=ijm-VzGGlLQJjB2eQWw-04R6belCJ_NzSL9Jr7VTu2Q,6259
|
13
|
+
spectre_core/batches/plugins/_iq_stream.py,sha256=DSto5ZzPk7A4VAe_HUAKNd2M9NuWqxcL--_Vneo08Bc,12583
|
14
|
+
spectre_core/capture_configs/__init__.py,sha256=sUgwilZvQHAexAw_wao49qoBnu0CEBHIicI1kNfvCHg,1645
|
15
|
+
spectre_core/capture_configs/_capture_config.py,sha256=ngbIzySgjsgBRJyrfgYZrJtr0wqcKDn8xBH0T1vi-yY,4546
|
16
|
+
spectre_core/capture_configs/_capture_modes.py,sha256=uFBMwHYJCDqqQfYJvAUKzKXTmSBANRZMLlRSKV8WRb8,898
|
17
|
+
spectre_core/capture_configs/_capture_templates.py,sha256=nSAxhOh1DeBzYY16evgOTkDuxRugGG5weJsICUouLPQ,10353
|
18
|
+
spectre_core/capture_configs/_parameters.py,sha256=9KoNuwzDKtnyeju53fkImi1SeUjDn89cNwDL8zxX-YU,5563
|
19
|
+
spectre_core/capture_configs/_pconstraints.py,sha256=bnl1m6M9iyo5KOsPKT_arwrrAZbxRKXVwTHQACzvs2g,5227
|
20
|
+
spectre_core/capture_configs/_pnames.py,sha256=05mrrGfYHudaD2dYyukijbW-YtUnifZRn05xcBGv-fI,1852
|
21
|
+
spectre_core/capture_configs/_ptemplates.py,sha256=p4lOi6W5B9gWv0d6ryNK9f_zxLHsj5PWW8Lmdco9ofg,24508
|
22
|
+
spectre_core/capture_configs/_pvalidators.py,sha256=0W-OMDY1lifRPonwgEAwoMYkA0PWbqlK5nE0zsYVcTw,9596
|
23
|
+
spectre_core/config/__init__.py,sha256=CVddibAIWU4cNerXCxfeUn_cvnWWDBm4pWeUifqM6Ko,502
|
24
|
+
spectre_core/config/_paths.py,sha256=Qn0KVe27P6Bo65MfHe4LpH_ryPvLgbTxKjc4MTw1BB8,4090
|
25
|
+
spectre_core/config/_time_formats.py,sha256=gS0j5zIvBhnV7KMYvTloloIbVwmCYn8MMKn3zNeQ4Xc,857
|
26
|
+
spectre_core/jobs/__init__.py,sha256=WKTvxvpciedm6tsKjU02iXJhIdNsMDt-BnMVwVme2Bo,412
|
27
|
+
spectre_core/jobs/_jobs.py,sha256=gGpxsLZZ7EdXBYGH-r_pKnRGWSapr78E5SK_VnulaGg,3844
|
28
|
+
spectre_core/jobs/_workers.py,sha256=9GPEJVqIFuOAXpY9gfJxX-0_UPJ6RBtUe5qC5JLiYNw,5023
|
29
|
+
spectre_core/logs/__init__.py,sha256=BHZTru9KyOUDPBnanM1EJK5E1BN6YAGrjhdKFZ1ysUM,484
|
30
|
+
spectre_core/logs/_configure.py,sha256=NlR3BEwhj5k0qlTooOLb6OFRbYcDT05eWN-9Sl9Hkbk,2208
|
31
|
+
spectre_core/logs/_decorators.py,sha256=u_Ixpr6aeKiSjM0mtqHuGXVGawNjgJPRvIpAj0zPSdQ,1169
|
32
|
+
spectre_core/logs/_logs.py,sha256=M6sIsb2xxos9Ytj509qqp2jXZtvFU5uon9jIwEHLEI8,6578
|
33
|
+
spectre_core/logs/_process_types.py,sha256=qnKfeXPk-6NOlNf4XtD8D3tYbA_ZVhHSZAKSd2MiVmY,488
|
34
|
+
spectre_core/plotting/__init__.py,sha256=9zhmCphR4DSHlWfJhHeWPbvIrh8Kycov5Ta6woSrUZg,517
|
35
|
+
spectre_core/plotting/_base.py,sha256=51125B7OwvVvDXU2utZ_z0xuUkaKMeJ55Jsp2I-SORg,8226
|
36
|
+
spectre_core/plotting/_format.py,sha256=gWnj12PfgODQRTCCEyH2_mY7GY0brFbmolBEJfDtO6c,1393
|
37
|
+
spectre_core/plotting/_panel_names.py,sha256=xeXUXAhzDoPYCgtjy_6zbwADHBtB0-jARnFOW-YTcAc,830
|
38
|
+
spectre_core/plotting/_panel_stack.py,sha256=ZlVhAzb5Go4PdjR3-TeeaRA8T2-spqQHvFHLJVx1Weg,8732
|
39
|
+
spectre_core/plotting/_panels.py,sha256=IaJ8EDLu5pvsN6kklNWc1ectCfgUsxwN0EKwT2wiFNo,16030
|
40
|
+
spectre_core/post_processing/__init__.py,sha256=PVr7AhKK5at0o3BzNlJeC_Z_J8ZNATjGVY7PYg7fSew,624
|
41
|
+
spectre_core/post_processing/_base.py,sha256=gtycVjtAStN5sW4KuzxVQngLzYCx3k-9B5IfmMZnu_g,5815
|
42
|
+
spectre_core/post_processing/_factory.py,sha256=fnabYFy7Qe3EkJcR7baj1VyPdikw-xTSuNC01w7VupU,2193
|
43
|
+
spectre_core/post_processing/_post_processor.py,sha256=0WLOwtx-FHK4t6dv-I6_1K9sRNn-625wPS11lqJ8Kho,1300
|
44
|
+
spectre_core/post_processing/_register.py,sha256=chK5bCQ-0bpMhplbKT3cdS5anLhIA5Tt_ONzThJHrw0,1249
|
45
|
+
spectre_core/post_processing/plugins/_event_handler_keys.py,sha256=LPA71kKsaLPyT2vpPJwm88-RWfX-AU0_T9H8-GdjINQ,614
|
46
|
+
spectre_core/post_processing/plugins/_fixed_center_frequency.py,sha256=24LB3iDMa2KvgM7jyRnEr7Y45VK46bUT7Nj8bXGiGwc,5231
|
47
|
+
spectre_core/post_processing/plugins/_swept_center_frequency.py,sha256=fzPAZ4zK1DRAHushUB-JS2IgKAuXyP4hdBLZJX6jBmo,20971
|
48
|
+
spectre_core/receivers/__init__.py,sha256=A-BuCrnIRdRZe6HGXlLzKHGm8Zjfb8I9dzslBTeUHn4,660
|
49
|
+
spectre_core/receivers/_base.py,sha256=E2aSYmveSMYxLrm5Uv235KlsehOyq82DvSolCIF6xug,10096
|
50
|
+
spectre_core/receivers/_factory.py,sha256=5NdwZzBmUEHZQHltggDmuEoi-DRS6fHPSBzxvmq50zs,1843
|
51
|
+
spectre_core/receivers/_register.py,sha256=jWS3Q_ZOZcqUFunxJwR5VRZN4_eS3LzcP-5edQdmj4c,1366
|
52
|
+
spectre_core/receivers/_spec_names.py,sha256=pLYM9rMoZkT3JmRvSNfWKFiIJmj07vrphDbw-fNhpO8,1611
|
53
|
+
spectre_core/receivers/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
|
+
spectre_core/receivers/plugins/_receiver_names.py,sha256=GZi4xznxscLBJXbfkZLtQ-m0U3GH362HiI5-y_FQO1k,426
|
55
|
+
spectre_core/receivers/plugins/_rsp1a.py,sha256=LAvjxcxIkZRPpc96wqkco7rQ-H3AvUowsp0WG8vgAkw,2438
|
56
|
+
spectre_core/receivers/plugins/_rspduo.py,sha256=ypr4xiEMOq4EJKFECz01PZjUJ2UcsWJVZRou8Ln5Ogw,3049
|
57
|
+
spectre_core/receivers/plugins/_sdrplay_receiver.py,sha256=QpQ2sRc9Tz2IZRL_LyBX3UPCQ270RQMHH2mP6Y_n1-o,6899
|
58
|
+
spectre_core/receivers/plugins/_test.py,sha256=t8oE4zQLYYWJV6SMIZAlNHs9mig263QJmP6XRLyF0RU,8277
|
59
|
+
spectre_core/receivers/plugins/gr/__init__.py,sha256=oFSWmGoXQLK5X5xHvWzTdNr9amuaiiGjZirXZVogACU,154
|
60
|
+
spectre_core/receivers/plugins/gr/_base.py,sha256=woFF6498aLIDf4EC7aD-TolY9LtZBqlLy-Vai_gfIvc,2571
|
61
|
+
spectre_core/receivers/plugins/gr/_rsp1a.py,sha256=Nq0VNWjzfTd4Mruz4FSk6bfso6zh1cMw-C-qn5LpPv8,6614
|
62
|
+
spectre_core/receivers/plugins/gr/_rspduo.py,sha256=s5g5nOQHiVHCESaHdj2VmgXl_LaiMaqXhTJfUbC7Iew,9811
|
63
|
+
spectre_core/receivers/plugins/gr/_test.py,sha256=YA3JKdJ_CT3J93pqHUjltKrQUoaDXzUloEJEXVHH718,5780
|
64
|
+
spectre_core/spectrograms/__init__.py,sha256=AsiOmn9XrAAHUvK-fdhRddAxX4M1Wd6TCtdmxGkl3FA,763
|
65
|
+
spectre_core/spectrograms/_analytical.py,sha256=Axnt9JOJnWXRRuVU5nHPz5QU09KoWqNZkR5NnTX6kMY,11356
|
66
|
+
spectre_core/spectrograms/_array_operations.py,sha256=rhiHjnqFGT1bffJygMbeYWb1H9VGBK6-uAgFh8I9owc,7547
|
67
|
+
spectre_core/spectrograms/_spectrogram.py,sha256=WhHEt_QpmzspDqYlzdZcJ8CAXxRfs8-JfP0T3NHpjLQ,28205
|
68
|
+
spectre_core/spectrograms/_transform.py,sha256=WZ5jAe3bOpNldxHDSHPf8Q_1ifBdWqXB_mlF6DL1VuE,11734
|
69
|
+
spectre_core/wgetting/__init__.py,sha256=UkS0Z0wuuqpoZ1EL35wJcDpjBiAaZgdZ7064yGESxNE,341
|
70
|
+
spectre_core/wgetting/_callisto.py,sha256=m9II6ayswrY4h_ST3TodioZ4C865lN_uOF-BozvjZAg,6952
|
71
|
+
spectre_core-0.0.13.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
72
|
+
spectre_core-0.0.13.dist-info/METADATA,sha256=1PBd2ql6_9g9BGrwb1bWhnY4MSqRV1hdkXne6uE184o,42100
|
73
|
+
spectre_core-0.0.13.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
74
|
+
spectre_core-0.0.13.dist-info/top_level.txt,sha256=-UsyjpFohXgZpgcZ9QbVeXhsIyF3Am8RxNFNDV_Ta2Y,13
|
75
|
+
spectre_core-0.0.13.dist-info/RECORD,,
|
@@ -1,96 +0,0 @@
|
|
1
|
-
# SPDX-FileCopyrightText: © 2024 Jimmy Fitzpatrick <jcfitzpatrick12@gmail.com>
|
2
|
-
# This file is part of SPECTRE
|
3
|
-
# SPDX-License-Identifier: GPL-3.0-or-later
|
4
|
-
|
5
|
-
from datetime import datetime, timedelta
|
6
|
-
from typing import Tuple
|
7
|
-
|
8
|
-
import numpy as np
|
9
|
-
from astropy.io import fits
|
10
|
-
from astropy.io.fits.hdu.image import PrimaryHDU
|
11
|
-
from astropy.io.fits.hdu.table import BinTableHDU
|
12
|
-
from astropy.io.fits.hdu.hdulist import HDUList
|
13
|
-
|
14
|
-
from spectre_core.spectrograms import Spectrogram, SpectrumTypes
|
15
|
-
from .._register import register_batch
|
16
|
-
from .._base import BaseBatch, BatchFile
|
17
|
-
|
18
|
-
|
19
|
-
@register_batch('callisto')
|
20
|
-
class _Batch(BaseBatch):
|
21
|
-
def __init__(self,
|
22
|
-
start_time: str,
|
23
|
-
tag: str):
|
24
|
-
super().__init__(start_time, tag)
|
25
|
-
self.add_file( FitsFile(self.parent_dir_path, self.name) )
|
26
|
-
|
27
|
-
|
28
|
-
class FitsFile(BatchFile):
|
29
|
-
def __init__(self,
|
30
|
-
parent_dir_path: str,
|
31
|
-
base_file_name: str):
|
32
|
-
super().__init__(parent_dir_path, base_file_name, "fits")
|
33
|
-
|
34
|
-
|
35
|
-
def read(self) -> Spectrogram:
|
36
|
-
with fits.open(self.file_path, mode='readonly') as hdulist:
|
37
|
-
primary_hdu = self._get_primary_hdu(hdulist)
|
38
|
-
dynamic_spectra = self._get_dynamic_spectra(primary_hdu)
|
39
|
-
spectrogram_start_datetime = self._get_spectrogram_start_datetime(primary_hdu)
|
40
|
-
bintable_hdu = self._get_bintable_hdu(hdulist)
|
41
|
-
times, frequencies = self._get_time_and_frequency(bintable_hdu)
|
42
|
-
spectrum_type = self._get_spectrum_type(primary_hdu)
|
43
|
-
|
44
|
-
if spectrum_type == SpectrumTypes.DIGITS:
|
45
|
-
dynamic_spectra_linearised = self._convert_units_to_linearised(dynamic_spectra)
|
46
|
-
return Spectrogram(dynamic_spectra_linearised[::-1, :], # reverse the spectra along the frequency axis
|
47
|
-
times,
|
48
|
-
frequencies[::-1], # sort the frequencies in ascending order
|
49
|
-
self.tag,
|
50
|
-
spectrogram_start_datetime,
|
51
|
-
spectrum_type)
|
52
|
-
else:
|
53
|
-
raise NotImplementedError(f"SPECTRE does not currently support spectrum type with BUNITS '{spectrum_type}'")
|
54
|
-
|
55
|
-
|
56
|
-
@property
|
57
|
-
def datetimes(self) -> np.ndarray:
|
58
|
-
with fits.open(self.file_path, mode='readonly') as hdulist:
|
59
|
-
bintable_data = hdulist[1].data
|
60
|
-
times = bintable_data['TIME'][0]
|
61
|
-
return [self.start_datetime + timedelta(seconds=t) for t in times]
|
62
|
-
|
63
|
-
|
64
|
-
def _get_primary_hdu(self, hdulist: HDUList) -> PrimaryHDU:
|
65
|
-
return hdulist['PRIMARY']
|
66
|
-
|
67
|
-
|
68
|
-
def _get_dynamic_spectra(self, primary_hdu: PrimaryHDU) -> np.ndarray:
|
69
|
-
return primary_hdu.data
|
70
|
-
|
71
|
-
|
72
|
-
def _get_spectrogram_start_datetime(self, primary_hdu: PrimaryHDU) -> datetime:
|
73
|
-
date_obs = primary_hdu.header['DATE-OBS']
|
74
|
-
time_obs = primary_hdu.header['TIME-OBS']
|
75
|
-
return datetime.strptime(f"{date_obs}T{time_obs}", "%Y-%m-%dT%H:%M:%S.%f")
|
76
|
-
|
77
|
-
|
78
|
-
def _get_bintable_hdu(self, hdulist: HDUList) -> BinTableHDU:
|
79
|
-
return hdulist[1]
|
80
|
-
|
81
|
-
|
82
|
-
def _get_time_and_frequency(self, bintable_hdu: BinTableHDU) -> Tuple[np.ndarray, np.ndarray]:
|
83
|
-
data = bintable_hdu.data
|
84
|
-
times = data['TIME'][0]
|
85
|
-
frequencies_MHz = data['FREQUENCY'][0]
|
86
|
-
frequencies = frequencies_MHz * 1e6 # convert to Hz
|
87
|
-
return times, frequencies
|
88
|
-
|
89
|
-
|
90
|
-
def _convert_units_to_linearised(self, dynamic_spectra: np.ndarray) -> np.ndarray:
|
91
|
-
digits_floats = np.array(dynamic_spectra, dtype='float')
|
92
|
-
# conversion as per ADC specs [see email from C. Monstein]
|
93
|
-
dB = (digits_floats / 255) * (2500 / 25)
|
94
|
-
return 10 ** (dB / 10)
|
95
|
-
|
96
|
-
|