Ejemplo n.º 1
0
 def test_comparison(self):
     lq1 = u.Magnitude(np.arange(1., 4.) * u.Jy)
     lq2 = u.Magnitude(2. * u.Jy)
     assert np.all((lq1 > lq2) == np.array([True, False, False]))
     assert np.all((lq1 == lq2) == np.array([False, True, False]))
     lq3 = u.Dex(2. * u.Jy)
     assert np.all((lq1 > lq3) == np.array([True, False, False]))
     assert np.all((lq1 == lq3) == np.array([False, True, False]))
     lq4 = u.Magnitude(2. * u.m)
     assert not (lq1 == lq4)
     assert lq1 != lq4
     with pytest.raises(u.UnitsError):
         lq1 < lq4
     q5 = 1.5 * u.Jy
     assert np.all((lq1 > q5) == np.array([True, False, False]))
     assert np.all((q5 < lq1) == np.array([True, False, False]))
     with pytest.raises(u.UnitsError):
         lq1 >= 2. * u.m
     with pytest.raises(u.UnitsError):
         lq1 <= lq1.value * u.mag
     # For physically dimensionless, we can compare with the function unit.
     lq6 = u.Magnitude(np.arange(1., 4.))
     fv6 = lq6.value * u.mag
     assert np.all(lq6 == fv6)
     # but not some arbitrary unit, of course.
     with pytest.raises(u.UnitsError):
         lq6 < 2. * u.m
Ejemplo n.º 2
0
    def __init__(self,
                 model="kpno",
                 extinction=None,
                 spectral_axis=None,
                 cache=True,
                 show_progress=False,
                 **kwargs):
        if extinction is not None:
            if not isinstance(extinction, u.Quantity):
                warnings.warn(
                    "Input extinction is not a Quanitity. Assuming it is given in magnitudes...",
                    AstropyUserWarning)
                extinction = u.Magnitude(
                    extinction, u.MagUnit(u.dimensionless_unscaled)).to(
                        u.dimensionless_unscaled
                    )  # Spectrum1D wants this to be linear
            if isinstance(
                    extinction,
                (u.LogUnit, u.Magnitude)) or extinction.unit == u.mag:
                # if in log or magnitudes, recast into Magnitude with dimensionless physical units
                extinction = u.Magnitude(extinction.value,
                                         u.MagUnit(
                                             u.dimensionless_unscaled)).to(
                                                 u.dimensionless_unscaled)
            if extinction.unit != u.dimensionless_unscaled:
                # if we're given something linear that's not dimensionless_unscaled,
                # it's an error
                msg = "Input extinction must have unscaled dimensionless units."
                raise ValueError(msg)

        if extinction is None and spectral_axis is None:
            if model not in SUPPORTED_EXTINCTION_MODELS:
                msg = (f"Requested extinction model, {model}, not in list "
                       f"of available models: {SUPPORTED_EXTINCTION_MODELS}")
                raise ValueError(msg)
            model_file = os.path.join("extinction", f"{model}extinct.dat")
            model_path = get_reference_file_path(path=model_file,
                                                 cache=cache,
                                                 show_progress=show_progress)
            t = Table.read(model_path,
                           format="ascii",
                           names=['wavelength', 'extinction'])

            # the specreduce_data models all provide wavelengths in angstroms
            spectral_axis = t['wavelength'].data * u.angstrom

            # the specreduce_data models all provide extinction in magnitudes at an airmass of 1
            extinction = u.Magnitude(t['extinction'].data,
                                     u.MagUnit(u.dimensionless_unscaled)).to(
                                         u.dimensionless_unscaled)

        if spectral_axis is None:
            msg = "Missing spectral axis for input extinction data."
            raise ValueError(msg)

        super(AtmosphericExtinction,
              self).__init__(flux=extinction,
                             spectral_axis=spectral_axis,
                             unit=u.dimensionless_unscaled,
                             **kwargs)
Ejemplo n.º 3
0
    def test_raise_to_power(self, power):
        """Check that raising LogQuantities to some power is only possible when
        the physical unit is dimensionless, and that conversion is turned off
        when the resulting logarithmic unit (say, mag**2) is incompatible."""
        lq = u.Magnitude(np.arange(1., 4.) * u.Jy)

        if power == 0:
            assert np.all(lq**power == 1.)
        elif power == 1:
            assert np.all(lq**power == lq)
        else:
            with pytest.raises(u.UnitsError):
                lq**power

        # with dimensionless, it works, but falls back to normal quantity
        # (except for power=1)
        lq2 = u.Magnitude(np.arange(10.))

        t = lq2**power
        if power == 0:
            assert t.unit is u.dimensionless_unscaled
            assert np.all(t.value == 1.)
        elif power == 1:
            assert np.all(t == lq2)
        else:
            assert not isinstance(t, type(lq2))
            assert t.unit == lq2.unit.function_unit**power
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(u.dimensionless_unscaled)
Ejemplo n.º 4
0
 def test_slice_get_and_set(self):
     lq1 = u.Magnitude(np.arange(1., 10.) * u.Jy)
     lq1[2:4] = 100. * u.Jy
     assert np.all(lq1[2:4] == u.Magnitude(100. * u.Jy))
     with pytest.raises(u.UnitsError):
         lq1[2:4] = 100. * u.m
     with pytest.raises(u.UnitsError):
         lq1[2:4] = 100. * u.mag
     with pytest.raises(u.UnitsError):
         lq1[2:4] = u.Magnitude(100. * u.m)
     assert np.all(lq1[2] == u.Magnitude(100. * u.Jy))
