pyreduce-astro 0.7a4__cp314-cp314-win_amd64.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.
- pyreduce/__init__.py +67 -0
- pyreduce/__main__.py +322 -0
- pyreduce/cli.py +342 -0
- pyreduce/clib/Release/_slitfunc_2d.cp311-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_2d.cp311-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_2d.cp312-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_2d.cp312-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_2d.cp313-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_2d.cp313-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_2d.cp314-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_2d.cp314-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_2d.obj +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp311-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp311-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp312-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp312-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp313-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp313-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp314-win_amd64.exp +0 -0
- pyreduce/clib/Release/_slitfunc_bd.cp314-win_amd64.lib +0 -0
- pyreduce/clib/Release/_slitfunc_bd.obj +0 -0
- pyreduce/clib/__init__.py +0 -0
- pyreduce/clib/_slitfunc_2d.cp311-win_amd64.pyd +0 -0
- pyreduce/clib/_slitfunc_2d.cp312-win_amd64.pyd +0 -0
- pyreduce/clib/_slitfunc_2d.cp313-win_amd64.pyd +0 -0
- pyreduce/clib/_slitfunc_2d.cp314-win_amd64.pyd +0 -0
- pyreduce/clib/_slitfunc_bd.cp311-win_amd64.pyd +0 -0
- pyreduce/clib/_slitfunc_bd.cp312-win_amd64.pyd +0 -0
- pyreduce/clib/_slitfunc_bd.cp313-win_amd64.pyd +0 -0
- pyreduce/clib/_slitfunc_bd.cp314-win_amd64.pyd +0 -0
- pyreduce/clib/build_extract.py +75 -0
- pyreduce/clib/slit_func_2d_xi_zeta_bd.c +1313 -0
- pyreduce/clib/slit_func_2d_xi_zeta_bd.h +55 -0
- pyreduce/clib/slit_func_bd.c +362 -0
- pyreduce/clib/slit_func_bd.h +17 -0
- pyreduce/clipnflip.py +147 -0
- pyreduce/combine_frames.py +861 -0
- pyreduce/configuration.py +191 -0
- pyreduce/continuum_normalization.py +329 -0
- pyreduce/cwrappers.py +404 -0
- pyreduce/datasets.py +238 -0
- pyreduce/echelle.py +413 -0
- pyreduce/estimate_background_scatter.py +130 -0
- pyreduce/extract.py +1362 -0
- pyreduce/extraction_width.py +77 -0
- pyreduce/instruments/__init__.py +0 -0
- pyreduce/instruments/aj.py +9 -0
- pyreduce/instruments/aj.yaml +51 -0
- pyreduce/instruments/andes.py +102 -0
- pyreduce/instruments/andes.yaml +72 -0
- pyreduce/instruments/common.py +711 -0
- pyreduce/instruments/common.yaml +57 -0
- pyreduce/instruments/crires_plus.py +103 -0
- pyreduce/instruments/crires_plus.yaml +101 -0
- pyreduce/instruments/filters.py +195 -0
- pyreduce/instruments/harpn.py +203 -0
- pyreduce/instruments/harpn.yaml +140 -0
- pyreduce/instruments/harps.py +312 -0
- pyreduce/instruments/harps.yaml +144 -0
- pyreduce/instruments/instrument_info.py +140 -0
- pyreduce/instruments/jwst_miri.py +29 -0
- pyreduce/instruments/jwst_miri.yaml +53 -0
- pyreduce/instruments/jwst_niriss.py +98 -0
- pyreduce/instruments/jwst_niriss.yaml +60 -0
- pyreduce/instruments/lick_apf.py +35 -0
- pyreduce/instruments/lick_apf.yaml +60 -0
- pyreduce/instruments/mcdonald.py +123 -0
- pyreduce/instruments/mcdonald.yaml +56 -0
- pyreduce/instruments/metis_ifu.py +45 -0
- pyreduce/instruments/metis_ifu.yaml +62 -0
- pyreduce/instruments/metis_lss.py +45 -0
- pyreduce/instruments/metis_lss.yaml +62 -0
- pyreduce/instruments/micado.py +45 -0
- pyreduce/instruments/micado.yaml +62 -0
- pyreduce/instruments/models.py +257 -0
- pyreduce/instruments/neid.py +156 -0
- pyreduce/instruments/neid.yaml +61 -0
- pyreduce/instruments/nirspec.py +215 -0
- pyreduce/instruments/nirspec.yaml +63 -0
- pyreduce/instruments/nte.py +42 -0
- pyreduce/instruments/nte.yaml +55 -0
- pyreduce/instruments/uves.py +46 -0
- pyreduce/instruments/uves.yaml +65 -0
- pyreduce/instruments/xshooter.py +39 -0
- pyreduce/instruments/xshooter.yaml +63 -0
- pyreduce/make_shear.py +607 -0
- pyreduce/masks/mask_crires_plus_det1.fits.gz +0 -0
- pyreduce/masks/mask_crires_plus_det2.fits.gz +0 -0
- pyreduce/masks/mask_crires_plus_det3.fits.gz +0 -0
- pyreduce/masks/mask_ctio_chiron.fits.gz +0 -0
- pyreduce/masks/mask_elodie.fits.gz +0 -0
- pyreduce/masks/mask_feros3.fits.gz +0 -0
- pyreduce/masks/mask_flames_giraffe.fits.gz +0 -0
- pyreduce/masks/mask_harps_blue.fits.gz +0 -0
- pyreduce/masks/mask_harps_red.fits.gz +0 -0
- pyreduce/masks/mask_hds_blue.fits.gz +0 -0
- pyreduce/masks/mask_hds_red.fits.gz +0 -0
- pyreduce/masks/mask_het_hrs_2x5.fits.gz +0 -0
- pyreduce/masks/mask_jwst_miri_lrs_slitless.fits.gz +0 -0
- pyreduce/masks/mask_jwst_niriss_gr700xd.fits.gz +0 -0
- pyreduce/masks/mask_lick_apf_.fits.gz +0 -0
- pyreduce/masks/mask_mcdonald.fits.gz +0 -0
- pyreduce/masks/mask_nes.fits.gz +0 -0
- pyreduce/masks/mask_nirspec_nirspec.fits.gz +0 -0
- pyreduce/masks/mask_sarg.fits.gz +0 -0
- pyreduce/masks/mask_sarg_2x2a.fits.gz +0 -0
- pyreduce/masks/mask_sarg_2x2b.fits.gz +0 -0
- pyreduce/masks/mask_subaru_hds_red.fits.gz +0 -0
- pyreduce/masks/mask_uves_blue.fits.gz +0 -0
- pyreduce/masks/mask_uves_blue_binned_2_2.fits.gz +0 -0
- pyreduce/masks/mask_uves_middle.fits.gz +0 -0
- pyreduce/masks/mask_uves_middle_2x2_split.fits.gz +0 -0
- pyreduce/masks/mask_uves_middle_binned_2_2.fits.gz +0 -0
- pyreduce/masks/mask_uves_red.fits.gz +0 -0
- pyreduce/masks/mask_uves_red_2x2.fits.gz +0 -0
- pyreduce/masks/mask_uves_red_2x2_split.fits.gz +0 -0
- pyreduce/masks/mask_uves_red_binned_2_2.fits.gz +0 -0
- pyreduce/masks/mask_xshooter_nir.fits.gz +0 -0
- pyreduce/pipeline.py +619 -0
- pyreduce/rectify.py +138 -0
- pyreduce/reduce.py +2065 -0
- pyreduce/settings/settings_AJ.json +19 -0
- pyreduce/settings/settings_ANDES.json +89 -0
- pyreduce/settings/settings_CRIRES_PLUS.json +89 -0
- pyreduce/settings/settings_HARPN.json +73 -0
- pyreduce/settings/settings_HARPS.json +69 -0
- pyreduce/settings/settings_JWST_MIRI.json +55 -0
- pyreduce/settings/settings_JWST_NIRISS.json +55 -0
- pyreduce/settings/settings_LICK_APF.json +62 -0
- pyreduce/settings/settings_MCDONALD.json +58 -0
- pyreduce/settings/settings_METIS_IFU.json +77 -0
- pyreduce/settings/settings_METIS_LSS.json +77 -0
- pyreduce/settings/settings_MICADO.json +78 -0
- pyreduce/settings/settings_NEID.json +73 -0
- pyreduce/settings/settings_NIRSPEC.json +58 -0
- pyreduce/settings/settings_NTE.json +60 -0
- pyreduce/settings/settings_UVES.json +54 -0
- pyreduce/settings/settings_XSHOOTER.json +78 -0
- pyreduce/settings/settings_pyreduce.json +184 -0
- pyreduce/settings/settings_schema.json +850 -0
- pyreduce/tools/__init__.py +0 -0
- pyreduce/tools/combine.py +117 -0
- pyreduce/trace.py +979 -0
- pyreduce/util.py +1366 -0
- pyreduce/wavecal/MICADO_HK_3arcsec_chip5.npz +0 -0
- pyreduce/wavecal/atlas/thar.fits +4946 -13
- pyreduce/wavecal/atlas/thar_list.txt +4172 -0
- pyreduce/wavecal/atlas/une.fits +0 -0
- pyreduce/wavecal/convert.py +38 -0
- pyreduce/wavecal/crires_plus_J1228_Open_det1.npz +0 -0
- pyreduce/wavecal/crires_plus_J1228_Open_det2.npz +0 -0
- pyreduce/wavecal/crires_plus_J1228_Open_det3.npz +0 -0
- pyreduce/wavecal/harpn_harpn_2D.npz +0 -0
- pyreduce/wavecal/harps_blue_2D.npz +0 -0
- pyreduce/wavecal/harps_blue_pol_2D.npz +0 -0
- pyreduce/wavecal/harps_red_2D.npz +0 -0
- pyreduce/wavecal/harps_red_pol_2D.npz +0 -0
- pyreduce/wavecal/mcdonald.npz +0 -0
- pyreduce/wavecal/metis_lss_l_2D.npz +0 -0
- pyreduce/wavecal/metis_lss_m_2D.npz +0 -0
- pyreduce/wavecal/nirspec_K2.npz +0 -0
- pyreduce/wavecal/uves_blue_360nm_2D.npz +0 -0
- pyreduce/wavecal/uves_blue_390nm_2D.npz +0 -0
- pyreduce/wavecal/uves_blue_437nm_2D.npz +0 -0
- pyreduce/wavecal/uves_middle_2x2_2D.npz +0 -0
- pyreduce/wavecal/uves_middle_565nm_2D.npz +0 -0
- pyreduce/wavecal/uves_middle_580nm_2D.npz +0 -0
- pyreduce/wavecal/uves_middle_600nm_2D.npz +0 -0
- pyreduce/wavecal/uves_middle_665nm_2D.npz +0 -0
- pyreduce/wavecal/uves_middle_860nm_2D.npz +0 -0
- pyreduce/wavecal/uves_red_580nm_2D.npz +0 -0
- pyreduce/wavecal/uves_red_600nm_2D.npz +0 -0
- pyreduce/wavecal/uves_red_665nm_2D.npz +0 -0
- pyreduce/wavecal/uves_red_760nm_2D.npz +0 -0
- pyreduce/wavecal/uves_red_860nm_2D.npz +0 -0
- pyreduce/wavecal/xshooter_nir.npz +0 -0
- pyreduce/wavelength_calibration.py +1871 -0
- pyreduce_astro-0.7a4.dist-info/METADATA +106 -0
- pyreduce_astro-0.7a4.dist-info/RECORD +182 -0
- pyreduce_astro-0.7a4.dist-info/WHEEL +4 -0
- pyreduce_astro-0.7a4.dist-info/entry_points.txt +2 -0
- pyreduce_astro-0.7a4.dist-info/licenses/LICENSE +674 -0
|
File without changes
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""
|
|
2
|
+
with our powers combined we increase snr
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
from spectres import spectres
|
|
10
|
+
from tqdm import tqdm
|
|
11
|
+
|
|
12
|
+
from .. import echelle, util
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def combine(files, output, plot=None):
|
|
18
|
+
# Create a Wavelength grid that will be used for all spectra
|
|
19
|
+
# Based on the one in the "first" fits file
|
|
20
|
+
e = echelle.read(files[0], continuum_normalization=False)
|
|
21
|
+
nord, ncol = e.spec.shape
|
|
22
|
+
|
|
23
|
+
# Prepare some empty arrays for storage of all the data
|
|
24
|
+
# TODO what if this becomes to large to handle?
|
|
25
|
+
waves = np.zeros((len(files), nord, ncol))
|
|
26
|
+
specs = np.zeros((len(files), nord, ncol))
|
|
27
|
+
sigms = np.zeros((len(files), nord, ncol))
|
|
28
|
+
conts = np.zeros((len(files), nord, ncol))
|
|
29
|
+
|
|
30
|
+
mask = np.full(len(files), True)
|
|
31
|
+
|
|
32
|
+
# Load all the data from all files
|
|
33
|
+
# And resample the spectrum and the continuum onto the shared grid
|
|
34
|
+
for k, file in tqdm(enumerate(files), desc="File", total=len(files)):
|
|
35
|
+
try:
|
|
36
|
+
e = echelle.read(file, continuum_normalization=False)
|
|
37
|
+
specs[k] = np.ma.filled(e.spec, 0)
|
|
38
|
+
waves[k] = np.ma.getdata(e.wave)
|
|
39
|
+
sigms[k] = np.ma.filled(e.sig, 1)
|
|
40
|
+
conts[k] = np.ma.filled(e.cont, 0)
|
|
41
|
+
except ValueError as ex:
|
|
42
|
+
logger.warning("Error in loading file %s. %s", file, ex)
|
|
43
|
+
mask[k] = False
|
|
44
|
+
|
|
45
|
+
waves = waves[mask]
|
|
46
|
+
specs = specs[mask]
|
|
47
|
+
sigms = sigms[mask]
|
|
48
|
+
conts = conts[mask]
|
|
49
|
+
|
|
50
|
+
# wmin, wmax = waves.min(axis=(0, 2)), waves.max(axis=(0, 2))
|
|
51
|
+
# wnew = np.geomspace(wmin, wmax, ncol, endpoint=True).T
|
|
52
|
+
# TODO something weird happens when changing the wavelength grid, that also depends on the wavelength
|
|
53
|
+
# Maybe points in the grid are interpreted differently, i.e. in the rebinning they are the center of the
|
|
54
|
+
# bin, but later on they are the edges?
|
|
55
|
+
wnew = np.copy(waves[0])
|
|
56
|
+
|
|
57
|
+
for k in tqdm(range(specs.shape[0]), desc="File"):
|
|
58
|
+
for i in tqdm(range(nord), desc="Order", leave=False):
|
|
59
|
+
conts[k, i], _ = spectres(wnew[i], waves[k, i], conts[k, i], sigms[k, i])
|
|
60
|
+
specs[k, i], sigms[k, i] = spectres(
|
|
61
|
+
wnew[i], waves[k, i], specs[k, i], sigms[k, i]
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# These are just for plotting
|
|
65
|
+
if plot:
|
|
66
|
+
sold = np.copy(specs[:, plot])
|
|
67
|
+
cold = np.copy(conts[:, plot])
|
|
68
|
+
|
|
69
|
+
# Median and MAD
|
|
70
|
+
# We use the MAD over the whole range though, since we need some data points to properly evaluate it
|
|
71
|
+
arr = specs / conts
|
|
72
|
+
mean = np.nanmedian(arr, axis=0)
|
|
73
|
+
std = np.nanmedian(np.abs(arr - mean), axis=[0, 2])[:, None]
|
|
74
|
+
vmin, vmax = mean - 5 * std, mean + 5 * std
|
|
75
|
+
|
|
76
|
+
# Disregard all values outside of 5 * MAD
|
|
77
|
+
where = (arr < vmin) | (arr > vmax)
|
|
78
|
+
specs[where] = 0
|
|
79
|
+
conts[where] = 1
|
|
80
|
+
sigms[where] = np.nan
|
|
81
|
+
weights = 1 / sigms
|
|
82
|
+
weights[np.isposinf(weights)] = np.sqrt(2) # TODO Why
|
|
83
|
+
weights[where] = 0
|
|
84
|
+
|
|
85
|
+
w2 = np.sum(weights, axis=0) == 0
|
|
86
|
+
weights[:, w2] = 1
|
|
87
|
+
|
|
88
|
+
# Take the average of the spectrum and the continuum
|
|
89
|
+
snew = np.average(specs, weights=weights, axis=0)
|
|
90
|
+
cnew = np.average(conts, weights=weights, axis=0)
|
|
91
|
+
snew = np.nan_to_num(snew, copy=False)
|
|
92
|
+
# unew = 1 / np.sqrt(np.nansum((conts/sigms)**2, axis=0))
|
|
93
|
+
|
|
94
|
+
# This is the uncertainty from the scatter
|
|
95
|
+
unew = np.sqrt(np.nansum(weights * (arr - snew) ** 2, axis=0) / len(files))
|
|
96
|
+
unew[unew == 0] = np.nansum(sigms, axis=0)[unew == 0]
|
|
97
|
+
|
|
98
|
+
snew /= cnew
|
|
99
|
+
cnew = np.ones_like(snew)
|
|
100
|
+
|
|
101
|
+
if plot:
|
|
102
|
+
for i in range(sold.shape[0]):
|
|
103
|
+
plt.plot(wnew[plot], sold[i] / cold[i])
|
|
104
|
+
plt.plot(wnew[plot], snew[plot], "--")
|
|
105
|
+
plt.fill_between(wnew[plot], vmin[plot], vmax[plot], alpha=0.5)
|
|
106
|
+
util.show_or_save("combine_spectra")
|
|
107
|
+
|
|
108
|
+
e.spec = snew
|
|
109
|
+
e.sig = unew
|
|
110
|
+
e.cont = cnew
|
|
111
|
+
e.mask = (snew == 0) | (cnew == 0)
|
|
112
|
+
del e["columns"]
|
|
113
|
+
|
|
114
|
+
e.header["barycorr"] = 0.0
|
|
115
|
+
e.save(output)
|
|
116
|
+
|
|
117
|
+
logger.info("Created combined file: %s", output)
|