spectre-core 0.0.18__tar.gz → 0.0.20__tar.gz

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.
Files changed (83) hide show
  1. {spectre_core-0.0.18 → spectre_core-0.0.20}/PKG-INFO +3 -2
  2. {spectre_core-0.0.18 → spectre_core-0.0.20}/pyproject.toml +1 -1
  3. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/_base.py +48 -0
  4. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/_batches.py +8 -11
  5. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/plugins/_iq_stream.py +0 -1
  6. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_capture_config.py +2 -5
  7. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/plotting/_base.py +7 -2
  8. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/plotting/_panel_stack.py +56 -12
  9. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/spectrograms/_transform.py +10 -10
  10. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/wgetting/_callisto.py +5 -5
  11. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core.egg-info/PKG-INFO +3 -2
  12. {spectre_core-0.0.18 → spectre_core-0.0.20}/LICENSE +0 -0
  13. {spectre_core-0.0.18 → spectre_core-0.0.20}/README.md +0 -0
  14. {spectre_core-0.0.18 → spectre_core-0.0.20}/setup.cfg +0 -0
  15. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/__init__.py +0 -0
  16. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/_file_io/__init__.py +0 -0
  17. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/_file_io/file_handlers.py +0 -0
  18. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/__init__.py +0 -0
  19. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/_factory.py +0 -0
  20. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/_register.py +0 -0
  21. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/plugins/_batch_keys.py +0 -0
  22. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/batches/plugins/_callisto.py +0 -0
  23. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/__init__.py +0 -0
  24. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_capture_modes.py +0 -0
  25. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_capture_templates.py +0 -0
  26. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_parameters.py +0 -0
  27. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_pconstraints.py +0 -0
  28. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_pnames.py +0 -0
  29. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_ptemplates.py +0 -0
  30. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/capture_configs/_pvalidators.py +0 -0
  31. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/config/__init__.py +0 -0
  32. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/config/_paths.py +0 -0
  33. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/config/_time_formats.py +0 -0
  34. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/exceptions.py +0 -0
  35. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/jobs/__init__.py +0 -0
  36. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/jobs/_jobs.py +0 -0
  37. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/jobs/_workers.py +0 -0
  38. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/logs/__init__.py +0 -0
  39. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/logs/_configure.py +0 -0
  40. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/logs/_decorators.py +0 -0
  41. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/logs/_logs.py +0 -0
  42. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/logs/_process_types.py +0 -0
  43. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/plotting/__init__.py +0 -0
  44. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/plotting/_format.py +0 -0
  45. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/plotting/_panel_names.py +0 -0
  46. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/plotting/_panels.py +0 -0
  47. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/__init__.py +0 -0
  48. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/_base.py +0 -0
  49. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/_factory.py +0 -0
  50. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/_post_processor.py +0 -0
  51. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/_register.py +0 -0
  52. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/plugins/_event_handler_keys.py +0 -0
  53. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/plugins/_fixed_center_frequency.py +0 -0
  54. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/post_processing/plugins/_swept_center_frequency.py +0 -0
  55. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/py.typed +0 -0
  56. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/__init__.py +0 -0
  57. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/_base.py +0 -0
  58. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/_factory.py +0 -0
  59. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/_register.py +0 -0
  60. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/_spec_names.py +0 -0
  61. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/__init__.py +0 -0
  62. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/_b200mini.py +0 -0
  63. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/_receiver_names.py +0 -0
  64. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/_rsp1a.py +0 -0
  65. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/_rspduo.py +0 -0
  66. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/_sdrplay_receiver.py +0 -0
  67. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/_test.py +0 -0
  68. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/_usrp.py +0 -0
  69. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/gr/__init__.py +0 -0
  70. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/gr/_base.py +0 -0
  71. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/gr/_rsp1a.py +0 -0
  72. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/gr/_rspduo.py +0 -0
  73. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/gr/_test.py +0 -0
  74. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/receivers/plugins/gr/_usrp.py +0 -0
  75. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/spectrograms/__init__.py +0 -0
  76. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/spectrograms/_analytical.py +0 -0
  77. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/spectrograms/_array_operations.py +0 -0
  78. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/spectrograms/_spectrogram.py +0 -0
  79. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core/wgetting/__init__.py +0 -0
  80. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core.egg-info/SOURCES.txt +0 -0
  81. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core.egg-info/dependency_links.txt +0 -0
  82. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core.egg-info/requires.txt +0 -0
  83. {spectre_core-0.0.18 → spectre_core-0.0.20}/src/spectre_core.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: spectre-core