Ejemplo n.º 5
0
 def test_item_get_and_set(self):
     lq1 = u.Magnitude(np.arange(1., 11.) * u.Jy)
     assert lq1[9] == u.Magnitude(10. * u.Jy)
     lq1[2] = 100. * u.Jy
     assert lq1[2] == u.Magnitude(100. * u.Jy)
     with pytest.raises(u.UnitsError):
         lq1[2] = 100. * u.m
     with pytest.raises(u.UnitsError):
         lq1[2] = 100. * u.mag
     with pytest.raises(u.UnitsError):
         lq1[2] = u.Magnitude(100. * u.m)
     assert lq1[2] == u.Magnitude(100. * u.Jy)
Ejemplo n.º 6
0
def test_write_byte_by_byte_units():
    t = ascii.read(test_dat)
    col_units = [None, u.C, u.kg, u.m / u.s, u.year]
    t._set_column_attribute('unit', col_units)
    # Add a column with magnitude units.
    # Note that magnitude has to be assigned for each value explicitly.
    t['magnitude'] = [u.Magnitude(25), u.Magnitude(-9)]
    col_units.append(u.mag)
    out = StringIO()
    t.write(out, format='ascii.mrt')
    # Read written table.
    tRead = ascii.read(out.getvalue(), format='cds')
    assert [tRead[col].unit for col in tRead.columns] == col_units
Ejemplo n.º 7
0
    def test_multiplication_division(self):
        """Check that multiplication/division with other quantities is only
        possible when the physical unit is dimensionless, and that this turns
        the result into a normal quantity."""
        lq = u.Magnitude(np.arange(1., 11.) * u.Jy)

        with pytest.raises(u.UnitsError):
            lq * (1. * u.m)

        with pytest.raises(u.UnitsError):
            (1. * u.m) * lq

        with pytest.raises(u.UnitsError):
            lq / lq

        for unit in (u.m, u.mag, u.dex):
            with pytest.raises(u.UnitsError):
                lq / unit

        lq2 = u.Magnitude(np.arange(1, 11.))

        with pytest.raises(u.UnitsError):
            lq2 * lq

        with pytest.raises(u.UnitsError):
            lq2 / lq

        with pytest.raises(u.UnitsError):
            lq / lq2

        # but dimensionless_unscaled can be cancelled
        r = lq2 / u.Magnitude(2.)
        assert r.unit == u.dimensionless_unscaled
        assert np.all(r.value == lq2.value / 2.)

        # with dimensionless, normal units OK, but return normal quantities
        tf = lq2 * u.m
        tr = u.m * lq2
        for t in (tf, tr):
            assert not isinstance(t, type(lq2))
            assert t.unit == lq2.unit.function_unit * u.m
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(lq2.unit.physical_unit)

        t = tf / (50. * u.cm)
        # now we essentially have the same quantity but with a prefactor of 2
        assert t.unit.is_equivalent(lq2.unit.function_unit)
        assert_allclose(t.to(lq2.unit.function_unit), lq2._function_view * 2)
Ejemplo n.º 8
0
    def test_comparison_to_non_quantities_fails(self):
        lq = u.Magnitude(np.arange(1., 10.) * u.Jy)
        with pytest.raises(TypeError):
            lq > 'a'

        assert not (lq == 'a')
        assert lq != 'a'
Ejemplo n.º 9
0
def compute_zp(tic_params, dbg=False, emulate_signal=False):

    # Calculate photons/sec/A/cm^2 for mag=0.0 source
    m_0 = compute_photon_rate(0.0, tic_params, emulate_signal)

    # Calculate effective capture cross-section
    eff_area = calculate_effective_area(tic_params, dbg)
    zp = m_0 * eff_area

    # If imaging, multiply by bandwidth of filter. If spectroscopy, just drop angstrom units
    if tic_params.get('imaging', False):
        zp *= tic_params['bandwidth'].to(u.angstrom)
    else:
        zp *= u.angstrom

    # Convert to magnitude
    zp_mag = None
    if zp != 0:
        zp_mag = -u.Magnitude(zp)
        if dbg:
            print('ZP (photons/sec)=', zp)
        if dbg:
            print('ZP (mag+extinct)=', zp_mag)

    return zp, zp_mag
Ejemplo n.º 10
0
def test_custom_mag_model():
    """
    Test creation of custom model from Quantity arrays
    """
    wave = np.linspace(0.3, 2.0, 50)
    extinction = u.Magnitude(1. / wave, u.MagUnit(u.dimensionless_unscaled))
    ext = AtmosphericExtinction(extinction=extinction, spectral_axis=wave * u.um)
    assert(len(ext.extinction_mag) > 0)
    assert(len(ext.transmission) > 0)
