Exemplo n.º 1
0
def test_rukia_fit():
    miles_wave, miles_flux = read_miles(
        data_test_file('MILES_res2.50_star_m0505V.fits'))
    miles_flux /= numpy.median(miles_flux)

    xsl_wave, xsl_flux, _ = read_xsl(
        data_test_file('xsl_spectrum_X0360_uvb.fits'))
    xsl_flux /= numpy.ma.median(xsl_flux)

    # Setup the fitting functions
    sigma = LegendrePolynomial(1)
    mulp = LegendrePolynomial(5)
    r = Rukia(sigma, mul_model=mulp)

    # Perform the fit
    r.fit(miles_wave,
          miles_flux,
          xsl_wave.data,
          xsl_flux.data,
          shift=0.0,
          fit_shift=True,
          rejiter=-1)

    assert numpy.sum(r.gpm) == 2176, 'Change in the number of pixels rejected.'
    assert numpy.sqrt(numpy.mean(numpy.square((r.flux-r.model(r.par))[r.gpm]))) < 0.01, \
            'Fit quality changed.'
Exemplo n.º 2
0
def test_manga_dap():
    odir = data_test_file('manga_dap_output')

    # Clean up previous failure
    if os.path.isdir(odir):
        shutil.rmtree(odir)

    # Run the DAP. The binning in plan.par is set to ALL binning, so
    # this run of the DAP just analyzes one spectrum and takes about a
    # minute.
    manga_dap.main(
        manga_dap.parse_args([
            '-c',
            data_test_file('datacube.ini'), '-p',
            data_test_file('plan.par'), '-a', odir
        ]))

    # Re-run to use existing files.  Takes about 40s.
    manga_dap.main(
        manga_dap.parse_args([
            '-c',
            data_test_file('datacube.ini'), '-p',
            data_test_file('plan.par'), '-a', odir
        ]))

    # Clean up
    shutil.rmtree(odir)
Exemplo n.º 3
0
def test_manga_dap_import():
    with pytest.raises(ImportError):
        manga_dap.main(
            manga_dap.parse_args(
                ['-c', data_test_file('datacube.ini'), '-m', 'junk']))

    with pytest.raises(AttributeError):
        manga_dap.main(
            manga_dap.parse_args(
                ['-c', data_test_file('datacube.ini'), '-o', 'junk']))
Exemplo n.º 4
0
def test_write():
    directory, ofile = TemplateLibrary.default_paths(
        'MILESHC', output_path=data_test_file())
    file_name = directory / ofile
    if file_name.exists():
        os.remove(str(file_name))
    tpl = TemplateLibrary('MILESHC',
                          match_resolution=False,
                          velscale_ratio=4,
                          spectral_step=1e-4,
                          log=True,
                          output_path=data_test_file(),
                          hardcopy=True)
    assert file_name.exists(), 'File not written'
    os.remove(str(file_name))
Exemplo n.º 5
0
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'
Exemplo n.º 6
0
def test_pixelmask():
    specfile = data_test_file('MaNGA_test_spectra.fits.gz')
    hdu = fits.open(specfile)
    pixelmask = SpectralPixelMask(artdb=ArtifactDB.from_key('BADSKY'),
                                  emldb=EmissionLineDB.from_key('ELPSCMSK'))
    assert numpy.sum(pixelmask.boolean(hdu['WAVE'].data, nspec=1)) == 489, \
                'Incorrect number of masked pixels'
Exemplo n.º 7
0
def test_drpbitmask():
    # Read the data
    specfile = data_test_file('MaNGA_test_spectra.fits.gz')
    hdu = fits.open(specfile)
    drpbm = DRPFitsBitMask()
    assert numpy.sum(drpbm.flagged(hdu['MASK'].data, MaNGADataCube.do_not_fit_flags())) == 4601, \
                'Flags changed'
