Skip to content

Commit

Permalink
new Util functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomas Stolker committed Aug 6, 2018
1 parent 6139dca commit 69bd966
Show file tree
Hide file tree
Showing 18 changed files with 1,255 additions and 1,199 deletions.
58 changes: 34 additions & 24 deletions PynPoint/ProcessingModules/BackgroundSubtraction.py
Expand Up @@ -3,6 +3,7 @@
"""

import sys
import math

import numpy as np

Expand All @@ -14,8 +15,7 @@
from PynPoint.ProcessingModules.ImageResizing import CropImagesModule
from PynPoint.ProcessingModules.StackingAndSubsampling import CombineTagsModule
from PynPoint.ProcessingModules.PSFpreparation import SortParangModule
from PynPoint.ProcessingModules.StarAlignment import StarExtractionModule
from PynPoint.Util.ModuleTools import progress, memory_frames
from PynPoint.Util.ModuleTools import progress, memory_frames, locate_star


class SimpleBackgroundSubtractionModule(ProcessingModule):
Expand Down Expand Up @@ -529,6 +529,8 @@ def __init__(self,
mask_star=0.7,
mask_planet=None,
subtract_mean=False,
subframe=None,
gaussian=0.15,
name_in="pca_background",
star_in_tag="im_star",
background_in_tag="im_background",
Expand All @@ -550,6 +552,13 @@ def __init__(self,
:param subtract_mean: The mean of the background images is subtracted from both the star
and background images before the PCA basis is constructed.
:type subtract_mean: bool
:param gaussian: Full width at half maximum (arcsec) of the Gaussian kernel that is used
to smooth the image before the star is located.
:type gaussian: float
:param subframe: Size (arcsec) of the subframe that is used to search for the star.
Cropping of the subframe is done around the center of the image.
The full images is used if set to None.
:type subframe: float
:param name_in: Unique name of the module instance.
:type name_in: str
:param star_in_tag: Tag of the database entry with the star images.
Expand Down Expand Up @@ -589,6 +598,8 @@ def __init__(self,
self.m_mask_star = mask_star
self.m_mask_planet = mask_planet
self.m_subtract_mean = subtract_mean
self.m_gaussian = gaussian
self.m_subframe = subframe

def run(self):
"""
Expand Down Expand Up @@ -687,10 +698,26 @@ def _dot_product(x_dot, *p):

memory = self._m_config_port.get_attribute("MEMORY")
pixscale = self.m_star_in_port.get_attribute("PIXSCALE")
star = self.m_star_in_port.get_attribute("STAR_POSITION")

nimages = self.m_star_in_port.get_shape()[0]
frames = memory_frames(memory, nimages)

self.m_mask_star /= pixscale

self.m_gaussian /= pixscale
self.m_gaussian = int(math.ceil(self.m_gaussian))

if self.m_subframe is not None:
self.m_subframe /= pixscale
self.m_subframe = int(math.ceil(self.m_subframe))

star = np.zeros((nimages, 2))
for i, _ in enumerate(star):
star[i, :] = locate_star(image=self.m_star_in_port[i, ],
center=None,
width=self.m_subframe,
fwhm=self.m_gaussian)

if self.m_mask_planet is not None:
parang = self.m_star_in_port.get_attribute("PARANG")

Expand All @@ -714,10 +741,6 @@ def _dot_product(x_dot, *p):
sys.stdout.write(" [DONE]\n")
sys.stdout.flush()

nimages = self.m_star_in_port.get_shape()[0]

frames = memory_frames(memory, nimages)

for i, _ in enumerate(frames[:-1]):
progress(i, len(frames[:-1]), "Calculating background model...")