Ejemplo n.º 11
0
    def test_addition_subtraction_to_normal_units_fails(self, other):
        lq = u.Magnitude(np.arange(1., 10.) * u.Jy)
        q = 1.23 * other
        with pytest.raises(u.UnitsError):
            lq + q

        with pytest.raises(u.UnitsError):
            lq - q

        with pytest.raises(u.UnitsError):
            q - lq
Ejemplo n.º 12
0
    def test_inplace_addition_subtraction_unit_checks(self, other):
        lu1 = u.mag(u.Jy)
        lq1 = u.Magnitude(np.arange(1., 10.), lu1)
        with pytest.raises(u.UnitsError):
            lq1 += other

        assert np.all(lq1.value == np.arange(1., 10.))
        assert lq1.unit == lu1

        with pytest.raises(u.UnitsError):
            lq1 -= other

        assert np.all(lq1.value == np.arange(1., 10.))
        assert lq1.unit == lu1
Ejemplo n.º 13
0
    def test_inplace_addition_subtraction(self, other):
        """Check that inplace addition/subtraction with quantities with
        magnitude or MagUnit units works, and that it changes the physical
        units appropriately."""
        lq = u.Magnitude(np.arange(1., 10.) * u.Jy)
        other_physical = other.to(getattr(other.unit, 'physical_unit',
                                          u.dimensionless_unscaled),
                                  equivalencies=u.logarithmic())
        lq_sf = lq.copy()
        lq_sf += other
        assert_allclose(lq_sf.physical, lq.physical * other_physical)

        lq_df = lq.copy()
        lq_df -= other
        assert_allclose(lq_df.physical, lq.physical / other_physical)
Ejemplo n.º 14
0
def flux2mag(flux, filtname, nusepoints=15):
    '''Load the zero magnitude from the dict file and convert it to
    flux'''
    zeroflux = loadfiltzeros(filtname)
    tfilt = get_filter(filtname)
    usepoints = np.linspace(np.min(tfilt['lambda'].to('Angstrom')),
                            np.max(tfilt['lambda'].to('Angstrom')),
                            num=nusepoints)
    new_throughput = np.full(nusepoints, np.nan)
    for ipoint in range(nusepoints):
        new_throughput[ipoint] = tfilt['transmis'][find_nearest(
            tfilt['lambda'], usepoints[ipoint])]
        zerofluxint = integrate_flux(zeroflux * new_throughput, usepoints)
    mag = u.Magnitude((-2.5 * np.log10(flux / zerofluxint)).value)
    return mag
Ejemplo n.º 15
0
 def errormag(self):
     """Return error as magnitude quantity.  
        The error on the magnitude is ~1/(S/N) which is ~(flux error)/flux.
        For a discussion of converting magitude errors to flux errors
        and vice versa, see e.g., https://www.eso.org/~ohainaut/ccd/sn.html
        and http://slittlefair.staff.shef.ac.uk/teaching/phy217/lectures/stats/L18/index.html
        This method uses the full calculation rather than the approximation.
     """
     if qh.isFluxDensity(self._error):
         # S/N is the fractional error on the flux
         # NtoS is 1/(S/N)
         NtoS = self._error / self._flux
         magerror = 2.5 * math.log10(1.0 + NtoS)
         return u.Magnitude(magerror)
     else:
         return self._error
Ejemplo n.º 16
0
    def fluxtomag(self, telescope, band, flux, mjy=True):
        """Return the magnitude given flux in Jansky as magnitude astropy Quantity.
          Parameters:
             telescope - string telescope name, one of
                         sloan, gaia, 2MASS, Spitzer, Herschel, Wise - case insensitive
             band      - wave band name of telescope e.g., 'u' for sloan, 'I1' for spitzer
             flux      - flux density of source, scalar in Jy or mJy, or Astropy Quantity with units of flux density
             mjy       - boolean, True if flux was given in mJy False if Jy. Ignored if flux is given as Quantity

        Example: fluxtomag(SLOAN,SDSS_u,156.85)  returns 10 mag
       """
        zpjy = self._filtersets[telescope.lower()][band].zp().to(u.Jy)
        if qh.isQuantity(flux):
            fval = flux.to(u.Jy).value
        else:
            if mjy == True: fval = flux / 1000.0
            else: fval = flux
        return u.Magnitude(-2.5 * np.log10(fval / zpjy.value))
Ejemplo n.º 17
0
 def test_different_units(self, unit):
     q = u.Magnitude(1.23, unit)
     assert q.unit.function_unit == getattr(unit, 'function_unit', unit)
     assert q.unit.physical_unit is getattr(unit, 'physical_unit',
                                            u.dimensionless_unscaled)
Ejemplo n.º 18
0
 def setup(self):
     self.lq = u.Magnitude(np.arange(1., 10.) * u.Jy)
     self.lq2 = u.Magnitude(np.arange(1., 5.))
