Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-37309: Nominally bring NightReport channel online #35

Merged
merged 32 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e2406ec
Add NightReport to namespace
mfisherlevine Dec 23, 2022
d838937
Change default method to heuristic and deal with not being on sky yet
mfisherlevine Jan 17, 2023
73ef8ce
Fix mislabed axis
mfisherlevine Jan 18, 2023
143035b
Reverse the order in the observation gap printout
mfisherlevine Jan 18, 2023
813ab4a
Move getDatesForSeqNums() to night report
mfisherlevine Jan 20, 2023
6c85878
Add filter and airmass seeing correction functions
mfisherlevine Jan 20, 2023
ef99d7e
Change airmass plot to real times from MJD
mfisherlevine Jan 20, 2023
381bc6d
Add ignore for calib values for plots
mfisherlevine Jan 20, 2023
8df5731
Fix midpoint test to deal with zero and non-zero exptimes
mfisherlevine Jan 20, 2023
1fc1eb5
Add versioning to night report data and pack save into dict vs tuple
mfisherlevine Jan 26, 2023
a81a98d
Make smoothing an optional parameter when plotting
mfisherlevine Jan 31, 2023
29eb0c0
Add DaytimeCheckout001 and DaytimeCheckout002 to calib ignore list
mfisherlevine Feb 1, 2023
0143131
Change background subtraction for StarTrackers to be very basic
mfisherlevine Feb 1, 2023
48b7e6f
Fix bug in getAltAzFromSkyPosition where TAI wasn't being handled cor…
mfisherlevine Feb 2, 2023
246c357
Fix incorrect copyright statement
mfisherlevine Feb 4, 2023
7dcfdb6
Turn on parallel overscan in bestEffortIsr
mfisherlevine Feb 9, 2023
d54d9da
Try to fix memory leak
mfisherlevine Feb 16, 2023
a80234e
Fix deprecated import
mfisherlevine Feb 17, 2023
ab35d43
Add basic test for quickSmooth
mfisherlevine Feb 17, 2023
d43136f
Add maxSources option to filterSourceCatOnBrightest
mfisherlevine Feb 22, 2023
3e2f90f
Fix bug where plotting was modifying pixel values
mfisherlevine Feb 22, 2023
f99434e
Add log messages to anet fitter
mfisherlevine Feb 22, 2023
e60c415
Add temporary header patching function
mfisherlevine Feb 22, 2023
d9be299
Stop fixing CRPIX to image centre now we are setting it
mfisherlevine Feb 22, 2023
522e376
Update collection name on TTS and how the site is determined
mfisherlevine Feb 22, 2023
7fe2961
Fix includeThresholdMultiplier for characterizeImage and background w…
mfisherlevine Feb 23, 2023
46da112
Use CRPIX values in the fit
mfisherlevine Feb 23, 2023
77f1f21
Turn off reEstimateBackground for characterizeImage
mfisherlevine Feb 23, 2023
d216c13
Change to aperture fluxes for sources in anet fitter
mfisherlevine Feb 23, 2023
34c50a3
Attempt to fix memory leak
mfisherlevine Feb 23, 2023
5cfdf02
Fix doc formatting
mfisherlevine Mar 8, 2023
fbf69ed
Reenable reEstimateBackground and make it use same minimal config
mfisherlevine Mar 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions python/lsst/summit/utils/__init__.py
Expand Up @@ -21,6 +21,7 @@