Expand Down Expand Up @@ -904,11 +927,7 @@ def __init__(self,
self.m_pca_number = pca_number
self.m_mask_star = mask_star
self.m_subtract_mean = subtract_mean

if subframe is None:
self.m_subframe = subframe
else:
self.m_subframe = (None, None, subframe)
self.m_subframe = subframe

self.m_image_in_tag = image_in_tag
self.m_image_out_tag = image_out_tag
Expand Down Expand Up @@ -984,7 +1003,8 @@ def _admin_end(count, n_dither):

if self.m_crop:
crop = CropImagesModule(size=self.m_size,
center=position,
center=(int(math.ceil(position[0])),
int(math.ceil(position[1]))),
name_in="crop"+str(i),
image_in_tag=self.m_image_in_tag,
image_out_tag="dither_crop"+str(i+1))
Expand Down Expand Up @@ -1025,21 +1045,11 @@ def _admin_end(count, n_dither):
bad.connect_database(self._m_data_base)
bad.run()

star = StarExtractionModule(name_in="star"+str(i),
image_in_tag=tag_extract,
image_out_tag=None,
position_out_tag="dither_star"+str(i+1),
image_size=None,
fwhm_star=self.m_gaussian,
position=self.m_subframe)

star.connect_database(self._m_data_base)
star.run()

pca = PCABackgroundSubtractionModule(pca_number=self.m_pca_number,
mask_star=self.m_mask_star,
mask_planet=self.m_mask_planet,
subtract_mean=self.m_subtract_mean,
subframe=self.m_subframe,
name_in="pca_background"+str(i),
star_in_tag="dither_star"+str(i+1),
background_in_tag="dither_background"+str(i+1),
Expand Down
3 changes: 0 additions & 3 deletions PynPoint/ProcessingModules/FluxAndPosition.py
Expand Up @@ -417,9 +417,6 @@ def _objective(arg):

npix = image_size(im_crop)[0]

if npix%2 == 0:
raise ValueError("An odd-sized image is expected.")

if self.m_merit == "hessian":

x_grid = y_grid = np.linspace(-(npix-1)/2, (npix-1)/2, npix)
Expand Down
150 changes: 58 additions & 92 deletions PynPoint/ProcessingModules/FrameSelection.py
Expand Up @@ -3,15 +3,14 @@
"""

import sys
import math
import warnings

import numpy as np

from astropy.nddata import Cutout2D

from PynPoint.Core.Processing import ProcessingModule
from PynPoint.ProcessingModules.StarAlignment import StarExtractionModule
from PynPoint.Util.ModuleTools import progress, memory_frames
from PynPoint.Util.ModuleTools import progress, memory_frames, locate_star, \
number_images_port, crop_image


class RemoveFramesModule(ProcessingModule):
Expand Down Expand Up @@ -264,14 +263,11 @@ def __init__(self,
stellar FWHM would be recommended. The position of the aperture has to
be specified with *position* when *fwhm=None*.
:type aperture: float
:param position: Subframe that is selected to search for the star. The tuple can contain a
single position (pix) and size (arcsec) as (pos_x, pos_y, size), or the
position and size can be defined for each image separately in which case
the tuple should be 2D (nimages x 3). Setting *position* to None will use
the full image to search for the star. If *position=(None, None, size)*
then the center of the image will be used. The value of *size* is not used
when *fwhm=None*.
:type position: tuple, float
:param position: Subframe that is selected to search for the star. The tuple contains the
center (pix) and size (arcsec) (pos_x, pos_y, size). Setting *position*
to None will use the full image to search for the star. If
*position=(None, None, size)* then the center of the image will be used.
:type position: (int, int, float)
:return: None
"""
Expand All @@ -293,114 +289,84 @@ def __init__(self,
self.m_aperture = aperture
self.m_threshold = threshold
self.m_position = position
self.m_rr_grid = None

def _initialize(self):
if self.m_image_in_port.tag == self.m_selected_out_tag or \
self.m_image_in_port.tag == self.m_removed_out_tag:
raise ValueError("Input and output ports should have a different tag.")

if self.m_index_out_port is not None:
self.m_index_out_port.del_all_data()
self.m_index_out_port.del_all_attributes()

pixscale = self.m_image_in_port.get_attribute("PIXSCALE")

if self.m_aperture[0] == "circular":
aperture = (0., self.m_aperture[1]/pixscale)

elif self.m_aperture[0] == "annulus" or self.m_aperture[0] == "ratio":
aperture = (self.m_aperture[1]/pixscale, self.m_aperture[2]/pixscale)

npix = self.m_image_in_port.get_shape()[1]

if self.m_position is None:
self.m_position = (float(npix)/2., float(npix)/2., None)

elif self.m_position[0] is None and self.m_position[1] is None:
self.m_position = (float(npix)/2., float(npix)/2., self.m_position[2])

return aperture
def run(self):
"""
Run method of the module. Smooths the images with a Gaussian kernel, locates the brightest
pixel in each image, measures the integrated flux around the brightest pixel, calculates
the median and standard deviation of the photometry, and applies sigma clipping to remove
low quality images.
def _photometry(self, images, starpos, aperture):
check_pos_in = any(np.floor(starpos[:]-aperture[1]) < 0.)
check_pos_out = any(np.ceil(starpos[:]+aperture[1]) > images.shape[0])
:return: None
"""

if check_pos_in or check_pos_out:
phot = np.nan
def _photometry(images, starpos, aperture):
check_pos_in = any(np.floor(starpos[:]-aperture[1]) < 0.)
check_pos_out = any(np.ceil(starpos[:]+aperture[1]) > images.shape[0])

else:
im_cut = Cutout2D(images,
(starpos[1], starpos[0]),
size=2.*aperture[1]).data
if check_pos_in or check_pos_out:
phot = np.nan

if self.m_rr_grid is None:
npix = im_cut.shape[0]
else:
im_crop = crop_image(images, starpos, 2*int(math.ceil(aperture[1])))

if npix%2 == 0:
x_grid = y_grid = np.linspace(-npix/2+0.5, npix/2-0.5, npix)
elif npix%2 == 1:
x_grid = y_grid = np.linspace(-(npix-1)/2, (npix-1)/2, npix)
npix = im_crop.shape[0]

x_grid = y_grid = np.linspace(-(npix-1)/2, (npix-1)/2, npix)
xx_grid, yy_grid = np.meshgrid(x_grid, y_grid)
self.m_rr_grid = np.sqrt(xx_grid*xx_grid+yy_grid*yy_grid)
rr_grid = np.sqrt(xx_grid*xx_grid+yy_grid*yy_grid)

if self.m_aperture[0] == "circular":
phot = np.sum(im_cut[self.m_rr_grid < aperture[1]])
if self.m_aperture[0] == "circular":
phot = np.sum(im_crop[rr_grid < aperture[1]])

elif self.m_aperture[0] == "annulus":
phot = np.sum(im_cut[(self.m_rr_grid > aperture[0]) &
(self.m_rr_grid < aperture[1])])
elif self.m_aperture[0] == "annulus":
phot = np.sum(im_crop[(rr_grid > aperture[0]) &
(rr_grid < aperture[1])])

elif self.m_aperture[0] == "ratio":
phot = np.sum(im_cut[self.m_rr_grid < aperture[0]]) / \
np.sum(im_cut[(self.m_rr_grid > aperture[0]) &
(self.m_rr_grid < aperture[1])])
elif self.m_aperture[0] == "ratio":
phot = np.sum(im_crop[rr_grid < aperture[0]]) / \
np.sum(im_crop[(rr_grid > aperture[0]) &
(rr_grid < aperture[1])])

return phot
return phot

def run(self):
"""
Run method of the module. Smooths the images with a Gaussian kernel, locates the brightest
pixel in each image, measures the integrated flux around the brightest pixel, calculates
the median and standard deviation of the photometry, and applies sigma clipping to remove
images that are of poor quality (e.g., due to opening of the AO loop).
if self.m_image_in_port.tag == self.m_selected_out_tag or \
self.m_image_in_port.tag == self.m_removed_out_tag:
raise ValueError("Input and output ports should have a different tag.")

:return: None
"""
if self.m_index_out_port is not None:
self.m_index_out_port.del_all_data()
self.m_index_out_port.del_all_attributes()

aperture = self._initialize()
pixscale = self.m_image_in_port.get_attribute("PIXSCALE")
nimages = number_images_port(self.m_image_in_port)

nimages = self.m_image_in_port.get_shape()[0]
if self.m_aperture[0] == "circular":
aperture = (0., self.m_aperture[1]/pixscale)

elif self.m_aperture[0] == "annulus" or self.m_aperture[0] == "ratio":
aperture = (self.m_aperture[1]/pixscale, self.m_aperture[2]/pixscale)

phot = np.zeros(nimages)
starpos = np.zeros((nimages, 2), dtype=np.int64)

if self.m_fwhm is None:
starpos = np.zeros((nimages, 2), dtype=np.int64)
starpos[:, 0] = self.m_position[0]
starpos[:, 1] = self.m_position[1]

else:
star = StarExtractionModule(name_in="star",
image_in_tag=self.m_image_in_port.tag,
image_out_tag=None,
index_out_tag=None,
image_size=None,
fwhm_star=self.m_fwhm,
position=self.m_position)

star.connect_database(self._m_data_base)
star.run()

self.m_image_in_port = self.add_input_port(self.m_image_in_port.tag)
starpos = self.m_image_in_port.get_attribute("STAR_POSITION")
for i, _ in enumerate(starpos):
starpos[i, :] = locate_star(image=self.m_image_in_port[i, ],
center=self.m_position[0:2],
width=int(math.ceil(self.m_position[2]/pixscale)),
fwhm=int(math.ceil(self.m_fwhm/pixscale)))

for i in range(nimages):
progress(i, nimages, "Running FrameSelectionModule...")

images = self.m_image_in_port[i]

phot[i] = self._photometry(images, starpos[i, :], aperture)
phot[i] = _photometry(images, starpos[i, :], aperture)

if self.m_method == "median":
phot_ref = np.nanmedian(phot)
Expand All @@ -409,7 +375,7 @@ def run(self):
phot_ref = np.nanmax(phot)

else:
raise ValueError("The method argument should be set to 'median' or 'max'.")
raise ValueError("The 'method' should be set to 'median' or 'max'.")

phot_std = np.nanstd(phot)

Expand Down Expand Up @@ -441,7 +407,7 @@ def run(self):
remove.run()

else:
print "No frames where removed with the frame selection. [WARNING]"
print "No frames where removed. [WARNING]"

self.m_image_in_port.close_port()

Expand Down

0 comments on commit 69bd966

Please sign in to comment.