LSSTApplications  18.0.0+46,18.0.0+95,19.0.0,19.0.0+1,19.0.0+2,19.0.0+4,19.0.0+5,19.0.0+6,19.0.0-1-g20d9b18+2,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+2,19.0.0-1-g5db401e+5,19.0.0-1-g6fe20d0+1,19.0.0-1-g7011481+4,19.0.0-1-g8c57eb9+2,19.0.0-1-gb5175dc+4,19.0.0-1-gd7f3e1b+4,19.0.0-1-gdc0e4a7+4,19.0.0-1-ge272bc4+2,19.0.0-1-gf46fa72,19.0.0-2-g0d9f9cd+4,19.0.0-2-g1c703f9ef+1,19.0.0-2-g3d9e4fb2+4,19.0.0-2-gd955cfd+4,19.0.0-2-gdbc0a5a+1,19.0.0-3-g2d13df8,19.0.0-3-g3c38ad5,19.0.0-4-g725f80e,19.0.0-7-gf796fef9+5,19.0.0-8-g608b899+1,w.2019.49
LSSTDataManagementBasePackage
Classes | Functions
lsst.ip.diffim.dcrModel Namespace Reference

Classes

class  DcrModel
 

Functions

def applyDcr (image, dcr, useInverse=False, splitSubfilters=False, splitThreshold=0., doPrefilter=True, order=3)
 
def calculateDcr (visitInfo, wcs, filterInfo, dcrNumSubfilters, splitSubfilters=False)
 
def calculateImageParallacticAngle (visitInfo, wcs)
 
def wavelengthGenerator (filterInfo, dcrNumSubfilters)
 

Function Documentation

◆ applyDcr()

def lsst.ip.diffim.dcrModel.applyDcr (   image,
  dcr,
  useInverse = False,
  splitSubfilters = False,
  splitThreshold = 0.,
  doPrefilter = True,
  order = 3 
)
Shift an image along the X and Y directions.

Parameters
----------
image : `numpy.ndarray`
    The input image to shift.
dcr : `tuple`
    Shift calculated with ``calculateDcr``.
    Uses numpy axes ordering (Y, X).
    If ``splitSubfilters`` is set, each element is itself a `tuple`
    of two `float`, corresponding to the DCR shift at the two wavelengths.
    Otherwise, each element is a `float` corresponding to the DCR shift at
    the effective wavelength of the subfilter.
useInverse : `bool`, optional
    Apply the shift in the opposite direction. Default: False
splitSubfilters : `bool`, optional
    Calculate DCR for two evenly-spaced wavelengths in each subfilter,
    instead of at the midpoint. Default: False
splitThreshold : `float`, optional
    Minimum DCR difference within a subfilter required to use ``splitSubfilters``
doPrefilter : `bool`, optional
    Spline filter the image before shifting, if set. Filtering is required,
    so only set to False if the image is already filtered.
    Filtering takes ~20% of the time of shifting, so if `applyDcr` will be
    called repeatedly on the same image it is more efficient to precalculate
    the filter.
order : `int`, optional
    The order of the spline interpolation, default is 3.

Returns
-------
shiftedImage : `numpy.ndarray`
    A copy of the input image with the specified shift applied.

Definition at line 585 of file dcrModel.py.

585  doPrefilter=True, order=3):
586  """Shift an image along the X and Y directions.
587 
588  Parameters
589  ----------
590  image : `numpy.ndarray`
591  The input image to shift.
592  dcr : `tuple`
593  Shift calculated with ``calculateDcr``.
594  Uses numpy axes ordering (Y, X).
595  If ``splitSubfilters`` is set, each element is itself a `tuple`
596  of two `float`, corresponding to the DCR shift at the two wavelengths.
597  Otherwise, each element is a `float` corresponding to the DCR shift at
598  the effective wavelength of the subfilter.
599  useInverse : `bool`, optional
600  Apply the shift in the opposite direction. Default: False
601  splitSubfilters : `bool`, optional
602  Calculate DCR for two evenly-spaced wavelengths in each subfilter,
603  instead of at the midpoint. Default: False
604  splitThreshold : `float`, optional
605  Minimum DCR difference within a subfilter required to use ``splitSubfilters``
606  doPrefilter : `bool`, optional
607  Spline filter the image before shifting, if set. Filtering is required,
608  so only set to False if the image is already filtered.
609  Filtering takes ~20% of the time of shifting, so if `applyDcr` will be
610  called repeatedly on the same image it is more efficient to precalculate
611  the filter.
612  order : `int`, optional
613  The order of the spline interpolation, default is 3.
614 
615  Returns
616  -------
617  shiftedImage : `numpy.ndarray`
618  A copy of the input image with the specified shift applied.
619  """
620  if doPrefilter:
621  prefilteredImage = ndimage.spline_filter(image, order=order)
622  else:
623  prefilteredImage = image
624  if splitSubfilters:
625  shiftAmp = np.max(np.abs([_dcr0 - _dcr1 for _dcr0, _dcr1 in zip(dcr[0], dcr[1])]))
626  if shiftAmp >= splitThreshold:
627  if useInverse:
628  shift = [-1.*s for s in dcr[0]]
629  shift1 = [-1.*s for s in dcr[1]]
630  else:
631  shift = dcr[0]
632  shift1 = dcr[1]
633  shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=False, order=order)
634  shiftedImage += ndimage.shift(prefilteredImage, shift1, prefilter=False, order=order)
635  shiftedImage /= 2.
636  return shiftedImage
637  else:
638  # If the difference in the DCR shifts is less than the threshold,
639  # then just use the average shift for efficiency.
640  dcr = (np.mean(dcr[0]), np.mean(dcr[1]))
641  if useInverse:
642  shift = [-1.*s for s in dcr]
643  else:
644  shift = dcr
645  shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=False, order=order)
646  return shiftedImage
647 
648 