from .bestEffort import *
from .spectrumExaminer import *
from .nightReport import *
from .imageExaminer import *
from .quickLook import *
from .butlerUtils import *
Expand Down
10 changes: 8 additions & 2 deletions python/lsst/summit/utils/astrometry/anet.py
Expand Up @@ -127,11 +127,13 @@ def __init__(self,
checkInParallel=True,
timeout=300,
binary='solve-field',
fluxSlot='base_CircularApertureFlux_3_0_instFlux',
):
self.indexFilePath = indexFilePath
self.checkInParallel = checkInParallel
self.timeout = timeout
self.binary = binary
self.fluxSlot = fluxSlot
if not shutil.which(binary):
raise RuntimeError(f"Could not find {binary} in path, please install 'solve-field' and either"
" put it on your PATH or specify the full path to it in the 'binary' argument")
Expand Down Expand Up @@ -180,7 +182,7 @@ def _writeFitsTable(self, sourceCat):
filename : `str`
The filename to which the catalog was written.
"""
fluxArray = sourceCat.columns.getGaussianInstFlux()
fluxArray = sourceCat[self.fluxSlot]
fluxFinite = np.logical_and(np.isfinite(fluxArray), fluxArray > 0)
fluxArray = fluxArray[fluxFinite]
indices = np.argsort(fluxArray)
Expand All @@ -192,6 +194,7 @@ def _writeFitsTable(self, sourceCat):
x = fits.Column(name='X', format='D', array=xArray)
y = fits.Column(name='Y', format='D', array=yArray)
flux = fits.Column(name='FLUX', format='D', array=fluxArray)
print(f' of which {len(fluxArray)} made it into the fit')
hdu = fits.BinTableHDU.from_columns([flux, x, y])

filename = tempfile.mktemp(suffix='.fits')
Expand Down Expand Up @@ -233,6 +236,7 @@ def run(self, exp, sourceCat, isWideField, *, percentageScaleError=10, radius=No
raise ValueError("No WCS in exposure")

configFile = self._writeConfigFile(wide=isWideField)
print(f'Fitting image with {len(sourceCat)} sources', end='')
fitsFile = self._writeFitsTable(sourceCat)

plateScale = wcs.getPixelScale().asArcseconds()
Expand All @@ -257,9 +261,11 @@ def run(self, exp, sourceCat, isWideField, *, percentageScaleError=10, radius=No
f"--scale-low {scaleMin:.3f} " # the scale range
f"--scale-high {scaleMax:.3f} " # the scale range
f"--scale-units arcsecperpix "
"--crpix-center " # the CRPIX is always the center of the image
f"--crpix-x {wcs.getPixelOrigin()[0]} " # set the pixel origin
f"--crpix-y {wcs.getPixelOrigin()[1]} " # set the pixel origin
f"--config {configFile} "
f"-D {tempDir} "
"--no-plots " # don't make plots
"--overwrite " # shouldn't matter as we're using temp files
)

Expand Down
22 changes: 15 additions & 7 deletions python/lsst/summit/utils/astrometry/plotting.py
Expand Up @@ -24,6 +24,7 @@
import matplotlib.pyplot as plt
from astropy.coordinates import Angle
import astropy.units as u
import copy

from lsst.obs.lsst.translators.latiss import AUXTEL_LOCATION
from .. import quickSmooth
Expand All @@ -32,7 +33,7 @@
# TODO: Add some of Craig's nice overlay stuff here

def plot(exp, icSrc=None, filteredSources=None, saveAs=None,
clipMin=1, clipMax=1000000):
clipMin=1, clipMax=1000000, doSmooth=True):
"""Plot an exposure, overlaying the selected sources and compass arrows.

