def test_against_brute_force(): specfile = data_test_file('MaNGA_test_spectra.fits.gz') hdu = fits.open(specfile) # Just test on the first spectrum old_wave = hdu['WAVE'].data old_flux = numpy.ma.MaskedArray(hdu['FLUX'].data[0, :], mask=hdu['MASK'].data[0, :] > 0) old_flux[(old_wave > 5570) & (old_wave < 5586)] = numpy.ma.masked old_ferr = numpy.ma.power(hdu['IVAR'].data[0, :], -0.5) z = hdu['Z'].data[0] # Do the brute force calculation borders = sampling.grid_borders(numpy.array([old_wave[0], old_wave[-1]]), old_wave.size, log=True)[0] _p = numpy.repeat(borders, 2)[1:-1].reshape(-1, 2) new_flux_brute = passband_integral(old_wave / (1 + z), old_flux, passband=_p, log=True) new_flux_brute /= (_p[:, 1] - _p[:, 0]) # Use resample r = sampling.Resample(old_flux, e=old_ferr, x=old_wave / (1 + z), newRange=[old_wave[0], old_wave[-1]], inLog=True, newLog=True) # The two shoule be the same assert numpy.isclose(numpy.mean(numpy.absolute(new_flux_brute-r.outy)), 0.0), \ 'Resampling and brute force calculation should be identical'
def test_gaussian_integral(): x = numpy.linspace(-6, 6, 100) g = stats.norm.pdf(x) passbands = numpy.array([[-6, 6], [-5, 5], [-4, 4], [-3, 3], [-2, 2], [-1, 1]]) assert numpy.all(numpy.isclose(bandpassfilter.passband_integral(x,g,passband=passbands), [1., 0.99999942, 0.99993731, 0.99727786, 0.95423538, 0.68231932])), \ 'Incorrect Gaussian integrals'
def test_passband_integral(): x = numpy.arange(3) y = numpy.ones(2) Y = bandpassfilter.passband_integral(x, y, borders=True) E = bandpassfilter.passband_integral(x, y, borders=True, quad=True) assert numpy.all(numpy.isclose([Y, E], [2.0, numpy.sqrt(2)])), 'Bad flat integral' Y = bandpassfilter.passband_integral(x, y, borders=True, passband=[0.5, 1.5]) E = bandpassfilter.passband_integral(x, y, borders=True, quad=True, passband=[0.5, 1.5]) assert numpy.all(numpy.isclose( [Y, E], [1.0, 1 / numpy.sqrt(2)])), 'Bad passband integral'
def resample_test(): root = os.path.join(os.environ['MANGA_SPECTRO_REDUX'], os.environ['MANGADRP_VER']) pltifu = '7815-1901' hdu = fits.open( os.path.join(root, pltifu.split('-')[0], 'stack', 'manga-{0}-LOGCUBE.fits.gz'.format(pltifu))) drpall_file = os.path.join( root, 'drpall-{0}.fits'.format(os.environ['MANGADRP_VER'])) drpall = fits.open(drpall_file)[1].data indx = drpall['PLATEIFU'] == pltifu z = drpall['NSA_Z'][indx][0] print(z) old_wave = hdu['WAVE'].data old_flux = numpy.ma.MaskedArray( (hdu['FLUX'].data[:, 10:12, 10]).T, mask=(hdu['MASK'].data[:, 10:12, 10]).T > 0) old_flux[:, (old_wave > 5570) & (old_wave < 5586)] = numpy.ma.masked old_ferr = numpy.ma.power((hdu['IVAR'].data[:, 10:12, 10]).T, -0.5) indx = (old_wave > old_wave[0] / (1 + z)) & (old_wave < old_wave[-2] / (1 + z)) t = time.perf_counter() new_flux_spectres = numpy.empty((old_flux.shape[0], numpy.sum(indx)), dtype=float) new_ferr_spectres = numpy.empty((old_flux.shape[0], numpy.sum(indx)), dtype=float) for i in range(old_flux.shape[0]): new_flux_spectres[i,:], new_ferr_spectres[i,:] \ = spectres.spectres(old_wave[indx], old_wave/(1+z), old_flux[i,:].filled(0.0), spec_errs=old_ferr[i,:].filled(0.0)) print('SpectRes Time: ', time.perf_counter() - t) t = time.perf_counter() borders = _pixel_borders(numpy.array([old_wave[0], old_wave[-1]]), old_wave.size, log=True)[0] _p = numpy.repeat(borders, 2)[1:-1].reshape(-1, 2) new_flux_brute = numpy.array([ passband_integral(old_wave / (1 + z), f, passband=_p, log=True) for f in old_flux.filled(0.0) ]) new_flux_brute /= (_p[:, 1] - _p[:, 0])[None, :] print('Brute Force Time: ', time.perf_counter() - t) t = time.perf_counter() r = Resample(old_flux, e=old_ferr, x=old_wave / (1 + z), newRange=[old_wave[0], old_wave[-1]], inLog=True, newLog=True) print('Resample Time: ', time.perf_counter() - t) print('Mean diff:') print(' spectres - brute = {0:.5e}'.format( numpy.mean(numpy.absolute(new_flux_spectres - new_flux_brute[:, indx])))) print(' spectres - resample = {0:.5e}'.format( numpy.mean(numpy.absolute(new_flux_spectres - r.outy[:, indx])))) print(' brute - resample = {0:.5e}'.format( numpy.mean(numpy.absolute(new_flux_brute - r.outy)))) for i in range(old_flux.shape[0]): pyplot.plot(old_wave / (1 + z), old_flux[i, :]) pyplot.plot(old_wave[indx], new_flux_spectres[i, :]) pyplot.plot(old_wave, new_flux_brute[i, :]) pyplot.plot(r.outx, r.outy[i, :]) pyplot.plot(r.outx, r.outf[i, :]) pyplot.show()
def resample_test(): # Read the example datacube and get the expected redshift You can download # these data using # https://github.com/sdss/mangadap/blob/master/download_test_data.py plt = 7815 ifu = 3702 drpver = 'v3_1_1' directory_path = defaults.dap_source_dir() / 'data' / 'remote' cube = MaNGADataCube.from_plateifu(plt, ifu, directory_path=directory_path) drpall_file = directory_path / f'drpall-{drpver}.fits' z = get_redshift(plt, ifu, drpall_file) # Pull out two example spectra from the datacube old_wave = cube.wave old_flux = numpy.ma.MaskedArray(cube.flux[10, 10:12, :], mask=cube.mask[10, 10:12, :] > 0) old_flux[:, (old_wave > 5570) & (old_wave < 5586)] = numpy.ma.masked old_ferr = numpy.ma.power(cube.ivar[10, 10:12, :], -0.5) if spectres is not None: # Use spectres to resample the spectrum, ignoring last pixel indx = (old_wave > old_wave[0] / (1 + z)) & (old_wave < old_wave[-2] / (1 + z)) t = time.perf_counter() new_flux_spectres = numpy.empty((old_flux.shape[0], numpy.sum(indx)), dtype=float) new_ferr_spectres = numpy.empty((old_flux.shape[0], numpy.sum(indx)), dtype=float) for i in range(old_flux.shape[0]): new_flux_spectres[i,:], new_ferr_spectres[i,:] \ = spectres.spectres(old_wave[indx], old_wave/(1+z), old_flux[i,:].filled(0.0), spec_errs=old_ferr[i,:].filled(0.0)) print('SpectRes Time: ', time.perf_counter() - t) # Use a brute-force integration of the spectra to resample the spectrum t = time.perf_counter() borders = grid_borders(numpy.array([old_wave[0], old_wave[-1]]), old_wave.size, log=True)[0] _p = numpy.repeat(borders, 2)[1:-1].reshape(-1, 2) new_flux_brute = numpy.array([ passband_integral(old_wave / (1 + z), f, passband=_p, log=True) for f in old_flux.filled(0.0) ]) new_flux_brute /= (_p[:, 1] - _p[:, 0])[None, :] print('Brute Force Time: ', time.perf_counter() - t) # Use the Resample class to resample the spectrum t = time.perf_counter() r = Resample(old_flux, e=old_ferr, x=old_wave / (1 + z), newRange=[old_wave[0], old_wave[-1]], inLog=True, newLog=True) print('Resample Time: ', time.perf_counter() - t) # Estimate the differences between the resampling methods (these should all # be the same to nearly numerical accuracy) print('Mean diff:') if spectres is not None: print(' spectres - brute = {0:.5e}'.format( numpy.mean( numpy.absolute(new_flux_spectres - new_flux_brute[:, indx])))) print(' spectres - resample = {0:.5e}'.format( numpy.mean(numpy.absolute(new_flux_spectres - r.outy[:, indx])))) print(' brute - resample = {0:.5e}'.format( numpy.mean(numpy.absolute(new_flux_brute - r.outy)))) # Plot the original and resampled versions for all spectra. The resampled # versions should all be indistinguishable. for i in range(old_flux.shape[0]): pyplot.plot(old_wave / (1 + z), old_flux[i, :], label='Data') if spectres is not None: pyplot.plot(old_wave[indx], new_flux_spectres[i, :], label='spectres') pyplot.plot(old_wave, new_flux_brute[i, :], label='brute') pyplot.plot(r.outx, r.outy[i, :], label='Resample') pyplot.plot(r.outx, r.outf[i, :], label='Good-pixel Mask') pyplot.legend() pyplot.xlabel('Wavelength') pyplot.ylabel('Flux') pyplot.show()