Ejemplo n.º 19
0
def na_back_directory(directory,
                      calibration=True,
                      read_pout=True,
                      write_pout=True,
                      write_plot=True,
                      create_outdir=True,
                      show=False,
                      **kwargs):
    rd = reduced_dir(directory, create=False)
    poutname = os.path.join(rd, 'Na_back.pout')
    pout = cached_pout(na_back_pipeline,
                       poutname=poutname,
                       read_pout=read_pout,
                       write_pout=write_pout,
                       create_outdir=create_outdir,
                       directory=directory,
                       **kwargs)
    if len(pout) == 0:
        log.debug(f'no Na background measurements found in {directory}')
        return {}
    _, pipe_meta = zip(*pout)
    na_back_list = [pm['Na_back'] for pm in pipe_meta]
    df = pd.DataFrame(na_back_list)
    df.sort_values('jd')
    just_date = df['date'].iloc[0]

    instr_mag = u.Magnitude(df['best_back'] * u.electron / u.s / u.pix**2)
    df['instr_mag'] = instr_mag

    #tdf = df.loc[df['airmass'] < 2.0]
    tdf = df.loc[df['airmass'] < 2.5]
    mean_back = np.mean(tdf['best_back'])
    std_back = np.std(tdf['best_back'])
    biweight_back = biweight_location(tdf['best_back'])
    mad_std_back = mad_std(tdf['best_back'])

    # https://stackoverflow.com/questions/20664980/pandas-iterate-over-unique-values-of-a-column-that-is-already-in-sorted-order
    # and
    # https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html

    #https://matplotlib.org/stable/tutorials/intermediate/color_cycle.html
    offset_cycler = cycler(color=['r', 'g', 'b', 'y'])
    plt.rc('axes', prop_cycle=offset_cycler)

    f = plt.figure(figsize=[8.5, 11])
    plt.suptitle(f"Na background {just_date}")
    offset_groups = df.groupby(['raoff', 'decoff']).groups
    ax = plt.subplot(3, 1, 1)
    for offset_idx in offset_groups:
        gidx = offset_groups[offset_idx]
        gdf = df.iloc[gidx]
        plot_dates = julian2num(gdf['jd'])
        plt.plot_date(plot_dates,
                      gdf['best_back'],
                      label=f"dRA {gdf.iloc[0]['raoff']} "
                      f"dDEC {gdf.iloc[0]['decoff']} armin")
        plt.axhline(y=biweight_back, color='red')
        plt.axhline(y=biweight_back + mad_std_back,
                    linestyle='--',
                    color='k',
                    linewidth=1)
        plt.axhline(y=biweight_back - mad_std_back,
                    linestyle='--',
                    color='k',
                    linewidth=1)
        plt.text(0.5,
                 biweight_back + 0.1 * mad_std_back,
                 f'{biweight_back:.4f} +/- {mad_std_back:.4f}',
                 ha='center',
                 transform=ax.get_yaxis_transform())
        plt.xlabel('date')
        plt.ylabel('electron/s')
    ax.legend()

    ax = plt.subplot(3, 1, 2)
    for offset_idx in offset_groups:
        gidx = offset_groups[offset_idx]
        gdf = df.iloc[gidx]
        plt.plot(gdf['airmass'], gdf['instr_mag'], '.')
        #plt.axhline(y=biweight_back, color='red')
        #plt.axhline(y=biweight_back+mad_std_back,
        #            linestyle='--', color='k', linewidth=1)
        #plt.axhline(y=biweight_back-mad_std_back,
        #            linestyle='--', color='k', linewidth=1)
        plt.xlabel('Airmass')
        plt.ylabel('mag (electron/s/pix^2')

    ax = plt.subplot(3, 1, 3)
    for offset_idx in offset_groups:
        gidx = offset_groups[offset_idx]
        gdf = df.iloc[gidx]
        plt.plot(gdf['alt'], gdf['best_back'], '.')
        plt.axhline(y=biweight_back, color='red')
        plt.axhline(y=biweight_back + mad_std_back,
                    linestyle='--',
                    color='k',
                    linewidth=1)
        plt.axhline(y=biweight_back - mad_std_back,
                    linestyle='--',
                    color='k',
                    linewidth=1)
        plt.xlabel('Alt')
        plt.ylabel('electron/s')

    f.subplots_adjust(hspace=0.3)
    if write_plot is True:
        write_plot = os.path.join(rd, 'Na_back.png')
    if isinstance(write_plot, str):
        plt.savefig(write_plot, transparent=True)
    if show:
        plt.show()
    plt.close()

    # Problem discussed in  https://mail.python.org/pipermail/tkinter-discuss/2019-December/004153.html
    gc.collect()

    return {
        'date': just_date,
        'jd': np.floor(df['jd'].iloc[0]),
        'biweight_back': biweight_back,
        'mad_std_back': mad_std_back,
        'na_back_list': na_back_list
    }
