Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0fba68d861+a3ea3d1d86,g1ec0fe41b4+e220e2fb2f,g1fd858c14a+120b017347,g35bb328faa+fcb1d3bbc8,g4d2262a081+bd92cbabc2,g53246c7159+fcb1d3bbc8,g56a49b3a55+8d793c2a3d,g60b5630c4e+4e8d433789,g67b6fd64d1+fad15079a7,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g8180f54f50+65cb53bb37,g8352419a5c+fcb1d3bbc8,g8852436030+ae791ba189,g89139ef638+fad15079a7,g9125e01d80+fcb1d3bbc8,g94187f82dc+4e8d433789,g989de1cb63+fad15079a7,g9ccd5d7f00+cce09d2c12,g9d31334357+4e8d433789,g9f33ca652e+323fd354f8,gabe3b4be73+1e0a283bba,gabf8522325+94c30d56e9,gb1101e3267+5e0f808207,gb58c049af0+f03b321e39,gb89ab40317+fad15079a7,gc0af124501+a88dc73679,gcf25f946ba+ae791ba189,gd6cbbdb0b4+8d7f1baacb,gdb1c4ca869+16879ca1a6,gde0f65d7ad+61e7a18ddf,ge1ad929117+4e8d433789,ge278dab8ac+4d6e48c014,ge35a86080c+6eff471efc,ge410e46f29+fad15079a7,gf5e32f922b+fcb1d3bbc8,gf618743f1b+8ff1364817,gf67bdafdda+fad15079a7,w.2025.17
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
lsst.meas.extensions.psfex.psfex Namespace Reference

Functions

 compute_fwhmrange (fwhm, maxvar, minin, maxin, plot=dict(fwhmHistogram=False))
 
 select_candidates (set, prefs, frmin, frmax, flags, flux, fluxerr, rmsSize, elong, vignet, plot=dict(), title="")
 
 showPsf (psf, set, ext=None, wcsData=None, trim=0, nspot=5, diagnostics=False, outDir="", frame=None, title=None)
 
 getFlags (tab=None)
 
 guessCalexp (fileName)
 
 makeitLsst (prefs, context, saveWcs=False, plot=dict())
 
 read_samplesLsst (prefs, set, filename, frmin, frmax, ext, next, catindex, context, pcval, nobj, plot=dict(showFlags=False, showRejection=False))
 
 load_samplesLsst (prefs, context, ext=psfexLib.Prefs.ALL_EXTENSIONS, next=1, plot=dict())
 

Variables

 plt = None
 

Function Documentation

◆ compute_fwhmrange()

lsst.meas.extensions.psfex.psfex.compute_fwhmrange ( fwhm,
maxvar,
minin,
maxin,
plot = dict(fwhmHistogram=False) )
Compute the FWHM range associated to a series of FWHM measurements.
    AUTHOR  E. Bertin (IAP, Leiden observatory & ESO)
    VERSION 20/03/2008

Parameters
----------
fwhm: iterable of `float`
    Iterable of full width half-maxima.
maxvar: `float`
    Maximum allowed FWHM variation.
minin: `float`
    Minimum allowed FWHM.
maxin: `float`
    Maximum allowed FWHM.
plot: `dict`, optional
    Dict of plotting options.

Returns
-------
fmin: `float`
    FWHM mode.
minout: `float`
    Lower FWHM range.
maxout: `float`
    Upper FWHM range.

Definition at line 43 of file psfex.py.

