LSSTApplications  19.0.0-14-gb0260a2+72efe9b372,20.0.0+7927753e06,20.0.0+8829bf0056,20.0.0+995114c5d2,20.0.0+b6f4b2abd1,20.0.0+bddc4f4cbe,20.0.0-1-g253301a+8829bf0056,20.0.0-1-g2b7511a+0d71a2d77f,20.0.0-1-g5b95a8c+7461dd0434,20.0.0-12-g321c96ea+23efe4bbff,20.0.0-16-gfab17e72e+fdf35455f6,20.0.0-2-g0070d88+ba3ffc8f0b,20.0.0-2-g4dae9ad+ee58a624b3,20.0.0-2-g61b8584+5d3db074ba,20.0.0-2-gb780d76+d529cf1a41,20.0.0-2-ged6426c+226a441f5f,20.0.0-2-gf072044+8829bf0056,20.0.0-2-gf1f7952+ee58a624b3,20.0.0-20-geae50cf+e37fec0aee,20.0.0-25-g3dcad98+544a109665,20.0.0-25-g5eafb0f+ee58a624b3,20.0.0-27-g64178ef+f1f297b00a,20.0.0-3-g4cc78c6+e0676b0dc8,20.0.0-3-g8f21e14+4fd2c12c9a,20.0.0-3-gbd60e8c+187b78b4b8,20.0.0-3-gbecbe05+48431fa087,20.0.0-38-ge4adf513+a12e1f8e37,20.0.0-4-g97dc21a+544a109665,20.0.0-4-gb4befbc+087873070b,20.0.0-4-gf910f65+5d3db074ba,20.0.0-5-gdfe0fee+199202a608,20.0.0-5-gfbfe500+d529cf1a41,20.0.0-6-g64f541c+d529cf1a41,20.0.0-6-g9a5b7a1+a1cd37312e,20.0.0-68-ga3f3dda+5fca18c6a4,20.0.0-9-g4aef684+e18322736b,w.2020.45
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, 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 696 of file dcrModel.py.

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

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

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

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

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

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

850 def wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters):
851  """Iterate over the wavelength endpoints of subfilters.
852 
853  Parameters
854  ----------
855  effectiveWavelength : `float`
856  The effective wavelength of the current filter, in nanometers.
857  bandwidth : `float`
858  The bandwidth of the current filter, in nanometers.
859  dcrNumSubfilters : `int`
860  Number of sub-filters used to model chromatic effects within a band.
861 
862  Yields
863  ------
864  `tuple` of two `float`
865  The next set of wavelength endpoints for a subfilter, in nanometers.
866  """
867  lambdaMin = effectiveWavelength - bandwidth/2
868  lambdaMax = effectiveWavelength + bandwidth/2
869  wlStep = bandwidth/dcrNumSubfilters
870  for wl in np.linspace(lambdaMin, lambdaMax, dcrNumSubfilters, endpoint=False):
871  yield (wl, wl + wlStep)
lsst::afw::coord.refraction.differentialRefraction
def differentialRefraction(wavelength, wavelengthRef, elevation, observatory, weather=None)
Definition: refraction.py:95
lsst::ip::diffim.dcrModel.wavelengthGenerator
def wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters)
Definition: dcrModel.py:850
lsst::ip::diffim.dcrModel.applyDcr
def applyDcr(image, dcr, useInverse=False, splitSubfilters=False, splitThreshold=0., doPrefilter=True, order=3)
Definition: dcrModel.py:696
lsst::ip::diffim.dcrModel.calculateImageParallacticAngle
def calculateImageParallacticAngle(visitInfo, wcs)
Definition: dcrModel.py:818
lsst::ip::diffim.dcrModel.calculateDcr
def calculateDcr(visitInfo, wcs, effectiveWavelength, bandwidth, dcrNumSubfilters, splitSubfilters=False)
Definition: dcrModel.py:762