Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterate object tracing #1882

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
26 changes: 26 additions & 0 deletions doc/object_finding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,30 @@ vs spatial position vector. The best way to choose these pixels is to run PypeIt
without it set. Then run :ref:`pypeit_show_2dspec` to view the sky-subtracted
image and decide which pixels to use for object finding. Then re-run ``PypeIt``.

Object Tracing
==============

For automatically identified objects (i.e., not manual extractions),
PypeIt improves the object trace by fitting the spatial position of the peak
as a function of wavelength. In some situations, the object trace is poorly
determined by the peak location, and the code will fail to trace the object
correctly. For example, if the slit edges are not well-defined, the object's
position relative to the slit edges is also poorly defined, and the object trace
is difficult to determine. The default is to perform several iterations (typically 9)
but for some cases this is insufficient. In these cases, the user can attempt to
increase the number of iterations to improve the object tracing, in combination with
a relatively low order polynomial, as follows

.. code-block:: ini

[reduce]
[[findobj]]
find_numiterfit = 100
trace_npoly = 4

Note that the default value is typically ``trace_npoly=5``. If you notice a relatively poor object trace, sometimes in
combination with the object counts being masked, increasing the number of iterations may help to
resolve your problem. If, on the other hand, your object is relatively faint, you
may benefit from using the trace of a standard star (this is the default behaviour),
and you can provide a 1D spectrum of a previously reduced standard star with the
``std_spec1d`` parameter.
3 changes: 2 additions & 1 deletion doc/releases/1.17.2dev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ Functionality/Performance Improvements and Additions
- Setup GUI allows resizing panels when viewing pypeit files.
- Setup GUI allows selecting which detector to view when viewing raw data.
- Added backwards compatibilty for old frames taken with the Bok B&C

- The object trace can now be iterated over with the `find_numiterfit`
parameter.