43def compute_fwhmrange(fwhm, maxvar, minin, maxin, plot=dict(fwhmHistogram=False)):
44 """Compute the FWHM range associated to a series of FWHM measurements.
45 AUTHOR E. Bertin (IAP, Leiden observatory & ESO)
46 VERSION 20/03/2008
47
48 Parameters
49 ----------
50 fwhm: iterable of `float`
51 Iterable of full width half-maxima.
52 maxvar: `float`
53 Maximum allowed FWHM variation.
54 minin: `float`
55 Minimum allowed FWHM.
56 maxin: `float`
57 Maximum allowed FWHM.
58 plot: `dict`, optional
59 Dict of plotting options.
60
61 Returns
62 -------
63 fmin: `float`
64 FWHM mode.
65 minout: `float`
66 Lower FWHM range.
67 maxout: `float`
68 Upper FWHM range.
69 """
70
71 nfwhm = len(fwhm)
72 fwhm.sort()
73
74 # Find the mode
75 nw = nfwhm//4
76 if nw < 4:
77 nw = 1
78 dfmin = psfexLib.BIG
79 fmin = 0.0
80 for i in range(nfwhm - nw):
81 df = fwhm[i + nw] - fwhm[i]
82 if df < dfmin:
83 dfmin = df
84 fmin = (fwhm[i + nw] + fwhm[i])/2.0
85
86 if nfwhm < 2:
87 fmin = fwhm[0]
88
89 dfmin = (maxvar + 1.0)**0.3333333
90 minout = fmin/dfmin if dfmin > 0.0 else 0.0
91 if minout < minin:
92 minout = minin
93
94 maxout = fmin*dfmin**2
95 if maxout > maxin:
96 maxout = maxin
97
98 if plt and plot.get("fwhmHistogram"):
99 plt.clf()
100 plt.hist(fwhm, nfwhm//10 + 1, normed=1, facecolor='g', alpha=0.75)
101 plt.xlabel("FWHM")
102 plt.axvline(fmin, color='red')
103 [plt.axvline(_, color='blue') for _ in (minout, maxout)]
104
105 input("Continue? ")
106
107 return fmin, minout, maxout
108
109

◆ getFlags()

lsst.meas.extensions.psfex.psfex.getFlags ( tab = None)

Definition at line 307 of file psfex.py.

307def getFlags(tab=None):
308 flagKeys = [
309 "base_PixelFlags_flag_edge",
310 "base_PixelFlags_flag_nodata",
311 # "base_PixelFlags_flag_interpolated",
312 # "base_PixelFlags_flag_interpolatedCenter",
313 # "base_PixelFlags_flag_saturated",
314 "base_PixelFlags_flag_saturatedCenter",
315 # "base_PixelFlags_flag_cr",
316 "base_PixelFlags_flag_crCenter",
317 "base_PixelFlags_flag_bad",
318 "base_PsfFlux_flag",
319 "parent",
320 ]
321
322 if tab is None:
323 flags = {}
324 for i, k in enumerate(flagKeys):
325 flags[1 << i] = re.sub(r"\_flag", "",
326 re.sub(r"^base\_", "", re.sub(r"^base\_PixelFlags\_flag\_", "", k)))
327 else:
328 flags = 0
329 for i, k in enumerate(flagKeys):
330 if k == "parent":
331 try:
332 isSet = tab.get("deblend_nChild") > 0
333 except KeyError:
334 isSet = 0
335 else:
336 isSet = tab.get(k)
337 flags = np.bitwise_or(flags, np.where(isSet, 1 << i, 0))
338
339 return flags
340
341

◆ guessCalexp()

lsst.meas.extensions.psfex.psfex.guessCalexp ( fileName)

Definition at line 342 of file psfex.py.

342def guessCalexp(fileName):
343 for guess in [
344 re.sub("/src", r"", fileName),
345 re.sub("(SRC([^.]+))", r"CORR\2-exp", fileName),
346 ]:
347 if guess != fileName and os.path.exists(guess):
348 return guess
349
350 raise RuntimeError("Unable to find a calexp to go with %s" % fileName)
351
352

◆ load_samplesLsst()

lsst.meas.extensions.psfex.psfex.load_samplesLsst ( prefs,
context,
ext = psfexLib.Prefs.ALL_EXTENSIONS,
next = 1,
plot = dict() )

Definition at line 544 of file psfex.py.

544def load_samplesLsst(prefs, context, ext=psfexLib.Prefs.ALL_EXTENSIONS, next=1, plot=dict()):
545 minsn = prefs.getMinsn()
546 maxelong = (prefs.getMaxellip() + 1.0)/(1.0 - prefs.getMaxellip()) if prefs.getMaxellip() < 1.0 else 100
547 min = prefs.getFwhmrange()[0]
548 max = prefs.getFwhmrange()[1]
549
550 filenames = prefs.getCatalogs()
551
552 ncat = len(filenames)
553 fwhmmin = np.empty(ncat)
554 fwhmmax = np.empty(ncat)
555
556 if not prefs.getAutoselectFlag():
557 fwhmmin = np.zeros(ncat) + prefs.getFwhmrange()[0]
558 fwhmmax = np.zeros(ncat) + prefs.getFwhmrange()[1]
559 fwhmmode = (fwhmmin + fwhmmax)/2.0
560 else:
561 fwhms = {}
562
563 # -- Try to estimate the most appropriate Half-light Radius range
564 # -- Get the Half-light radii
565 nobj = 0
566 for i, fileName in enumerate(filenames):
567 fwhms[i] = []
568
569 if prefs.getVerboseType() != prefs.QUIET:
570 print("Examining Catalog #%d" % (i+1))
571
572 # ---- Read input catalog
573 tab = afwTable.SourceCatalog.readFits(fileName)
574
575 # -------- Fill the FWHM array
576 shape = tab.getShapeDefinition()
577 ixx = tab.get("%s.xx" % shape)
578 iyy = tab.get("%s.yy" % shape)
579
580 rmsSize = np.sqrt(0.5*(ixx + iyy))
581 elong = 0.5*(ixx - iyy)/(ixx + iyy)
582
583 flux = tab.get(prefs.getPhotfluxRkey())
584 fluxErr = tab.get(prefs.getPhotfluxerrRkey())
585
586 flags = getFlags(tab)
587
588 good = np.logical_and(flux/fluxErr > minsn,
589 np.logical_not(flags & prefs.getFlagMask()))
590 good = np.logical_and(good, elong < maxelong)
591 fwhm = 2.0*rmsSize
592 good = np.logical_and(good, fwhm >= min)
593 good = np.logical_and(good, fwhm < max)
594 fwhms[i] = fwhm[good]
595
596 if prefs.getVarType() == prefs.VAR_NONE:
597 if nobj:
598 fwhms_all = np.empty(sum([len(f) for f in fwhms.values()]))
599 i = 0
600 for f in fwhms.values():
601 fwhms_all[i:len(f)] = f
602 i += len(f)
603 mode, min, max = compute_fwhmrange(fwhms_all, prefs.getMaxvar(),
604 prefs.getFwhmrange()[0], prefs.getFwhmrange()[1],
605 plot=plot)
606 else:
607 raise RuntimeError("No source with appropriate FWHM found!!")
608 mode = min = max = 2.35/(1.0 - 1.0/psfexLib.cvar.INTERPFAC)
609
610 fwhmmin = np.zeros(ncat) + min
611 fwhmmax = np.zeros(ncat) + max
612 fwhmmode = np.zeros(ncat) + mode
613 else:
614 fwhmmode = np.empty(ncat)
615 fwhmmin = np.empty(ncat)
616 fwhmmax = np.empty(ncat)
617
618 for i in range(ncat):
619 nobj = len(fwhms[i])
620 if (nobj):
621 fwhmmode[i], fwhmmin[i], fwhmmax[i] = \
622 compute_fwhmrange(fwhms[i], prefs.getMaxvar(),
623 prefs.getFwhmrange()[0], prefs.getFwhmrange()[1], plot=plot)
624 else:
625 raise RuntimeError("No source with appropriate FWHM found!!")
626 fwhmmode[i] = fwhmmin[i] = fwhmmax[i] = 2.35/(1.0 - 1.0/psfexLib.cvar.INTERPFAC)
627
628 # Read the samples
629 mode = psfexLib.BIG # mode of FWHM distribution
630
631 sets = []
632 for i, fileName in enumerate(filenames):
633 set = None
634 for ext in range(next):
635 set = read_samplesLsst(prefs, set, fileName, fwhmmin[i]/2.0, fwhmmax[i]/2.0,
636 ext, next, i, context,
637 context.getPc(i) if context.getNpc() else None, nobj, plot=plot)
638
639 if fwhmmode[i] < mode:
640 mode = fwhmmode[i]
641
642 set.setFwhm(mode)
643
644 if prefs.getVerboseType() != prefs.QUIET:
645 if set.getNsample():
646 print("%d samples loaded." % set.getNsample())
647 else:
648 raise RuntimeError("No appropriate source found!!")
649
650 sets.append(set)
651
652 return sets

◆ makeitLsst()

lsst.meas.extensions.psfex.psfex.makeitLsst ( prefs,
context,
saveWcs = False,
plot = dict() )
This is the python wrapper that reads lsst tables

Definition at line 353 of file psfex.py.

353def makeitLsst(prefs, context, saveWcs=False, plot=dict()):
354 """This is the python wrapper that reads lsst tables
355 """
356 # Create an array of PSFs (one PSF for each extension)
357 if prefs.getVerboseType() != prefs.QUIET:
358 print("----- %d input catalogues:" % prefs.getNcat())
359
360 if saveWcs: # only needed for making plots
361 wcssList = []
362
363 fields = psfexLib.vectorField()
364 for cat in prefs.getCatalogs():
365 field = psfexLib.Field(cat)
366 wcss = []
367 wcssList.append(wcss)
368 with fits.open(cat):
369 # Hack: I want the WCS so I'll guess where the calexp is to be
370 # found
371 calexpFile = guessCalexp(cat)
372 md = readMetadata(calexpFile)
373 wcs = afwGeom.makeSkyWcs(md)
374
375 if not wcs:
376 cdMatrix = np.array([1.0, 0.0, 0.0, 1.0])
377 cdMatrix.shape = (2, 2)
378 wcs = afwGeom.makeSkyWcs(crpix=geom.PointD(0, 0),
379 crval=geom.SpherePoint(0.0, 0.0, geom.degrees),
380 cdMatrix=cdMatrix)
381
382 naxis1, naxis2 = md.getScalar("NAXIS1"), md.getScalar("NAXIS2")
383 # Find how many rows there are in the catalogue
384 md = readMetadata(cat)
385
386 field.addExt(wcs, naxis1, naxis2, md.getScalar("NAXIS2"))
387 if saveWcs:
388 wcss.append((wcs, naxis1, naxis2))
389
390 field.finalize()
391 fields.append(field)
392
393 fields[0].getNext() # number of extensions
394
395 prefs.getPsfStep()
396
397 sets = psfexLib.vectorSet()
398 for set in load_samplesLsst(prefs, context, plot=plot):
399 sets.append(set)
400
401 psfexLib.makeit(fields, sets)
402
403 ret = [[f.getPsfs() for f in fields], sets]
404 if saveWcs:
405 ret.append(wcssList)
406
407 return ret
408
409
Point in an unspecified spherical coordinate system.
Definition SpherePoint.h:57
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
Definition SkyWcs.cc:521

◆ read_samplesLsst()

lsst.meas.extensions.psfex.psfex.read_samplesLsst ( prefs,
set,
filename,
frmin,
frmax,
ext,
next,
catindex,
context,
pcval,
nobj,
plot = dict(showFlags=False, showRejection=False) )

Definition at line 410 of file psfex.py.

411 plot=dict(showFlags=False, showRejection=False)):
412 # allocate a new set iff set is None
413 if not set:
414 set = psfexLib.Set(context)
415
416 cmin, cmax = None, None
417 if set.getNcontext():
418 cmin = np.empty(set.getNcontext())
419 cmax = np.empty(set.getNcontext())
420 for i in range(set.getNcontext()):
421 if set.getNsample():
422 cmin[i] = set.getContextOffset(i) - set.getContextScale(i)/2.0
423 cmax[i] = cmin[i] + set.getContextScale(i)
424 else:
425 cmin[i] = psfexLib.BIG
426 cmax[i] = -psfexLib.BIG
427 #
428 # Read data
429 #
430 tab = afwTable.SourceCatalog.readFits(filename)
431
432 centroid = tab.getCentroidDefinition()
433 xm = tab.get("%s.x" % centroid)
434 ym = tab.get("%s.y" % centroid)
435
436 shape = tab.getShapeDefinition()
437 ixx = tab.get("%s.xx" % shape)
438 iyy = tab.get("%s.yy" % shape)
439
440 rmsSize = np.sqrt(0.5*(ixx + iyy))
441 elong = 0.5*(ixx - iyy)/(ixx + iyy)
442
443 flux = tab.get(prefs.getPhotfluxRkey())
444 fluxErr = tab.get(prefs.getPhotfluxerrRkey())
445 flags = getFlags(tab)
446
447 #
448 # Now the VIGNET data
449 #
450 vigw, vigh = 35, 35 # [prefs.getPsfsize()[i] for i in range(2)]
451 if set.empty():
452 set.setVigSize(vigw, vigh)
453
454 vignet = np.empty(nobj*vigw*vigh, "float32").reshape(nobj, vigw, vigh)
455
456 # Hack: I want the WCS so I'll guess where the calexp is to be found
457 calexpFile = guessCalexp(filename)
458 mi = afwImage.MaskedImageF(calexpFile)
459 backnoise2 = np.median(mi.getVariance().getArray())
460 gain = 1.0
461
462 edgeBit = [k for k, v in getFlags().items() if v == "edge"][0]
463
464 for i, xc, yc in zip(range(nobj), xm, ym):
465 try:
466 x, y = int(xc), int(yc)
467 except ValueError:
468 flags[i] |= edgeBit # mark star as bad
469
470 try:
471 pstamp = mi[x - vigw//2:x + vigw//2 + 1, y - vigh//2:y + vigh//2 + 1]
472 vignet[i] = pstamp.getImage().getArray().transpose()
473 except Exception:
474 flags[i] |= edgeBit # mark star as bad
475
476 # Try to load the set of context keys
477 pc = 0
478 contextvalp = []
479 for i, key in enumerate(context.getName()):
480 if context.getPcflag(i):
481 contextvalp.append(pcval[pc])
482 pc += 1
483 elif key[0] == ':':
484 try:
485 contextvalp.append(tab.header[key[1:]])
486 except KeyError:
487 raise RuntimeError("*Error*: %s parameter not found in the header of %s" %
488 (key[1:], filename))
489 else:
490 try:
491 contextvalp.append(tab.get(key))
492 except KeyError:
493 raise RuntimeError("*Error*: %s parameter not found in the header of %s" %
494 (key, filename))
495 set.setContextname(i, key)
496
497 # Now examine each vector of the shipment
498 good = select_candidates(set, prefs, frmin, frmax,
499 flags, flux, fluxErr, rmsSize, elong, vignet,
500 plot=plot, title="%s[%d]" % (filename, ext + 1) if next > 1 else filename)
501 #
502 # Insert the good candidates into the set
503 #
504 if not vignet.dtype.isnative:
505 # without the swap setVig fails with
506 # "ValueError: 'unaligned arrays cannot be converted to C++'"
507 vignet = vignet.byteswap()
508
509 for i in np.where(good)[0]:
510 sample = set.newSample()
511 sample.setCatindex(catindex)
512 sample.setExtindex(ext)
513
514 sample.setVig(vignet[i])
515 sample.setNorm(float(flux[i]))
516 sample.setBacknoise2(backnoise2)
517 sample.setGain(gain)
518 sample.setX(float(xm[i]))
519 sample.setY(float(ym[i]))
520 sample.setFluxrad(float(rmsSize[i]))
521
522 for j in range(set.getNcontext()):
523 sample.setContext(j, float(contextvalp[j][i]))
524
525 set.finiSample(sample, prefs.getProfAccuracy())
526
527 # ---- Update min and max
528 for j in range(set.getNcontext()):
529 cmin[j] = contextvalp[j][good].min()
530 cmax[j] = contextvalp[j][good].max()
531
532 # Update the scaling
533 if set.getNsample():
534 for i in range(set.getNcontext()):
535 set.setContextScale(i, cmax[i] - cmin[i])
536 set.setContextOffset(i, (cmin[i] + cmax[i])/2.0)
537
538 # Don't waste memory!
539 set.trimMemory()
540
541 return set
542
543

◆ select_candidates()

lsst.meas.extensions.psfex.psfex.select_candidates ( set,
prefs,
frmin,
frmax,
flags,
flux,
fluxerr,
rmsSize,
elong,
vignet,
plot = dict(),
title = "" )

Definition at line 110 of file psfex.py.

112 plot=dict(), title=""):
113 maxbad = prefs.getBadpixNmax()
114 maxbadflag = prefs.getBadpixFlag()
115 maxelong = (prefs.getMaxellip() + 1.0)/(1.0 - prefs.getMaxellip()) if prefs.getMaxellip() < 1.0 else 100.0
116 minsn = prefs.getMinsn()
117
118 sn = flux/np.where(fluxerr > 0, fluxerr, 1)
119 sn[fluxerr <= 0] = -psfexLib.BIG
120 # ---- Apply some selection over flags, fluxes...
121 plotFlags = plot.get("showFlags") if plt else False
122 plotRejection = plot.get("showRejection") if plt else False
123
124 bad = flags & prefs.getFlagMask() != 0
125 set.setBadFlags(int(sum(bad != 0)))
126
127 if plotRejection:
128 selectionVectors = []
129 selectionVectors.append((bad, "flags %d" % sum(bad != 0)))
130
131 dbad = sn < minsn
132 set.setBadSN(int(sum(dbad)))
133 bad = np.logical_or(bad, dbad)
134 if plotRejection:
135 selectionVectors.append((dbad, "S/N %d" % sum(dbad)))
136
137 dbad = rmsSize < frmin
138 set.setBadFrmin(int(sum(dbad)))
139 bad = np.logical_or(bad, dbad)
140 if plotRejection:
141 selectionVectors.append((dbad, "frmin %d" % sum(dbad)))
142
143 dbad = rmsSize > frmax
144 set.setBadFrmax(int(sum(dbad)))
145 bad = np.logical_or(bad, dbad)
146 if plotRejection:
147 selectionVectors.append((dbad, "frmax %d" % sum(dbad)))
148
149 dbad = elong > maxelong
150 set.setBadElong(int(sum(dbad)))
151 bad = np.logical_or(bad, dbad)
152 if plotRejection:
153 selectionVectors.append((dbad, "elong %d" % sum(dbad)))
154
155 # -- ... and check the integrity of the sample
156 if maxbadflag:
157 nbad = np.array([(v <= -psfexLib.BIG).sum() for v in vignet])
158 dbad = nbad > maxbad
159 set.setBadPix(int(sum(dbad)))
160 bad = np.logical_or(bad, dbad)
161 if plotRejection:
162 selectionVectors.append((dbad, "badpix %d" % sum(dbad)))
163
164 good = np.logical_not(bad)
165 if plotFlags or plotRejection:
166 imag = -2.5*np.log10(flux)
167 plt.clf()
168
169 alpha = 0.5
170 if plotFlags:
171 labels = getFlags()
172
173 isSet = np.where(flags == 0x0)[0]
174 plt.plot(imag[isSet], rmsSize[isSet], 'o', alpha=alpha, label="good")
175
176 for i in range(16):
177 mask = 1 << i
178 if mask & prefs.getFlagMask():
179 isSet = np.where(np.bitwise_and(flags, mask))[0]
180 if isSet.any():
181 plt.plot(imag[isSet], rmsSize[isSet], 'o', alpha=alpha, label=labels[mask])
182 else:
183 for bad, label in selectionVectors:
184 plt.plot(imag[bad], rmsSize[bad], 'o', alpha=alpha, label=label)
185
186 plt.plot(imag[good], rmsSize[good], 'o', color="black", label="selected")
187 [plt.axhline(_, color='red') for _ in [frmin, frmax]]
188 plt.xlim(np.median(imag[good]) + 5*np.array([-1, 1]))
189 plt.ylim(-0.1, 2*frmax)
190 plt.legend(loc=2)
191 plt.xlabel("Instrumental Magnitude")
192 plt.ylabel("rmsSize")
193 plt.title("%s %d selected" % (title, sum(good)))
194
195 input("Continue? ")
196
197 return good
198
199