Ejemplo n.º 20
0
    #        (fm.BESSEL_I,"FLUX_I","FLUX_ERROR_I"),
    #        (fm.TWOMASS_J,"FLUX_J","FLUX_ERROR_J"),
    #        (fm.TWOMASS_H,"FLUX_H","FLUX_ERROR_H"),
    #        (fm.TWOMASS_K,"FLUX_K","FLUX_ERROR_K")
]

#print(cols)

tfinal = Table.read("sdss_standards.votab")
seds = []
for i in tfinal:
    s = SED(i['StarName'], i['Distance_distance'] * u.pc,
            (i['Distance_merr'], i['Distance_perr']) * u.pc,
            i['RA_d'] * u.degree, i['DEC_d'] * u.degree)
    for c in cols:
        s.addData(c[0], u.Magnitude(i[c[1]]), u.Magnitude(i[c[2]]), 1)
    seds.append(s)
print(seds[0].header())
counter = 0
#spec = gridspec.Gridspec(nrows=4,ncols=4)
if False:
    for s in seds:
        if counter % 16 == 0:
            ax1 = ax2 = 0
            fig, ax = plt.subplots(ncols=4, nrows=4)
        axs = ax.reshape(-1)
        #    print(s.sedfitterinput())
        axs[counter].scatter(s.wavelengths(), s.fluxes(), c='k-')
        axs[counter].set_title(s._name)
        if counter % 16 == 15:
            plt.show()
Ejemplo n.º 21
0
    import filtermanage as fm
    pm = SED("MySource",
             distance=100 * u.pc,
             disterr=1 * u.pc,
             ra=13.3 * u.hour,
             dec=-22 * u.degree)
    # will raise exception
    try:
        pm = SED("testbaddistance", 100 * u.degree, 13.3 * u.hour,
                 -22 * u.degree)
    except Exception as e:
        print("EXCEPTION CAUGHT:", e)
    q = 1 * u.Jy
    #source id 4885742854871204860
    pm.addData(fm.SDSS_z,
               u.Magnitude(14.15327),
               u.Magnitude(0.007049335),
               validity=1)
    pm.addData(fm.SDSS_i,
               u.Magnitude(14.29342),
               u.Magnitude(0.006180155),
               validity=1)
    #pm.addData(fm.TWOMASS_K,q, q/100.0,validity=1)
    print(pm.errors())
    print(pm.errors().to(u.uJy))
    if False:
        # will raise warning
        pm.addData("3J", q / 10, q / 300.0, 1)
        pm.addData(fm.SDSS_u, q / 100, q / 1000.0, 0)
        print(pm.sedfitterinput())
Ejemplo n.º 22
0
 def make_cluster_rates(self, masses, ins, bandpass=None):
     filter = ins.filter
     instrument = ins.DETECTOR
     try:
         coords = np.load(os.path.join(self.gridpath, 'input.npy'),
                          allow_pickle=True)
     except UnicodeError:
         coords = np.load(os.path.join(self.gridpath, 'input.npy'),
                          allow_pickle=True,
                          encoding='bytes')
     m, t, g, i = self.get_star_info()
     temps = np.interp(masses, m, t)
     gravs = np.interp(masses, m, g)
     mags = np.interp(masses, m, i)
     metals = np.full_like(mags, self.metallicity)
     if os.path.exists(
             os.path.join(
                 self.gridpath,
                 'result_{}_{}.npy'.format(instrument.lower(),
                                           filter.lower()))):
         values = np.load(os.path.join(
             self.gridpath,
             'result_{}_{}.npy'.format(instrument.lower(), filter.lower())),
                          allow_pickle=True)
         interpolation_function = RegularGridInterpolator(
             tuple([x for x in coords]), values)
         try:
             countrates = interpolation_function(
                 np.array((metals, gravs, temps, mags)).T)
         except ValueError as v:
             self.log('error',
                      'Exception caught when interpolating: {}'.format(v))
             min_mag = coords[-1][0]
             max_mag = coords[-1][-1]
             interpolation_function = RegularGridInterpolator(
                 tuple([x for x in coords]),
                 values,
                 bounds_error=False,
                 fill_value=0.)
             mags_min = np.full_like(mags, min_mag)
             mags_max = np.full_like(mags, max_mag)
             countrates = interpolation_function(
                 np.array((metals, gravs, temps, mags)).T)
             countrates_min = interpolation_function(
                 np.array((metals, gravs, temps, mags_min)).T)
             countrates_min = countrates_min * np.power(
                 10, -(mags - min_mag) / 2.512)
             countrates_max = interpolation_function(
                 np.array((metals, gravs, temps, mags_max)).T)
             countrates_max = countrates_max * np.power(
                 10, -(mags - max_mag) / 2.512)
             countrates[np.where(
                 mags < mags_min)] = countrates_min[np.where(
                     mags < mags_min)]
             countrates[np.where(
                 mags > mags_max)] = countrates_max[np.where(
                     mags > mags_max)]
     else:
         self.log(
             'warning',
             'Could not find result file "result_{}_{}.npy" from {}'.format(
                 instrument.lower(), filter.lower(), self.gridpath))
         #             raise FileNotFoundError('Could not find result file "result_{}_{}.npy" from {}'.format(instrument.lower(), filter.lower(), self.gridpath))
         import synphot as syn
         import stsynphot as stsyn
         countrates = np.array(())
         johnson_i = syn.SpectralElement.from_filter('johnson_i')
         for te, log_g, z, j_i in zip(temps, gravs, metals, mags):
             spectrum = stsyn.grid_to_spec('phoenix', te, z, log_g)
             spectrum = spectrum.normalize(u.Magnitude(j_i), johnson_i)
             obs = syn.Observation(spectrum,
                                   bandpass,
                                   binset=spectrum.waveset)
             countrates = np.append(countrates, obs.countrate(ins.AREA))
             self.log(
                 'info', 'Manually created star {} of {}'.format(
                     len(countrates), len(temps)))
     return countrates