Plots the exposure on a logNorm scale, with the brightest sources, as
Expand All @@ -55,15 +56,18 @@ def plot(exp, icSrc=None, filteredSources=None, saveAs=None,
Clip values in the image below this value to ``clipMin``.
clipMax : `float`
Clip values in the image above this value to ``clipMax``.
doSmooth : `bool`, optional
Smooth the image slightly to improve the visability of low SNR sources?
"""
plt.figure(figsize=(16, 16))
arr = exp.image.array
arr = np.clip(arr, clipMin, clipMax)
arr = quickSmooth(arr) # smooth slightly to help visualize
plt.imshow(np.arcsinh(arr)/10,
fig = plt.figure(figsize=(16, 16))
data = copy.deepcopy(exp.image.array)
data = np.clip(data, clipMin, clipMax)
if doSmooth:
data = quickSmooth(data) # smooth slightly to help visualize
mfisherlevine marked this conversation as resolved.
Show resolved Hide resolved
plt.imshow(np.arcsinh(data)/10,
interpolation='None', cmap='gray', origin='lower')

height, width = exp.image.array.shape
height, width = data.shape
leftFraction = .15 # fraction into the image to start the N/E compass
rightFraction = .225 # fraction into the image to start the az/el compass
fontsize = 20 # for the compass labels
Expand Down Expand Up @@ -136,3 +140,7 @@ def plot(exp, icSrc=None, filteredSources=None, saveAs=None,
if saveAs:
plt.savefig(saveAs)
plt.show()

plt.gcf().clear()
del fig
del data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this still isn't working, you might want to try gc.collect(). If that doesn't work, @natelust is the the expert.

47 changes: 41 additions & 6 deletions python/lsst/summit/utils/astrometry/utils.py
Expand Up @@ -147,11 +147,27 @@ def getAverageElFromHeader(header):
return (elStart + elEnd) / 2


def patchHeader(header):
"""This is a TEMPORARY function to patch some info into the headers.
"""
if header.get('SECPIX') == '3.11':
# the narrow camera currently is wrong about its place scale by of ~2.2
header['SECPIX'] = '1.44'
# update the boresight locations until this goes into the header
# service
header['CRPIX1'] = 1898.10
header['CRPIX2'] = 998.47
if header.get('SECPIX') == '8.64':
# update the boresight locations until this goes into the header
# service
header['CRPIX1'] = 1560.85
header['CRPIX2'] = 1257.15
return header


def genericCameraHeaderToWcs(exp):
header = exp.getMetadata().toDict()
width, height = exp.image.array.shape
header['CRPIX1'] = width/2
header['CRPIX2'] = height/2
header = patchHeader(header)

header['CTYPE1'] = 'RA---TAN-SIP'
header['CTYPE2'] = 'DEC--TAN-SIP'
Expand Down Expand Up @@ -243,17 +259,30 @@ def runCharactierizeImage(exp, snr, minPix):
charConfig.doApCorr = False
charConfig.doDeblend = False
charConfig.repair.doCosmicRay = False
charConfig.repair.doInterpolate = True

charConfig.detection.minPixels = minPix
charConfig.detection.thresholdValue = snr
charConfig.detection.includeThresholdMultiplier = 1

# fit background with the most simple thing possible as we don't need
# much sophistication here. weighting=False is *required* for very
# large binSizes.
charConfig.background.algorithm = 'CONSTANT'
charConfig.background.approxOrderX = 0
charConfig.background.approxOrderY = -1
charConfig.background.binSize = max(exp.getWidth(), exp.getHeight())
charConfig.background.weighting = False

# set this to use all the same minimal settings as those above
charConfig.detection.background = charConfig.background

charTask = CharacterizeImageTask(config=charConfig)

charResult = charTask.run(exp)
return charResult


def filterSourceCatOnBrightest(catalog, brightFraction, minSources=15,
def filterSourceCatOnBrightest(catalog, brightFraction, minSources=15, maxSources=200,
flux_field="base_CircularApertureFlux_3_0_instFlux"):
"""Filter a sourceCat on the brightness, leaving only the top fraction.

Expand All @@ -270,6 +299,8 @@ def filterSourceCatOnBrightest(catalog, brightFraction, minSources=15,
Return this fraction of the brightest sources.
minSources : `int`, optional
Always return at least this many sources.
maxSources : `int`, optional
Never return more than this many sources.
flux_field : `str`, optional
Name of flux field to filter on.

Expand All @@ -280,6 +311,10 @@ def filterSourceCatOnBrightest(catalog, brightFraction, minSources=15,
"""
assert minSources > 0
assert brightFraction > 0 and brightFraction <= 1
if not maxSources >= minSources:
raise ValueError('maxSources must be greater than or equal to minSources, got '
f'{maxSources=}, {minSources=}')

maxFlux = np.nanmax(catalog[flux_field])
result = catalog.subset(catalog[flux_field] > maxFlux * 0.001)

Expand All @@ -290,4 +325,4 @@ def filterSourceCatOnBrightest(catalog, brightFraction, minSources=15,
result.sort(item.key)
result = result.copy(deep=True) # make it memory contiguous
end = int(np.ceil(len(result)*brightFraction))
return result[-max(end, minSources):]
return result[-min(maxSources, max(end, minSources)):]
2 changes: 1 addition & 1 deletion python/lsst/summit/utils/bestEffort.py
Expand Up @@ -217,8 +217,8 @@ def getExposure(self, expIdOrDataId, extraIsrOptions={}, skipCosmics=False, forc
isrConfig.doWrite = False # this task writes separately, no need for this
isrConfig.doSaturation = True # saturation very important for roundness measurement in qfm
isrConfig.doSaturationInterpolation = True
isrConfig.overscan.leadingColumnsToSkip = 5
isrConfig.overscan.fitType = 'MEDIAN_PER_ROW'
isrConfig.overscan.doParallelOverscan = True

# apply general overrides
self._applyConfigOverrides(isrConfig, self.defaultExtraIsrOptions)
Expand Down
2 changes: 1 addition & 1 deletion python/lsst/summit/utils/butlerUtils.py
Expand Up @@ -91,7 +91,7 @@ def getLatissDefaultCollections():
site = ''

if site == 'tucson':
collections.append("LATISS-test-data-TTS")
collections.append("LATISS-test-data")
return collections
if site == 'summit':
collections.append("LATISS-test-data")
Expand Down