Exemplo n.º 8
0
def test_multi_read():
    plan = AnalysisPlan.from_toml(data_test_file('dr17.toml'))

    assert len(plan.keys()) == 4, 'Number of example plans changed'

    assert plan['plan3'][
        'key'] == 'HYB10-MILESHC-MASTARSSP', 'Plan key changed'
    assert plan.binning['plan1']['key'] == 'SPX', 'Binning changed'
    assert plan.elfit['plan4'][
        'key'] == 'EFITHC2DB', 'Emission-line fitting key changed'
Exemplo n.º 9
0
def test_read():
    plan = AnalysisPlan.from_toml(data_test_file('global_bin.toml'))

    assert len(plan.keys()) == 1, 'Number of example plans changed'
    assert list(plan.keys())[0] == 'default', 'Name changed'

    assert plan.binning['default'][
        'key'] == 'ALL', 'Default DRP reduction QA key changed.'
    assert plan.elfit['default'][
        'key'] == 'EFITSSP', 'Default emission-line fit key changed.'
Exemplo n.º 10
0
def test_from_config():
    cfg = MaNGAConfig.from_config(data_test_file("datacube.ini"))
    assert isinstance(cfg.directory_path,
                      Path), 'Directory should be a Path instance'
    # TODO: This passes locally, but will fail the tox CI tests.  Determine how
    # to perform this in tox?
    #assert cfg.directory_path == Path(remote_data_file()).resolve(), 'Directory path changed'
    assert cfg.plate == 7815, 'Plate changed'
    assert cfg.log, 'Log binning should be true'
    assert cfg.mode == 'CUBE', 'Should be in CUBE mode'
    assert cfg.file_name == 'manga-7815-3702-LOGCUBE.fits.gz'
Exemplo n.º 11
0
def test_mangaplan():
    cfg = MaNGAConfig(7815, 3702)
    plan = MaNGAAnalysisPlan.from_toml(data_test_file('dr17.toml'), cube=cfg)

    assert plan.dap_file_root(cfg) == 'manga-7815-3702', 'Bad root'
    assert plan.dap_file_root(cfg, mode='MAPS', plan_index=0) \
                == 'manga-7815-3702-MAPS-SPX-MILESHC-MASTARSSP', 'Bad full root'
    assert plan.common_path().parts[-2:] == (str(cfg.plate), str(cfg.ifudesign)), \
                'Bad common subdirectories'
    assert plan.method_path().parts[-2:] == (str(cfg.plate), str(cfg.ifudesign)), \
                'Bad method subdirectories'
    assert plan.method_path(qa=True).parts[-2:] == (str(cfg.ifudesign), 'qa'), \
                'Bad qa subdirectories'
