lsst.synpipe  15.0-3-g11fe1a0
positionStarFakes.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # encoding: utf-8
3 
4 from __future__ import print_function
5 from __future__ import absolute_import
6 from builtins import str
7 import numpy as np
8 
9 import pyfits as fits
10 
11 import lsst.afw.geom as afwGeom
12 import lsst.afw.math as afwMath
13 import lsst.afw.image as afwImage
14 import lsst.pex.config as afwConfig
15 
16 from lsst.pipe.tasks.fakes import BaseFakeSourcesConfig, BaseFakeSourcesTask
17 
18 from . import FakeSourceLib as fsl
19 
20 
21 class PositionStarFakesConfig(BaseFakeSourcesConfig):
22  starList = afwConfig.Field(dtype=str,
23  doc="Catalog of stars with mags ra/dec")
24  seed = afwConfig.Field(dtype=int, default=1,
25  doc="Seed for random number generator")
26 
27 
28 class PositionStarFakesTask(BaseFakeSourcesTask):
29  ConfigClass = PositionStarFakesConfig
30 
31  def __init__(self, **kwargs):
32  BaseFakeSourcesTask.__init__(self, **kwargs)
33  print("RNG seed:", self.config.seed)
34  self.rng = afwMath.Random(seed=self.config.seed)
35  self.npRand = np.random.RandomState(self.config.seed)
36  try:
37  self.starData = fits.open(self.config.starList)[1].data
38  except Exception:
39  raise
40 
41  def run(self, exposure, background):
42 
43  self.log.info("Adding fake stars at real positions")
44  psf = exposure.getPsf()
45  psfBBox = psf.computeImage().getBBox()
46  margin = max(psfBBox.getWidth(), psfBBox.getHeight())/2 + 1
47 
48  PARENT = afwImage.PARENT
49  md = exposure.getMetadata()
50  expBBox = exposure.getBBox(PARENT)
51  wcs = exposure.getWcs()
52 
53  for istar, star in enumerate(self.starData):
54  try:
55  starident = star["ID"]
56  except KeyError:
57  starident = istar + 1
58 
59  try:
60  flux = exposure.getCalib().getFlux(float(star['mag']))
61  except KeyError:
62  raise KeyError("No mag column in %s" % self.config.starList)
63 
64  try:
65  starCoord = afwGeom.SpherePoint(star['RA'], star['DEC'], afwGeom.degrees)
66  except KeyError:
67  raise KeyError("No RA/DEC column in table".format(self.config.starList))
68 
69  starXY = wcs.skyToPixel(starCoord)
70  bboxI = exposure.getBBox(PARENT)
71  bboxI.grow(int(margin))
72  if not bboxI.contains(afwGeom.Point2I(starXY)):
73  continue
74 
75  starImage = psf.computeImage(starXY)
76  starImage *= flux
77  starBBox = starImage.getBBox(PARENT)
78 
79  # Check that we're within the larger exposure, otherwise crop
80  if expBBox.contains(starBBox) is False:
81  newBBox = starImage.getBBox(PARENT)
82  newBBox.clip(expBBox)
83  if newBBox.getArea() <= 0:
84  self.log.info("Skipping fake %d" % starident)
85  continue
86  self.log.info("Cropping FAKE%d from %s to %s" % (starident,
87  str(starBBox), str(newBBox)))
88  starImage = starImage.Factory(starImage, newBBox, PARENT)
89  starBBox = newBBox
90 
91  starMaskedImage = afwImage.MaskedImageF(starImage.convertF())
92 
93  starMaskedImage.getMask().set(self.bitmask)
94 
95  md.set("FAKE%s" % str(starident), "%.3f, %.3f" % (starXY.getX(),
96  starXY.getY()))
97  self.log.info("Adding fake %s at: %.1f,%.1f" % (str(starident),
98  starXY.getX(),
99  starXY.getY()))
100 
101  maskedImage = exposure.getMaskedImage()
102  BBox = starMaskedImage.getBBox(PARENT)
103  subMaskedImage = maskedImage.Factory(exposure.getMaskedImage(),
104  BBox,
105  PARENT)
106  subMaskedImage += starMaskedImage