3
- Version: 0.0.18
3
+ Version: 0.0.20
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
@@ -692,6 +692,7 @@ Requires-Dist: astropy==6.0.1
692
692
  Requires-Dist: matplotlib==3.5.0
693
693
  Requires-Dist: watchdog==4.0.0
694
694
  Requires-Dist: mypy==1.14.1
695
+ Dynamic: license-file
695
696
 
696
697
  # spectre-core
697
698
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "spectre-core"
7
- version = "0.0.18"
7
+ version = "0.0.20"
8
8
  maintainers = [
9
9
  { name="Jimmy Fitzpatrick", email="jcfitzpatrick12@gmail.com" },
10
10
  ]
@@ -4,8 +4,10 @@
4
4
 
5
5
  from datetime import datetime
6
6
  from typing import TypeVar
7
+ from base64 import b64encode
7
8
  from functools import cached_property
8
9
  from abc import ABC, abstractmethod
10
+ from dataclasses import dataclass
9
11
 
10
12
  from spectre_core._file_io import BaseFileHandler
11
13
  from spectre_core.config import get_batches_dir_path, TimeFormat
@@ -64,6 +66,40 @@ class BatchFile(BaseFileHandler[T]):
64
66
  ) -> str:
65
67
  """The batch name tag."""
66
68
  return self._tag
69
+
70
+
71
+ @dataclass(frozen=True)
72
+ class _BatchExtension:
73
+ """Supported extensions for a `BaseBatch`, inherited by all derived classes.
74
+
75
+ :ivar PNG: Corresponds to the `.png` file extension.
76
+ """
77
+ PNG: str = "png"
78
+
79
+
80
+ class _PngFile(BatchFile[str]):
81
+ """Stores an image visualising the data for the batch."""
82
+ def __init__(
83
+ self,
84
+ batch_parent_dir_path: str,
85
+ batch_name: str
86
+ ) -> None:
87
+ """Initialise a `_PngFile` instance.
88
+
89
+ :param batch_parent_dir_path: The parent directory for the batch.
90
+ :param batch_name: The batch name.
91
+ """
92
+ super().__init__(batch_parent_dir_path, batch_name, _BatchExtension.PNG)
93
+
94
+
95
+ def _read(self) -> str:
96
+ """Reads the PNG file and returns it base64-encoded.
97
+
98
+ :return: Base64-encoded string representation of the image.
99
+ """
100
+ with open(self.file_path, "rb") as f:
101
+ encoded = b64encode(f.read())
102
+ return encoded.decode("ascii")
67
103
 
68
104
 
69
105
  class BaseBatch(ABC):
@@ -98,6 +134,10 @@ class BaseBatch(ABC):
98
134
  # internal register of batch files
99
135
  self._batch_files: dict[str, BatchFile] = {}
100
136
 
137
+ # Add the files shared by all derived classes
138
+ self._png_file = _PngFile(self.parent_dir_path, self.name)
139
+ self.add_file( self._png_file )
140
+
101
141
 
102
142
  @property
103
143
  @abstractmethod
@@ -166,6 +206,14 @@ class BaseBatch(ABC):
166
206
  """
167
207
  return self._batch_files
168
208
 
209
+
210
+ @property
211
+ def png_file(
212
+ self
213
+ ) -> _PngFile:
214
+ """The batch file corresponding to the `.png` extension."""
215
+ return self._png_file
216
+
169
217
 
170
218
  def add_file(
171
219
  self,
@@ -209,23 +209,20 @@ class Batches(Generic[T]):
209
209
  return self._get_from_index(subscript)
210
210
 
211
211
 
212
- def get_spectrogram_from_range(
212
+ def get_spectrogram(
213
213
  self,
214
- start_time: str,
215
- end_time: str
214
+ start_datetime: datetime,
215
+ end_datetime: datetime
216
216
  ) -> Spectrogram:
217
217
  """
