LSST Applications g0f08755f38+9c285cab97,g1635faa6d4+13f3999e92,g1653933729+a8ce1bb630,g1a0ca8cf93+bf6eb00ceb,g28da252d5a+0829b12dee,g29321ee8c0+5700dc9eac,g2bbee38e9b+9634bc57db,g2bc492864f+9634bc57db,g2cdde0e794+c2c89b37c4,g3156d2b45e+41e33cbcdc,g347aa1857d+9634bc57db,g35bb328faa+a8ce1bb630,g3a166c0a6a+9634bc57db,g3e281a1b8c+9f2c4e2fc3,g414038480c+077ccc18e7,g41af890bb2+fde0dd39b6,g5fbc88fb19+17cd334064,g781aacb6e4+a8ce1bb630,g80478fca09+55a9465950,g82479be7b0+d730eedb7d,g858d7b2824+9c285cab97,g9125e01d80+a8ce1bb630,g9726552aa6+10f999ec6a,ga5288a1d22+2a84bb7594,gacf8899fa4+c69c5206e8,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gc28159a63d+9634bc57db,gcf0d15dbbd+4b7d09cae4,gda3e153d99+9c285cab97,gda6a2b7d83+4b7d09cae4,gdaeeff99f8+1711a396fd,ge2409df99d+5e831397f4,ge79ae78c31+9634bc57db,gf0baf85859+147a0692ba,gf3967379c6+41c94011de,gf3fb38a9a8+8f07a9901b,gfb92a5be7c+9c285cab97,w.2024.46
LSST Data Management Base Package
Loading...
Searching...
No Matches
Classes | Functions
lsst.ip.diffim.dcrModel Namespace Reference

Classes

class  DcrModel
 

Functions

 applyDcr (image, dcr, useInverse=False, splitSubfilters=False, splitThreshold=0., doPrefilter=True, order=3)
 
 calculateDcr (visitInfo, wcs, effectiveWavelength, bandwidth, dcrNumSubfilters, splitSubfilters=False, bbox=None)
 
 calculateImageParallacticAngle (visitInfo, wcs)
 
 wavelengthGenerator (effectiveWavelength, bandwidth, dcrNumSubfilters)
 

Function Documentation

◆ applyDcr()

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

667 doPrefilter=True, order=3):
668 """Shift an image along the X and Y directions.
669
670 Parameters
671 ----------
672 image : `numpy.ndarray`
673 The input image to shift.
674 dcr : `tuple`
675 Shift calculated with ``calculateDcr``.
676 Uses numpy axes ordering (Y, X).
677 If ``splitSubfilters`` is set, each element is itself a `tuple`
678 of two `float`, corresponding to the DCR shift at the two wavelengths.
679 Otherwise, each element is a `float` corresponding to the DCR shift at
680 the effective wavelength of the subfilter.
681 useInverse : `bool`, optional
682 Apply the shift in the opposite direction. Default: False
683 splitSubfilters : `bool`, optional
684 Calculate DCR for two evenly-spaced wavelengths in each subfilter,
685 instead of at the midpoint. Default: False
686 splitThreshold : `float`, optional
687 Minimum DCR difference within a subfilter required to use
688 ``splitSubfilters``
689 doPrefilter : `bool`, optional
690 Spline filter the image before shifting, if set. Filtering is required,
691 so only set to False if the image is already filtered.
692 Filtering takes ~20% of the time of shifting, so if `applyDcr` will be
693 called repeatedly on the same image it is more efficient to
694 precalculate the filter.
695 order : `int`, optional
696 The order of the spline interpolation, default is 3.
697
698 Returns
699 -------
700 shiftedImage : `numpy.ndarray`
701 A copy of the input image with the specified shift applied.
702 """
703 if doPrefilter and order > 1:
704 prefilteredImage = ndimage.spline_filter(image, order=order)
705 else:
706 prefilteredImage = image
707 if splitSubfilters:
708 shiftAmp = np.max(np.abs([_dcr0 - _dcr1 for _dcr0, _dcr1 in zip(dcr[0], dcr[1])]))
709 if shiftAmp >= splitThreshold:
710 if useInverse:
711 shift = [-1.*s for s in dcr[0]]
712 shift1 = [-1.*s for s in dcr[1]]
713 else:
714 shift = dcr[0]
715 shift1 = dcr[1]
716 shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=False, order=order)
717 shiftedImage += ndimage.shift(prefilteredImage, shift1, prefilter=False, order=order)
718 shiftedImage /= 2.
719 return shiftedImage
720 else:
721 # If the difference in the DCR shifts is less than the threshold,
722 # then just use the average shift for efficiency.
723 dcr = (np.mean(dcr[0]), np.mean(dcr[1]))
724 if useInverse:
725 shift = [-1.*s for s in dcr]
726 else:
727 shift = dcr
728 shiftedImage = ndimage.shift(prefilteredImage, shift, prefilter=False, order=order)
729 return shiftedImage
730
731

◆ calculateDcr()

lsst.ip.diffim.dcrModel.calculateDcr ( visitInfo,
wcs,
effectiveWavelength,
bandwidth,
dcrNumSubfilters,
splitSubfilters = False,
bbox = None )
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
bbox : `lsst.afw.geom.Box2I`, optional
    Bounding box for the region of interest for evaluating the local
    pixelScale (defaults to the Sky Origin of the ``wcs`` provided if
    ``bbox`` is None).

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

Definition at line 732 of file dcrModel.py.