◆ showPsf()

lsst.meas.extensions.psfex.psfex.showPsf ( psf,
set,
ext = None,
wcsData = None,
trim = 0,
nspot = 5,
diagnostics = False,
outDir = "",
frame = None,
title = None )
Show a PSF on display (e.g., ds9)

Definition at line 200 of file psfex.py.

201 diagnostics=False, outDir="", frame=None, title=None):
202 """Show a PSF on display (e.g., ds9)
203 """
204
205 if ext is not None:
206 psf = psf[ext]
207
208 if wcsData:
209 if ext is not None:
210 wcsData = wcsData[ext]
211 wcs, naxis1, naxis2 = wcsData
212 else:
213 wcs, naxis1, naxis2 = None, None, None
214
215 naxis = [naxis1, naxis2]
216 for i in range(2):
217 if naxis[i] is None:
218 # cmin, cmax are the range of input star positions
219 cmin, cmax = [set.getContextOffset(i) + d*set.getContextScale(i) for d in (-0.5, 0.5)]
220 naxis[i] = cmax + cmin # a decent guess
221
222 if naxis[0] > naxis[1]:
223 nx, ny = int(nspot*naxis[0]/float(naxis[1]) + 0.5), nspot
224 else:
225 nx, ny = nspot, int(nspot*naxis[1]/float(naxis[0]) + 0.5)
226
227 mos = afwDisplay.utils.Mosaic(gutter=2, background=0.02)
228
229 xpos, ypos = np.linspace(0, naxis[0], nx), np.linspace(0, naxis[1], ny)
230 for y in ypos:
231 for x in xpos:
232 psf.build(x, y)
233
234 im = afwImage.ImageF(*psf.getLoc().shape)
235 im.getArray()[:] = psf.getLoc()
236 im /= float(im.getArray().max())
237 if trim:
238 if trim > im.getHeight()//2:
239 trim = im.getHeight()//2
240
241 im = im[trim:-trim, trim:-trim]
242
243 mos.append(im)
244
245 mosaic = mos.makeMosaic(mode=nx)
246 if frame is not None:
247 afwDisplay.Display(frame=frame).mtv(mosaic, title=title)
248 #
249 # Figure out the WCS for the mosaic
250 #
251 pos = []
252 pos.append([geom.PointD(0, 0), wcs.pixelToSky(geom.PointD(0, 0))])
253 pos.append([geom.PointD(*mosaic.getDimensions()), wcs.pixelToSky(geom.PointD(naxis1, naxis2))])
254
255 CD = []
256 for i in range(2):
257 delta = pos[1][1][i].asDegrees() - pos[0][1][i].asDegrees()
258 CD.append(delta/(pos[1][0][i] - pos[0][0][i]))
259 CD = np.array(CD)
260 CD.shape = (2, 2)
261 mosWcs = afwGeom.makeSkyWcs(crval=pos[0][0], crpix=pos[0][1], cdMatrix=CD)
262
263 if ext is not None:
264 title = "%s-%d" % (title, ext)
265
266 if frame is not None:
267 afwDisplay.Display(frame=frame).mtv(mosaic, title=title, wcs=mosWcs)
268
269 if diagnostics:
270 outFile = "%s-mod.fits" % title
271 if outDir:
272 outFile = os.path.join(outDir, outFile)
273 mosaic.writeFits(outFile, mosWcs.getFitsMetadata())
274
275 mos = afwDisplay.utils.Mosaic(gutter=4, background=0.002)
276 for i in range(set.getNsample()):
277 s = set.getSample(i)
278 if ext is not None and s.getExtindex() != ext:
279 continue
280
281 smos = afwDisplay.utils.Mosaic(gutter=2, background=-0.003)
282 for func in [s.getVig, s.getVigResi]:
283 arr = func()
284 if func == s.getVig:
285 norm = float(arr.max()) if True else s.getNorm()
286
287 arr /= norm
288 im = afwImage.ImageF(*arr.shape)
289 im.getArray()[:] = arr
290 smos.append(im)
291
292 mos.append(smos.makeMosaic(mode="x"))
293
294 mosaic = mos.makeMosaic(title=title)
295
296 if frame is not None:
297 afwDisplay.Display(frame=frame + 1).mtv(mosaic, title=title)
298
299 if diagnostics:
300 outFile = "%s-psfstars.fits" % title
301 if outDir:
302 outFile = os.path.join(outDir, outFile)
303
304 mosaic.writeFits(outFile)
305
306

Variable Documentation

◆ plt

lsst.meas.extensions.psfex.psfex.plt = None

Definition at line 30 of file psfex.py.