218
218
  Retrieve a spectrogram spanning the specified time range.
219
219
 
220
- :param start_time: The start time of the range (inclusive).
221
- :param end_time: The end time of the range (inclusive).
220
+ :param start_datetime: The start time of the range (inclusive).
221
+ :param end_datetime: The end time of the range (inclusive).
222
222
  :raises FileNotFoundError: If no spectrogram data is available within the specified time range.
223
223
  :return: A spectrogram created by stitching together data from all matching batches.
224
224
  """
225
- # Convert input strings to datetime objects
226
- start_datetime = datetime.strptime(start_time, TimeFormat.DATETIME)
227
- end_datetime = datetime.strptime(end_time, TimeFormat.DATETIME)
228
-
225
+
229
226
  spectrograms = []
230
227
  for batch in self:
231
228
  # skip batches without spectrogram data
@@ -238,10 +235,10 @@ class Batches(Generic[T]):
238
235
 
239
236
  # Check if the batch overlaps with the input time range
240
237
  if start_datetime <= upper_bound and lower_bound <= end_datetime:
241
- spectrograms.append( time_chop(spectrogram, start_time, end_time) )
238
+ spectrograms.append( time_chop(spectrogram, start_datetime, end_datetime) )
242
239
 
243
240
  if spectrograms:
244
241
  return join_spectrograms(spectrograms)
245
242
  else:
246
243
  raise FileNotFoundError(f"No spectrogram data found for the time range "
247
- f"{start_time} to {end_time}.")
244
+ f"{start_datetime} to {end_datetime}.")
@@ -317,7 +317,6 @@ class IQStreamBatch(BaseBatch):
317
317
  :param tag: The batch name tag.
318
318
  """
319
319
  super().__init__(start_time, tag)
320
- self._batch_files = {}
321
320
  self._fits_file = _FitsFile(self.parent_dir_path, self.name)
322
321
  self._bin_file = _BinFile (self.parent_dir_path, self.name)
323
322
  self._hdr_file = _HdrFile (self.parent_dir_path, self.name)
@@ -42,7 +42,7 @@ class CaptureConfig(JsonHandler):
42
42
  self._validate_tag(tag)
43
43
  self._tag = tag
44
44
  super().__init__(get_configs_dir_path(),
45
- f"capture_{tag}")
45
+ tag)
46
46
 
47
47
  @property