Exemplo n.º 12
0
def test_moments_with_continuum():
    # Read the data
    specfile = data_test_file('MaNGA_test_spectra.fits.gz')
    hdu = fits.open(specfile)
    drpbm = DRPFitsBitMask()
    flux = numpy.ma.MaskedArray(hdu['FLUX'].data,
                                mask=drpbm.flagged(
                                    hdu['MASK'].data,
                                    MaNGADataCube.do_not_fit_flags()))
    ferr = numpy.ma.power(hdu['IVAR'].data, -0.5)
    flux[ferr.mask] = numpy.ma.masked
    ferr[flux.mask] = numpy.ma.masked
    nspec = flux.shape[0]

    # Instantiate the template libary
    velscale_ratio = 4
    tpl = TemplateLibrary('MILESHC',
                          match_resolution=False,
                          velscale_ratio=velscale_ratio,
                          spectral_step=1e-4,
                          log=True,
                          hardcopy=False)
    tpl_sres = numpy.mean(tpl['SPECRES'].data, axis=0)

    # Get the pixel mask
    pixelmask = SpectralPixelMask(artdb=ArtifactDB.from_key('BADSKY'),
                                  emldb=EmissionLineDB.from_key('ELPSCMSK'))

    # Instantiate the fitting class
    ppxf = PPXFFit(StellarContinuumModelBitMask())

    # Perform the fit
    fit_wave, fit_flux, fit_mask, fit_par \
        = ppxf.fit(tpl['WAVE'].data.copy(), tpl['FLUX'].data.copy(), hdu['WAVE'].data, flux, ferr,
                   hdu['Z'].data, numpy.full(nspec, 100.), iteration_mode='no_global_wrej',
                   reject_boxcar=100, ensemble=False, velscale_ratio=velscale_ratio,
                   mask=pixelmask, matched_resolution=False, tpl_sres=tpl_sres,
                   obj_sres=hdu['SRES'].data, degree=8, moments=2)

    # Remask the continuum fit
    sc_continuum = StellarContinuumModel.reset_continuum_mask_window(
        numpy.ma.MaskedArray(fit_flux, mask=fit_mask > 0))

    # Read the database that define the emission lines and passbands
    momdb = EmissionMomentsDB.from_key('ELBMILES')

    # Measure the moments
    elmombm = EmissionLineMomentsBitMask()
    elmom = EmissionLineMoments.measure_moments(momdb,
                                                hdu['WAVE'].data,
                                                flux,
                                                continuum=sc_continuum,
                                                redshift=hdu['Z'].data,
                                                bitmask=elmombm)

    # Measure the EW based on the moments
    include_band = numpy.array([numpy.invert(momdb.dummy)]*nspec) \
                        & numpy.invert(elmombm.flagged(elmom['MASK'],
                                                       flag=['BLUE_EMPTY', 'RED_EMPTY']))
    line_center = (1.0 + hdu['Z'].data)[:, None] * momdb['restwave'][None, :]
    elmom['BMED'], elmom['RMED'], pos, elmom['EWCONT'], elmom['EW'], elmom['EWERR'] \
            = emission_line_equivalent_width(hdu['WAVE'].data, flux, momdb['blueside'],
                                             momdb['redside'], line_center, elmom['FLUX'],
                                             redshift=hdu['Z'].data,
                                             line_flux_err=elmom['FLUXERR'],
                                             include_band=include_band)

    # Check the flags
    reference = {
        'BLUE_INCOMP': 21,
        'MAIN_JUMP': 0,
        'UNDEFINED_MOM2': 42,
        'JUMP_BTWN_SIDEBANDS': 0,
        'RED_JUMP': 0,
        'DIVBYZERO': 0,
        'NO_ABSORPTION_CORRECTION': 0,
        'RED_EMPTY': 21,
        'UNDEFINED_BANDS': 8,
        'DIDNOTUSE': 0,
        'UNDEFINED_MOM1': 0,
        'FORESTAR': 0,
        'NON_POSITIVE_CONTINUUM': 0,
        'LOW_SNR': 0,
        'MAIN_EMPTY': 21,
        'BLUE_JUMP': 0,
        'RED_INCOMP': 21,
        'MAIN_INCOMP': 21,
        'BLUE_EMPTY': 21
    }
    assert numpy.all([
        reference[k] == numpy.sum(elmombm.flagged(elmom['MASK'], flag=k))
        for k in elmombm.keys()
    ]), 'Number of flagged measurements changed'

    # Check that the values are finite
    assert numpy.all([ numpy.all(numpy.isfinite(elmom[n])) for n in elmom.dtype.names]), \
                        'Found non-finite values in output'

    # Check the band definitions
    assert numpy.all(numpy.equal(elmom['REDSHIFT'],
                                 hdu['Z'].data)), 'Redshift changed'
    assert numpy.all(numpy.isclose(numpy.mean(momdb['blueside'], axis=1)[None,:],
                                   elmom['BCEN']/(1+hdu['Z'].data[:,None]))
                        | elmombm.flagged(elmom['MASK'], flag='UNDEFINED_BANDS')), \
                'Blue passband center incorrect'
    assert numpy.all(numpy.isclose(numpy.mean(momdb['redside'], axis=1)[None,:],
                                   elmom['RCEN']/(1+hdu['Z'].data[:,None]))
                        | elmombm.flagged(elmom['MASK'], flag='UNDEFINED_BANDS')), \
                'Red passband center incorrect'

    # Check the values
    assert numpy.all(
        numpy.absolute(elmom['FLUX'][0] - numpy.array([
            0.63, 0.00, 0.22, -1.32, -0.88, -0.68, -0.44, -0.13, -1.14, -0.07,
            -0.11, 0.01, 0.38, 0.73, 0.71, 0.44, 0.08, 0.74, 1.30, 2.34, 0.55,
            0.44
        ])) < 0.01), 'Fluxes too different'

    assert numpy.all(numpy.absolute(elmom['MOM1'][0] -
                        numpy.array([ 14682.6,      0.0, 14843.2, 14865.8, 14890.4, 14404.7,
                                      14208.6,  12376.0, 14662.5, 14148.5, 15804.1, 17948.4,
                                      14874.5,  14774.9, 14840.5, 14746.0, 15093.1, 14857.8,
                                      14839.0,  14840.2, 14876.0, 14859.5])) < 0.1), \
                    '1st moments too different'

    assert numpy.all(numpy.absolute(elmom['MOM2'][0] -
                        numpy.array([322.2,   0.0, 591.4, 436.4, 474.6,   0.0,   0.0,   0.0,
                                     364.6,   0.0,   0.0,   0.0, 289.1, 226.9, 282.6, 283.8,
                                     227.0, 207.7, 207.7, 253.6, 197.0, 212.4])) < 0.1), \
                    '2nd moments too different'

    assert numpy.all(numpy.absolute(elmom['EW'][0] -
                        numpy.array([ 0.63,  0.00,  0.20, -1.28, -0.76, -0.54, -0.30, -0.09,
                                     -0.61, -0.03, -0.04,  0.00,  0.13,  0.25,  0.24,  0.13,
                                      0.02,  0.22,  0.38,  0.69,  0.17,  0.13])) < 0.01), \
                    'EW too different'
