def test_defocus(): radius = 6.5/2 lyot_radius = 6.5/2.5 waves = [0, 0.5, 1, 2, 4, 8] nsteps = len(waves) plt.clf() fig, axarr = plt.subplots(1,nsteps, squeeze=True, num=1) psfs = [] #for nwaves in range(nsteps): for i, nwaves in enumerate(waves): osys = poppy.OpticalSystem("test", oversample=2) osys.addPupil('Circle', radius=radius) lens =poppy.ThinLens(nwaves=nwaves, reference_wavelength=1e-6) osys.addPupil(optic=lens) osys.addDetector(pixelscale=0.010, fov_arcsec=10.0) psf = osys.calcPSF(wavelength=1e-6) psfs.append(psf) norm = matplotlib.colors.LogNorm(vmin=1e-8, vmax=1e-4) poppy.imshow_with_mouseover(psf[0].data, ax=axarr[i], norm=norm ) axarr[i].set_title('%.1f waves defocus' % nwaves) #wf = osys.inputWavefront() #wf2 = wf * osys.planes[0] #wf3 = wf2* osys.planes[1] stop()
def do_test_10_multiproc(self): # for the sake of a reasonably realistic usage case, we use the BLC setup from Test 9 kind = 'circular' radius = 6.5/2 lyot_radius = 6.5/2.5 osys = poppy.OpticalSystem("test", oversample=self.oversample) osys.addPupil('Circle', radius=radius) osys.addImage() osys.addImage('BandLimitedCoron', kind=kind, sigma=5.0) osys.addPupil() osys.addPupil('Circle', radius=lyot_radius) osys.addDetector(pixelscale=self.pixelscale, fov_arcsec=5.0) osys.source_offset_r = 1.5 # make the PSF easy to see... nlam= 6 source = {'weights': [0.1]*nlam, 'wavelengths': np.linspace(2.0e-6, 3.0e-6, nlam)} _log.info("Calculating multiprocess PSF") times = [] times.append(time.time()) psf2 = osys.calcPSFmultiproc(source) times.append(time.time()) tmulti = times[-1]-times[-2] _log.info(" Time for multiprocessor: %f s " % (tmulti)) _log.info("Calculating single process PSF") times.append(time.time()) psf1 = osys.calcPSF(source['wavelengths'], source['weights']) times.append(time.time()) tsing = times[-1]-times[-2] _log.info(" Time for single processor: %f s " % (tsing)) _log.info(" Speedup factor: %f " % (tsing/tmulti)) plt.clf() ax = plt.subplot(1,3,1) webbpsf.display_PSF(psf1) ax = plt.subplot(1,3,2) webbpsf.display_PSF(psf2) ax = plt.subplot(1,3,3) poppy.imshow_with_mouseover(psf1[0].data - psf2[0].data, ax=ax) self.assertTrue( (psf1[0].data == psf2[0].data).all() ) _log.info("Exact same result achieved both ways.")
def test_thinlens(self): radius = 6.5/2 lyot_radius = 6.5/2.5 nsteps = 5 plt.clf() fig, axarr = plt.subplots(1,nsteps, squeeze=True, num=1) psfs = [] for nwaves in range(nsteps): osys = poppy.OpticalSystem("test", oversample=self.oversample) osys.addPupil('Circle', radius=radius) osys.addPupil(optic=poppy.ThinLens(nwaves=nwaves, reference_wavelength=self.wavelength)) osys.addDetector(pixelscale=self.pixelscale, fov_arcsec=5.0) psf = osys.calcPSF(wavelength=self.wavelength) psfs.append(psf) norm = matplotlib.colors.LogNorm(vmin=1e-8, vmax=1e-4) poppy.imshow_with_mouseover(psf[0].data, ax=axarr[nwaves], norm=norm) # FIXME need evaluation here. stop()
def validate_vs_krist_sims(clobber=False, normalize=False, which='spot', no_sam=False): """ Compare with PSFs provided by John Krist """ if which=='spot': image_mask = 'MASK430R' pupil_mask = 'CIRCLYOT' else: image_mask = 'MASKLWB' pupil_mask = 'WEDGELYOT' P.subplots_adjust(left=0.07, right=0.95, top=0.9, bottom=0.05) nc = webbpsf_core.NIRCam() nc.pupilopd=None nc.filter = 'F460M' nc.image_mask = image_mask nc.pupil_mask = pupil_mask nc.options['no_sam'] = no_sam nc.pixelscale = 0.065 # match the Krist sims exacly. vs 0.648 official cor_vmin = 1e-12 cor_vmax=1e-5 P.clf() fig = P.gcf() fig.text(0.2, 0.95, 'Krist', horizontalalignment='center', size=18) fig.text(0.50, 0.95, 'Perrin', horizontalalignment='center', size=18) fig.text(0.80, 0.95, 'Difference P-K', horizontalalignment='center', size=18) fig.text(0.05, 1./6, 'off-axis 4.6$\mu$m', verticalalignment='center', rotation='vertical' , size=18) fig.text(0.05, 0.48, 'occulted 4.6$\mu$m', verticalalignment='center', rotation='vertical' , size=18) fig.text(0.05, 5./6-0.05, image_mask + ' occulter', verticalalignment='center', rotation='vertical' , size=18) P.subplot(331) mask1 = 'nircam_4600nm_%s_occ.fits' % which mask1f = fits.open(mask1) poppy.display_PSF(mask1f, title="", pixelscale='PIXSIZE', vmin=0, vmax=1, scale='linear', cmap=matplotlib.cm.gray) P.subplot(332) os = nc._get_optical_system() os.planes[1].display(ax=P.gca(), what='intensity', colorbar_orientation='vertical') P.gca().set_title('') P.gca().set_xbound(-8,8) P.gca().set_ybound(-8,8) wf = poppy.Wavefront(wavelength=4.6e-6, npix = mask1f[0].data.shape[0], pixelscale = mask1f[0].header['PIXSIZE']) trans = os.planes[1].getPhasor(wf)**2 P.subplot(333) if normalize: to_plot = (trans-mask1f[0].data) / (trans+mask1f[0].data)/2 vmin, vmax = -1, 1 else: to_plot = (trans-mask1f[0].data) vmin, vmax = -1e-3, 1e-3 poppy.imshow_with_mouseover(to_plot, cmap=matplotlib.cm.gray, vmin=vmin, vmax=vmax, extent=[-8, 8, -8, 8]) P.colorbar(P.gca().images[0], orientation='vertical') try: fits.PrimaryHDU(trans).writeto('test_nircam_4600nm_%s_occ.fits' % which, clobber=clobber) except: pass #---- occulted -- P.subplot(334) k1 = 'nircam_4600nm_%s.fits' % which k1f = fits.open(k1) print("Total of %s is %f" % (k1, k1f[0].data.sum())) poppy.display_PSF(k1f, title="", pixelscale='SAMPLING', vmin=cor_vmin, vmax=cor_vmax) P.subplot(335) my1 = 'test_'+k1 mypsf1 = webbpsf_core.calc_or_load_psf('test_'+k1, nc, nlambda=1,monochromatic=4.6e-6, oversample=4, fov_pixels=247, clobber=clobber) print("Total of %s is %f" % (my1, mypsf1[0].data.sum())) #nc.calcPSF(nlambda=1) poppy.display_PSF(mypsf1, ext=1, title="", adjust_for_oversampling=True, vmin=cor_vmin, vmax=cor_vmax) P.subplot(336) poppy.display_PSF_difference( mypsf1, k1f, ext2=0, ext1=1, title="", vmax=1e-7, normalize=normalize) #---- unocculted -- P.subplot(337) k2 = 'nircam_4600nm_%s_fieldpsf.fits' % which k2f = fits.open(k2) poppy.display_PSF(k2f, title="", pixelscale='SAMPLING') print("Total of %s is %f" % (k2, k2f[0].data.sum())) nc.image_mask = None # make a coronagraphic-off-axis type PSF but still on-axis in the array my2 = 'test_'+k2 mypsf2 = webbpsf_core.calc_or_load_psf('test_'+k2, nc, nlambda=1, monochromatic=4.6e-6, oversample=4, fov_pixels=247, clobber=clobber) P.subplot(338) poppy.display_PSF(mypsf2, title="", ext=1, adjust_for_oversampling=True) print("Total of %s is %f" % (my2, mypsf2[0].data.sum())) P.subplot(339) poppy.display_PSF_difference( mypsf2, k2f, ext2=0, ext1=1, title="", vmax=1e-5, normalize=normalize) print("shape of %s is %s" % (k1, k1f[0].data.shape)) print("shape of %s is %s" % (my1, mypsf1[1].data.shape)) P.savefig('results_nircam_coron_comparison_%s.pdf' % which) stop()
def display_PSF(HDUlist_or_filename=None, ext=0, vmin=1e-8,vmax=1e-1, scale='log', cmap = matplotlib.cm.jet, title=None, imagecrop=None, adjust_for_oversampling=False, normalize='None', crosshairs=False, markcentroid=False, colorbar=True, colorbar_orientation='vertical', pixelscale='PIXELSCL', ax=None, return_ax=False): """Display nicely a PSF from a given HDUlist or filename This is extensively configurable. In addition to making an attractive display, for interactive usage this function provides a live display of the pixel value at a given (x,y) as you mouse around the image. Parameters ---------- HDUlist_or_filename : pyfits.HDUlist or string FITS file containing image to display. ext : int FITS extension. default = 0 vmin, vmax : float min and max for image display scaling scale : str 'linear' or 'log', default is log cmap : matplotlib.cm.Colormap instance Colormap to use. Default is matplotlib.cm.jet ax : matplotlib.Axes instance Axes to display into. title : string, optional imagecrop : float size of region to display (default is whole image) normalize : string set to 'peak' to normalize peak intensity =1, or to 'total' to normalize total flux=1. Default is no normalization. adjust_for_oversampling : bool rescale to conserve surface brightness for oversampled PSFs? (making this True conserves surface brightness but not total flux) default is False, to conserve total flux. markcentroid : bool Draw a crosshairs at the image centroid location? Centroiding is computed with the JWST-standard moving box algorithm. colorbar : bool Draw a colorbar? colorbar_orientation : str either 'horizontal' or 'vertical'; default is vertical. pixelscale : str or float if str, interpreted as the FITS keyword name for the pixel scale in arcsec/pixels. if float, used as the pixelscale directly. """ if isinstance(HDUlist_or_filename, str): HDUlist = pyfits.open(HDUlist_or_filename) elif isinstance(HDUlist_or_filename, pyfits.HDUList): HDUlist = HDUlist_or_filename else: raise ValueError("input must be a filename or HDUlist") if adjust_for_oversampling: try: scalefactor = HDUlist[ext].header['OVERSAMP']**2 except: poppy._log.error("Could not determine oversampling scale factor; therefore NOT rescaling fluxes.") scalefactor=1 im = HDUlist[ext].data *scalefactor else: im = HDUlist[ext].data if normalize.lower() == 'peak': poppy._log.debug("Displaying image normalized to peak = 1") im /= im.max() elif normalize.lower() =='total': poppy._log.debug("Displaying image normalized to PSF total = 1") im /= im.sum() if scale == 'linear': norm=matplotlib.colors.Normalize(vmin=vmin, vmax=vmax) else: norm=matplotlib.colors.LogNorm(vmin=vmin, vmax=vmax) if type(pixelscale) is str: halffov = HDUlist[ext].header[pixelscale]*HDUlist[ext].data.shape[0]/2 else: try: pixelscale = float(pixelscale) except: poppy._log.warning("Provided pixelscale is neither float nor str; cannot use it. Using default=1 instead.") pixelscale = 1.0 halffov = pixelscale*HDUlist[ext].data.shape[0]/2 unit="arcsec" extent = [-halffov, halffov, -halffov, halffov] ax = poppy.imshow_with_mouseover( im ,extent=extent,cmap=cmap, norm=norm, ax=ax) if imagecrop is not None: halffov = min( (imagecrop/2, halffov)) ax.set_xbound(-halffov, halffov) ax.set_ybound(-halffov, halffov) if crosshairs: ax.axhline(0,ls=":", color='k') ax.axvline(0,ls=":", color='k') if title is None: try: fspec = "%s, %s" % (HDUlist[ext].header['INSTRUME'], HDUlist[ext].header['FILTER']) except: fspec= str(HDUlist_or_filename) title="PSF sim for "+fspec ax.set_title(title) if colorbar: cb = plt.colorbar(ax.images[0], ax=ax, orientation=colorbar_orientation) if scale.lower() =='log': ticks = np.logspace(np.log10(vmin), np.log10(vmax), np.log10(vmax/vmin)+1) if colorbar_orientation=='horizontal' and vmax==1e-1 and vmin==1e-8: ticks = [1e-8, 1e-6, 1e-4, 1e-2, 1e-1] # looks better cb.set_ticks(ticks) cb.set_ticklabels(ticks) if normalize.lower() == 'peak': cb.set_label('Intensity relative to peak pixel') else: cb.set_label('Fractional intensity per pixel') if markcentroid: poppy._log.info("measuring centroid to mark on plot...") ceny, cenx = measure_centroid(HDUlist, ext=ext, units='arcsec', relativeto='center', boxsize=20, threshhold=0.1) ax.plot(cenx, ceny, 'k+', markersize=15, markeredgewidth=1) poppy._log.info("centroid: (%f, %f) " % (cenx, ceny)) plt.draw() if return_ax: if colorbar: return (ax, cb) else: return ax
def display_PSF_difference(HDUlist_or_filename1=None, HDUlist_or_filename2=None, ext1=0, ext2=0, vmax=1e-4, title=None, imagecrop=None, adjust_for_oversampling=False, crosshairs=False, colorbar=True, colorbar_orientation='vertical', print_=False, ax=None, return_ax=False, vmin=None, normalize=False, normalize_to_second=False): """Display nicely the difference of two PSFs from given files Parameters ---------- HDUlist_or_filename1,2 : pyfits.HDUlist or string FITS files containing image to difference ext1, ext2 : int FITS extension. default = 0 vmax : float for the scaling title : string, optional imagecrop : float size of region to display (default is whole image) normalize : bool Display (difference image)/(mean image) instead of just the difference image. adjust_for_oversampling : bool rescale to conserve surface brightness for oversampled PSFs? (making this True conserves surface brightness but not total flux) default is False, to conserve total flux. """ if isinstance(HDUlist_or_filename1, str): HDUlist1 = pyfits.open(HDUlist_or_filename1) elif isinstance(HDUlist_or_filename1, pyfits.HDUList): HDUlist1 = HDUlist_or_filename1 else: raise ValueError("input must be a filename or HDUlist") if isinstance(HDUlist_or_filename2, str): HDUlist2 = pyfits.open(HDUlist_or_filename2) elif isinstance(HDUlist_or_filename2, pyfits.HDUList): HDUlist2 = HDUlist_or_filename2 else: raise ValueError("input must be a filename or HDUlist") if adjust_for_oversampling: scalefactor = HDUlist1[ext1].header['OVERSAMP']**2 im1 = HDUlist1[ext1].data *scalefactor scalefactor = HDUlist2[ext2].header['OVERSAMP']**2 im2 = HDUlist1[ext2].data *scalefactor else: im1 = HDUlist1[ext1].data im2 = HDUlist2[ext2].data diff_im = im1-im2 if normalize: avg_im = (im1+im2)/2 diff_im /= avg_im cbtitle = 'Image difference / average (per pixel)' #Relative intensity difference per pixel' if normalize_to_second: diff_im /= im2 cbtitle = 'Image difference / original (per pixel)' #Relative intensity difference per pixel' else: cbtitle = 'Intensity difference per pixel' if vmin is None: vmin = -vmax if print_: rms_diff = np.sqrt((diff_im**2).mean()) print "RMS of difference image: %f" % rms_diff norm=matplotlib.colors.Normalize(vmin=vmin, vmax=vmax) #print "Display range: ", vmin, vmax cmap = matplotlib.cm.gray halffov = HDUlist1[ext1].header['PIXELSCL']*HDUlist1[ext1].data.shape[0]/2 unit="arcsec" extent = [-halffov, halffov, -halffov, halffov] ax = poppy.imshow_with_mouseover( diff_im ,extent=extent,cmap=cmap, norm=norm, ax=ax) if imagecrop is not None: halffov = min( (imagecrop/2, halffov)) ax.set_xbound(-halffov, halffov) ax.set_ybound(-halffov, halffov) if crosshairs: ax.axhline(0,ls=":", color='k') ax.axvline(0,ls=":", color='k') if title is None: try: fspec= str(HDUlist_or_filename1) +"-"+str(HDUlist_or_filename2) #fspec = "Difference Image " # "%s, %s" % (HDUlist[ext].header['INSTRUME'], HDUlist[ext].header['FILTER']) except: fspec= str(HDUlist_or_filename1) +"-"+str(HDUlist_or_filename2) title="Difference of "+fspec ax.set_title(title) if colorbar: cb = plt.colorbar(ax.images[0], ax=ax, orientation=colorbar_orientation) #ticks = np.logspace(np.log10(vmin), np.log10(vmax), np.log10(vmax/vmin)+1) #if vmin == 1e-8 and vmax==1e-1: #ticks = [1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1] #ticks = [vmin, -0.5*vmax, 0, 0.5*vmax, vmax] #cb.set_ticks(ticks) #cb.set_ticklabels(ticks) #stop() cb.set_label(cbtitle) if return_ax: if colorbar: return (ax, cb) else: return ax