733 bbox=None):
734 """Calculate the shift in pixels of an exposure due to DCR.
735
736 Parameters
737 ----------
738 visitInfo : `lsst.afw.image.VisitInfo`
739 Metadata for the exposure.
740 wcs : `lsst.afw.geom.SkyWcs`
741 Coordinate system definition (wcs) for the exposure.
742 effectiveWavelength : `float`
743 The effective wavelengths of the current filter, in nanometers.
744 bandwidth : `float`
745 The bandwidth of the current filter, in nanometers.
746 dcrNumSubfilters : `int`
747 Number of sub-filters used to model chromatic effects within a band.
748 splitSubfilters : `bool`, optional
749 Calculate DCR for two evenly-spaced wavelengths in each subfilter,
750 instead of at the midpoint. Default: False
751 bbox : `lsst.afw.geom.Box2I`, optional
752 Bounding box for the region of interest for evaluating the local
753 pixelScale (defaults to the Sky Origin of the ``wcs`` provided if
754 ``bbox`` is None).
755
756 Returns
757 -------
758 dcrShift : `tuple` of two `float`
759 The 2D shift due to DCR, in pixels.
760 Uses numpy axes ordering (Y, X).
761 """
762 rotation = calculateImageParallacticAngle(visitInfo, wcs)
763 dcrShift = []
764 weight = [0.75, 0.25]
765 for wl0, wl1 in wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters):
766 # Note that diffRefractAmp can be negative, since it's relative to the
767 # midpoint of the full band
768 diffRefractAmp0 = differentialRefraction(wavelength=wl0, wavelengthRef=effectiveWavelength,
769 elevation=visitInfo.getBoresightAzAlt().getLatitude(),
770 observatory=visitInfo.getObservatory(),
771 weather=visitInfo.getWeather())
772 diffRefractAmp1 = differentialRefraction(wavelength=wl1, wavelengthRef=effectiveWavelength,
773 elevation=visitInfo.getBoresightAzAlt().getLatitude(),
774 observatory=visitInfo.getObservatory(),
775 weather=visitInfo.getWeather())
776 if bbox is not None:
777 pixelScale = wcs.getPixelScale(bbox.getCenter()).asArcseconds()
778 else:
779 pixelScale = wcs.getPixelScale().asArcseconds()
780
781 if splitSubfilters:
782 diffRefractPix0 = diffRefractAmp0.asArcseconds()/pixelScale
783 diffRefractPix1 = diffRefractAmp1.asArcseconds()/pixelScale
784 diffRefractArr = [diffRefractPix0*weight[0] + diffRefractPix1*weight[1],
785 diffRefractPix0*weight[1] + diffRefractPix1*weight[0]]
786 shiftX = [diffRefractPix*np.sin(rotation.asRadians()) for diffRefractPix in diffRefractArr]
787 shiftY = [diffRefractPix*np.cos(rotation.asRadians()) for diffRefractPix in diffRefractArr]
788 dcrShift.append(((shiftY[0], shiftX[0]), (shiftY[1], shiftX[1])))
789 else:
790 diffRefractAmp = (diffRefractAmp0 + diffRefractAmp1)/2.
791 diffRefractPix = diffRefractAmp.asArcseconds()/pixelScale
792 shiftX = diffRefractPix*np.sin(rotation.asRadians())
793 shiftY = diffRefractPix*np.cos(rotation.asRadians())
794 dcrShift.append((shiftY, shiftX))
795 return dcrShift
796
797

◆ calculateImageParallacticAngle()

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

798def calculateImageParallacticAngle(visitInfo, wcs):
799 """Calculate the total sky rotation angle of an exposure.
800
801 Parameters
802 ----------
803 visitInfo : `lsst.afw.image.VisitInfo`
804 Metadata for the exposure.
805 wcs : `lsst.afw.geom.SkyWcs`
806 Coordinate system definition (wcs) for the exposure.
807
808 Returns
809 -------
810 `lsst.geom.Angle`
811 The rotation of the image axis, East from North.
812 Equal to the parallactic angle plus any additional rotation of the
813 coordinate system.
814 A rotation angle of 0 degrees is defined with
815 North along the +y axis and East along the +x axis.
816 A rotation angle of 90 degrees is defined with
817 North along the +x axis and East along the -y axis.
818 """
819 parAngle = visitInfo.getBoresightParAngle().asRadians()
820 cd = wcs.getCdMatrix()
821 if wcs.isFlipped:
822 cdAngle = (np.arctan2(-cd[0, 1], cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
823 rotAngle = (cdAngle + parAngle)*geom.radians
824 else:
825 cdAngle = (np.arctan2(cd[0, 1], -cd[0, 0]) + np.arctan2(cd[1, 0], cd[1, 1]))/2.
826 rotAngle = (cdAngle - parAngle)*geom.radians
827 return rotAngle
828
829

◆ wavelengthGenerator()

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

830def wavelengthGenerator(effectiveWavelength, bandwidth, dcrNumSubfilters):
831 """Iterate over the wavelength endpoints of subfilters.
832
833 Parameters
834 ----------
835 effectiveWavelength : `float`
836 The effective wavelength of the current filter, in nanometers.
837 bandwidth : `float`
838 The bandwidth of the current filter, in nanometers.
839 dcrNumSubfilters : `int`
840 Number of sub-filters used to model chromatic effects within a band.
841
842 Yields
843 ------
844 `tuple` of two `float`
845 The next set of wavelength endpoints for a subfilter, in nanometers.
846 """
847 lambdaMin = effectiveWavelength - bandwidth/2
848 lambdaMax = effectiveWavelength + bandwidth/2
849 wlStep = bandwidth/dcrNumSubfilters
850 for wl in np.linspace(lambdaMin, lambdaMax, dcrNumSubfilters, endpoint=False):
851 yield (wl, wl + wlStep)