Exemplo n.º 13
0
def test_sasuke():
    # Read the data
    specfile = data_test_file('MaNGA_test_spectra.fits.gz')
    hdu = fits.open(specfile)
    drpbm = DRPFitsBitMask()
    flux = numpy.ma.MaskedArray(hdu['FLUX'].data,
                                mask=drpbm.flagged(
                                    hdu['MASK'].data,
                                    MaNGADataCube.do_not_fit_flags()))
    ferr = numpy.ma.power(hdu['IVAR'].data, -0.5)
    flux[ferr.mask] = numpy.ma.masked
    ferr[flux.mask] = numpy.ma.masked
    nspec = flux.shape[0]

    # Instantiate the template libary
    velscale_ratio = 4
    tpl = TemplateLibrary('MILESHC',
                          match_resolution=False,
                          velscale_ratio=velscale_ratio,
                          spectral_step=1e-4,
                          log=True,
                          hardcopy=False)
    tpl_sres = numpy.mean(tpl['SPECRES'].data, axis=0)

    # Get the pixel mask
    pixelmask = SpectralPixelMask(artdb=ArtifactDB.from_key('BADSKY'),
                                  emldb=EmissionLineDB.from_key('ELPSCMSK'))

    # Instantiate the fitting class
    ppxf = PPXFFit(StellarContinuumModelBitMask())

    # Perform the fit
    sc_wave, sc_flux, sc_mask, sc_par \
        = ppxf.fit(tpl['WAVE'].data.copy(), tpl['FLUX'].data.copy(), hdu['WAVE'].data, flux, ferr,
                   hdu['Z'].data, numpy.full(nspec, 100.), iteration_mode='no_global_wrej',
                   reject_boxcar=100, ensemble=False, velscale_ratio=velscale_ratio,
                   mask=pixelmask, matched_resolution=False, tpl_sres=tpl_sres,
                   obj_sres=hdu['SRES'].data, degree=8, moments=2)

    # Mask the 5577 sky line
    pixelmask = SpectralPixelMask(artdb=ArtifactDB.from_key('BADSKY'))

    # Read the emission line fitting database
    emldb = EmissionLineDB.from_key('ELPMILES')
    assert emldb['name'][
        18] == 'Ha', 'Emission-line database names or ordering changed'

    # Instantiate the fitting class
    emlfit = Sasuke(EmissionLineModelBitMask())

    # Perform the fit
    el_wave, model, el_flux, el_mask, el_fit, el_par \
            = emlfit.fit(emldb, hdu['WAVE'].data, flux, obj_ferr=ferr, obj_mask=pixelmask,
                         obj_sres=hdu['SRES'].data, guess_redshift=hdu['Z'].data,
                         guess_dispersion=numpy.full(nspec, 100.), reject_boxcar=101,
                         stpl_wave=tpl['WAVE'].data, stpl_flux=tpl['FLUX'].data,
                         stpl_sres=tpl_sres, stellar_kinematics=sc_par['KIN'],
                         etpl_sinst_mode='offset', etpl_sinst_min=10.,
                         velscale_ratio=velscale_ratio, matched_resolution=False)

    # Rejected pixels
    assert numpy.sum(emlfit.bitmask.flagged(el_mask, flag='PPXF_REJECT')) == 266, \
                'Different number of rejected pixels'

    # Unable to fit
    assert numpy.array_equal(emlfit.bitmask.flagged_bits(el_fit['MASK'][5]), ['NO_FIT']), \
                'Expected NO_FIT in 6th spectrum'

    # No *attempted* fits should fail
    assert numpy.sum(emlfit.bitmask.flagged(el_fit['MASK'], flag='FIT_FAILED')) == 0, \
                'Fits should not fail'

    # Number of used templates
    assert numpy.array_equal(numpy.sum(numpy.absolute(el_fit['TPLWGT']) > 1e-10, axis=1),
                             [25, 22, 34, 32, 27,  0, 16, 22]), \
                'Different number of templates with non-zero weights'

    # No additive coefficients
    assert numpy.all(el_fit['ADDCOEF'] == 0), \
                'No additive coefficients should exist'

    # No multiplicative coefficients
    assert numpy.all(el_fit['MULTCOEF'] == 0), \
                'No multiplicative coefficients should exist'

    # Fit statistics
    assert numpy.all(
        numpy.absolute(
            el_fit['RCHI2'] -
            numpy.array([2.34, 1.22, 1.58, 1.88, 3.20, 0., 1.05, 0.88])) < 0.02
    ), 'Reduced chi-square are too different'

    assert numpy.all(
        numpy.absolute(el_fit['RMS'] - numpy.array(
            [0.036, 0.019, 0.036, 0.024, 0.051, 0.000, 0.012, 0.012])) < 0.001
    ), 'RMS too different'

    assert numpy.all(numpy.absolute(el_fit['FRMS'] -
                                    numpy.array([0.021, 0.025, 0.025, 0.033, 0.018, 0.000,
                                                 1.052, 0.101])) < 0.001), \
            'Fractional RMS too different'

    assert numpy.all(numpy.absolute(el_fit['RMSGRW'][:,2] -
                                    numpy.array([0.070, 0.038, 0.071, 0.047, 0.101, 0.000, 0.026,
                                                 0.024])) < 0.001), \
            'Median absolute residual too different'

    # All lines should have the same velocity
    assert numpy.all(numpy.all(el_par['KIN'][:,:,0] == el_par['KIN'][:,None,0,0], axis=1)), \
                'All velocities should be the same'

    # Test velocity values
    # TODO: Need some better examples!
    assert numpy.all(numpy.absolute(el_par['KIN'][:,0,0] -
                                    numpy.array([14704.9, 14869.3, 14767.1, 8161.9, 9258.7, 0.0,
                                                  5130.9,  5430.3])) < 0.1), \
                'Velocities are too different'

    # H-alpha dispersions
    assert numpy.all(numpy.absolute(el_par['KIN'][:,18,1] -
                                    numpy.array([1000.5, 1000.5, 224.7, 124.9, 171.2, 0.0, 81.2,
                                                   50.0])) < 1e-1), \
            'H-alpha dispersions are too different'
