Skip to content

Commit

Permalink
Computing estimated PSF-width for FWM-based centroiding in S3
Browse files Browse the repository at this point in the history
Resolves #380
  • Loading branch information
taylorbell57 committed Nov 1, 2024
1 parent 10d1a4d commit 6f30088
Showing 1 changed file with 19 additions and 22 deletions.
41 changes: 19 additions & 22 deletions src/eureka/S3_data_reduction/source_pos.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def source_pos(flux, meta, shdr, m, n, plot=True, guess=None):
src_ypos = shdr['SRCYPOS'] - meta.ywindow[0]
elif meta.src_pos_type == 'weighted':
# find the source location using a flux-weighted mean approach
src_ypos = source_pos_FWM(flux, meta, m, n, plot)
src_ypos, src_ywidth = source_pos_FWM(flux, meta, m, n, plot)

Check warning on line 159 in src/eureka/S3_data_reduction/source_pos.py

View check run for this annotation

Codecov / codecov/patch

src/eureka/S3_data_reduction/source_pos.py#L159

Added line #L159 was not covered by tests
elif meta.src_pos_type == 'gaussian':
# find the source location using a gaussian fit
src_ypos, src_ywidth = source_pos_gauss(flux, meta, m, n, plot)
Expand All @@ -174,7 +174,7 @@ def source_pos(flux, meta, shdr, m, n, plot=True, guess=None):
'position type. Options: header, gaussian, weighted,' +
' max, hst, or a numeric value.')

if meta.src_pos_type == 'gaussian':
if meta.src_pos_type in ['weighted', 'gaussian']:
return int(round(src_ypos)), src_ypos, src_ywidth, n
else:
return int(round(src_ypos)), src_ypos, np.zeros_like(src_ypos), n
Expand Down Expand Up @@ -292,40 +292,37 @@ def source_pos_FWM(flux, meta, m, n=0, plot=True):
-------
y_pos : float
The central position of the star.
Notes
-----
History:
- 2021-06-24 Taylor Bell
Initial version
- 2021-07-14 Sebastian Zieba
Modified
- 2022-07-11 Caroline Piaulet
Add option to fit any integration (not hardcoded to be the first)
y_width : float
The estimated PSF-width of the star.
'''
x_dim = flux.shape[0]

# Get the brightest row for later comparison
pos_max = source_pos_median(flux, meta, m, n=n, plot=False)

ymin = pos_max-meta.spec_hw
if ymin < 0:
ymin = None
ymax = min(flux.shape[0], pos_max+meta.spec_hw)
ymax = min(flux.shape[0], pos_max+meta.spec_hw+1)

Check warning on line 306 in src/eureka/S3_data_reduction/source_pos.py

View check run for this annotation

Codecov / codecov/patch

src/eureka/S3_data_reduction/source_pos.py#L306

Added line #L306 was not covered by tests
y_pixels = np.arange(0, x_dim)[ymin:ymax]

sum_row = np.ma.sum(flux, axis=1)[ymin:ymax]
sum_row -= (sum_row[0]+sum_row[-1])/2
# Take the median along each row to get a collapsed, 1D profile
med_row = np.ma.median(flux, axis=1)[ymin:ymax]

Check warning on line 310 in src/eureka/S3_data_reduction/source_pos.py

View check run for this annotation

Codecov / codecov/patch

src/eureka/S3_data_reduction/source_pos.py#L310

Added line #L310 was not covered by tests
# Get the FWM-based position
y_pos = np.ma.sum(med_row*y_pixels)/np.ma.sum(med_row)

Check warning on line 312 in src/eureka/S3_data_reduction/source_pos.py

View check run for this annotation

Codecov / codecov/patch

src/eureka/S3_data_reduction/source_pos.py#L312

Added line #L312 was not covered by tests

y_pos = np.ma.sum(sum_row*y_pixels)/np.ma.sum(sum_row)
# Compute squared pixel indices w.r.t. the centroid
y_pixels2 = (y_pixels - y_pos)**2

Check warning on line 315 in src/eureka/S3_data_reduction/source_pos.py

View check run for this annotation

Codecov / codecov/patch

src/eureka/S3_data_reduction/source_pos.py#L315

Added line #L315 was not covered by tests
# Get FWM-based PSF width estimates
y_width = np.sqrt(np.ma.sum(med_row*y_pixels2)/np.ma.sum(med_row))

Check warning on line 317 in src/eureka/S3_data_reduction/source_pos.py

View check run for this annotation

Codecov / codecov/patch

src/eureka/S3_data_reduction/source_pos.py#L317

Added line #L317 was not covered by tests

# Diagnostic plot
if meta.isplots_S3 >= 1 and plot:
plots_s3.source_position(meta, x_dim, pos_max, m, n, isFWM=True,
y_pixels=y_pixels, sum_row=sum_row,
y_pixels=y_pixels, sum_row=med_row,
y_pos=y_pos)

return y_pos
return y_pos, y_width

Check warning on line 325 in src/eureka/S3_data_reduction/source_pos.py

View check run for this annotation

Codecov / codecov/patch

src/eureka/S3_data_reduction/source_pos.py#L325

Added line #L325 was not covered by tests


def gauss(x, a, x0, sigma, off):
Expand Down Expand Up @@ -383,7 +380,7 @@ def source_pos_gauss(flux, meta, m, n=0, plot=True):
-------
y_pos : float
The central position of the star.
y_width : int
y_width : float
The std of the fitted Gaussian.
Notes
Expand All @@ -405,7 +402,7 @@ def source_pos_gauss(flux, meta, m, n=0, plot=True):
ymin = pos_max-meta.spec_hw
if ymin < 0:
ymin = None
ymax = min(flux.shape[0], pos_max+meta.spec_hw)
ymax = min(flux.shape[0], pos_max+meta.spec_hw+1)
y_pixels = np.arange(0, x_dim)[ymin:ymax]
med_row = np.ma.median(flux, axis=1)[ymin:ymax]

Expand All @@ -416,7 +413,7 @@ def source_pos_gauss(flux, meta, m, n=0, plot=True):
p0 = [np.ma.max(med_row), pos_max, sigma0, np.ma.median(med_row)]

# Fit
popt, pcov = curve_fit(gauss, y_pixels, med_row, p0, maxfev=10000)
popt, _ = curve_fit(gauss, y_pixels, med_row, p0, maxfev=10000)

# Diagnostic plot
if meta.isplots_S3 >= 1 and plot:
Expand Down

0 comments on commit 6f30088

Please sign in to comment.