48
48
  def tag(
@@ -60,11 +60,8 @@ class CaptureConfig(JsonHandler):
60
60
 
61
61
  Some substrings are reserved for third-party spectrogram data.
62
62
  """
63
- if "_" in tag:
64
- raise InvalidTagError(f"Tags cannot contain an underscore. Received {tag}")
65
-
66
63
  if "callisto" in tag:
67
- raise ValueError(f"The substring `callisto` is not allowed in a capture config tag.")
64
+ raise ValueError(f"The substring `callisto` is reserved, and is not allowed in a capture config tag.")
68
65
 
69
66
 
70
67
  @property
@@ -5,6 +5,7 @@
5
5
  from abc import ABC, abstractmethod
6
6
  from typing import Optional, Literal
7
7
  from enum import Enum
8
+ from datetime import datetime
8
9
 
9
10
  import numpy.typing as npt
10
11
  import numpy as np
@@ -13,6 +14,7 @@ from matplotlib.axes import Axes
13
14
  from matplotlib.figure import Figure
14
15
 
15
16
  from spectre_core.spectrograms import Spectrogram, TimeType
17
+ from spectre_core.config import TimeFormat
16
18
  from ._format import PanelFormat
17
19
  from ._panel_names import PanelName
18
20
 
@@ -284,8 +286,11 @@ class BaseTimeSeriesPanel(BasePanel):
284
286
  if self.time_type == TimeType.RELATIVE:
285
287
  self.ax.set_xlabel('Time [s]')
286
288
  else:
287
- self.ax.set_xlabel('Time [UTC]')
288
- self.ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
289
+ #TODO: Adapt for time ranges greater than one day
290
+ start_date = datetime.strftime(self.spectrogram.start_datetime.astype(datetime),
291
+ TimeFormat.DATE)
292
+ self.ax.set_xlabel(f'Time [UTC] (Start Date: {start_date})')
293
+ self.ax.xaxis.set_major_formatter(mdates.DateFormatter(TimeFormat.TIME))
289
294
 
290
295
 
291
296
 
@@ -2,18 +2,22 @@
2
2
  # This file is part of SPECTRE
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
4
 
5
+ import os
5
6
  import numpy as np
6
- import numpy.typing as npt
7
7
  from typing import Optional, Tuple, cast
8
8
  import matplotlib.pyplot as plt
9
9
  from matplotlib.figure import Figure
10
10
  from matplotlib.axes import Axes
11
+ from matplotlib import use
12
+ from datetime import datetime
11
13
 
12
14
  from spectre_core.spectrograms import TimeType
15
+ from spectre_core.config import TimeFormat, get_batches_dir_path
13
16
  from ._base import BasePanel, XAxisType
14
17
  from ._format import PanelFormat
15
- from ._panels import PanelName, SpectrogramPanel, TimeCutsPanel, FrequencyCutsPanel
16
-
18
+ from ._panels import (
19
+ PanelName, SpectrogramPanel, TimeCutsPanel, FrequencyCutsPanel
20
+ )
17
21
 
18
22
  def _is_cuts_panel(
19
23
  panel: BasePanel
@@ -43,17 +47,22 @@ class PanelStack:
43
47
  self,
44
48
  panel_format: PanelFormat = PanelFormat(),
45
49
  time_type: TimeType = TimeType.RELATIVE,
46
- figsize: Tuple[int, int] = (10, 10)
50
+ figsize: Tuple[int, int] = (15, 8),
51
+ non_interactive: bool = False
47
52
  ) -> None:
48
53
  """Initialize an instance of `PanelStack`.
49
54
 
50
55
  :param panel_format: Formatting applied across all panels in the stack. Defaults to `PanelFormat()`.
51
56
  :param time_type: The type of time assigned to spectrograms, defaults to `TimeType.RELATIVE`.
52
- :param figsize: The size of the `matplotlib` figure as (width, height). Defaults to (10, 10).
57
+ :param figsize: The size of the `matplotlib` figure as (width, height). Defaults to (15, 8).
53
58
  """
54
59
  self._panel_format = panel_format
55
60
  self._time_type = time_type
56
61
  self._figsize = figsize
62
+
63
+ if non_interactive:
64
+ # Use a non-interactive matplotlib backend, which can only write files.
65
+ use('agg')
57
66
 
58
67
  self._panels : list[BasePanel] = []
59
68
  self._superimposed_panels: list[BasePanel] = []
@@ -116,14 +125,15 @@ class PanelStack:
116
125
  def add_panel(
117
126
  self,
118
127
  panel: BasePanel,
119
- identifier: Optional[str] = None
128
+ identifier: Optional[str] = None,
129
+ panel_format: Optional[PanelFormat] = None
120
130
  ) -> None:
121
131
  """Add a panel to the stack.
122
132
 
123
133
  :param panel: An instance of a `BasePanel` subclass to be added to the stack.
124
134
  :param identifier: An optional string to link the panel with others for superimposing.
125
135
  """
126
- panel.panel_format = self._panel_format
136
+ panel.panel_format = panel_format or self._panel_format
127
137
  panel.time_type = self._time_type
128
138
  if identifier:
129
139
  panel.identifier = identifier
@@ -133,7 +143,8 @@ class PanelStack:
133
143
  def superimpose_panel(
134
144
  self,
135
145
  panel: BasePanel,
136
- identifier: Optional[str] = None
146
+ identifier: Optional[str] = None,
147
+ panel_format: Optional[PanelFormat] = None
137
148
  ) -> None:
138
149
  """Superimpose a panel onto an existing panel in the stack.
139
150
 
@@ -142,7 +153,8 @@ class PanelStack:
142
153
  """
143
154
  if identifier:
144
155
  panel.identifier = identifier
145
- panel.panel_format = self._panel_format
156
+ panel.panel_format = panel_format or self._panel_format
157
+ panel.time_type = self._time_type
146
158
  self._superimposed_panels.append(panel)
147
159
 
148
160
 
@@ -234,11 +246,13 @@ class PanelStack:
234
246
  if _is_cuts_panel(super_panel):
235
247
  self._overlay_cuts(super_panel)
236
248
 
237
-
238
- def show(
249
+ def _make_figure(
239
250
  self
240
251
  ) -> None:
241
- """Display the panel stack figure."""
252
+ """Make the panel stack figure."""
253
+ if self.num_panels < 1:
254
+ raise ValueError(f"There must be at least one panel in the stack.")
255
+
242
256
  self._init_plot_style()
243
257
  self._create_figure_and_axes()
244
258
  self._assign_axes()
@@ -258,4 +272,34 @@ class PanelStack:
258
272
  self._overlay_cuts(panel)
259
273
 
260
274
  self._overlay_superimposed_panels()
275
+
276
+ def show(
277
+ self
278
+ ) -> None:
279
+ """Display the panel stack figure."""
280
+ self._make_figure()
261
281
  plt.show()
282
+
283
+
284
+ def save(
285
+ self,
286
+ ) -> str:
287
+ """Save the panel stack figure as a batch file under the tag of the first
288
+ panel in the stack. The file format is `png`.
289
+
290
+ :return: The file path of the newly created batch file containing the figure.
291
+ """
292
+ self._make_figure()
293
+ first_panel = self._panels[0]
294
+
295
+ start_dt = cast(datetime, first_panel.spectrogram.start_datetime.astype(datetime))
296
+ batch_name = f"{start_dt.strftime(TimeFormat.DATETIME)}_{first_panel.spectrogram.tag}"
297
+ batch_file_path = os.path.join(
298
+ get_batches_dir_path(start_dt.year, start_dt.month, start_dt.day),
299
+ f"{batch_name}.png"
300
+ )
301
+ plt.savefig(batch_file_path)
302
+ return batch_file_path
303
+
304
+
305
+
@@ -58,30 +58,30 @@ def frequency_chop(
58
58
 
59
59
  def time_chop(
60
60
  spectrogram: Spectrogram,
61
- start_time: str,
62
- end_time: str
61
+ start_datetime: datetime,
62
+ end_datetime: datetime
63
63
  ) -> Spectrogram:
64
64
  """
65
65
  Extracts a portion of the spectrogram within the specified time range.
66
66
 
67
67
  :param spectrogram: The input spectrogram to process.
68
- :param start_time: The starting time of the desired range.
69
- :param end_time: The ending time of the desired range.
68
+ :param start_datetime: The starting time of the desired range.
69
+ :param end_datetime: The ending time of the desired range.
70
70
  :raises ValueError: If the specified time range is entirely outside the spectrogram's time range.
71
71
  :raises ValueError: If the start and end indices for the time range are identical.
72
72
  :return: A new spectrogram containing only the specified time range.
73
73
  """
74
- start_datetime = np.datetime64( datetime.strptime(start_time, TimeFormat.DATETIME) )
75
- end_datetime = np.datetime64( datetime.strptime(end_time , TimeFormat.DATETIME) )
74
+ start_datetime64 = np.datetime64(start_datetime)
75
+ end_datetime64 = np.datetime64(end_datetime)
76
76
 
77
- is_entirely_below_time_range = (start_datetime < spectrogram.datetimes[0] and end_datetime < spectrogram.datetimes[0])
78
- is_entirely_above_time_range = (start_datetime > spectrogram.datetimes[-1] and end_datetime > spectrogram.datetimes[-1])
77
+ is_entirely_below_time_range = (start_datetime64 < spectrogram.datetimes[0] and end_datetime64 < spectrogram.datetimes[0])
78
+ is_entirely_above_time_range = (start_datetime64 > spectrogram.datetimes[-1] and end_datetime64 > spectrogram.datetimes[-1])
79
79
  if is_entirely_below_time_range or is_entirely_above_time_range:
80
80
  raise ValueError(f"Requested time interval is entirely out of range of the input spectrogram.")
81
81
 
82
82
  # find the index of the nearest matching spectrums in the spectrogram.
83
- start_index = find_closest_index(start_datetime, spectrogram.datetimes)
84
- end_index = find_closest_index(end_datetime, spectrogram.datetimes)
83
+ start_index = find_closest_index(start_datetime64, spectrogram.datetimes)
84
+ end_index = find_closest_index(end_datetime64, spectrogram.datetimes)
85
85
 
86
86
  # enforce distinct start and end indices
87
87
  if start_index == end_index:
@@ -9,7 +9,7 @@ import gzip
9
9
  from datetime import datetime
10
10
 
11
11
  from spectre_core.config import (
12
- get_spectre_data_dir_path, get_batches_dir_path, TimeFormat, trim_spectre_data_dir_path
12
+ get_spectre_data_dir_path, get_batches_dir_path, TimeFormat
13
13
  )
14
14
 
15
15
  from enum import Enum
@@ -136,12 +136,12 @@ def _unzip_file_to_batches(
136
136
  Decompress a `.fit.gz` file and save it as a `.fits` batch file.
137
137
 
138
138
  :param gz_path: Path to the `.fit.gz` file.
139
- :return: The file path of the newly created batch file, relative to `SPECTRE_DATA_DIR_PATH`.
139
+ :return: The file path of the newly created batch file, as absolute paths within the container's file system.
140
140
  """
141
141
  fits_path = _get_batch_path(gz_path)
142
142
  with gzip.open(gz_path, "rb") as f_in, open(fits_path, "wb") as f_out:
143
143
  shutil.copyfileobj(f_in, f_out)
144
- return trim_spectre_data_dir_path(f_out.name)
144
+ return f_out.name
145
145
 
146
146
 
147
147
  def _unzip_to_batches(
@@ -152,7 +152,7 @@ def _unzip_to_batches(
152
152
  batch files.
153
153
 
154
154
  :param tmp_dir: Path to the temporary directory containing `.gz` files.
155
- :return: A list of file names of all newly created batch files, relative to `SPECTRE_DATA_DIR_PATH`.
155
+ :return: A list of file names of all newly created batch files, as absolute paths within the container's file system.
156
156
  """
157
157
  batch_file_names = []
158
158
  for entry in os.scandir(tmp_dir):
@@ -203,7 +203,7 @@ def download_callisto_data(
203
203
  :param year: Year of the observation.
204
204
  :param month: Month of the observation.
205
205
  :param day: Day of the observation.
206
- :return: A list of file names of all newly created batch files, relative to `SPECTRE_DATA_DIR_PATH`.
206
+ :return: A list of file names of all newly created batch files, as absolute paths within the container's file system.
207
207
  """
208
208
  tmp_dir = os.path.join(get_spectre_data_dir_path(), "tmp")
209
209
  # if there are any residual files in the temporary directory, remove them.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: spectre-core
3
- Version: 0.0.18
3
+ Version: 0.0.20
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
@@ -692,6 +692,7 @@ Requires-Dist: astropy==6.0.1
692
692
  Requires-Dist: matplotlib==3.5.0
693
693
  Requires-Dist: watchdog==4.0.0
694
694
  Requires-Dist: mypy==1.14.1
695
+ Dynamic: license-file
695
696
 
696
697
  # spectre-core
697
698
 
File without changes
File without changes
File without changes