Exemplo n.º 14
0
def test_moments():

    # Read the data
    specfile = data_test_file('MaNGA_test_spectra.fits.gz')
    hdu = fits.open(specfile)
    drpbm = DRPFitsBitMask()
    flux = numpy.ma.MaskedArray(hdu['FLUX'].data,
                                mask=drpbm.flagged(
                                    hdu['MASK'].data,
                                    MaNGADataCube.do_not_fit_flags()))
    ferr = numpy.ma.power(hdu['IVAR'].data, -0.5)
    flux[ferr.mask] = numpy.ma.masked
    ferr[flux.mask] = numpy.ma.masked
    nspec = flux.shape[0]

    # Read the database that define the emission lines and passbands
    momdb = EmissionMomentsDB.from_key('ELBMILES')

    # Measure the moments
    elmombm = EmissionLineMomentsBitMask()
    elmom = EmissionLineMoments.measure_moments(momdb,
                                                hdu['WAVE'].data,
                                                flux,
                                                redshift=hdu['Z'].data,
                                                bitmask=elmombm)

    # Measure the EW based on the moments
    include_band = numpy.array([numpy.invert(momdb.dummy)]*nspec) \
                        & numpy.invert(elmombm.flagged(elmom['MASK'],
                                                       flag=['BLUE_EMPTY', 'RED_EMPTY']))
    line_center = (1.0 + hdu['Z'].data)[:, None] * momdb['restwave'][None, :]
    elmom['BMED'], elmom['RMED'], pos, elmom['EWCONT'], elmom['EW'], elmom['EWERR'] \
            = emission_line_equivalent_width(hdu['WAVE'].data, flux, momdb['blueside'],
                                             momdb['redside'], line_center, elmom['FLUX'],
                                             redshift=hdu['Z'].data,
                                             line_flux_err=elmom['FLUXERR'],
                                             include_band=include_band)

    # Check the flags
    reference = {
        'BLUE_INCOMP': 21,
        'MAIN_JUMP': 0,
        'UNDEFINED_MOM2': 46,
        'JUMP_BTWN_SIDEBANDS': 0,
        'RED_JUMP': 0,
        'DIVBYZERO': 0,
        'NO_ABSORPTION_CORRECTION': 176,
        'RED_EMPTY': 21,
        'UNDEFINED_BANDS': 8,
        'DIDNOTUSE': 0,
        'UNDEFINED_MOM1': 0,
        'FORESTAR': 0,
        'NON_POSITIVE_CONTINUUM': 0,
        'LOW_SNR': 0,
        'MAIN_EMPTY': 21,
        'BLUE_JUMP': 0,
        'RED_INCOMP': 21,
        'MAIN_INCOMP': 21,
        'BLUE_EMPTY': 21
    }
    assert numpy.all([
        reference[k] == numpy.sum(elmombm.flagged(elmom['MASK'], flag=k))
        for k in elmombm.keys()
    ]), 'Number of flagged measurements changed'

    # Check that the values are finite
    assert numpy.all([ numpy.all(numpy.isfinite(elmom[n])) for n in elmom.dtype.names]), \
                        'Found non-finite values in output'

    # Check the band definitions
    assert numpy.all(numpy.equal(elmom['REDSHIFT'],
                                 hdu['Z'].data)), 'Redshift changed'
    assert numpy.all(numpy.isclose(numpy.mean(momdb['blueside'], axis=1)[None,:],
                                   elmom['BCEN']/(1+hdu['Z'].data[:,None]))
                        | elmombm.flagged(elmom['MASK'], flag='UNDEFINED_BANDS')), \
                'Blue passband center incorrect'
    assert numpy.all(numpy.isclose(numpy.mean(momdb['redside'], axis=1)[None,:],
                                   elmom['RCEN']/(1+hdu['Z'].data[:,None]))
                        | elmombm.flagged(elmom['MASK'], flag='UNDEFINED_BANDS')), \
                'Red passband center incorrect'

    # Check the values
    assert numpy.allclose(elmom['FLUX'][0],
                          numpy.array([
                              -0.83366296, 0., -0.7368989, -6.84760392,
                              -5.8392653, -3.84394899, -9.63158548,
                              -10.1459227, -1.86639944, 0.19851703, 0.04831539,
                              -5.58001859, 0.86652478, -1.3277138, 4.48556862,
                              0.12541773, -1.37675776, 1.14456948, -1.41808526,
                              2.48743805, -0.31254732, 0.04046428
                          ]),
                          rtol=0.0,
                          atol=1e-2), 'Fluxes changed'
    assert numpy.allclose(
        elmom['MOM1'][0],
        numpy.array([
            15403.91870501, 0., 13866.58355013, 14816.45834376, 14861.90408263,
            14545.21106265, 14929.76054479, 14774.62443577, 14943.56586856,
            13010.07824437, 15933.25294444, 14918.25984067, 14425.53398781,
            15207.53998774, 14803.71786274, 14160.66542001, 14720.66321017,
            14706.89675211, 14880.91017052, 14901.49219165, 14880.79548007,
            15615.43369812
        ]),
        rtol=0.0,
        atol=1e-1), '1st moments changed'
    assert numpy.allclose(elmom['MOM2'][0],
                          numpy.array([
                              0., 0., 0., 439.76305578, 479.32501708,
                              325.96571646, 348.71402151, 362.29430475,
                              128.76827924, 0., 0., 322.61461489, 268.26542796,
                              27.14271982, 259.24977286, 0., 181.94055378,
                              129.62366078, 147.48288905, 225.76488299,
                              132.57819153, 0.
                          ]),
                          rtol=0.0,
                          atol=1e-1), '2nd moments changed'
    assert numpy.allclose(elmom['EW'][0],
                          numpy.array([
                              -0.83148156, 0., -0.67854382, -6.65583709,
                              -4.99844209, -3.06783667, -6.6506484,
                              -6.86724193, -0.99166185, 0.08843696, 0.01728948,
                              -1.81199184, 0.28592615, -0.46054113, 1.48650809,
                              0.03822714, -0.40850899, 0.33980593, -0.42043643,
                              0.73608197, -0.09406925, 0.01217937
                          ]),
                          rtol=0.0,
                          atol=1e-2), 'EW changed'
