Move the processing code under pipeline/
Preparing to merge this repository into a combined astrophotography repo. session-scripts/ becomes pipeline/ because the scripts import layout.py from their own directory and must stay together, and because 'pipeline' says what it is rather than how it came about. observing/ stays at the top level: observing plans are not processing code.
This commit is contained in:
parent
653ca103cd
commit
c6299f41ab
53 changed files with 0 additions and 0 deletions
|
|
@ -1,77 +0,0 @@
|
|||
"""Step 4: smooth elliptical model, model-subtracted residual, and renders.
|
||||
|
||||
The model is the Pass B isophote table (stars and dust lane masked) turned into
|
||||
a 2-D image with sb_model.build, with a Sersic extrapolation inside a = 62 px
|
||||
where no dust-free azimuth exists. Subtracting it leaves everything that is
|
||||
not a smooth ellipse: the dust lane, foreground stars, and any shell, tidal
|
||||
feature or halo asymmetry.
|
||||
|
||||
Outputs
|
||||
sb-model.fits the smooth model
|
||||
sb-residual.fits luminance minus model
|
||||
NGC5128-sb-model-residual.png 4-panel: data / model / residual / binned deep residual
|
||||
NGC5128-sb-residual-deep.png heavily binned residual alone, for shell hunting
|
||||
"""
|
||||
import numpy as np
|
||||
from astropy.io import fits
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
from scipy.ndimage import gaussian_filter
|
||||
from sb_common import *
|
||||
import sb_model
|
||||
|
||||
XC, YC = np.load(path('_geom.npy'))
|
||||
P = np.load(path('_profile.npz'))
|
||||
tB = dict(np.load(path('_isoB.npz')))
|
||||
star = fits.getdata(path('sb-mask-stars.fits')).astype(bool)
|
||||
dust = fits.getdata(path('sb-mask-dust.fits')).astype(bool)
|
||||
A_IN, A_OUT = float(P['a_in']), float(P['a_out'])
|
||||
mue, re_as, nser = P['sersic']
|
||||
|
||||
|
||||
def sersic_mu(a_as):
|
||||
bn = 2 * nser - 1 / 3. + 0.009876 / nser
|
||||
return mue + 2.5 * bn / np.log(10) * ((a_as / re_as) ** (1. / nser) - 1.)
|
||||
|
||||
|
||||
# ---- build a profile that is defined at every radius -----------------------
|
||||
ac = P['a']
|
||||
Lp = P['Luminance'].copy()
|
||||
inner = ac < A_IN
|
||||
Lp[inner] = 10 ** ((MU0 - sersic_mu(ac[inner] * PIXSCALE)) / 2.5)
|
||||
okp = np.isfinite(Lp) & (ac < 1500)
|
||||
tab = dict(sma=ac[okp], intens=Lp[okp],
|
||||
eps=np.interp(ac[okp], tB['sma'], np.where(np.isfinite(tB['eps']),
|
||||
tB['eps'], 0.15)),
|
||||
pa=np.interp(ac[okp], tB['sma'], np.where(np.isfinite(tB['pa']),
|
||||
tB['pa'], 150.)))
|
||||
model, a_map = sb_model.build((3194, 4788), XC, YC, tab, block=2)
|
||||
fits.PrimaryHDU(model).writeto(path('sb-model.fits'), overwrite=True)
|
||||
|
||||
PEDL = float(P['ped'])
|
||||
L = load('Luminance')
|
||||
res = (L - model).astype(np.float32)
|
||||
fits.PrimaryHDU(res).writeto(path('sb-residual.fits'), overwrite=True)
|
||||
print('model built; residual rms inside a<600 px: %.2f ADU/px'
|
||||
% res[(a_map < 600) & ~star & ~dust].std())
|
||||
|
||||
|
||||
def binned(img, mask, B):
|
||||
"""Masked block mean, returning NaN where a block is mostly masked."""
|
||||
H, W = img.shape
|
||||
h, w = H // B, W // B
|
||||
a = img[:h * B, :w * B].reshape(h, B, w, B)
|
||||
m = (~mask)[:h * B, :w * B].reshape(h, B, w, B)
|
||||
n = m.sum(axis=(1, 3))
|
||||
s = np.where(m, a, 0).sum(axis=(1, 3))
|
||||
return np.where(n > 0.35 * B * B, s / np.maximum(n, 1), np.nan)
|
||||
|
||||
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ renders
|
||||
import sb_render_tail
|
||||
sb_render_tail.run(dict(res=res, model=model, a_map=a_map, L=L, star=star,
|
||||
dust=dust, XC=XC, YC=YC, PEDL=PEDL, A_OUT=A_OUT,
|
||||
tab=tab, binned=binned))
|
||||
Loading…
Add table
Add a link
Reference in a new issue