Ejemplo n.º 23
0
 def test_function_values(self, value, unit):
     lq = u.Magnitude(value, unit)
     assert lq == value
     assert lq.unit.function_unit == u.mag
     assert lq.unit.physical_unit == getattr(unit, 'physical_unit',
                                             value.unit.physical_unit)
Ejemplo n.º 24
0
 def test_error_on_lq_as_power(self):
     lq = u.Magnitude(np.arange(1., 4.) * u.Jy)
     with pytest.raises(TypeError):
         lq**lq
Ejemplo n.º 25
0
def extract_photometry(ccddata,
                       catalog,
                       catalog_coords,
                       target,
                       image_path=None,
                       aperture_radius=2. * u.arcsec,
                       bg_radius_in=None,
                       bg_radius_out=None):
    apertures = SkyCircularAperture(catalog_coords, aperture_radius)
    if bg_radius_in is not None and bg_radius_out is not None:
        apertures = [
            apertures,
            SkyCircularAnnulus(catalog_coords, bg_radius_in, bg_radius_out)
        ]
    photometry = aperture_photometry(ccddata, apertures)
    target_row = photometry[target][0]
    if target_row['xcenter'].value < 0. or target_row['xcenter'].value > ccddata.shape[1] or \
            target_row['ycenter'].value < 0. or target_row['ycenter'].value > ccddata.shape[0]:
        logging.error(
            'target not contained in the image (or coordinate solution is bad)'
        )
        return
    if 'aperture_sum_1' in photometry.colnames:
        flux = photometry['aperture_sum_0'] - photometry['aperture_sum_1']
        dflux = (photometry['aperture_sum_err_0']**2. +
                 photometry['aperture_sum_err_1']**2.)**0.5
    else:
        flux = photometry['aperture_sum']
        dflux = photometry['aperture_sum_err']
    photometry['aperture_mag'] = u.Magnitude(flux / ccddata.meta['exptime'])
    photometry['aperture_mag_err'] = 2.5 / np.log(10.) * dflux / flux
    photometry = hstack([catalog, photometry])
    photometry['zeropoint'] = photometry['catalog_mag'] - photometry[
        'aperture_mag'].value
    zeropoints = photometry['zeropoint'][~target].filled(np.nan)
    zp = np.nanmedian(zeropoints)
    zperr = mad_std(
        zeropoints,
        ignore_nan=True) / np.isfinite(zeropoints).sum()**0.5  # std error
    target_row = photometry[target][0]
    mag = target_row['aperture_mag'].value + zp
    dmag = (target_row['aperture_mag_err'].value**2. + zperr**2.)**0.5
    with open(lc_file, 'a') as f:
        f.write(
            f'{ccddata.meta["MJD-OBS"]:11.5f} {mag:6.3f} {dmag:5.3f} {zp:6.3f} {zperr:5.3f} {ccddata.meta["FILTER"]:>6s} '
            f'{ccddata.meta["TELESCOP"]:>16s} {ccddata.meta["filename"]:>22s}\n'
        )

    if image_path is not None:
        ax = plt.axes()
        mark = ',' if np.isfinite(
            photometry['aperture_mag']).sum() > 1000 else '.'
        ax.plot(photometry['aperture_mag'],
                photometry['catalog_mag'],
                ls='none',
                marker=mark,
                zorder=1,
                label='calibration stars')
        ax.plot(mag - zp, mag, ls='none', marker='*', zorder=3, label='target')
        yfit = np.array([21., 13.])
        xfit = yfit - zp
        ax.plot(xfit, yfit, label=f'$Z = {zp:.2f}$ mag', zorder=2)
        ax.set_xlabel('Instrumental Magnitude')
        ax.set_ylabel('AB Magnitude')
        ax.legend()
        plt.savefig(image_path, overwrite=True)
        plt.savefig('latest_cal.pdf', overwrite=True)
        plt.close()

        plt.figure(figsize=(6., 6.))
        imshow_norm(ccddata.data, interval=ZScaleInterval())
        plt.axis('off')
        plt.axis('tight')
        plt.tight_layout(pad=0.)
        if isinstance(apertures, list):
            for aperture in apertures:
                aperture.to_pixel(ccddata.wcs).plot(color='r', lw=1)
        else:
            apertures.to_pixel(ccddata.wcs).plot(color='r', lw=1)
        image_filename = ccddata.meta['filename'].replace('.fz', '').replace(
            '.fits', '.png')
        plt.savefig(os.path.join(image_dir, image_filename), overwrite=True)
        plt.savefig('latest_image.png', overwrite=True)
        plt.close()
