4
4
5
5
import astropy .units as u
6
6
import numpy as np
7
- from specutils import Spectrum1D
7
+ from specutils import Spectrum
8
8
9
- from astrodb_utils import AstroDBError
9
+ from astrodb_utils import AstroDBError , exit_function
10
10
11
11
matplotlib_check = importlib .util .find_spec ("matplotlib" )
12
12
if matplotlib_check is not None :
13
13
import matplotlib .pyplot as plt
14
14
15
15
16
- __all__ = [
17
- "check_spectrum_plottable"
18
- ]
16
+ __all__ = ["check_spectrum_plottable" ]
19
17
20
18
logger = logging .getLogger (__name__ )
21
19
22
20
23
- def check_spectrum_class (spectrum , raise_error = True ):
24
- try :
25
- Spectrum1D .read (spectrum )
26
- return True
27
- except Exception as error_message :
28
- msg = f"Unable to load file as Spectrum1D object:{ spectrum } "
29
- logger .debug (f"{ error_message } " )
30
- if raise_error :
31
- logger .error (msg )
32
- raise AstroDBError (msg )
33
- else :
34
- logger .warning (msg )
35
- return False
21
+ def check_spectrum_plottable (
22
+ spectrum_path : str | Spectrum , raise_error : bool = True , show_plot : bool = False , format : str = None
23
+ ):
24
+ """
25
+ Check if spectrum is readable and plottable with specutils.
26
+ show_plot = True requires matplotlib to be installed.
27
+
28
+ Parameters
29
+ ----------
30
+ spectrum_path : str or Spectrum
31
+ Path to spectrum file or Spectrum object
32
+
33
+ raise_error : bool. Default=True
34
+ True: Raise error if spectrum is not plottable
35
+ False: Do not raise error if spectrum is not plottable. Log warning instead.
36
+
37
+ show_plot : bool. Default=False
38
+ True: Show plot of spectrum. Matplotlib must be installed.
39
+
40
+ format : str, optional
41
+ Format of the spectrum file. If not provided, the format will be inferred by specutils.
42
+
43
+ Returns
44
+ -------
45
+ bool
46
+ True: Spectrum is plottable
47
+ False: Spectrum is not plottable
36
48
49
+ """
50
+ # check if spectrum is a Spectrum object or a file path
51
+ # if it's a file path, check if it can be read as a Spectrum object
52
+ if isinstance (spectrum_path , Spectrum ):
53
+ spectrum = spectrum_path
54
+ elif isinstance (spectrum_path , str ):
55
+ try :
56
+ spectrum = Spectrum .read (spectrum_path , format = format )
57
+ except Exception as error_message :
58
+ msg = f"Unable to load file as Spectrum object:{ spectrum_path } :\n { error_message } "
59
+ exit_function (msg , raise_error = raise_error )
60
+ else :
61
+ msg = f"Input is not a valid path or Spectrum object: { spectrum_path } "
62
+ exit_function (msg , raise_error = raise_error )
63
+
64
+ # checking spectrum has good units
65
+ wave_unit_check = _check_spectrum_wave_units (spectrum , raise_error = raise_error )
66
+ if not wave_unit_check :
67
+ return False
68
+
69
+ flux_unit_check = _check_spectrum_flux_units (spectrum , raise_error = raise_error )
70
+ if not flux_unit_check :
71
+ return False
72
+
73
+ # check for NaNs
74
+ nan_check = _check_spectrum_not_nans (spectrum , raise_error = raise_error )
75
+ if not nan_check :
76
+ return False
37
77
38
- def check_spectrum_not_nans (spectrum , raise_error = True ):
78
+ if show_plot :
79
+ _plot_spectrum (spectrum )
80
+
81
+ return True
82
+
83
+
84
+ def _check_spectrum_not_nans (spectrum , raise_error = True ):
39
85
nan_check : np .ndarray = ~ np .isnan (spectrum .flux ) & ~ np .isnan (spectrum .spectral_axis )
40
86
wave = spectrum .spectral_axis [nan_check ]
41
87
if not len (wave ):
@@ -50,7 +96,7 @@ def check_spectrum_not_nans(spectrum, raise_error=True):
50
96
return True
51
97
52
98
53
- def check_spectrum_wave_units (spectrum , raise_error = True ):
99
+ def _check_spectrum_wave_units (spectrum , raise_error = True ):
54
100
try :
55
101
spectrum .spectral_axis .to (u .micron ).value
56
102
return True
@@ -83,31 +129,18 @@ def check_spectrum_wave_units(spectrum, raise_error=True):
83
129
return False
84
130
85
131
86
- def check_spectrum_flux_units (spectrum , raise_error = True ):
87
- try :
88
- spectrum .flux .to (u .erg / u .s / u .cm ** 2 / u .AA ).value
132
+ def _check_spectrum_flux_units (spectrum , raise_error = True ):
133
+ expected_units = [
134
+ u .get_physical_type (u .erg / u .s / u .cm ** 2 / u .AA ),
135
+ u .get_physical_type (u .Jy ),
136
+ ]
137
+
138
+ unit_type = u .get_physical_type (spectrum .flux .unit )
139
+
140
+ if unit_type in expected_units :
89
141
return True
90
- except AttributeError as e :
91
- logger .debug (f"{ e } " )
92
- msg = f"Unable to parse flux: { spectrum } "
93
- if raise_error :
94
- logger .error (msg )
95
- raise AstroDBError (msg )
96
- else :
97
- logger .warning (msg )
98
- return False
99
- except u .UnitConversionError as e :
100
- logger .debug (f"{ e } " )
101
- msg = f"Unable to convert flux to erg/s/cm^2/Angstrom: { spectrum } "
102
- if raise_error :
103
- logger .error (msg )
104
- raise AstroDBError (msg )
105
- else :
106
- logger .warning (msg )
107
- return False
108
- except ValueError as e :
109
- logger .debug (f"{ e } " )
110
- msg = f"Value error: { spectrum } :"
142
+ else :
143
+ msg = f"flux units are not expected: { spectrum .flux .unit } . Expecting { expected_units } ."
111
144
if raise_error :
112
145
logger .error (msg )
113
146
raise AstroDBError (msg )
@@ -116,67 +149,12 @@ def check_spectrum_flux_units(spectrum, raise_error=True):
116
149
return False
117
150
118
151
119
- def plot_spectrum (spectrum ):
152
+ def _plot_spectrum (spectrum ):
120
153
if "matplotlib" in sys .modules :
121
154
plt .plot (spectrum .spectral_axis , spectrum .flux )
122
- plt .xlabel ("Dispersion ({spectrum.spectral_axis.unit})" )
123
- plt .ylabel ("Flux ({spectrum.flux.unit})" )
155
+ plt .xlabel (f "Dispersion ({ spectrum .spectral_axis .unit } )" )
156
+ plt .ylabel (f "Flux ({ spectrum .flux .unit } )" )
124
157
plt .show ()
125
158
else :
126
159
msg = "To display the spectrum, matplotlib most be installed."
127
160
logger .warning (msg )
128
-
129
-
130
- def check_spectrum_plottable (spectrum_path , raise_error = True , show_plot = False ):
131
- """
132
- Check if spectrum is readable and plottable with specutils.
133
- show_plot = True requires matplotlib to be installed.
134
-
135
- Parameters
136
- ----------
137
- spectrum_path : str
138
- Path to spectrum file
139
-
140
- raise_error : bool. Default=True
141
- True: Raise error if spectrum is not plottable
142
- False: Do not raise error if spectrum is not plottable. Log warning instead.
143
-
144
- show_plot : bool. Default=False
145
- True: Show plot of spectrum. Matplotlib must be installed.
146
-
147
- Returns
148
- -------
149
- bool
150
- True: Spectrum is plottable
151
- False: Spectrum is not plotable
152
-
153
- """
154
- # load the spectrum and make sure it's readable as a Spectrum1D object, has units, is not all NaNs.
155
- if isinstance (spectrum_path , Spectrum1D ):
156
- spectrum = spectrum_path
157
- class_check = True
158
- else :
159
- class_check = check_spectrum_class (spectrum_path , raise_error = raise_error )
160
- if not class_check :
161
- return False
162
- else :
163
- spectrum = Spectrum1D .read (spectrum_path )
164
-
165
- # checking spectrum has good units
166
- wave_unit_check = check_spectrum_wave_units (spectrum , raise_error = raise_error )
167
- if not wave_unit_check :
168
- return False
169
-
170
- flux_unit_check = check_spectrum_flux_units (spectrum , raise_error = raise_error )
171
- if not flux_unit_check :
172
- return False
173
-
174
- # check for NaNs
175
- nan_check = check_spectrum_not_nans (spectrum , raise_error = raise_error )
176
- if not nan_check :
177
- return False
178
-
179
- if show_plot :
180
- plot_spectrum (spectrum )
181
-
182
- return True
0 commit comments