LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
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, effectiveWavelength, bandwidth, dcrNumSubfilters, splitSubfilters=False)
 
def calculateImageParallacticAngle (visitInfo, wcs)
 
def wavelengthGenerator (effectiveWavelength, bandwidth, 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 694 of file dcrModel.py.

695  doPrefilter=True, order=3):
696  """Shift an image along the X and Y directions.
697 
698  Parameters
699  ----------
700  image : `numpy.ndarray`
701  The input image to shift.
702  dcr : `tuple`
703  Shift calculated with ``calculateDcr``.
704  Uses numpy axes ordering (Y, X).
705  If ``splitSubfilters`` is set, each element is itself a `tuple`
706  of two `float`, corresponding to the DCR shift at the two wavelengths.
707  Otherwise, each element is a `float` corresponding to the DCR shift at
708  the effective wavelength of the subfilter.
709  useInverse : `bool`, optional
710  Apply the shift in the opposite direction. Default: False
711  splitSubfilters : `bool`, optional
712  Calculate DCR for two evenly-spaced wavelengths in each subfilter,
713  instead of at the midpoint. Default: False
714  splitThreshold : `float`, optional
715  Minimum DCR difference within a subfilter required to use
716  ``splitSubfilters``
717  doPrefilter : `bool`, optional
718  Spline filter the image before shifting, if set. Filtering is required,
719  so only set to False if the image is already filtered.
720  Filtering takes ~20% of the time of shifting, so if `applyDcr` will be
721  called repeatedly on the same image it is more efficient to
722  precalculate the filter.
723  order : `int`, optional
724  The order of the spline interpolation, default is 3.
725 
726  Returns
727  -------
728  shiftedImage : `numpy.ndarray`
729  A copy of the input image with the specified shift applied.
730  """
731  if doPrefilter:
732  prefilteredImage = ndimage.spline_filter(image, order=order)
733  else:
734  prefilteredImage = image
735  if splitSubfilters:
736  shiftAmp = np.max(np.abs([_dcr0 - _dcr1 for _dcr0, _dcr1 in zip(dcr[0], dcr[1])]))
737  if shiftAmp >= splitThreshold:
738  if useInverse:
739  shift = [-1.*s for s in dcr[0]]
740  shift1 = [-1.*s for s in dcr[1]]
741  else:
742  shift = dcr[0]
743  shift1 = dcr[1]
744  shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=False, order=order)
745  shiftedImage += ndimage.shift(prefilteredImage, shift1, prefilter=False, order=order)
746  shiftedImage /= 2.
747  return shiftedImage
748  else:
749  # If the difference in the DCR shifts is less than the threshold,
750  # then just use the average shift for efficiency.
751  dcr = (np.mean(dcr[0]), np.mean(dcr[1]))
752  if useInverse:
753  shift = [-1.*s for s in dcr]
754  else:
755  shift = dcr
756  shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=False, order=order)
757  return shiftedImage
758 
759 

◆ calculateDcr()