Instrument-specific Updates
---------------------------
Expand Down
1 change: 1 addition & 0 deletions pypeit/coadd2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,7 @@ def compute_offsets(self, offsets):
inmask=inmask[iexp,:,:], fwhm=self.par['reduce']['findobj']['find_fwhm'],
trim_edg=self.par['reduce']['findobj']['find_trim_edge'],
maxdev=self.par['reduce']['findobj']['find_maxdev'],
numiterfit=self.par['reduce']['findobj']['find_numiterfit'],
ncoeff=3, snr_thresh=self.par['reduce']['findobj']['snr_thresh'], nperslit=1,
find_min_max=self.par['reduce']['findobj']['find_min_max'],
show_trace=self.debug_offsets, show_peaks=self.debug_offsets)
Expand Down
2 changes: 1 addition & 1 deletion pypeit/coadd3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def __init__(self, airmass, parangle, pressure, temperature, humidity, cosdec, w
parangle (:obj:`float`):
The parallactic angle of the observations (units=radians, relative to North, towards East is postive)
pressure (:obj:`float`):
The atmospheric pressure during the observations in Pascal. Valid range is from 10kPa - 140 kPa.
The atmospheric pressure during the observations in mbar. Valid range is from 100 mbar - 1400 mbar.
temperature (:obj:`float`):
Temperature in degree Celsius. Valid temperate range is -40 to
100 degree Celsius.
Expand Down
25 changes: 16 additions & 9 deletions pypeit/core/findobj_skymask.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def ech_findobj_ineach_order(
det='DET01', inmask=None, std_trace=None, ncoeff=5,
hand_extract_dict=None,
box_radius=2.0, fwhm=3.0,
use_user_fwhm=False, maxdev=2.0, nperorder=2,
use_user_fwhm=False, maxdev=2.0, nperorder=2, numiterfit=9,
extract_maskwidth=3.0, snr_thresh=10.0,
specobj_dict=None, trim_edg=(5,5),
show_peaks=False, show_single_fits=False,
Expand Down Expand Up @@ -260,6 +260,8 @@ def ech_findobj_ineach_order(
maxdev (:obj:`float`, optional):
Maximum deviation of pixels from polynomial fit to trace
used to reject bad pixels in trace fitting.
numiterfit (:obj:`int`, optional):
Number of iterations to use when fitting the object traces.
nperorder (:obj:`int`, optional):
Maximum number of objects allowed per order. If there are more
detections than this number, the code will select the ``nperorder``
Expand Down Expand Up @@ -331,7 +333,7 @@ def ech_findobj_ineach_order(
spec_min_max=spec_min_max[:,iord],
inmask=inmask_iord,std_trace=std_in,
ncoeff=ncoeff, fwhm=fwhm, use_user_fwhm=use_user_fwhm, maxdev=maxdev,
hand_extract_dict=hand_extract_dict,
numiterfit=numiterfit, hand_extract_dict=hand_extract_dict,
nperslit=nperorder, extract_maskwidth=extract_maskwidth,
snr_thresh=snr_thresh, trim_edg=trim_edg,
boxcar_rad=box_radius/plate_scale_ord[iord],
Expand Down Expand Up @@ -1038,7 +1040,7 @@ def ech_objfind(image, ivar, slitmask, slit_left, slit_righ, slit_spat_id, order
nabove_min_snr=2, pca_explained_var=99.0,
box_radius=2.0, fwhm=3.0,
use_user_fwhm=False, maxdev=2.0,
nperorder=2,
nperorder=2, numiterfit=9,
extract_maskwidth=3.0, snr_thresh=10.0,
specobj_dict=None, trim_edg=(5,5),
show_peaks=False, show_fits=False,
Expand Down Expand Up @@ -1181,6 +1183,8 @@ def ech_objfind(image, ivar, slitmask, slit_left, slit_righ, slit_spat_id, order
maxdev (:obj:`float`, optional):
Maximum deviation of pixels from polynomial fit to trace
used to reject bad pixels in trace fitting.
numiterfit (:obj:`int`, optional):
Number of iterations to perform when building the trace fits.
hand_extract_dict (:obj:`dict`, optional):
Dictionary with info on manual extraction; see
:class:`~pypeit.manual_extract.ManualExtractionObj`.
Expand Down Expand Up @@ -1290,6 +1294,7 @@ def ech_objfind(image, ivar, slitmask, slit_left, slit_righ, slit_spat_id, order
use_user_fwhm=use_user_fwhm,
nperorder=nperorder,
maxdev=maxdev,
numiterfit=numiterfit,
box_radius=box_radius,
objfindQA_filename=objfindQA_filename,
hand_extract_dict=manual_extract_dict)
Expand Down Expand Up @@ -1500,7 +1505,7 @@ def get_fwhm(fwhm_in, nsamp, smash_peakflux, spat_fracpos, flux_smash_smth):
def objs_in_slit(image, ivar, thismask, slit_left, slit_righ,
inmask=None, fwhm=3.0,
sigclip_smash=5.0, use_user_fwhm=False, boxcar_rad=7.,
maxdev=2.0, spec_min_max=None, hand_extract_dict=None, std_trace=None,
maxdev=2.0, numiterfit=9, spec_min_max=None, hand_extract_dict=None, std_trace=None,
ncoeff=5, nperslit=None, snr_thresh=10.0, trim_edg=(5,5),
extract_maskwidth=4.0, specobj_dict=None, find_min_max=None,
show_peaks=False, show_fits=False, show_trace=False,
Expand Down Expand Up @@ -1588,6 +1593,8 @@ def objs_in_slit(image, ivar, thismask, slit_left, slit_righ,
maxdev (:obj:`float`, optional):
Maximum deviation of pixels from polynomial fit to trace
used to reject bad pixels in trace fitting.
numiterfit (:obj:`int`, optional):
Number of iterations to use in the iterative trace fitting.
spec_min_max (:obj:`tuple`, optional):
2-tuple defining the minimum and maximum pixel in the spectral
direction with useable data for this slit/order. If None, the
Expand Down Expand Up @@ -1667,9 +1674,9 @@ def objs_in_slit(image, ivar, thismask, slit_left, slit_righ,
detected.
"""

#debug_all=True
debug_all = False
if debug_all:
show_peaks=True
show_peaks = True
show_fits = True
show_trace = True

Expand Down Expand Up @@ -1905,16 +1912,16 @@ def objs_in_slit(image, ivar, thismask, slit_left, slit_righ,

# Fit the object traces
if len(sobjs) > 0:
msgs.info('Fitting the object traces')
msgs.info('Fitting the traces')
# Note the transpose is here to pass in the TRACE_SPAT correctly.
xinit_fweight = np.copy(sobjs.TRACE_SPAT.T).astype(float)
spec_mask = (spec_vec >= spec_min_max_out[0]) & (spec_vec <= spec_min_max_out[1])
trc_inmask = np.outer(spec_mask, np.ones(len(sobjs), dtype=bool))
xfit_fweight = fit_trace(image, xinit_fweight, ncoeff, bpm=np.invert(inmask), maxshift=1.,
xfit_fweight = fit_trace(image, xinit_fweight, ncoeff, bpm=np.invert(inmask), maxshift=1., niter=numiterfit,
trace_bpm=np.invert(trc_inmask), fwhm=fwhm, maxdev=maxdev,
idx=sobjs.NAME, debug=show_fits)[0]
xinit_gweight = np.copy(xfit_fweight)
xfit_gweight = fit_trace(image, xinit_gweight, ncoeff, bpm=np.invert(inmask), maxshift=1.,
xfit_gweight = fit_trace(image, xinit_gweight, ncoeff, bpm=np.invert(inmask), maxshift=1., niter=numiterfit,
trace_bpm=np.invert(trc_inmask), fwhm=fwhm, maxdev=maxdev,
weighting='gaussian', idx=sobjs.NAME, debug=show_fits)[0]

Expand Down
2 changes: 2 additions & 0 deletions pypeit/find_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ def find_objects_pypeline(self, image, ivar, std_trace=None,
use_user_fwhm=self.par['reduce']['extraction']['use_user_fwhm'],
boxcar_rad=self.par['reduce']['extraction']['boxcar_radius'] / self.get_platescale(), #pixels
maxdev=self.par['reduce']['findobj']['find_maxdev'],
numiterfit=self.par['reduce']['findobj']['find_numiterfit'],
find_min_max=self.par['reduce']['findobj']['find_min_max'],
extract_maskwidth=self.par['reduce']['skysub']['local_maskwidth'],
qa_title=qa_title, nperslit=maxnumber,
Expand Down Expand Up @@ -959,6 +960,7 @@ def find_objects_pypeline(self, image, ivar, std_trace=None,
use_user_fwhm=self.par['reduce']['extraction']['use_user_fwhm'],
fof_link = self.par['reduce']['findobj']['fof_link'],
maxdev=self.par['reduce']['findobj']['find_maxdev'],
numiterfit=self.par['reduce']['findobj']['find_numiterfit'],
nperorder=nperorder,
max_snr=self.par['reduce']['findobj']['ech_find_max_snr'],
min_snr=self.par['reduce']['findobj']['ech_find_min_snr'],
Expand Down
8 changes: 6 additions & 2 deletions pypeit/par/pypeitpar.py
Original file line number Diff line number Diff line change
Expand Up @@ -4161,7 +4161,7 @@ class FindObjPar(ParSet):

def __init__(self, trace_npoly=None, snr_thresh=None, find_trim_edge=None,
find_maxdev=None, find_extrap_npoly=None, maxnumber_sci=None, maxnumber_std=None,
find_fwhm=None, ech_find_max_snr=None, ech_find_min_snr=None,
find_fwhm=None, ech_find_max_snr=None, ech_find_min_snr=None, find_numiterfit=None,
ech_find_nabove_min_snr=None, skip_second_find=None, skip_final_global=None,
skip_skysub=None, find_negative=None, find_min_max=None, std_spec1d=None,
use_std_trace=None, fof_link = None):
Expand Down Expand Up @@ -4221,6 +4221,10 @@ def __init__(self, trace_npoly=None, snr_thresh=None, find_trim_edge=None,
dtypes['find_maxdev'] = [int, float]
descr['find_maxdev'] = 'Maximum deviation of pixels from polynomial fit to trace used to reject bad pixels in trace fitting.'

defaults['find_numiterfit'] = 9
dtypes['find_numiterfit'] = int
descr['find_numiterfit'] = 'Number of iterations to perform on the trace fitting.'

defaults['find_fwhm'] = 5.0
dtypes['find_fwhm'] = [int, float]
descr['find_fwhm'] = 'Indicates roughly the fwhm of objects in pixels for object finding'
Expand Down Expand Up @@ -4319,7 +4323,7 @@ def from_dict(cls, cfg):
# Basic keywords
parkeys = ['trace_npoly', 'snr_thresh', 'find_trim_edge',
'find_extrap_npoly', 'maxnumber_sci', 'maxnumber_std',
'find_maxdev', 'find_fwhm', 'ech_find_max_snr',
'find_maxdev', 'find_numiterfit', 'find_fwhm', 'ech_find_max_snr',
'ech_find_min_snr', 'ech_find_nabove_min_snr', 'skip_second_find',
'skip_final_global', 'skip_skysub', 'find_negative', 'find_min_max',
'std_spec1d', 'use_std_trace', 'fof_link']
Expand Down
Loading