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