def lsst.ip.diffim.dcrModel.calculateDcr (   visitInfo,
  wcs,
  effectiveWavelength,
  bandwidth,
  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.
effectiveWavelength : `float`
    The effective wavelengths of the current filter, in nanometers.
bandwidth : `float`
    The bandwidth of the current filter, in nanometers.
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 760 of file dcrModel.py.

760 def calculateDcr(visitInfo, wcs, effectiveWavelength, bandwidth, dcrNumSubfilters, splitSubfilters=False):
761  """Calculate the shift in pixels of an exposure due to DCR.
762 
763  Parameters
764  ----------
765  visitInfo : `lsst.afw.image.VisitInfo`
766  Metadata for the exposure.
767  wcs : `lsst.afw.geom.SkyWcs`
768  Coordinate system definition (wcs) for the exposure.
769  effectiveWavelength : `float`
770  The effective wavelengths of the current filter, in nanometers.
771  bandwidth : `float`
772  The bandwidth of the current filter, in nanometers.
773  dcrNumSubfilters : `int`
774  Number of sub-filters used to model chromatic effects within a band.
775  splitSubfilters : `bool`, optional
776  Calculate DCR for two evenly-spaced wavelengths in each subfilter,
777  instead of at the midpoint. Default: False
778 
779  Returns
780  -------
781  dcrShift : `tuple` of two `float`
782  The 2D shift due to DCR, in pixels.
783  Uses numpy axes ordering (Y, X).
784  """
785  rotation = calculateImageParallacticAngle(visitInfo, wcs)
786  dcrShift = []
787  weight = [0.75, 0.25]
788  for wl0, wl1 in wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters):
789  # Note that diffRefractAmp can be negative, since it's relative to the
790  # midpoint of the full band
791  diffRefractAmp0 = differentialRefraction(wavelength=wl0, wavelengthRef=effectiveWavelength,
792  elevation=visitInfo.getBoresightAzAlt().getLatitude(),
793  observatory=visitInfo.getObservatory(),
794  weather=visitInfo.getWeather())
795  diffRefractAmp1 = differentialRefraction(wavelength=wl1, wavelengthRef=effectiveWavelength,
796  elevation=visitInfo.getBoresightAzAlt().getLatitude(),
797  observatory=visitInfo.getObservatory(),
798  weather=visitInfo.getWeather())
799  if splitSubfilters:
800  diffRefractPix0 = diffRefractAmp0.asArcseconds()/wcs.getPixelScale().asArcseconds()
801  diffRefractPix1 = diffRefractAmp1.asArcseconds()/wcs.getPixelScale().asArcseconds()
802  diffRefractArr = [diffRefractPix0*weight[0] + diffRefractPix1*weight[1],
803  diffRefractPix0*weight[1] + diffRefractPix1*weight[0]]
804  shiftX = [diffRefractPix*np.sin(rotation.asRadians()) for diffRefractPix in diffRefractArr]
805  shiftY = [diffRefractPix*np.cos(rotation.asRadians()) for diffRefractPix in diffRefractArr]
806  dcrShift.append(((shiftY[0], shiftX[0]), (shiftY[1], shiftX[1])))
807  else:
808  diffRefractAmp = (diffRefractAmp0 + diffRefractAmp1)/2.
809  diffRefractPix = diffRefractAmp.asArcseconds()/wcs.getPixelScale().asArcseconds()
810  shiftX = diffRefractPix*np.sin(rotation.asRadians())
811  shiftY = diffRefractPix*np.cos(rotation.asRadians())
812  dcrShift.append((shiftY, shiftX))
813  return dcrShift
814 
815 
def differentialRefraction(wavelength, wavelengthRef, elevation, observatory, weather=None)
Definition: _refraction.py:94
def wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters)
Definition: dcrModel.py:848
def calculateImageParallacticAngle(visitInfo, wcs)
Definition: dcrModel.py:816
def calculateDcr(visitInfo, wcs, effectiveWavelength, bandwidth, dcrNumSubfilters, splitSubfilters=False)
Definition: dcrModel.py:760

◆ 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 816 of file dcrModel.py.

816 def calculateImageParallacticAngle(visitInfo, wcs):
817  """Calculate the total sky rotation angle of an exposure.
818 
819  Parameters
820  ----------
821  visitInfo : `lsst.afw.image.VisitInfo`
822  Metadata for the exposure.
823  wcs : `lsst.afw.geom.SkyWcs`
824  Coordinate system definition (wcs) for the exposure.
825 
826  Returns
827  -------
828  `lsst.geom.Angle`
829  The rotation of the image axis, East from North.
830  Equal to the parallactic angle plus any additional rotation of the
831  coordinate system.
832  A rotation angle of 0 degrees is defined with
833  North along the +y axis and East along the +x axis.
834  A rotation angle of 90 degrees is defined with
835  North along the +x axis and East along the -y axis.
836  """
837  parAngle = visitInfo.getBoresightParAngle().asRadians()
838  cd = wcs.getCdMatrix()
839  if wcs.isFlipped:
840  cdAngle = (np.arctan2(-cd[0, 1], cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
841  rotAngle = (cdAngle + parAngle)*geom.radians
842  else:
843  cdAngle = (np.arctan2(cd[0, 1], -cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
844  rotAngle = (cdAngle - parAngle)*geom.radians
845  return rotAngle
846 
847 

◆ wavelengthGenerator()

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

Parameters
----------
effectiveWavelength : `float`
    The effective wavelength of the current filter, in nanometers.
bandwidth : `float`
    The bandwidth of the current filter, in nanometers.
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 nanometers.

Definition at line 848 of file dcrModel.py.

848 def wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters):
849  """Iterate over the wavelength endpoints of subfilters.
850 
851  Parameters
852  ----------
853  effectiveWavelength : `float`
854  The effective wavelength of the current filter, in nanometers.
855  bandwidth : `float`
856  The bandwidth of the current filter, in nanometers.
857  dcrNumSubfilters : `int`
858  Number of sub-filters used to model chromatic effects within a band.
859 
860  Yields
861  ------
862  `tuple` of two `float`
863  The next set of wavelength endpoints for a subfilter, in nanometers.
864  """
865  lambdaMin = effectiveWavelength - bandwidth/2
866  lambdaMax = effectiveWavelength + bandwidth/2
867  wlStep = bandwidth/dcrNumSubfilters
868  for wl in np.linspace(lambdaMin, lambdaMax, dcrNumSubfilters, endpoint=False):
869  yield (wl, wl + wlStep)