◆ calculateDcr()

def lsst.ip.diffim.dcrModel.calculateDcr (   visitInfo,
  wcs,
  filterInfo,
  dcrNumSubfilters,
  splitSubfilters = False 
)
Calculate the shift in pixels of an exposure due to DCR.

Parameters
----------
visitInfo : `lsst.afw.image.VisitInfo`
    Metadata for the exposure.
wcs : `lsst.afw.geom.SkyWcs`
    Coordinate system definition (wcs) for the exposure.
filterInfo : `lsst.afw.image.Filter`
    The filter definition, set in the current instruments' obs package.
dcrNumSubfilters : `int`
    Number of sub-filters used to model chromatic effects within a band.
splitSubfilters : `bool`, optional
    Calculate DCR for two evenly-spaced wavelengths in each subfilter,
    instead of at the midpoint. Default: False

Returns
-------
dcrShift : `tuple` of two `float`
    The 2D shift due to DCR, in pixels.
    Uses numpy axes ordering (Y, X).

Definition at line 649 of file dcrModel.py.

649 def calculateDcr(visitInfo, wcs, filterInfo, dcrNumSubfilters, splitSubfilters=False):
650  """Calculate the shift in pixels of an exposure due to DCR.
651 
652  Parameters
653  ----------
654  visitInfo : `lsst.afw.image.VisitInfo`
655  Metadata for the exposure.
656  wcs : `lsst.afw.geom.SkyWcs`
657  Coordinate system definition (wcs) for the exposure.
658  filterInfo : `lsst.afw.image.Filter`
659  The filter definition, set in the current instruments' obs package.
660  dcrNumSubfilters : `int`
661  Number of sub-filters used to model chromatic effects within a band.
662  splitSubfilters : `bool`, optional
663  Calculate DCR for two evenly-spaced wavelengths in each subfilter,
664  instead of at the midpoint. Default: False
665 
666  Returns
667  -------
668  dcrShift : `tuple` of two `float`
669  The 2D shift due to DCR, in pixels.
670  Uses numpy axes ordering (Y, X).
671  """
672  rotation = calculateImageParallacticAngle(visitInfo, wcs)
673  dcrShift = []
674  weight = [0.75, 0.25]
675  lambdaEff = filterInfo.getFilterProperty().getLambdaEff()
676  for wl0, wl1 in wavelengthGenerator(filterInfo, dcrNumSubfilters):
677  # Note that diffRefractAmp can be negative, since it's relative to the midpoint of the full band
678  diffRefractAmp0 = differentialRefraction(wavelength=wl0, wavelengthRef=lambdaEff,
679  elevation=visitInfo.getBoresightAzAlt().getLatitude(),
680  observatory=visitInfo.getObservatory(),
681  weather=visitInfo.getWeather())
682  diffRefractAmp1 = differentialRefraction(wavelength=wl1, wavelengthRef=lambdaEff,
683  elevation=visitInfo.getBoresightAzAlt().getLatitude(),
684  observatory=visitInfo.getObservatory(),
685  weather=visitInfo.getWeather())
686  if splitSubfilters:
687  diffRefractPix0 = diffRefractAmp0.asArcseconds()/wcs.getPixelScale().asArcseconds()
688  diffRefractPix1 = diffRefractAmp1.asArcseconds()/wcs.getPixelScale().asArcseconds()
689  diffRefractArr = [diffRefractPix0*weight[0] + diffRefractPix1*weight[1],
690  diffRefractPix0*weight[1] + diffRefractPix1*weight[0]]
691  shiftX = [diffRefractPix*np.sin(rotation.asRadians()) for diffRefractPix in diffRefractArr]
692  shiftY = [diffRefractPix*np.cos(rotation.asRadians()) for diffRefractPix in diffRefractArr]
693  dcrShift.append(((shiftY[0], shiftX[0]), (shiftY[1], shiftX[1])))
694  else:
695  diffRefractAmp = (diffRefractAmp0 + diffRefractAmp1)/2.
696  diffRefractPix = diffRefractAmp.asArcseconds()/wcs.getPixelScale().asArcseconds()
697  shiftX = diffRefractPix*np.sin(rotation.asRadians())
698  shiftY = diffRefractPix*np.cos(rotation.asRadians())
699  dcrShift.append((shiftY, shiftX))
700  return dcrShift
701 
702 
def calculateImageParallacticAngle(visitInfo, wcs)
Definition: dcrModel.py:703
def wavelengthGenerator(filterInfo, dcrNumSubfilters)
Definition: dcrModel.py:735
def differentialRefraction(wavelength, wavelengthRef, elevation, observatory, weather=None)
Definition: refraction.py:95
def calculateDcr(visitInfo, wcs, filterInfo, dcrNumSubfilters, splitSubfilters=False)
Definition: dcrModel.py:649