Exemplo n.º 15
0
def test_ppxffit():
    # Read the data
    specfile = data_test_file('MaNGA_test_spectra.fits.gz')
    hdu = fits.open(specfile)
    drpbm = DRPFitsBitMask()
    flux = numpy.ma.MaskedArray(hdu['FLUX'].data,
                                mask=drpbm.flagged(
                                    hdu['MASK'].data,
                                    MaNGADataCube.do_not_fit_flags()))
    ferr = numpy.ma.power(hdu['IVAR'].data, -0.5)
    flux[ferr.mask] = numpy.ma.masked
    ferr[flux.mask] = numpy.ma.masked
    nspec = flux.shape[0]

    # Instantiate the template libary
    velscale_ratio = 4
    tpl = TemplateLibrary('MILESHC',
                          match_resolution=False,
                          velscale_ratio=velscale_ratio,
                          spectral_step=1e-4,
                          log=True,
                          hardcopy=False)
    tpl_sres = numpy.mean(tpl['SPECRES'].data, axis=0)

    # Get the pixel mask
    pixelmask = SpectralPixelMask(artdb=ArtifactDB.from_key('BADSKY'),
                                  emldb=EmissionLineDB.from_key('ELPSCMSK'))

    # Instantiate the fitting class
    ppxf = PPXFFit(StellarContinuumModelBitMask())

    # Perform the fit
    fit_wave, fit_flux, fit_mask, fit_par \
        = ppxf.fit(tpl['WAVE'].data.copy(), tpl['FLUX'].data.copy(), hdu['WAVE'].data, flux, ferr,
                   hdu['Z'].data, numpy.full(nspec, 100.), iteration_mode='no_global_wrej',
                   reject_boxcar=100, ensemble=False, velscale_ratio=velscale_ratio,
                   mask=pixelmask, matched_resolution=False, tpl_sres=tpl_sres,
                   obj_sres=hdu['SRES'].data, degree=8, moments=2)

    # Test the results

    # Rejected pixels
    assert numpy.sum(ppxf.bitmask.flagged(fit_mask, flag='PPXF_REJECT')) == 119, \
                'Different number of rejected pixels'

    # Unable to fit
    assert numpy.array_equal(ppxf.bitmask.flagged_bits(fit_par['MASK'][5]), ['NO_FIT']), \
                'Expected NO_FIT in 6th spectrum'

    # Number of used templates
    assert numpy.array_equal(numpy.sum(numpy.absolute(fit_par['TPLWGT']) > 1e-10, axis=1),
                             [12, 13, 17, 15, 15,  0,  8, 12]), \
                'Different number of templates with non-zero weights'

    # Number of additive coefficients
    assert fit_par['ADDCOEF'].shape[
        1] == 9, 'Incorrect number of additive coefficients'

    # No multiplicative coefficients
    assert numpy.all(fit_par['MULTCOEF'] == 0), \
                'No multiplicative coefficients should exist'

    # Kinematics and errors
    assert numpy.all(numpy.absolute(fit_par['KIN'] -
                        numpy.array([[ 14880.7, 292.9], [ 15053.4, 123.2],
                                     [ 14787.5, 236.4], [  8291.8, 169.7],
                                     [  9261.4, 202.7], [     0.0,   0.0],
                                     [  5123.5,  63.8], [  5455.6,  51.8]])) < 0.1), \
                'Kinematics are too different'

    assert numpy.all(numpy.absolute(fit_par['KINERR'] -
                        numpy.array([[2.0,1.9], [1.5,1.7], [ 2.4, 2.4], [2.2,2.3],
                                     [1.1,1.1], [0.0,0.0], [26.1,30.8], [4.7,7.5]])) < 0.1), \
                'Kinematic errors are too different'

    # Velocity dispersion corrections
    assert numpy.all(numpy.absolute(fit_par['SIGMACORR_SRES'] -
                        numpy.array([23.5, 10.1, 27.3, 38.7, 22.3,  0.0, 63.8, 23.8])) < 0.1), \
                'SRES corrections are too different'

    assert numpy.all(numpy.absolute(fit_par['SIGMACORR_EMP'] -
                        numpy.array([22.6,  0.0, 26.0, 38.2, 18.0,  0.0, 70.1,  0.0])) < 0.1), \
                'EMP corrections are too different'

    # Figures of merit
    assert numpy.all(numpy.absolute(fit_par['RCHI2'] -
                        numpy.array([ 1.94, 1.18, 1.40, 1.53, 2.50, 0.00, 1.06, 0.86])) < 0.01), \
                'Reduced chi-square too different'

    assert numpy.all(
        numpy.absolute(fit_par['RMS'] - numpy.array(
            [0.033, 0.019, 0.034, 0.023, 0.046, 0.000, 0.015, 0.015])) < 0.001
    ), 'RMS too different'

    assert numpy.all(
        numpy.absolute(fit_par['FRMS'] - numpy.array(
            [0.018, 0.023, 0.023, 0.032, 0.018, 0.000, 33.577, 0.148])) < 0.001
    ), 'Fractional RMS too different'

    assert numpy.all(
        numpy.absolute(fit_par['RMSGRW'][:, 2] - numpy.array(
            [0.067, 0.037, 0.068, 0.046, 0.093, 0.000, 0.029, 0.027])) < 0.001
    ), 'Median absolute residual too different'
Exemplo n.º 16
0
def test_from_config():
    cube = MaNGADataCube.from_config(data_test_file('datacube.ini'))
    assert cube.meta['z'] == 0.0293823, 'Bad config file read'
    assert cube.meta['ell'] == 0.110844, 'Bad config file read'
Exemplo n.º 17
0
def test_read():
    plan = AnalysisPlanSet.from_par_file(data_test_file('plan.par'))

    assert len(plan) == 1, 'Number of example plans changed'
    assert plan[0]['bin_key'] == 'ALL', 'Binning changed'
    assert plan[0]['elfit_key'] == 'EFITMPL11HC', 'Emission-line fitting key changed'