Ejemplo n.º 26
0
class TestLogQuantityArithmetic:
    def test_multiplication_division(self):
        """Check that multiplication/division with other quantities is only
        possible when the physical unit is dimensionless, and that this turns
        the result into a normal quantity."""
        lq = u.Magnitude(np.arange(1., 11.) * u.Jy)

        with pytest.raises(u.UnitsError):
            lq * (1. * u.m)

        with pytest.raises(u.UnitsError):
            (1. * u.m) * lq

        with pytest.raises(u.UnitsError):
            lq / lq

        for unit in (u.m, u.mag, u.dex):
            with pytest.raises(u.UnitsError):
                lq / unit

        lq2 = u.Magnitude(np.arange(1, 11.))

        with pytest.raises(u.UnitsError):
            lq2 * lq

        with pytest.raises(u.UnitsError):
            lq2 / lq

        with pytest.raises(u.UnitsError):
            lq / lq2

        # but dimensionless_unscaled can be cancelled
        r = lq2 / u.Magnitude(2.)
        assert r.unit == u.dimensionless_unscaled
        assert np.all(r.value == lq2.value / 2.)

        # with dimensionless, normal units OK, but return normal quantities
        tf = lq2 * u.m
        tr = u.m * lq2
        for t in (tf, tr):
            assert not isinstance(t, type(lq2))
            assert t.unit == lq2.unit.function_unit * u.m
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(lq2.unit.physical_unit)

        t = tf / (50. * u.cm)
        # now we essentially have the same quantity but with a prefactor of 2
        assert t.unit.is_equivalent(lq2.unit.function_unit)
        assert_allclose(t.to(lq2.unit.function_unit), lq2._function_view * 2)

    @pytest.mark.parametrize('power', (2, 0.5, 1, 0))
    def test_raise_to_power(self, power):
        """Check that raising LogQuantities to some power is only possible when
        the physical unit is dimensionless, and that conversion is turned off
        when the resulting logarithmic unit (say, mag**2) is incompatible."""
        lq = u.Magnitude(np.arange(1., 4.) * u.Jy)

        if power == 0:
            assert np.all(lq**power == 1.)
        elif power == 1:
            assert np.all(lq**power == lq)
        else:
            with pytest.raises(u.UnitsError):
                lq**power

        # with dimensionless, it works, but falls back to normal quantity
        # (except for power=1)
        lq2 = u.Magnitude(np.arange(10.))

        t = lq2**power
        if power == 0:
            assert t.unit is u.dimensionless_unscaled
            assert np.all(t.value == 1.)
        elif power == 1:
            assert np.all(t == lq2)
        else:
            assert not isinstance(t, type(lq2))
            assert t.unit == lq2.unit.function_unit**power
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(u.dimensionless_unscaled)

    def test_error_on_lq_as_power(self):
        lq = u.Magnitude(np.arange(1., 4.) * u.Jy)
        with pytest.raises(TypeError):
            lq**lq

    @pytest.mark.parametrize('other', pu_sample)
    def test_addition_subtraction_to_normal_units_fails(self, other):
        lq = u.Magnitude(np.arange(1., 10.) * u.Jy)
        q = 1.23 * other
        with pytest.raises(u.UnitsError):
            lq + q

        with pytest.raises(u.UnitsError):
            lq - q

        with pytest.raises(u.UnitsError):
            q - lq

    @pytest.mark.parametrize(
        'other', (1.23 * u.mag, 2.34 * u.mag(), u.Magnitude(
            3.45 * u.Jy), u.Magnitude(4.56 * u.m), 5.67 * u.Unit(2 * u.mag),
                  u.Magnitude(6.78, 2. * u.mag)))
    def test_addition_subtraction(self, other):
        """Check that addition/subtraction with quantities with magnitude or
        MagUnit units works, and that it changes the physical units
        appropriately."""
        lq = u.Magnitude(np.arange(1., 10.) * u.Jy)
        other_physical = other.to(getattr(other.unit, 'physical_unit',
                                          u.dimensionless_unscaled),
                                  equivalencies=u.logarithmic())

        lq_sf = lq + other
        assert_allclose(lq_sf.physical, lq.physical * other_physical)

        lq_sr = other + lq
        assert_allclose(lq_sr.physical, lq.physical * other_physical)

        lq_df = lq - other
        assert_allclose(lq_df.physical, lq.physical / other_physical)

        lq_dr = other - lq
        assert_allclose(lq_dr.physical, other_physical / lq.physical)

    @pytest.mark.parametrize('other', pu_sample)
    def test_inplace_addition_subtraction_unit_checks(self, other):
        lu1 = u.mag(u.Jy)
        lq1 = u.Magnitude(np.arange(1., 10.), lu1)
        with pytest.raises(u.UnitsError):
            lq1 += other

        assert np.all(lq1.value == np.arange(1., 10.))
        assert lq1.unit == lu1

        with pytest.raises(u.UnitsError):
            lq1 -= other

        assert np.all(lq1.value == np.arange(1., 10.))
        assert lq1.unit == lu1

    @pytest.mark.parametrize(
        'other', (1.23 * u.mag, 2.34 * u.mag(), u.Magnitude(
            3.45 * u.Jy), u.Magnitude(4.56 * u.m), 5.67 * u.Unit(2 * u.mag),
                  u.Magnitude(6.78, 2. * u.mag)))
    def test_inplace_addition_subtraction(self, other):
        """Check that inplace addition/subtraction with quantities with
        magnitude or MagUnit units works, and that it changes the physical
        units appropriately."""
        lq = u.Magnitude(np.arange(1., 10.) * u.Jy)
        other_physical = other.to(getattr(other.unit, 'physical_unit',
                                          u.dimensionless_unscaled),
                                  equivalencies=u.logarithmic())
        lq_sf = lq.copy()
        lq_sf += other
        assert_allclose(lq_sf.physical, lq.physical * other_physical)

        lq_df = lq.copy()
        lq_df -= other
        assert_allclose(lq_df.physical, lq.physical / other_physical)

    def test_complicated_addition_subtraction(self):
        """For fun, a more complicated example of addition and subtraction."""
        dm0 = u.Unit('DM', 1. / (4. * np.pi * (10. * u.pc)**2))
        DMmag = u.mag(dm0)
        m_st = 10. * u.STmag
        dm = 5. * DMmag
        M_st = m_st - dm
        assert M_st.unit.is_equivalent(u.erg / u.s / u.AA)
        assert np.abs(M_st.physical / (m_st.physical * 4. * np.pi *
                                       (100. * u.pc)**2) - 1.) < 1.e-15
