[PIPE2D-693] Flux errors near the dichroic are underestimated Created: 09/Jan/21 Updated: 20/Feb/21 Resolved: 20/Feb/21 |
|
| Status: | Done |
| Project: | DRP 2-D Pipeline |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Story | Priority: | Normal |
| Reporter: | rhl | Assignee: | price |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
| Story Points: | 2 |
| Sprint: | 2DDRP-2021 A 2 |
| Reviewers: | hassan |
| Description |
|
The extracted spectra in the pfsArm file can be very unstable near the dichroic transitions; this is not surprising, but the errors are underestimated. Please fix. This could be due to inaccurate fibre traces or to some other problem.
|
| Comments |
| Comment by rhl [ 09/Jan/21 ] |
|
See e.g. |
| Comment by rhl [ 09/Jan/21 ] |
|
That data is the b arm of visit 47, spectrograph 1 |
| Comment by price [ 02/Feb/21 ] |
|
rhl Could you please attach the script used to create this plot? |
| Comment by price [ 11/Feb/21 ] |
|
I found a sky fiber (fiberId=350) with some crazy fluxes and a bad chi value (> 100) between 643 and 645 nm (fairly clean region of sky, without strong lines). I tracked this down to a bad fiberProfile, due to not neglecting the BAD_FLAT mask plane. Bad chi: Bad profile: Fixed profile: New chi: |
| Comment by price [ 11/Feb/21 ] |
|
Notes:
PIPE2D-693: Flux errors near the dichroic are underestimated
(Had to hack repositoryCfg.yaml to replace /scratch/pprice/jenkins/weekly/2020-12-14 with /projects/HSC/PFS/saved/weekly-2020-12-14)
def fitLine(xx, yy):
xMean = xx.mean()
yMean = yy.mean()
dx = xx - xMean
dy = yy - yMean
xySum = np.sum(dx*dy)
xxSum = np.sum(dx**2)
slope = xySum/xxSum
intercept = yMean - slope*xMean
from types import SimpleNamespace
return SimpleNamespace(slope=slope, intercept=intercept, xMean=xMean, yMean=yMean)
import numpy as np
import matplotlib.pyplot as plt
from lsst.daf.persistence import Butler
from pfs.datamodel import TargetType
butler = Butler("/projects/HSC/PFS/saved/weekly-2020-12-14/process/rerun/weekly/pipeline/brn/pipeline")
dataId = dict(visit=47, arm="b")
pfsArm = butler.get("pfsArm", dataId)
pfsConfig = butler.get("pfsConfig", dataId)
skyIndices = pfsConfig.selectByTargetType(TargetType.SKY, pfsArm.fiberId)
wlMin, wlMax = 641, 646
chiRms = []
for ii in skyIndices:
wlSelect = (pfsArm.wavelength[ii] > wlMin) & (pfsArm.wavelength[ii] < wlMax)
wl = pfsArm.wavelength[ii][wlSelect]
flux = pfsArm.flux[ii][wlSelect]
error = np.sqrt(pfsArm.variance[ii][wlSelect])
line = fitLine(wl, flux)
fit = line.slope*wl + line.intercept
chi = (flux - fit)/error
lq, uq = np.percentile(chi, (25.0, 75.0))
rms = 0.741*(uq - lq)
chiRms.append(rms)
print(pfsArm.fiberId[ii], rms)
_ = plt.plot(wl, chi, "k-")
plt.xlabel("Wavelength (nm)")
plt.ylabel(r"\chi")
plt.show()
fiberId=350 has a bad chi in the 641-646 region. pfsArm.plot([350]) shows a strange feature in that region.
detrend.py /projects/HSC/PFS/saved/weekly-2020-12-14/process --calib /projects/HSC/PFS/saved/weekly-2020-12-14/process/CALIB --rerun price/pipe2d-693 --id visit=47 arm=b
fiberId = 350
from lsst.afw.display import Display
ds9 = Display(backend="ds9", frame=1)
butler = Butler("/projects/HSC/PFS/saved/weekly-2020-12-14/process/rerun/price/pipe2d-693")
calexp = butler.get("calexp", dataId)
detMap = butler.get("detectorMap", dataId)
ds9.mtv(calexp)
detMap.display(ds9, [fiberId], [wlMin, wlMax])
Looks clean. The peak in the spectrum is at y=3966, but there's nothing there in the image.
Maybe the problem is in the fiberTrace?
profiles = butler.get("fiberProfiles", dataId)
ft = profiles[fiberId].makeFiberTraceFromDetectorMap(detMap, fiberId)
ds9.mtv(ft.trace)
Yes, there's a strange discontinuity in the fiberTrace image at y=3966, so that's the source of the problem.
detrend.py /projects/HSC/PFS/saved/weekly-2020-12-14/process --calib /projects/HSC/PFS/saved/weekly-2020-12-14/process/CALIB --rerun price/pipe2d-693 --id visit=36^38 arm=b
quartz = butler.get("calexp", visit=36, arm="b")
ds9.mtv(quartz)
detMap.display(ds9, [fiberId], [wlMin, wlMax])
Confirmed that the fiber of interest is on visit=36. No obvious problems apparent in the image.
prof = profiles[fiberId]
plt.plot(prof.norm, "k-")
plt.xlim(3966, 3982)
plt.show()
The normalisation is negative...?
prof.plot()
The final sub-profile (y=4016) looks awful: no clear locus of points. It seems likely that this is the cause.
The calexp has a lot of BAD_FLAT masked pixels at the end, but that's not in the list of mask planes for buildFiberProfiles... fixed.
constructFiberProfiles.py /projects/HSC/PFS/saved/weekly-2020-12-14/process --calib=/projects/HSC/PFS/saved/weekly-2020-12-14/process/CALIB --rerun=price/pipe2d-693 --doraise --cores 1 --id visit=35^37 arm=b
from pfs.drp.stella import FiberProfileSet
profiles = FiberProfileSet.readFits("/projects/HSC/PFS/saved/weekly-2020-12-14/process/rerun/price/pipe2d-693/FIBERPROFILES/pfsFiberProfiles-2020-11-26-000036-b1.fits")
The final sub-profile (now at y=3950) now looks MUCH nicer!
There's still a discontinuity in the fiberTrace, now at y=4048. The normalisation is now noise around zero rather than crazy negative.
Let's extract spectra with this, and see if it's improved...
(lsst-scipipe) pprice@tiger2-sumire:/scratch/pprice/pipe2d-693 $ combineFiberProfiles.py pfsFiberProfiles-2020-11-26-000035-b1.fits /projects/HSC/PFS/saved/weekly-2020-12-14/process/rerun/price/pipe2d-693/FIBERPROFILES/pfsFiberProfiles-2020-11-26-00003?-b1.fits
profiles = FiberProfileSet("pfsFiberProfiles-2020-11-26-000035-b1.fits")
traces = profiles.makeFiberTracesFromDetectorMap(detMap)
spectra = traces.extractSpectra(calexp.maskedImage)
for ss in spectra:
ss.setWavelength(detMap.getWavelength(ss.fiberId))
pfsArm = spectra.toPfsArm(dataId)
Now when I plot chi between 643 and 645 nm, all values are less than 3, and generally less than 2: there are no wild outliers.
|
| Comment by price [ 19/Feb/21 ] |
|
More notes: RHL asks: > Have you checked that the quoted errors across the dichroic are correct, in the sense that the red-side and blue-side measurements of the flux at a given wavelength are statistically consistent? (lsst-scipipe) pprice@tiger2-sumire:/scratch/pprice/pipe2d-693 $ $PFS_PIPE2D_DIR/weekly/process_weekly.sh -r pipe2d-693 -D /scratch/pprice/pipe2d-693/fixed/ detrend.py /scratch/pprice/pipe2d-693/fixed --calib /scratch/pprice/pipe2d-693/fixed/CALIB --rerun pipe2d-693/pipeline/brn/pipeline --id visit=47 arm=b^r -j 2 import numpy as np from lsst.daf.persistence import Butler butler = Butler("/scratch/pprice/pipe2d-693/fixed/rerun/pipe2d-693/pipeline/brn/pipeline") blueId = dict(visit=47, arm="b") redId = dict(visit=47, arm="r") blue = butler.get("pfsArm", blueId) red = butler.get("pfsArm", redId) wlMin, wlMax = 643, 645 for ii in range(len(red)): redSelect = (red.wavelength[ii] > wlMin) & (red.wavelength[ii] < wlMax) redFlux = red.flux[ii][redSelect].mean() redErr = np.sqrt(red.variance[ii][redSelect]).mean() blueSelect = (blue.wavelength[ii] > wlMin) & (blue.wavelength[ii] < wlMax) blueFlux = blue.flux[ii][blueSelect].mean() blueErr = np.sqrt(blue.variance[ii][blueSelect]).mean() diff = np.abs(redFlux - blueFlux) err = np.hypot(redErr, blueErr) nSigma = diff/err if nSigma > 3: print(ii, red.fiberId[ii], blue.fiberId[ii], redFlux, redErr, redSelect.sum(), blueFlux, blueErr, blueSelect.sum()) 151 160 160 0.004514443263991073 0.000411609902932711 23 0.04298878209533732 0.0013043212679074675 30 162 171 171 0.12044178672043664 0.0016886640203687363 23 0.13277716863815206 0.00340707000100194 31 163 172 172 0.13493079559900753 0.001793808020948718 23 0.156978592248888 0.0037948187510930113 31 327 364 364 0.1681084379102511 0.0022442062516512913 23 0.13056916431689652 0.0031925625966626276 30 337 374 374 0.12048133641788118 0.001687048880942079 23 0.16057112050003808 0.004201387857562435 31 392 433 433 0.12349895673745459 0.001663794545175998 23 0.18600130173594448 0.004604363788815017 31 396 437 437 0.0038277092440687304 0.0003792050218488275 23 0.1664399803512527 0.04771144933588916 30 419 460 460 0.12122264921626778 0.0016422057235593282 23 0.14605515479435868 0.0036308343087460503 31 index = 392 fiberId = blue.fiberId[index] import matplotlib.pyplot as plt plt.plot(blue.wavelength[index], blue.flux[index], "b-") plt.plot(red.wavelength[index], red.flux[index], "r-") plt.xlabel("Wavelength (nm)") plt.ylabel("Flux (uncalibrated)") plt.show() There's a large bump in the blue that isn't there in the red. blueDetMap = butler.get("detectorMap", blueId) redDetMap = butler.get("detectorMap", redId) blueImage = butler.get("calexp", blueId) redImage = butler.get("calexp", redId) from lsst.afw.display import Display blueDisplay = Display(backend="ds9", frame=1) blueDisplay.mtv(blueImage) blueDetMap.display(blueDisplay, [blue.fiberId[index]], [wlMin, wlMax]) redDisplay = Display(backend="ds9", frame=2) redDisplay.mtv(redImage) redDetMap.displindeay(redDisplay, [red.fiberId[index]], [wlMin, wlMax]) It's not visible in the image. It must be in the fiberTrace. It can't be in the flat, since I'm looking at the flattened image. profiles = butler.get("fiberProfiles", blueId) prof = profiles[fiberId] Display(backend="ds9", frame=2).mtv(prof.makeFiberTraceFromDetectorMap(blueDetMap, fiberId).trace) There's a negative feature that peaks around y=4004, x=-4 relative to the trace --> 647.1 nm. The bump in the spectrum is peaked at 643.2 nm --> y=3945. There's a smaller negative feature in the trace there too. But that more extreme negative feature doesn't appear to have done anything awful to the spectrum. Could it be due to some coupling to the neighbouring fibers? Nothing in their fiberTraces around the row of interest, and no flux stolen from their spectra. plt.plot(profiles[432].norm, "r-") plt.plot(profiles[433].norm, "k-") plt.plot(profiles[434].norm, "b-") plt.show() The black line, which is for the troublesome fiber, undercuts the line for both the other fibers, at around the right place. Dividing by this deficit is causing an excess in the extracted spectrum. plt.plot(profiles[434].norm/profiles[433].norm, "k-") plt.show() Yes, there's the bump, peaking at 3945. constructFiberProfiles.py /scratch/pprice/pipe2d-693/fixed --calib=/scratch/pprice/pipe2d-693/fixed/CALIB --rerun=fiberProfiles --doraise --batch-type=smp --cores=10 --no-versions --clobber-config --id visit=37 butler = Butler("/scratch/pprice/pipe2d-693/fixed/rerun/fiberProfiles") exposure = butler.get("postISRCCD", visit=37, arm="b") profiles = FiberProfileSet.readFits("/scratch/pprice/pipe2d-693/fixed/rerun/fiberProfiles/FIBERPROFILES/pfsFiberProfiles-2020-01-01-000037-b1.fits") plt.plot(profiles[435].norm/profiles[433].norm, "k-") plt.show() The bump is gone now. Not sure why. Maybe I got some versions wrong? Let's re-run everything after checking the versions. (lsst-scipipe) pprice@tiger2-sumire:/scratch/pprice/pipe2d-693 $ $PFS_PIPE2D_DIR/weekly/process_weekly.sh -r pipe2d-693 -D /scratch/pprice/pipe2d-693/revised The bump is still there. constructFiberProfiles.py /scratch/pprice/pipe2d-693/revised --calib=/scratch/pprice/pipe2d-693/revised/CALIB --rerun=fiberProfiles --doraise --batch-type=smp --cores=10 --no-versions --clobber-config --id visit=35^37 arm=b combineFiberProfiles.py pfsFiberProfiles-2020-01-01-000000-b1.fits revised/rerun/fiberProfiles/FIBERPROFILES/pfsFiberProfiles-2020-01-01-00003*.fits Looks fine. Must be something to do with the timing of the construction of the profiles. Maybe the detectorMap? reduceArc.py is run after constructFiberProfiles.py, so the official profiles must be created using the original detectorMap, which is slightly off. Let's turn on doBlindFind. In fact, it's on by default. But the extraction of the spectra uses the old detectorMap, rather than the results of the blind find! Fix that. (lsst-scipipe) pprice@tiger2-sumire:/scratch/pprice/pipe2d-693 $ $PFS_PIPE2D_DIR/weekly/process_weekly.sh -r pipe2d-693 -D /scratch/pprice/pipe2d-693/fix2 The bump is gone! merged = butler.get("pfsMerged", blueId) merged.plot([433]) Good! There's something at y=209, at wavelength=389nm, which might be a bit bluer than we care about (<10% throughput). Increased profiles.centerFit.order=9 to get better fits to the traces and ran again as fix3. Ideally, we should fit a detectorMap and measure the profile at the same time (the detectorMap gives the best model of the traces, but the traces are used to extract the spectra, which is (currently) required to do line identification. Looking for red-blue differences > 3 sigma on this new dataset, we find: 151 160 160 0.004270502681566373 0.0003893999866585177 23 0.03895871326810748 0.0012311061697475381 30 There's a huge spike in the blue, which is due to a CR visible in the image. Ready to call this done. |
| Comment by price [ 19/Feb/21 ] |
|
Not a lot of changes, but enough to make the fluxes in the dichroic consistent. |
| Comment by price [ 20/Feb/21 ] |
|
Merged to master. |