def test_resample2(): """Spectrum class: testing resampling function with a spectrum of integers and resampling to a smaller pixel size""" wave = WaveCoord(crpix=2.0, cdelt=3.0, crval=0.5, cunit=u.nm) spectrum1 = Spectrum(data=np.array([0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0]), wave=wave) flux1 = spectrum1.sum()[0] * spectrum1.wave.get_step() spectrum2 = spectrum1.resample(0.3) flux2 = spectrum2.sum()[0] * spectrum2.wave.get_step() assert_almost_equal(flux1, flux2, 2)
def residual(p, datacube=datacube, pos=None, specwidth=spectralpixel, galcen=galcen, galPA=galPA): par = p.valuesdict() incli = par['incli'] col_denst = par['col_dens'] h = par['height'] bes = par['dop_param'] v_max = par['vel_max'] h_vt = par['h_v'] csize = par['csize'] r_0t = par['r_0'] print(par) h_v = 10**h_vt col_dens = 10**col_denst r_0 = 10**r_0t coord_sky = datacube.wcs.pix2sky([int(pos[0]), int(pos[1])], unit=u.deg) dec = coord_sky[0][0] ra = coord_sky[0][1] c1 = SkyCoord(ra * u.degree, dec * u.degree, frame='icrs') flux = datacube[:, int(pos[0]), int(pos[1])] abso = flux.data[specwidth[0]:specwidth[1] + 1] sigma = np.sqrt(flux.var[specwidth[0]:specwidth[1] + 1]) scale = 7.28 # z=0.73379 # plat scale (kpc/") for Planck c1 = SkyCoord(ra * u.degree, dec * u.degree, frame='icrs') #D = scale * galcen.separation(c1).arcsec #pa = galcen.position_angle(c1).to(u.deg) #alpha = galPA - pa.value alpha = csu.get_alpha(c1, galcen, galPA) D = csu.get_impactparam(c1, galcen, scale) lam2 = np.arange(4825.12, 4886.37 + 1.5, 0.1) wave1 = WaveCoord(cdelt=0.1, crval=4825.12, cunit=u.angstrom) model = Disco(h, incli, Rcore=0.1) spec = model.averagelos(D, alpha, lam2, 100, 12, z, csize, col_dens, bes, r_0, v_max, h_v, 0) spe = Spectrum(wave=wave1, data=spec) rspe = spe.resample(1.25) fluxmodel = rspe.data absomodel = fluxmodel[specwidth[0]:specwidth[1] + 1] #ymodelt = np.concatenate((ymodel[0][14:36],ymodel[1][16:36],ymodel[2][16:36])) rest = ((abso - absomodel) / sigma)**2 dif = abso - absomodel return (fluxmodel, rest, datacube[:, int(pos[0]), int(pos[1])].data, sigma, dif)
scale = 7.28 # z=0.73379 # plat scale (kpc/") for Planck c1 = SkyCoord(ra * u.degree, dec * u.degree, frame='icrs') alpha = csu.get_alpha(c1, galcen, galPA) D = csu.get_impactparam(c1, galcen, scale) flux = datacube[:, i, j] abso = flux.data[specwidth[0]:specwidth[1] + 1] sigma = np.sqrt(flux.var[specwidth[0]:specwidth[1] + 1]) lam2 = np.arange(4825.12, 4886.37 + 1.5, 0.1) wave1 = WaveCoord(cdelt=0.1, crval=4825.12, cunit=u.angstrom) model = Disco(h, incli, Rcore=0.1) spec = model.averagelos(D, alpha, lam2, 100, 12, z, csize, col_dens, bes, r_0, v_max, h_v, 0) spe = Spectrum(wave=wave1, data=spec) rspe = spe.resample(1.25) fluxmodel = rspe.data absomodel = fluxmodel[specwidth[0]:specwidth[1] + 1] #ymodelt = np.concatenate((ymodel[0][14:36],ymodel[1][16:36],ymodel[2][16:36])) dif = np.sum(((abso - absomodel) / sigma)**2) ima.data[i, j] = dif ima.mask[i, j] = False else: ima.data[i, j] = 0 ima.mask[i, j] = True ima.plot(colorbar='v') plt.show()
def test_resample(): """Spectrum class: Test resampling""" # Choose the dimensions of the spectrum, choosing a large number that is # *not* a convenient power of 2. oldshape = 4000 # Choose the wavelength pixel size and the default wavelength units. oldstep = 1.0 oldunit = u.angstrom # Create the wavelength axis coordinates. wave = WaveCoord(crpix=2.0, cdelt=oldstep, crval=0.5, cunit=oldunit, shape=oldshape) # Specify the desired increase in pixel size, and the resulting pixel size. factor = 6.5 newstep = ((factor * oldstep) * oldunit).to(u.nm).value # Specify the wavelength at which the peak of the resampled spectrum should # be expected. expected_peak_wave = 3000.0 # Create the array in which the test spectrum will be composed. data = np.zeros(oldshape) # Get the wavelength coordinates of each pixel in the spectrum. w = wave.coord() # Add the following list gaussians to the spectrum, where each # gaussian is specified as: (amplitude, sigma_in_pixels, # center_wavelength). Given that narrow gaussians are reduced in # amplitude by resampling more than wide gaussians, we arrange # that the peak gaussian before and after correctly resampling are # different. gaussians = [ (0.5, 12.0, 800.0), (0.7, 5.0, 1200.0), (0.4, 700.0, 1600.0), (1.5, 2.6, 1980.0), # Peak before resampling (1.2, 2.6, 2000.0), (1.3, 15.0, expected_peak_wave), # Peak if resampled correctly (1.0, 2.0, 3200.0) ] for amp, sigma, center in gaussians: sigma *= oldstep data += amp * np.exp(-0.5 * ((center - w) / sigma)**2) # Fill the variance array with a simple window function. var = np.hamming(oldshape) # Add gaussian random noise to the spectrum, but leave 3 output # pixel widths zero at each end of the spectrum so that the PSF of # the output grid doesn't spread flux from the edges off the edge # of the output grid. It takes about 3 pixel widths for the gaussian # PSF to drop to about 0.01 of its peak. margin = np.ceil(3 * factor).astype(int) data[margin:-margin] += np.random.normal(scale=0.1, size=data.shape - 2 * margin) # Install the spectral data in a Spectrum container. oldsp = Spectrum(data=data, var=var, wave=wave) # Mask a few pixels. masked_slice = slice(900, 910) oldsp.mask[masked_slice] = True # Create a down-sampled version of the input spectrum. newsp = oldsp.resample(newstep, unit=u.nm) # Check that the integral flux in the resampled spectrum matches that of # the original spectrum. expected_flux = oldsp.sum(weight=False)[0] * oldsp.wave.get_step( unit=oldunit) actual_flux = newsp.sum(weight=False)[0] * newsp.wave.get_step( unit=oldunit) assert_allclose(actual_flux, expected_flux, 1e-2) # Do the same test, but with fluxes weighted by the inverse of the variances. expected_flux = oldsp.sum(weight=True)[0] * oldsp.wave.get_step( unit=oldunit) actual_flux = newsp.sum(weight=True)[0] * newsp.wave.get_step(unit=oldunit) assert_allclose(actual_flux, expected_flux, 1e-2) # Check that the peak of the resampled spectrum is at the wavelength # where the strongest gaussian was centered in the input spectrum. assert_allclose(np.argmax(newsp.data), newsp.wave.pixel(expected_peak_wave, nearest=True)) # Now upsample the downsampled spectrum to the original pixel size. # This won't recover the same spectrum, since higher spatial frequencies # are lost when downsampling, but the total flux should be about the # same, and the peak should be at the same wavelength as the peak in # original spectrum within one pixel width of the downsampled spectrum. newsp2 = newsp.resample(oldstep, unit=oldunit) # Check that the doubly resampled spectrum has the same integrated flux # as the original. expected_flux = oldsp.sum(weight=False)[0] * oldsp.wave.get_step( unit=oldunit) actual_flux = newsp2.sum(weight=False)[0] * newsp2.wave.get_step( unit=oldunit) assert_allclose(actual_flux, expected_flux, 1e-2) # Check that the peak of the up-sampled spectrum is at the wavelength # of the peak of the down-sampled spectrum to within the pixel resolution # of the downsampled spectrum. assert_allclose( newsp.wave.pixel(newsp2.wave.coord(np.argmax(newsp2.data)), nearest=True), newsp.wave.pixel(expected_peak_wave, nearest=True)) # Check that pixels that were masked in the input spectrum are still # masked in the final spectrum. np.testing.assert_equal(newsp2.mask[masked_slice], oldsp.mask[masked_slice])
('r_0', 1, True), ('vel_max', 195, True), ('h_v', 4.5, True), ) par = params.valuesdict() incli = par['incli'] col_denst = par['col_dens'] h = par['height'] bes = par['dop_param'] v_max = par['vel_max'] h_vt = par['h_v'] csize = par['csize'] r_0t = par['r_0'] r_0 = 10**r_0t h_v = 10**h_vt model = Disco(h, incli, Rcore=0.1) lam2 = np.arange(4825.12, 4886.37 + 1.5, 0.1) wave1 = WaveCoord(cdelt=0.1, crval=4825.12, cunit=u.angstrom) spec = model.averagelos(5, 25, lam2, 100, 12, 0.73379, csize, bes, r_0, v_max, h_v, 0) spe = Spectrum(wave=wave1, data=spec) rspec = spe.resample(1.25) wave = np.arange(rspec.get_start(), rspec.get_end() + rspec.get_step(), rspec.get_step()) print(rspec) plt.plot(lam2, spec, 'b') plt.plot(wave, rspec.data, 'g') plt.show()