Ejemplo n.º 27
0
def lunar_background(sunlit_fraction, airmass, cusp_angle, ext=0.172):
    """
    Estimate lunar V-band background, based on Schaefer, Bulder & Bourgeois 1992.
    
    Parameters
    ----------
    sunlit_fraction : float
        Fraction of Lunar disc which is illuminated (1=Full Moon)
    airmass : float
        Airmass of observations
    cusp_angle : ~astropy.units.Quantity
        Location of star on Lunar limb during occultation
        
    Returns
    --------
    ugriz : ~astropy.units.Quantity
        ugriz background brightnesses in Mags/arcsec**2
    """
    # Illuminance of Sun
    # all illuminances in footcandles!
    Isun = 1.174e4 

    # covert sunlit fraction to phase angle
    alpha = np.arccos(2*sunlit_fraction-1) * u.rad
    alpha = alpha.to(u.deg).value
    
    # visual magnitude of entire moon.
    m = -12.73 + 0.026*np.fabs(alpha) + 4.0e-9*alpha**4
    # Illuminance of Moon
    Imoon = 10**(-0.4*(m+16.57)) 
    
    # Calculate the complement for calculating Earthshine
    alpha = 180-np.fabs(alpha)
    m = -12.73 + 0.026*np.fabs(alpha) + 4.0e-9*alpha**4
    Imoon_prime = 10**(-0.4*(m+16.57)) 

    # Illuminance of Earth as viewed from the Moon, found
    # by scaling Moon's brightness by area and Albedos
    Iearth = 78*Imoon_prime
    
    # Apparent surface brightness of Earthshine
    # all surface brightnesses in nanolamberts!
    Bmoon0 = 1.65e9 * 10.0**(-0.4*ext*airmass)
    B_es = Bmoon0*Iearth/Isun
        
    # Now the scattered moonlight
    theta_moon = 0.26 # angular size of moon, degrees
    # effective separation between source and center of Moon
    theta = theta_moon * (1.0 - 0.4*np.exp(-cusp_angle.to(u.deg).value/30))
    theta = theta * (np.cos(cusp_angle)**2 + (1-sunlit_fraction+np.sin(cusp_angle))**2)**0.5

    B_sc = 6.25e7 * Imoon / theta**2.0 
    B_sc = B_sc * (10.0**(-0.4*ext*airmass) - 10.0**(-0.8*ext*airmass)) 
    B_total = B_sc+B_es

    # now convert from nanolamberts to mag/sq arcsec
    V = (20.7233-np.log(B_total.value/34.08))/0.92104
    U = V+0.2
    B = V+0.5
    R = V-0.3
    I = V-1.0
    magsq = np.array([U,B,V,R,I])
    return u.Magnitude(ubv2ugr(magsq))/u.arcsec**2
Ejemplo n.º 28
0
def cps2mag(cps, band):
    """Convert GALEX counts per second to AB magnitudes."""
    return u.Magnitude(cps) + zero_point(band)