◆ calculateImageParallacticAngle()

def lsst.ip.diffim.dcrModel.calculateImageParallacticAngle (   visitInfo,
  wcs 
)
Calculate the total sky rotation angle of an exposure.

Parameters
----------
visitInfo : `lsst.afw.image.VisitInfo`
    Metadata for the exposure.
wcs : `lsst.afw.geom.SkyWcs`
    Coordinate system definition (wcs) for the exposure.

Returns
-------
`lsst.geom.Angle`
    The rotation of the image axis, East from North.
    Equal to the parallactic angle plus any additional rotation of the
    coordinate system.
    A rotation angle of 0 degrees is defined with
    North along the +y axis and East along the +x axis.
    A rotation angle of 90 degrees is defined with
    North along the +x axis and East along the -y axis.

Definition at line 703 of file dcrModel.py.

703 def calculateImageParallacticAngle(visitInfo, wcs):
704  """Calculate the total sky rotation angle of an exposure.
705 
706  Parameters
707  ----------
708  visitInfo : `lsst.afw.image.VisitInfo`
709  Metadata for the exposure.
710  wcs : `lsst.afw.geom.SkyWcs`
711  Coordinate system definition (wcs) for the exposure.
712 
713  Returns
714  -------
715  `lsst.geom.Angle`
716  The rotation of the image axis, East from North.
717  Equal to the parallactic angle plus any additional rotation of the
718  coordinate system.
719  A rotation angle of 0 degrees is defined with
720  North along the +y axis and East along the +x axis.
721  A rotation angle of 90 degrees is defined with
722  North along the +x axis and East along the -y axis.
723  """
724  parAngle = visitInfo.getBoresightParAngle().asRadians()
725  cd = wcs.getCdMatrix()
726  if wcs.isFlipped:
727  cdAngle = (np.arctan2(-cd[0, 1], cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
728  rotAngle = (cdAngle + parAngle)*geom.radians
729  else:
730  cdAngle = (np.arctan2(cd[0, 1], -cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
731  rotAngle = (cdAngle - parAngle)*geom.radians
732  return rotAngle
733 
734 
def calculateImageParallacticAngle(visitInfo, wcs)
Definition: dcrModel.py:703

◆ wavelengthGenerator()

def lsst.ip.diffim.dcrModel.wavelengthGenerator (   filterInfo,
  dcrNumSubfilters 
)
Iterate over the wavelength endpoints of subfilters.

Parameters
----------
filterInfo : `lsst.afw.image.Filter`
    The filter definition, set in the current instruments' obs package.
dcrNumSubfilters : `int`
    Number of sub-filters used to model chromatic effects within a band.

Yields
------
`tuple` of two `float`
    The next set of wavelength endpoints for a subfilter, in nm.

Definition at line 735 of file dcrModel.py.

735 def wavelengthGenerator(filterInfo, dcrNumSubfilters):
736  """Iterate over the wavelength endpoints of subfilters.
737 
738  Parameters
739  ----------
740  filterInfo : `lsst.afw.image.Filter`
741  The filter definition, set in the current instruments' obs package.
742  dcrNumSubfilters : `int`
743  Number of sub-filters used to model chromatic effects within a band.
744 
745  Yields
746  ------
747  `tuple` of two `float`
748  The next set of wavelength endpoints for a subfilter, in nm.
749  """
750  lambdaMin = filterInfo.getFilterProperty().getLambdaMin()
751  lambdaMax = filterInfo.getFilterProperty().getLambdaMax()
752  wlStep = (lambdaMax - lambdaMin)/dcrNumSubfilters
753  for wl in np.linspace(lambdaMin, lambdaMax, dcrNumSubfilters, endpoint=False):
754  yield (wl, wl + wlStep)
755 
def wavelengthGenerator(filterInfo, dcrNumSubfilters)
Definition: dcrModel.py:735