PyNOT-redux 2.1.3__tar.gz → 2.2.1__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.
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/PKG-INFO +1 -1
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/PyNOT_redux.egg-info/PKG-INFO +1 -1
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/PyNOT_redux.egg-info/SOURCES.txt +21 -2
- pynot_redux-2.2.1/pynot/VERSION +1 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/extract_gui.py +4 -22
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/fitsio.py +32 -14
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/main.py +52 -1
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/scombine.py +13 -6
- pynot_redux-2.2.1/pynot/viewer/__init__.py +0 -0
- pynot_redux-2.2.1/pynot/viewer/containers.py +82 -0
- pynot_redux-2.2.1/pynot/viewer/default_linelists.json +103 -0
- pynot_redux-2.2.1/pynot/viewer/dust.py +149 -0
- pynot_redux-2.2.1/pynot/viewer/linelists.py +170 -0
- pynot_redux-2.2.1/pynot/viewer/messages.py +34 -0
- pynot_redux-2.2.1/pynot/viewer/models.py +300 -0
- pynot_redux-2.2.1/pynot/viewer/notes.py +262 -0
- pynot_redux-2.2.1/pynot/viewer/spectrum.py +386 -0
- pynot_redux-2.2.1/pynot/viewer/tablemodels.py +258 -0
- pynot_redux-2.2.1/pynot/viewer/targets.py +115 -0
- pynot_redux-2.2.1/pynot/viewer/templates/Assef_2010.dat +323 -0
- pynot_redux-2.2.1/pynot/viewer/templates/FeII.Vestergaard.dat +4182 -0
- pynot_redux-2.2.1/pynot/viewer/templates/FeIII.Vestergaard.dat +4182 -0
- pynot_redux-2.2.1/pynot/viewer/templates/Hernan_Caballero_quasar_NIR_template.txt +512 -0
- pynot_redux-2.2.1/pynot/viewer/templates/QSO_selsing.dat +5334 -0
- pynot_redux-2.2.1/pynot/viewer/templates/QSO_template.Krawczyk_all.dat +273 -0
- pynot_redux-2.2.1/pynot/viewer/templates/QSO_template.Krawczyk_high.dat +273 -0
- pynot_redux-2.2.1/pynot/viewer/templates/QSO_template.Krawczyk_low.dat +273 -0
- pynot_redux-2.2.1/pynot/viewer/viewer.py +944 -0
- pynot_redux-2.1.3/pynot/VERSION +0 -1
- pynot_redux-2.1.3/pynot/india.py +0 -163
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/.gitattributes +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/.github/dependabot.yml +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/.gitignore +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/LICENSE +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/MANIFEST.in +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/PyNOT_redux.egg-info/dependency_links.txt +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/PyNOT_redux.egg-info/entry_points.txt +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/PyNOT_redux.egg-info/requires.txt +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/PyNOT_redux.egg-info/top_level.txt +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/README.md +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/.extract_msg +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/.identify_msg +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/.instrument.cfg +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/.response_msg +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/__init__.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/alfosc.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/HeAr_linelist.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/HeNe_linelist.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/ThAr_linelist.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/al-gr18_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/al-gr19_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/al-gr4_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/al-gr7_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/alfosc_filters.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/default_options.yml +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/default_options_img.yml +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/ef-gr13_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/ef-gr14_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/ef-gr1_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/ef-gr3_pixeltable.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/efosc_filters.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/lapalma.ext +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/lasilla.ext +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/paranal.ext +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/bd174708.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/bd262606.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/bd332642.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/bd75325.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/eg21.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/feige110.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/feige34.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/gd153.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/gd50.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/gd71.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/hd19445.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/hd84937.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/hd93521.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/he3.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/hiltner600.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/ltt3864.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/tcs_namelist.txt +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calib/std/wolf1346.dat +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/calibs.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/__init__.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/alfosc.rules +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/efosc.rules +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/help/welcome_msg_extract.html +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/help/welcome_msg_identify.html +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/help/welcome_msg_response.html +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/io.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/obs.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/data/organizer.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/efosc.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/extraction.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/functions.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/identify_gui.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/images.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/insconfig.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/logging.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/operations.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/phot.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/phot_redux.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/redux.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/reports.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/response.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/response_gui.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/scired.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/skysub.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/tasks.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/transients.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/txtio.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/wavecal.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/wcs.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pynot/welcome.py +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/pyproject.toml +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/requirements.txt +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/setup.cfg +0 -0
- {pynot_redux-2.1.3 → pynot_redux-2.2.1}/setup.py +0 -0
|
@@ -28,7 +28,6 @@ pynot/fitsio.py
|
|
|
28
28
|
pynot/functions.py
|
|
29
29
|
pynot/identify_gui.py
|
|
30
30
|
pynot/images.py
|
|
31
|
-
pynot/india.py
|
|
32
31
|
pynot/insconfig.py
|
|
33
32
|
pynot/logging.py
|
|
34
33
|
pynot/main.py
|
|
@@ -92,4 +91,24 @@ pynot/data/obs.py
|
|
|
92
91
|
pynot/data/organizer.py
|
|
93
92
|
pynot/data/help/welcome_msg_extract.html
|
|
94
93
|
pynot/data/help/welcome_msg_identify.html
|
|
95
|
-
pynot/data/help/welcome_msg_response.html
|
|
94
|
+
pynot/data/help/welcome_msg_response.html
|
|
95
|
+
pynot/viewer/__init__.py
|
|
96
|
+
pynot/viewer/containers.py
|
|
97
|
+
pynot/viewer/default_linelists.json
|
|
98
|
+
pynot/viewer/dust.py
|
|
99
|
+
pynot/viewer/linelists.py
|
|
100
|
+
pynot/viewer/messages.py
|
|
101
|
+
pynot/viewer/models.py
|
|
102
|
+
pynot/viewer/notes.py
|
|
103
|
+
pynot/viewer/spectrum.py
|
|
104
|
+
pynot/viewer/tablemodels.py
|
|
105
|
+
pynot/viewer/targets.py
|
|
106
|
+
pynot/viewer/viewer.py
|
|
107
|
+
pynot/viewer/templates/Assef_2010.dat
|
|
108
|
+
pynot/viewer/templates/FeII.Vestergaard.dat
|
|
109
|
+
pynot/viewer/templates/FeIII.Vestergaard.dat
|
|
110
|
+
pynot/viewer/templates/Hernan_Caballero_quasar_NIR_template.txt
|
|
111
|
+
pynot/viewer/templates/QSO_selsing.dat
|
|
112
|
+
pynot/viewer/templates/QSO_template.Krawczyk_all.dat
|
|
113
|
+
pynot/viewer/templates/QSO_template.Krawczyk_high.dat
|
|
114
|
+
pynot/viewer/templates/QSO_template.Krawczyk_low.dat
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.2.1
|
|
@@ -51,27 +51,6 @@ def run_gui(input_fname, output_fname, app=None, **ext_kwargs):
|
|
|
51
51
|
del gui
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
# def save_ascii_spectrum(fname, wl, flux, err, hdr, bg=None):
|
|
55
|
-
# """Write spectrum to an ascii text file with header saved to separate text file."""
|
|
56
|
-
# if bg is not None:
|
|
57
|
-
# data_table = np.column_stack([wl, flux, err, bg])
|
|
58
|
-
# fmt = "%12.4f % .3e %.3e %.3e"
|
|
59
|
-
# col_names = "# Wavelength Flux Error Sky"
|
|
60
|
-
# else:
|
|
61
|
-
# data_table = np.column_stack([wl, flux, err])
|
|
62
|
-
# fmt = "%12.4f % .3e %.3e"
|
|
63
|
-
# col_names = "# Wavelength Flux Error"
|
|
64
|
-
#
|
|
65
|
-
# basename, ext = os.path.splitext(fname)
|
|
66
|
-
# header_fname = basename + '_hdr.txt'
|
|
67
|
-
#
|
|
68
|
-
# with open(fname, 'w') as output:
|
|
69
|
-
# output.write(col_names + "\n")
|
|
70
|
-
# np.savetxt(output, data_table, fmt=fmt)
|
|
71
|
-
# hdr.tofile(header_fname, sep='\n', endcard=False, padding=False, overwrite=True)
|
|
72
|
-
# return True, "File saved successfully"
|
|
73
|
-
|
|
74
|
-
|
|
75
54
|
def get_FWHM(y, x=None):
|
|
76
55
|
"""
|
|
77
56
|
Measure the FWHM of the profile given as `y`.
|
|
@@ -1669,7 +1648,10 @@ class ExtractGUI(QtWidgets.QMainWindow):
|
|
|
1669
1648
|
def update_xmask_in_points(self):
|
|
1670
1649
|
# Clear old shapes:
|
|
1671
1650
|
for item in self.xmask:
|
|
1672
|
-
|
|
1651
|
+
try:
|
|
1652
|
+
item.remove()
|
|
1653
|
+
except NotImplementedError:
|
|
1654
|
+
pass
|
|
1673
1655
|
self.xmask = list()
|
|
1674
1656
|
xmin, xmax, ymin, ymax = self.get_limits()
|
|
1675
1657
|
if xmin > 0 or xmax < self.image2d.data.shape[1]+1:
|
|
@@ -3,6 +3,8 @@ __author__ = "Jens-Kristian Krogager"
|
|
|
3
3
|
|
|
4
4
|
import warnings
|
|
5
5
|
from astropy.io import fits
|
|
6
|
+
from astropy import units as u
|
|
7
|
+
from astropy.table import QTable
|
|
6
8
|
import numpy as np
|
|
7
9
|
import os
|
|
8
10
|
|
|
@@ -129,8 +131,8 @@ def get_wavelength_from_header(hdr):
|
|
|
129
131
|
|
|
130
132
|
# -- These names are used to define proper column names for Wavelength, Flux and Error:
|
|
131
133
|
wavelength_column_names = ['wl', 'lam', 'lambda', 'loglam', 'wave', 'wavelength', 'awav']
|
|
132
|
-
flux_column_names = ['data', 'spec', 'flux', 'flam', 'fnu', 'flux_density']
|
|
133
|
-
error_column_names = ['err', 'sig', 'error', 'ivar', 'sigma', 'var', 'err_flux']
|
|
134
|
+
flux_column_names = ['data', 'spec', 'flux', 'flam', 'fnu', 'flux_density', 'reduced_flux']
|
|
135
|
+
error_column_names = ['err', 'sig', 'error', 'ivar', 'sigma', 'var', 'err_flux', 'flux_ivar', 'flux_var', 'flux_err']
|
|
134
136
|
mask_column_names = ['mask', 'qual', 'dq', 'qc']
|
|
135
137
|
|
|
136
138
|
# -- These names are used to define proper ImageHDU names for Flux and Error:
|
|
@@ -139,7 +141,7 @@ error_HDU_names = ['ERR', 'ERRS', 'SIG', 'SIGMA', 'ERROR', 'ERRORS', 'IVAR', 'VA
|
|
|
139
141
|
mask_HDU_names = ['MASK', 'QUAL', 'QC', 'DQ']
|
|
140
142
|
|
|
141
143
|
|
|
142
|
-
def get_spectrum_fits_table(
|
|
144
|
+
def get_spectrum_fits_table(table_hdu):
|
|
143
145
|
"""
|
|
144
146
|
Scan the TableData for columns containing wavelength, flux, error and mask.
|
|
145
147
|
All arrays of {wavelength, flux and error} must be present.
|
|
@@ -163,7 +165,12 @@ def get_spectrum_fits_table(tbdata):
|
|
|
163
165
|
Numpy boolean array of pixel mask. `True` if the pixel is 'good',
|
|
164
166
|
`False` if the pixel is bad and should not be used.
|
|
165
167
|
"""
|
|
166
|
-
|
|
168
|
+
tbdata = QTable.read(table_hdu)
|
|
169
|
+
# table_names = [name.lower() for name in tbdata.names]
|
|
170
|
+
for colname in tbdata.colnames:
|
|
171
|
+
tbdata.rename_column(colname, colname.lower())
|
|
172
|
+
table_names = tbdata.colnames
|
|
173
|
+
|
|
167
174
|
wl_in_table = False
|
|
168
175
|
for colname in wavelength_column_names:
|
|
169
176
|
if colname in table_names:
|
|
@@ -185,9 +192,10 @@ def get_spectrum_fits_table(tbdata):
|
|
|
185
192
|
for colname in error_column_names:
|
|
186
193
|
if colname in table_names:
|
|
187
194
|
error_in_table = True
|
|
188
|
-
if
|
|
189
|
-
|
|
190
|
-
|
|
195
|
+
if 'ivar' in colname.lower():
|
|
196
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
197
|
+
error = 1 / np.sqrt(tbdata[colname])
|
|
198
|
+
elif 'var' in colname.lower():
|
|
191
199
|
error = np.sqrt(tbdata[colname])
|
|
192
200
|
else:
|
|
193
201
|
error = tbdata[colname]
|
|
@@ -365,17 +373,19 @@ def load_fits_spectrum(fname, ext=None, iraf_obj=None):
|
|
|
365
373
|
else:
|
|
366
374
|
is_fits_table = isinstance(HDUlist[1], fits.BinTableHDU) or isinstance(HDUlist[1], fits.TableHDU)
|
|
367
375
|
if is_fits_table:
|
|
368
|
-
if ext:
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
376
|
+
if not ext:
|
|
377
|
+
ext = 1
|
|
378
|
+
|
|
379
|
+
table_hdu = HDUlist[ext]
|
|
380
|
+
tbdata = table_hdu.data
|
|
381
|
+
data_hdr = table_hdu.header
|
|
374
382
|
|
|
375
383
|
has_multi_extensions = len(HDUlist) > 2
|
|
376
384
|
if has_multi_extensions and (ext is None):
|
|
377
385
|
msg = "[WARNING] - More than one data extension detected in the file"
|
|
378
|
-
wavelength, data, error, mask = get_spectrum_fits_table(
|
|
386
|
+
wavelength, data, error, mask = get_spectrum_fits_table(table_hdu)
|
|
387
|
+
if 'CUNIT1' in data_hdr:
|
|
388
|
+
wavelength *= u.Unit(data_hdr['CUNIT1'])
|
|
379
389
|
return wavelength, data, error, mask, data_hdr, msg
|
|
380
390
|
|
|
381
391
|
elif len(HDUlist) == 2:
|
|
@@ -538,3 +548,11 @@ def create_error_image(base_fname, overwrite=False):
|
|
|
538
548
|
hdu.append(ext)
|
|
539
549
|
output_msg = " - Successfully created an error image"
|
|
540
550
|
return output_msg
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
def detect_4most_MEC(fname):
|
|
554
|
+
prim = fits.getheader(fname)
|
|
555
|
+
is_qmost = prim.get('INSTRUME', 'NONE').strip() == 'QMOST'
|
|
556
|
+
hdr = fits.getheader(fname, 1)
|
|
557
|
+
has_mec_extname = hdr.get('EXTNAME') in ['OBMETATAB', 'SPECTAB', 'FIBMETATAB']
|
|
558
|
+
return is_qmost & has_mec_extname
|
|
@@ -372,6 +372,10 @@ def main(inspect=False):
|
|
|
372
372
|
help="Set this option for 2D spectra of extended sources to turn off automatic localization")
|
|
373
373
|
parser_scomb.add_argument("--mef", action="store_false",
|
|
374
374
|
help="Set this option to save output as a multiextension FITS file instead of a FITS table.")
|
|
375
|
+
parser_scomb.add_argument("--imin", type=int, default=0,
|
|
376
|
+
help="Slice each input spectrum along dispersion axis [imin:imax], only for 1D spectra")
|
|
377
|
+
parser_scomb.add_argument("--imax", type=int, default=None,
|
|
378
|
+
help="Slice each input spectrum along dispersion axis [imin:imax], only for 1D spectra")
|
|
375
379
|
|
|
376
380
|
|
|
377
381
|
# -- extract :: Extraction of 1D spectrum from 2D
|
|
@@ -389,6 +393,31 @@ def main(inspect=False):
|
|
|
389
393
|
set_default_pars(parser_ext, section='extract', default_type=int,
|
|
390
394
|
ignore_pars=['interactive'])
|
|
391
395
|
|
|
396
|
+
# -- view :: View 1D spectra in an interactive window
|
|
397
|
+
parser_view = tasks.add_parser('view', formatter_class=set_help_width(31),
|
|
398
|
+
help="Display and interact with 1D spectra")
|
|
399
|
+
parser_view.add_argument("files", type=str, nargs='*',
|
|
400
|
+
help="Filenames of spectral data to load. Each file is loaded as one target")
|
|
401
|
+
parser_view.add_argument("-t", "--table", type=str,
|
|
402
|
+
help="Filename of association table. Each line in the file gives a comma-separated list of filenames. "
|
|
403
|
+
"All files in one line are loaded as a single target.")
|
|
404
|
+
parser_view.add_argument("-c", "--container", action="store_true",
|
|
405
|
+
help="Load the file(s) as a FITS container "
|
|
406
|
+
"(such as 4MOST MEC, SDSS bricks, or a large collection of files)")
|
|
407
|
+
parser_view.add_argument("-l", "--list", type=str, default='',
|
|
408
|
+
help="File list. Name of a text file where each line is the path of one spectrum."
|
|
409
|
+
"(Useful for loading many files in `container` mode with `-c`)")
|
|
410
|
+
# redshift_table=None, z_col=None, name_col=None, cls_col=None
|
|
411
|
+
parser_view.add_argument("-z", type=str, default='',
|
|
412
|
+
help="Filename of redshift catalog with a name, redshift and spectral type column. "
|
|
413
|
+
"Set column names using `--ncol`, `--zcol`, `--tcol`")
|
|
414
|
+
parser_view.add_argument("--ncol", type=str, default='',
|
|
415
|
+
help="Name of the target name column in `-z REDSHIFT_TABLE`")
|
|
416
|
+
parser_view.add_argument("--zcol", type=str, default='',
|
|
417
|
+
help="Name of the redshift column in `-z REDSHIFT_TABLE`")
|
|
418
|
+
parser_view.add_argument("--tcol", type=str, default='',
|
|
419
|
+
help="Name of the spectral type column in `-z REDSHIFT_TABLE`")
|
|
420
|
+
|
|
392
421
|
|
|
393
422
|
# Spectral Redux:
|
|
394
423
|
parser_redux = tasks.add_parser('spex', formatter_class=set_help_width(30),
|
|
@@ -770,7 +799,7 @@ def main(inspect=False):
|
|
|
770
799
|
|
|
771
800
|
if data_is_1d:
|
|
772
801
|
out_args = combine_1d(filelist, output=args.output, method=args.method,
|
|
773
|
-
scale=args.scale, table_output=args.mef)
|
|
802
|
+
scale=args.scale, table_output=args.mef, imin=args.imin, imax=args.imax)
|
|
774
803
|
else:
|
|
775
804
|
out_args = combine_2d(filelist, output=args.output, method=args.method, trim=args.trim,
|
|
776
805
|
scale=args.scale, extended=args.extended, dispaxis=args.axis)
|
|
@@ -796,6 +825,28 @@ def main(inspect=False):
|
|
|
796
825
|
gui.show()
|
|
797
826
|
app.exit(app.exec_())
|
|
798
827
|
|
|
828
|
+
elif task == 'view':
|
|
829
|
+
from PyQt5 import QtWidgets
|
|
830
|
+
from pynot.viewer.viewer import MainWindow
|
|
831
|
+
|
|
832
|
+
app = QtWidgets.QApplication(sys.argv)
|
|
833
|
+
screenSize = app.primaryScreen().size()
|
|
834
|
+
ratio = 0.85
|
|
835
|
+
if args.list:
|
|
836
|
+
with open(args.list) as l:
|
|
837
|
+
input_files = [line.strip() for line in l.readlines()]
|
|
838
|
+
else:
|
|
839
|
+
input_files = args.files
|
|
840
|
+
main = MainWindow(input_files,
|
|
841
|
+
assn_table=args.table,
|
|
842
|
+
container_mode=args.container,
|
|
843
|
+
width=ratio*screenSize.width(),
|
|
844
|
+
height=ratio*screenSize.height(),
|
|
845
|
+
redshift_table=args.z,
|
|
846
|
+
z_col=args.zcol, name_col=args.ncol, cls_col=args.tcol,
|
|
847
|
+
)
|
|
848
|
+
main.show()
|
|
849
|
+
app.exit(app.exec_())
|
|
799
850
|
|
|
800
851
|
# -- Imaging tasks:
|
|
801
852
|
elif task == 'phot':
|
|
@@ -353,7 +353,7 @@ def combine_2d(files, output=None, method='mean', scale=False, extended=False, d
|
|
|
353
353
|
|
|
354
354
|
|
|
355
355
|
|
|
356
|
-
def combine_1d(files, output=None, method='mean', scale=False, table_output=True):
|
|
356
|
+
def combine_1d(files, output=None, method='mean', scale=False, table_output=True, imin=0, imax=None):
|
|
357
357
|
"""Combine a list of 1d-spectra using either median or mean combination.
|
|
358
358
|
For median combination, only the overlapping parts of the spectra will be
|
|
359
359
|
combined. The mean combination uses a weighted average over the entire
|
|
@@ -376,6 +376,12 @@ def combine_1d(files, output=None, method='mean', scale=False, table_output=True
|
|
|
376
376
|
|
|
377
377
|
table_output : bool [default=True]
|
|
378
378
|
Use FITS table for the output format? Otherwise use a MultiExtension Fits File
|
|
379
|
+
|
|
380
|
+
imin : int
|
|
381
|
+
Apply slicing to each spectrum from imin to imax.
|
|
382
|
+
|
|
383
|
+
imax : int | None
|
|
384
|
+
Apply slicing to each spectrum from imin to imax.
|
|
379
385
|
"""
|
|
380
386
|
|
|
381
387
|
wl_all = list()
|
|
@@ -385,6 +391,7 @@ def combine_1d(files, output=None, method='mean', scale=False, table_output=True
|
|
|
385
391
|
size_all = list()
|
|
386
392
|
scales = list()
|
|
387
393
|
|
|
394
|
+
cut = slice(imin, imax)
|
|
388
395
|
msg = list()
|
|
389
396
|
for fname in files:
|
|
390
397
|
if fname.endswith('.fits') or fname.endswith('.fit'):
|
|
@@ -401,11 +408,11 @@ def combine_1d(files, output=None, method='mean', scale=False, table_output=True
|
|
|
401
408
|
msg.append(load_msg)
|
|
402
409
|
msg.append(" - Loaded ASCII spectrum: %s" % fname)
|
|
403
410
|
|
|
404
|
-
wl_all.append(wl)
|
|
405
|
-
flux_all.append(flux)
|
|
406
|
-
err_all.append(err)
|
|
407
|
-
mask_all.append(mask)
|
|
408
|
-
size_all.append(len(wl))
|
|
411
|
+
wl_all.append(wl[cut])
|
|
412
|
+
flux_all.append(flux[cut])
|
|
413
|
+
err_all.append(err[cut])
|
|
414
|
+
mask_all.append(mask[cut])
|
|
415
|
+
size_all.append(len(wl[cut]))
|
|
409
416
|
if scale:
|
|
410
417
|
nonzero = flux.nonzero()[0]
|
|
411
418
|
idx_0 = min(nonzero) + len(nonzero)/2
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import numpy as np
|
|
3
|
+
from astropy.io import fits
|
|
4
|
+
import astropy.units as u
|
|
5
|
+
|
|
6
|
+
from pynot.viewer.spectrum import Spectrum
|
|
7
|
+
from pynot.viewer.targets import Target
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GenericFileContainer:
|
|
11
|
+
def __init__(self, filelist):
|
|
12
|
+
self.filelist = filelist
|
|
13
|
+
self.view = []
|
|
14
|
+
for f in self.filelist:
|
|
15
|
+
for key in ['OBJ_NME', 'OBJ_UID', 'OBJECT']:
|
|
16
|
+
try:
|
|
17
|
+
name = fits.getval(f, key)
|
|
18
|
+
except Exception:
|
|
19
|
+
pass
|
|
20
|
+
else:
|
|
21
|
+
name = f
|
|
22
|
+
self.view.append(os.path.basename(name))
|
|
23
|
+
|
|
24
|
+
def __len__(self):
|
|
25
|
+
return len(self.filelist)
|
|
26
|
+
|
|
27
|
+
def __getitem__(self, index):
|
|
28
|
+
target = Target(name=self.view[index])
|
|
29
|
+
spec = Spectrum.read(self.filelist[index])
|
|
30
|
+
target.add_spectrum(spec)
|
|
31
|
+
return target
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class QMEC:
|
|
35
|
+
def __init__(self, filename, view):
|
|
36
|
+
self.filename = filename
|
|
37
|
+
self.view = view
|
|
38
|
+
|
|
39
|
+
def __len__(self):
|
|
40
|
+
return len(self.view)
|
|
41
|
+
|
|
42
|
+
def __getitem__(self, index):
|
|
43
|
+
return self.get_target(index)
|
|
44
|
+
|
|
45
|
+
def get_target(self, index):
|
|
46
|
+
target = Target(name=self.view[index])
|
|
47
|
+
with fits.open(self.filename) as hdu:
|
|
48
|
+
data = hdu['SPECTAB'].data[index]
|
|
49
|
+
hdr = hdu['SPECTAB'].header
|
|
50
|
+
|
|
51
|
+
flux = data['FLUX'].flatten()
|
|
52
|
+
try:
|
|
53
|
+
ivar = data['FLUX_IVAR'].flatten()
|
|
54
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
55
|
+
error = 1 / np.sqrt(ivar)
|
|
56
|
+
except Exception:
|
|
57
|
+
error = data['ERR_FLUX'].flatten()
|
|
58
|
+
npix = len(flux)
|
|
59
|
+
wavelength = np.arange(npix) * hdr['1CDLT1'] + hdr['1CRVL1']
|
|
60
|
+
wavelength *= u.Unit(hdr['1CUNI1'])
|
|
61
|
+
flux_unit = u.Unit(hdr['TUNIT1'])
|
|
62
|
+
spectrum = Spectrum(wavelength=wavelength,
|
|
63
|
+
flux=flux*flux_unit,
|
|
64
|
+
error=error*flux_unit,
|
|
65
|
+
name=f"[{index}]",
|
|
66
|
+
filename=self.filename+f"[{index}]",
|
|
67
|
+
meta=dict(hdr))
|
|
68
|
+
target.add_spectrum(spectrum)
|
|
69
|
+
return target
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def read(filename):
|
|
74
|
+
with fits.open(filename) as hdu:
|
|
75
|
+
names_columns = ['OBJECT', 'OBJ_NME', 'OBJ_UID']
|
|
76
|
+
for colname in names_columns:
|
|
77
|
+
if colname in hdu['FIBMETATAB'].data.names:
|
|
78
|
+
view = hdu['FIBMETATAB'].data[colname]
|
|
79
|
+
break
|
|
80
|
+
else:
|
|
81
|
+
view = [f"Object #{num}" for num in range(len(hdu['FIBMETATAB'].data))]
|
|
82
|
+
return QMEC(filename, view)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"": [],
|
|
3
|
+
|
|
4
|
+
"Common Lines": [
|
|
5
|
+
["Ly-α", 1215.67, true],
|
|
6
|
+
["N V 1240", 1240.14, true],
|
|
7
|
+
["Si IV / O IV]", 1399, true],
|
|
8
|
+
["C IV", 1549.06, true],
|
|
9
|
+
["C III]", 1908.73, true],
|
|
10
|
+
["Mg II", 2798.75, true],
|
|
11
|
+
["H-α", 6564.61, true],
|
|
12
|
+
["H-β", 4862.68, true],
|
|
13
|
+
["H-γ", 4341.68, true],
|
|
14
|
+
["H-δ", 4102.89, true],
|
|
15
|
+
["H-ε", 3971.20, true],
|
|
16
|
+
["[O II] 3727", 3727.09, true],
|
|
17
|
+
["[O II] 3729", 3729.88, true],
|
|
18
|
+
["[Ne III] 3870", 3869.86, true],
|
|
19
|
+
["[O III] 4364", 4364.44, true],
|
|
20
|
+
["[O III] 4960", 4960.30, true],
|
|
21
|
+
["[O III] 5008", 5008.24, true],
|
|
22
|
+
["[N II] 6550", 6549.86, true],
|
|
23
|
+
["[N II] 6585", 6585.27, true],
|
|
24
|
+
["[S II] 6718", 6718.29, true],
|
|
25
|
+
["[S II] 6733", 6732.67, true],
|
|
26
|
+
["Ca II K", 3934.78, true],
|
|
27
|
+
["Ca II H", 3969.59, true],
|
|
28
|
+
["Mg I b", 5176.70, true],
|
|
29
|
+
["Na I D", 5891.58, true]
|
|
30
|
+
],
|
|
31
|
+
|
|
32
|
+
"Quasar Lines": [
|
|
33
|
+
["O VI", 1033.83, true],
|
|
34
|
+
["Ly-α", 1215.67, true],
|
|
35
|
+
["Ly-β", 1025.72, true],
|
|
36
|
+
["N V 1240", 1240.14, true],
|
|
37
|
+
["O I", 1304.35, true],
|
|
38
|
+
["Si IV / O IV]", 1399, true],
|
|
39
|
+
["C IV", 1549.06, true],
|
|
40
|
+
["He II 1640", 1640.42, true],
|
|
41
|
+
["C III]", 1908.73, true],
|
|
42
|
+
["Mg II", 2798.75, true],
|
|
43
|
+
["H-α", 6564.61, true],
|
|
44
|
+
["H-β", 4862.68, true],
|
|
45
|
+
["H-γ", 4341.68, true],
|
|
46
|
+
["H-δ", 4102.89, true],
|
|
47
|
+
["H-ε", 3971.20, true],
|
|
48
|
+
["[O II] 3727", 3727.09, true],
|
|
49
|
+
["[O II] 3729", 3729.88, true],
|
|
50
|
+
["[Ne III] 3870", 3869.86, true],
|
|
51
|
+
["[O III] 4960", 4960.30, true],
|
|
52
|
+
["[O III] 5008", 5008.24, true],
|
|
53
|
+
["[N II] 6550", 6549.86, true],
|
|
54
|
+
["[N II] 6585", 6585.27, true],
|
|
55
|
+
["[S II] 6718", 6718.29, true],
|
|
56
|
+
["[S II] 6733", 6732.67, true]
|
|
57
|
+
],
|
|
58
|
+
|
|
59
|
+
"ISM Absorption": [
|
|
60
|
+
["CI_1656", 1656.93, true],
|
|
61
|
+
["CI_1560", 1560.31, true],
|
|
62
|
+
["CI_1328", 1328.83, true],
|
|
63
|
+
["SII_1250", 1250.578, true],
|
|
64
|
+
["SII_1253", 1253.805, true],
|
|
65
|
+
["SII_1259", 1259.518, true],
|
|
66
|
+
["OI_1302", 1302.17, true],
|
|
67
|
+
["FeII_1608", 1608.45, true],
|
|
68
|
+
["SiII_1260", 1260.42, true],
|
|
69
|
+
["SiII_1304", 1304.37, true],
|
|
70
|
+
["CII_1334", 1334.53, true],
|
|
71
|
+
["SiIV_1393", 1393.76, true],
|
|
72
|
+
["SiIV_1402", 1402.77, true],
|
|
73
|
+
["SiII_1526", 1526.71, true],
|
|
74
|
+
["CIV_1548", 1548.19, true],
|
|
75
|
+
["CIV_1550", 1550.77, true],
|
|
76
|
+
["FeII_1608", 1608.45, true],
|
|
77
|
+
["AlII_1670", 1670.79, true],
|
|
78
|
+
["SiII_1808", 1808.01, true],
|
|
79
|
+
["AlIII_1854", 1854.72, true],
|
|
80
|
+
["AlIII_1862", 1862.79, true],
|
|
81
|
+
["TiII_1910", 1910.61, true],
|
|
82
|
+
["TiII_3073", 3073.86, true],
|
|
83
|
+
["TiII_3242", 3242.91, true],
|
|
84
|
+
["TiII_3384", 3384.73, true],
|
|
85
|
+
["FeII_2344", 2344.21, true],
|
|
86
|
+
["FeII_2374", 2374.46, true],
|
|
87
|
+
["FeII_2382", 2382.76, true],
|
|
88
|
+
["MnII_2576", 2576.87, true],
|
|
89
|
+
["FeII_2586", 2586.65, true],
|
|
90
|
+
["MnII_2594", 2594.50, true],
|
|
91
|
+
["FeII_2600", 2600.17, true],
|
|
92
|
+
["MnII_2606", 2606.46, true],
|
|
93
|
+
["MgII_2796", 2796.35, true],
|
|
94
|
+
["MgII_2803", 2803.53, true],
|
|
95
|
+
["MgI_2852", 2852.96, true],
|
|
96
|
+
["NaI_5891", 5891.58, true],
|
|
97
|
+
["NaI_5897", 5897.56, true],
|
|
98
|
+
["ZnII_2026", 2026.14, true],
|
|
99
|
+
["ZnII_2062", 2062.66, true],
|
|
100
|
+
["CaII_3934", 3934.77, true],
|
|
101
|
+
["CaII_3969", 3969.59, true]
|
|
102
|
+
]
|
|
103
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
from scipy.interpolate import UnivariateSpline as spline
|
|
4
|
+
|
|
5
|
+
parameters = {
|
|
6
|
+
'SMC': {'c1': -4.959, 'c2': 2.264, 'c3': 0.389, 'c4': 0.0, 'x0': 4.579, 'gamma': 0.934, 'Rv': 2.74},
|
|
7
|
+
'LMC': {'c1': -0.89, 'c2': 0.998, 'c3': 2.719, 'c4': 0.0, 'x0': 4.579, 'gamma': 0.934, 'Rv': 3.41},
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def MW_reddening(wl, Rv=3.1):
|
|
12
|
+
"""
|
|
13
|
+
Average Galactic reddening law parametrized by Fitzpatrick & Massa (2007).
|
|
14
|
+
|
|
15
|
+
INPUT
|
|
16
|
+
wl: wavelength in Angstrom
|
|
17
|
+
|
|
18
|
+
Rv: if not given, the average value of 3.1 is assumed.
|
|
19
|
+
|
|
20
|
+
Returns A(l)/A(V) evaluated at the input wavelengths.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
if isinstance(wl, float):
|
|
24
|
+
wl = np.array([wl])
|
|
25
|
+
convert2float = True
|
|
26
|
+
else:
|
|
27
|
+
convert2float = False
|
|
28
|
+
|
|
29
|
+
k_in = 1./(wl*1.e-4)
|
|
30
|
+
|
|
31
|
+
c4 = 0.319
|
|
32
|
+
c3 = 2.991
|
|
33
|
+
c2 = 5.0/Rv - 0.85
|
|
34
|
+
c1 = 2.09 - 2.84*c2
|
|
35
|
+
x0 = 4.592
|
|
36
|
+
gamma = 0.922
|
|
37
|
+
pars_avg = {'c1': c1, 'c2': c2, 'c3': c3, 'c4': c4,
|
|
38
|
+
'x0': x0, 'gamma': gamma, 'Rv': Rv}
|
|
39
|
+
|
|
40
|
+
ksi = FM2007(k_in, **pars_avg)
|
|
41
|
+
|
|
42
|
+
if convert2float:
|
|
43
|
+
ksi = float(ksi)
|
|
44
|
+
return ksi
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def FM2007(wl, c1, c2, c3, c4, Rv, x0=4.579, gamma=0.934):
|
|
48
|
+
"""
|
|
49
|
+
Fitzpatrick & Mazza extinction curve
|
|
50
|
+
Return ksi = A(lambda)/A(V) instead of E(B-lambda)/E(B-V).
|
|
51
|
+
Using O2 and O3 as free parameters for optical spline.
|
|
52
|
+
O2 = 1.33 +/- 0.01
|
|
53
|
+
O3 = 2.0 +/- 0.1
|
|
54
|
+
O1 is kept fixed to ensure correct normalization.
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
wl : np.ndarray
|
|
59
|
+
Wavelength array in angstrom
|
|
60
|
+
|
|
61
|
+
pars : dict
|
|
62
|
+
Parameters for the extinction curve:
|
|
63
|
+
(c1, c2, c3, c4, x0, gamma, Rv)
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
ksi : np.ndarray
|
|
68
|
+
Array of A(lambda) / A(v) for the given input wavelength array.
|
|
69
|
+
"""
|
|
70
|
+
k = 1 / (wl*1.e-4)
|
|
71
|
+
|
|
72
|
+
D = k**2/((k**2 - x0**2)**2 + k**2*gamma**2)
|
|
73
|
+
|
|
74
|
+
F = 0.5392*(k-5.9)**2 + 0.05644*(k-5.9)**3
|
|
75
|
+
F[k < 5.9] = 0.
|
|
76
|
+
|
|
77
|
+
# Use Fitzpatrick & Massa 1990 original formulation
|
|
78
|
+
# with fixed UV polynomial:
|
|
79
|
+
Ebv = c1 + c2*k + c3*D + c4*F
|
|
80
|
+
|
|
81
|
+
# Use IR power-law from Fitzpatrick & Massa 2007
|
|
82
|
+
# assuming the correlation ketween k_IR and Rv.
|
|
83
|
+
# Their eq. 7:
|
|
84
|
+
Ebv_IR = (-0.83 + 0.63*Rv)*k**1.84 - Rv
|
|
85
|
+
|
|
86
|
+
# Use spline points from 1 < x < 3.7
|
|
87
|
+
# Anchor to UV and IR parts to make smooth transition: (FM2007)
|
|
88
|
+
U1 = 3.85 # anchor at 2600A
|
|
89
|
+
U2 = 3.7 # anchor at 2700A
|
|
90
|
+
O_UV1 = c1 + c2*U1 + c3*U1**2/((U1**2 - x0**2)**2 + U1**2*gamma**2)
|
|
91
|
+
O_UV2 = c1 + c2*U2 + c3*U2**2/((U2**2 - x0**2)**2 + U2**2*gamma**2)
|
|
92
|
+
O_IRopt = (-0.83 + 0.63*Rv)*1.0**1.84 - Rv # anchor at 1.0
|
|
93
|
+
O_IR = (-0.83 + 0.63*Rv)*0.75**1.84 - Rv # anchor at 0.75
|
|
94
|
+
|
|
95
|
+
# Array of anchor points for spline
|
|
96
|
+
O = np.array([O_IR, O_IRopt, 0., O_UV2, O_UV1])
|
|
97
|
+
|
|
98
|
+
# Array of inverse wavelength for spline anchors:
|
|
99
|
+
k_anchor = np.array([0.75, 1., 1.808, U2, U1])
|
|
100
|
+
|
|
101
|
+
Ebv_spline_func = spline(k_anchor, O)
|
|
102
|
+
Ebv_spline = Ebv_spline_func(k)
|
|
103
|
+
|
|
104
|
+
# stitch together the pieces
|
|
105
|
+
Ebv = Ebv*(k >= 3.7) + Ebv_spline*(k < 3.7)*(k > 1.) + Ebv_IR*(k <= 1.)
|
|
106
|
+
|
|
107
|
+
ksi = Ebv/Rv + 1.
|
|
108
|
+
|
|
109
|
+
return ksi
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class DustModel:
|
|
113
|
+
name = ''
|
|
114
|
+
|
|
115
|
+
def __init__(self, name: str, pars: dict[str, float], functor=FM2007):
|
|
116
|
+
self.name = name
|
|
117
|
+
self.pars = pars
|
|
118
|
+
self.functor = functor
|
|
119
|
+
|
|
120
|
+
def __call__(self, x: np.ndarray, Av=1.0):
|
|
121
|
+
model = 10**(-0.4 * self.functor(x, **self.pars) * Av)
|
|
122
|
+
return 10**(-0.4 * self.functor(x, **self.pars) * Av)
|
|
123
|
+
|
|
124
|
+
def __repr__(self):
|
|
125
|
+
return self.__str__()
|
|
126
|
+
|
|
127
|
+
def __str__(self):
|
|
128
|
+
return self.name
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class SMCDustModel(DustModel):
|
|
132
|
+
name = 'SMC'
|
|
133
|
+
|
|
134
|
+
def __init__(self):
|
|
135
|
+
super().__init__(name='SMC', pars=parameters['SMC'])
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class LMCDustModel(DustModel):
|
|
139
|
+
name = 'LMC'
|
|
140
|
+
|
|
141
|
+
def __init__(self):
|
|
142
|
+
super().__init__(name='LMC', pars=parameters['LMC'])
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class MWDustModel(DustModel):
|
|
146
|
+
name = 'MW'
|
|
147
|
+
|
|
148
|
+
def __init__(self):
|
|
149
|
+
super().__init__(name='MW', pars={'Rv': 3.1}, functor=MW_reddening)
|