Exemple #1
0
def model_errors(catmag, band, sigma=3., mode='mag', trange=[1, 1600]):
    """
    Give upper and lower expected bounds as a function of the nominal
	    magnitude of a source. Very useful for identifying outliers.

    :param catmag: Nominal AB magnitude of the source.

    :type catmag: float

    :param band: The band to use, either 'FUV' or 'NUV'.

    :type band: str

    :param sigma: How many sigma out to set the bounds.

    :type sigma: float

    :param mode: Units in which to report bounds. Either 'cps' or 'mag'.

    :type mode: str

    :param trange: Set of integration times to compute the bounds on, in
        seconds.

    :type trange: list

    :returns: tuple -- A two-element tuple containing the lower and upper
        bounds, respectively.
	"""

    if mode != 'cps' and mode != 'mag':
        print('mode must be set to "cps" or "mag"')
        exit(0)

    x = np.arange(trange[0], trange[1])

    cnt = gt.mag2counts(catmag, band)

    ymin = (cnt * x / x) - sigma * np.sqrt(cnt * x) / x

    ymax = (cnt * x / x) + sigma * np.sqrt(cnt * x) / x

    if mode == 'mag':
        ymin = gt.counts2mag(ymin, band)
        ymax = gt.counts2mag(ymax, band)

    return ymin, ymax
Exemple #2
0
def model_errors(catmag, band, sigma=3., mode='mag', trange=[1, 1600]):
    """
    Give upper and lower expected bounds as a function of the nominal
	    magnitude of a source. Very useful for identifying outliers.

    :param catmag: Nominal AB magnitude of the source.

    :type catmag: float

    :param band: The band to use, either 'FUV' or 'NUV'.

    :type band: str

    :param sigma: How many sigma out to set the bounds.

    :type sigma: float

    :param mode: Units in which to report bounds. Either 'cps' or 'mag'.

    :type mode: str

    :param trange: Set of integration times to compute the bounds on, in
        seconds.

    :type trange: list

    :returns: tuple -- A two-element tuple containing the lower and upper
        bounds, respectively.
	"""

    if mode != 'cps' and mode != 'mag':
        print('mode must be set to "cps" or "mag"')
        exit(0)

    x = np.arange(trange[0], trange[1])

    cnt = gt.mag2counts(catmag, band)

    ymin = (cnt*x/x)-sigma*np.sqrt(cnt*x)/x

    ymax = (cnt*x/x)+sigma*np.sqrt(cnt*x)/x

    if mode == 'mag':
        ymin = gt.counts2mag(ymin, band)
        ymax = gt.counts2mag(ymax, band)

    return ymin, ymax
Exemple #3
0
def get_inff(lc, clipsigma=3, quiet=True, band='NUV', binsize=30.):
    """ Calculates the Instantaneous Non-Flare Flux values. """
    sclip = sigma_clip(np.array(lc['cps']), sigma=clipsigma)
    inff = np.ma.median(sclip)
    inff_err = np.sqrt(inff * len(sclip) * binsize) / (len(sclip) * binsize)
    if inff and not quiet:
        print('Quiescent at {m} AB mag.'.format(m=gt.counts2mag(inff, band)))
    return inff, inff_err
Exemple #4
0
def apcorrect_cps(lc, band, aper=gt.aper2deg(7)):
    """ Apply the aperture correction in units of linear counts-per-second.
    Aperture correction is linear in magnitude units, so convert the count rate
    into AB mag, correct it, and then convert it back.
    """
    return (gt.mag2counts(
        gt.counts2mag(lc['cps'].values, band) - gt.apcorrect1(aper, band),
        band))
Exemple #5
0
def data_errors(catmag, band, t, sigma=3., mode='mag'):
    """
    Given an array (of counts or mags), return an array of n-sigma error values.

    :param catmag: Nominal AB magnitude of the source.

    :type catmag: float

    :param t: Set of integration times to compute the bounds on, in seconds.

    :type t: list @CHASE - is this scalar or list? Also, consider trange
        instead of t to match first method?@

    :param band: The band to use, either 'FUV' or 'NUV'.

    :type band: str

    :param sigma: How many sigma out to set the bounds.

    :type sigma: float

    :param mode: Units in which to report bounds. Either 'cps' or 'mag'.

    :type mode: str

    :returns: tuple -- A two-element tuple containing the lower and upper
        uncertainty, respectively.
    """

    if mode != 'cps' and mode != 'mag':
        print('mode must be set to "cps" or "mag"')
        exit(0)

    cnt = gt.mag2counts(catmag, band)

    ymin = (cnt * t / t) - sigma * np.sqrt(cnt * t) / t

    ymax = (cnt * t / t) + sigma * np.sqrt(cnt * t) / t

    if mode == 'mag':
        ymin = gt.counts2mag(ymin, band)
        ymax = gt.counts2mag(ymax, band)

    return ymin, ymax
Exemple #6
0
def data_errors(catmag, band, t, sigma=3., mode='mag'):
    """
    Given an array (of counts or mags), return an array of n-sigma error values.

    :param catmag: Nominal AB magnitude of the source.

    :type catmag: float

    :param t: Set of integration times to compute the bounds on, in seconds.

    :type t: list @CHASE - is this scalar or list? Also, consider trange
        instead of t to match first method?@

    :param band: The band to use, either 'FUV' or 'NUV'.

    :type band: str

    :param sigma: How many sigma out to set the bounds.

    :type sigma: float

    :param mode: Units in which to report bounds. Either 'cps' or 'mag'.

    :type mode: str

    :returns: tuple -- A two-element tuple containing the lower and upper
        uncertainty, respectively.
    """

    if mode != 'cps' and mode != 'mag':
        print('mode must be set to "cps" or "mag"')
        exit(0)

    cnt = gt.mag2counts(catmag, band)

    ymin = (cnt*t/t)-sigma*np.sqrt(cnt*t)/t

    ymax = (cnt*t/t)+sigma*np.sqrt(cnt*t)/t

    if mode == 'mag':
        ymin = gt.counts2mag(ymin, band)
        ymax = gt.counts2mag(ymax, band)

    return ymin, ymax
Exemple #7
0
def dmag_errors(t, band, sigma=3., mode='mag', mags=np.arange(13, 24, 0.1)):
    """
    Given an exposure time, give dmag error bars at a range of magnitudes.

    :param t: Set of integration times to compute the bounds on, in seconds.

    :type t: list @CHASE - is this scalar or list? Also, consider trange
        instead of t to match first method?@

    :param band: The band to use, either 'FUV' or 'NUV'.

    :type band: str

    :param sigma: How many sigma out to set the bounds.

    :type sigma: float

    :param mode: Units in which to report bounds. Either 'cps' or 'mag'.

    :type mode: str

    :param mags: Set of magnitudes to compute uncertainties on.

    :type mags: numpy.ndarray

    :returns: tuple -- A three-element tuple containing the magnitudes and
        their lower and upper uncertainties, respectively.
    """

    cnts = gt.mag2counts(mags, band) * t

    ymin = (cnts - sigma / np.sqrt(cnts)) / t

    ymax = (cnts + sigma / np.sqrt(cnts)) / t

    if mode == 'mag':
        ymin = mags - gt.counts2mag(ymin, band)
        ymax = mags - gt.counts2mag(ymax, band)

    return mags, ymin, ymax
Exemple #8
0
def dmag_errors(t, band, sigma=3., mode='mag', mags=np.arange(13, 24, 0.1)):
    """
    Given an exposure time, give dmag error bars at a range of magnitudes.

    :param t: Set of integration times to compute the bounds on, in seconds.

    :type t: list @CHASE - is this scalar or list? Also, consider trange
        instead of t to match first method?@

    :param band: The band to use, either 'FUV' or 'NUV'.

    :type band: str

    :param sigma: How many sigma out to set the bounds.

    :type sigma: float

    :param mode: Units in which to report bounds. Either 'cps' or 'mag'.

    :type mode: str

    :param mags: Set of magnitudes to compute uncertainties on.

    :type mags: numpy.ndarray

    :returns: tuple -- A three-element tuple containing the magnitudes and
        their lower and upper uncertainties, respectively.
    """

    cnts = gt.mag2counts(mags, band)*t

    ymin = (cnts-sigma/np.sqrt(cnts))/t

    ymax = (cnts+sigma/np.sqrt(cnts))/t

    if mode == 'mag':
        ymin = mags-gt.counts2mag(ymin, band)
        ymax = mags-gt.counts2mag(ymax, band)

    return mags, ymin, ymax
Exemple #9
0
def calculate_flare_energy(lc,
                           frange,
                           distance,
                           binsize=30,
                           band='NUV',
                           effective_widths={
                               'NUV': 729.94,
                               'FUV': 255.45
                           },
                           quiescence=None):
    """ Calculates the energy of a flare in erg. """
    if not quiescence:
        q, _ = get_inff(lc)
        # Convert to aperture-corrected flux
        q = gt.mag2counts(
            gt.counts2mag(q, band) - gt.apcorrect1(gt.aper2deg(6), band), band)
    else:
        q = quiescence[0]

    # Convert from parsecs to cm
    distance_cm = distance * 3.086e+18
    if 'cps_apcorrected' in lc.keys():
        # Converting from counts / sec to flux units.
        flare_flux = (np.array(
            gt.counts2flux(np.array(lc.iloc[frange]['cps_apcorrected']), band))
                      - gt.counts2flux(q, band))
    else:
        # Really need to have aperture-corrected counts/sec.
        raise ValueError("Need aperture-corrected cps fluxes to continue.")
    # Zero any flux values where the flux is below the INFF so that we don't subtract from the total flux!
    flare_flux = np.array([0 if f < 0 else f for f in flare_flux])
    flare_flux_err = gt.counts2flux(np.array(lc.iloc[frange]['cps_err']), band)
    tbins = (np.array(lc.iloc[frange]['t1'].values) -
             np.array(lc.iloc[frange]['t0'].values))
    # Caluclate the area under the curve.
    integrated_flux = (binsize * flare_flux).sum()
    """
    GALEX effective widths from
    http://svo2.cab.inta-csic.es/svo/theory/fps3/index.php?id=GALEX/GALEX.NUV
    width = 729.94 A
    http://svo2.cab.inta-csic.es/svo/theory/fps3/index.php?id=GALEX/GALEX.FUV
    width = 255.45 A
    """
    # Convert integrated flux to a fluence using the GALEX effective widths.
    fluence = integrated_flux * effective_widths[band]
    fluence_err = (np.sqrt(
        ((gt.counts2flux(lc.iloc[frange]['cps_err'], band) * binsize)**
         2).sum()) * effective_widths[band])
    energy = (4 * np.pi * (distance_cm**2) * fluence)
    energy_err = (4 * np.pi * (distance_cm**2) * fluence_err)
    return energy, energy_err
Exemple #10
0
import gPhoton.galextools as gt

magrange = np.arange(14, 24, 1)

expt_ratio = 0.8  # Estimate of ration of effective to raw exposure time
t_raw = np.arange(1, 1600, 1)
t_eff = expt_ratio * t_raw

for sigma in [1, 3]:
    fig = plt.figure(figsize=(8 * 2, 6 * 2))
    for i, band in enumerate(['FUV', 'NUV']):
        plt.subplot(2, 1, i)
        plt.grid(b=True)
        plt.semilogx()
        plt.xlim(1, 1600)
        plt.title('{b} Detection Threshholds'.format(b=band))
        plt.xlabel('Exposure Bin Depth (s)')
        plt.ylabel('{n} Sigma Error (AB Mag)'.format(n=sigma))
        for mag in magrange:
            cps = gt.mag2counts(mag, band)
            cps_err = sigma * np.sqrt(cps * t_eff) / t_eff
            mag_err = mag - gt.counts2mag(cps + cps_err, band)
            plt.plot(t_raw, mag_err, label=mag)
        plt.legend()
    plt.savefig('GALEX {n} Sigma Detection Limits.png'.format(n=sigma))
Exemple #11
0
def quickmag(band, ra0, dec0, tranges, radius, annulus=None, stepsz=None,
             verbose=0, detsize=1.25, coadd=False):
    """
    Primary wrapper function for generating and synthesizing all of the
        parameters and calculations necessary to create light curves.

    :param band: The band being used, either 'FUV' or 'NUV'.

    :type band: str

    :param ra0: Right ascension, in degrees, of the target position.

    :type ra0: float

    :param dec0: Declination, in degrees, of the target position.

    :type dec0: float

    :param tranges: Set of time ranges to query within in GALEX time seconds.

    :type tranges: list

    :param radius: The radius of the  photometric aperture, in degrees.

    :type radius: float

    :param annulus: Radii of the inner and outer extents of the background
        annulus, in degrees.

    :type annulus: list

    :param stepsz: The size of the time bins to use, in seconds.

    :type stepsz: float

    :param verbose: Verbosity level, a value of 0 is minimum verbosity.

    :type verbose: int

    :param detsize: Effective diameter, in degrees, of the field-of-view.

    :param coadd: Set to True if calculating a total flux instead of flux
        from each time bin.

    :type coadd: bool

    :returns: dict -- The light curve, including input parameters.
    """

    if verbose:
        mc.print_inline("Retrieving all of the target events.")
    searchradius = radius if annulus is None else annulus[1]
    data = pullphotons(band, ra0, dec0, tranges, searchradius, verbose=verbose,
                       detsize=detsize)
    if not data:
        return None

    if verbose:
        mc.print_inline("Binning data according to requested depth.")

    # Multiple ways of defining bins
    try:
        trange = [np.array(tranges).min(), np.array(tranges).max()]
    except ValueError:
        trange = tranges

    if coadd:
        bins = np.array(trange)
    elif stepsz:
        bins = np.append(np.arange(trange[0], trange[1], stepsz), max(trange))
    else:
        bins = np.unique(np.array(tranges).flatten())

    lcurve = {'params':gphot_params(band, [ra0, dec0], radius, annulus=annulus,
                                    verbose=verbose, detsize=detsize,
                                    stepsz=stepsz, trange=trange)}

    # This is equivalent in function to np.digitize(data['t'],bins) except
    # that it's much, much faster. See numpy issue #2656 at
    # https://github.com/numpy/numpy/issues/2656
    bin_ix = np.searchsorted(bins, data['t'], "right")
    try:
        lcurve['t0'] = bins[np.unique(bin_ix)-1]
        lcurve['t1'] = bins[np.unique(bin_ix)]
        lcurve['exptime'] = np.array(
            dbt.compute_exptime(band,
                                tranges if coadd else list(zip(
                                    lcurve['t0'], lcurve['t1'])),
                                verbose=verbose, coadd=coadd, detsize=detsize,
                                skypos=[ra0, dec0]))
    except IndexError:
        if np.isnan(data['t']):
            if verbose:
                mc.print_inline(
                    "No valid data available in {t}".format(t=tranges))
        lcurve['t0'] = np.array([np.nan])
        lcurve['t1'] = np.array([np.nan])
        lcurve['exptime'] = np.array([0])

    angSep = mc.angularSeparation(ra0, dec0, data['ra'], data['dec'])

    aper_ix = np.where(angSep <= radius)
    lcurve['t0_data'] = reduce_lcurve(bin_ix, aper_ix, data['t'], np.min)
    lcurve['t1_data'] = reduce_lcurve(bin_ix, aper_ix, data['t'], np.max)
    lcurve['t_mean'] = reduce_lcurve(bin_ix, aper_ix, data['t'], np.mean)
    lcurve['q_mean'] = reduce_lcurve(bin_ix, aper_ix, data['q'], np.mean)
    lcurve['counts'] = reduce_lcurve(bin_ix, aper_ix, data['t'], len)
    lcurve['flat_counts'] = reduce_lcurve(bin_ix, aper_ix,
                                          1./data['response'], np.sum)
    lcurve['responses'] = reduce_lcurve(bin_ix, aper_ix, data['response'],
                                        np.mean)
    lcurve['detxs'] = reduce_lcurve(bin_ix, aper_ix, data['col'], np.mean)
    lcurve['detys'] = reduce_lcurve(bin_ix, aper_ix, data['row'], np.mean)
    lcurve['detrad'] = mc.distance(lcurve['detxs'], lcurve['detys'], 400, 400)
    lcurve['racent'] = reduce_lcurve(bin_ix, aper_ix, data['ra'], np.mean)
    lcurve['deccent'] = reduce_lcurve(bin_ix, aper_ix, data['dec'], np.mean)

    skybgmcatdata = dbt.get_mcat_data([ra0, dec0], radius)
    lcurve['mcat_bg'] = lcurve['exptime']*np.array(
        [dbt.mcat_skybg(band, [ra0, dec0], radius, trange=tr,
                        mcat=skybgmcatdata, verbose=verbose)
         for tr in zip(lcurve['t0'], lcurve['t1'])])

    if annulus is not None:
        annu_ix = np.where((angSep > annulus[0]) & (angSep <= annulus[1]))
        lcurve['bg_counts'] = reduce_lcurve(bin_ix, annu_ix, data['t'], len)
        lcurve['bg_flat_counts'] = reduce_lcurve(
            bin_ix, annu_ix, data['response'], np.sum)
        lcurve['bg'] = (mc.area(radius)*lcurve['bg_flat_counts'] /
                        (mc.area(annulus[1])-mc.area(annulus[0])))
    else:
        lcurve['bg_counts'] = np.zeros(len(lcurve['counts']))
        lcurve['bg_flat_counts'] = np.zeros(len(lcurve['counts']))
        lcurve['bg'] = np.zeros(len(lcurve['counts']))

    lcurve['cps'] = lcurve['flat_counts']/lcurve['exptime']
    lcurve['cps_err'] = aperture_error(lcurve['flat_counts'], lcurve['exptime'])
    lcurve['cps_bgsub'] = (lcurve['flat_counts']-
                           lcurve['bg'])/lcurve['exptime']
    lcurve['cps_bgsub_err'] = aperture_error(
        lcurve['flat_counts'], lcurve['exptime'], bgcounts=lcurve['bg'])
    lcurve['cps_mcatbgsub'] = (lcurve['flat_counts']-
                               lcurve['mcat_bg'])/lcurve['exptime']
    lcurve['cps_mcatbgsub_err'] = aperture_error(
        lcurve['flat_counts'], lcurve['exptime'], bgcounts=lcurve['mcat_bg'])
    lcurve['flux'] = gxt.counts2flux(lcurve['cps'], band)
    lcurve['flux_err'] = gxt.counts2flux(lcurve['cps_err'], band)
    lcurve['flux_bgsub'] = gxt.counts2flux(lcurve['cps_bgsub'], band)
    lcurve['flux_bgsub_err'] = gxt.counts2flux(lcurve['cps_bgsub_err'], band)
    lcurve['flux_mcatbgsub'] = gxt.counts2flux(lcurve['cps_mcatbgsub'], band)
    lcurve['flux_mcatbgsub_err'] = gxt.counts2flux(
        lcurve['cps_mcatbgsub_err'], band)

    # NOTE: These conversions to mag can throw logarithm warnings if the
    # background is brighter than the source, resuling in a negative cps which
    # then gets propagated as a magnitude of NaN.
    lcurve['mag'] = gxt.counts2mag(lcurve['cps'], band)
    lcurve['mag_err_1'] = (lcurve['mag'] -
                           gxt.counts2mag(lcurve['cps'] + lcurve['cps_err'],
                                          band))
    lcurve['mag_err_2'] = (gxt.counts2mag(lcurve['cps'] -
                                          lcurve['cps_err'], band) -
                           lcurve['mag'])
    lcurve['mag_bgsub'] = gxt.counts2mag(lcurve['cps_bgsub'], band)
    lcurve['mag_bgsub_err_1'] = (lcurve['mag_bgsub'] -
                                 gxt.counts2mag(lcurve['cps_bgsub'] +
                                                lcurve['cps_bgsub_err'], band))
    lcurve['mag_bgsub_err_2'] = (gxt.counts2mag(lcurve['cps_bgsub'] -
                                                lcurve['cps_bgsub_err'], band) -
                                 lcurve['mag_bgsub'])
    lcurve['mag_mcatbgsub'] = gxt.counts2mag(lcurve['cps_mcatbgsub'], band)
    lcurve['mag_mcatbgsub_err_1'] = (lcurve['mag_mcatbgsub'] -
                                     gxt.counts2mag(lcurve['cps_mcatbgsub'] +
                                                    lcurve['cps_mcatbgsub_err'],
                                                    band))
    lcurve['mag_mcatbgsub_err_2'] = (gxt.counts2mag(lcurve['cps_mcatbgsub'] -
                                                    lcurve['cps_mcatbgsub_err'],
                                                    band) -
                                     lcurve['mag_mcatbgsub'])

    lcurve['photons'] = data

    lcurve['flags'] = getflags(band, bin_ix, lcurve, verbose=verbose)

    return lcurve
Exemple #12
0
 def test_counts2mag_NUV(self):
     self.assertAlmostEqual(gt.counts2mag(10,'NUV'),-2.5*np.log10(10)+20.08)
Exemple #13
0
 def test_counts2mag_FUV(self):
     self.assertAlmostEqual(gt.counts2mag(10,'FUV'),-2.5*np.log10(10)+18.82)
def quickmag(band,
             ra0,
             dec0,
             tranges,
             radius,
             annulus=None,
             stepsz=None,
             verbose=0,
             detsize=1.25,
             coadd=False):
    """
    Primary wrapper function for generating and synthesizing all of the
        parameters and calculations necessary to create light curves.

    :param band: The band being used, either 'FUV' or 'NUV'.

    :type band: str

    :param ra0: Right ascension, in degrees, of the target position.

    :type ra0: float

    :param dec0: Declination, in degrees, of the target position.

    :type dec0: float

    :param tranges: Set of time ranges to query within in GALEX time seconds.

    :type tranges: list

    :param radius: The radius of the  photometric aperture, in degrees.

    :type radius: float

    :param annulus: Radii of the inner and outer extents of the background
        annulus, in degrees.

    :type annulus: list

    :param stepsz: The size of the time bins to use, in seconds.

    :type stepsz: float

    :param verbose: Verbosity level, a value of 0 is minimum verbosity.

    :type verbose: int

    :param detsize: Effective diameter, in degrees, of the field-of-view.

    :param coadd: Set to True if calculating a total flux instead of flux
        from each time bin.

    :type coadd: bool

    :returns: dict -- The light curve, including input parameters.
    """

    if verbose:
        mc.print_inline("Retrieving all of the target events.")
    searchradius = radius if annulus is None else annulus[1]
    data = pullphotons(band,
                       ra0,
                       dec0,
                       tranges,
                       searchradius,
                       verbose=verbose,
                       detsize=detsize)
    if not data:
        return None

    if verbose:
        mc.print_inline("Binning data according to requested depth.")

    # Multiple ways of defining bins
    try:
        trange = [np.array(tranges).min(), np.array(tranges).max()]
    except ValueError:
        trange = tranges

    if coadd:
        bins = np.array(trange)
    elif stepsz:
        bins = np.append(np.arange(trange[0], trange[1], stepsz), max(trange))
    else:
        bins = np.unique(np.array(tranges).flatten())

    lcurve = {
        'params':
        gphot_params(band, [ra0, dec0],
                     radius,
                     annulus=annulus,
                     verbose=verbose,
                     detsize=detsize,
                     stepsz=stepsz,
                     trange=trange)
    }

    # This is equivalent in function to np.digitize(data['t'],bins) except
    # that it's much, much faster. See numpy issue #2656 at
    # https://github.com/numpy/numpy/issues/2656
    bin_ix = np.searchsorted(bins, data['t'], "right")
    try:
        lcurve['t0'] = bins[np.unique(bin_ix) - 1]
        lcurve['t1'] = bins[np.unique(bin_ix)]
        lcurve['exptime'] = np.array(
            dbt.compute_exptime(
                band,
                tranges if coadd else list(zip(lcurve['t0'], lcurve['t1'])),
                verbose=verbose,
                coadd=coadd,
                detsize=detsize,
                skypos=[ra0, dec0]))
    except IndexError:
        if np.isnan(data['t']):
            if verbose:
                mc.print_inline(
                    "No valid data available in {t}".format(t=tranges))
        lcurve['t0'] = np.array([np.nan])
        lcurve['t1'] = np.array([np.nan])
        lcurve['exptime'] = np.array([0])

    angSep = mc.angularSeparation(ra0, dec0, data['ra'], data['dec'])

    aper_ix = np.where(angSep <= radius)
    lcurve['t0_data'] = reduce_lcurve(bin_ix, aper_ix, data['t'], np.min)
    lcurve['t1_data'] = reduce_lcurve(bin_ix, aper_ix, data['t'], np.max)
    lcurve['t_mean'] = reduce_lcurve(bin_ix, aper_ix, data['t'], np.mean)
    lcurve['q_mean'] = reduce_lcurve(bin_ix, aper_ix, data['q'], np.mean)
    lcurve['counts'] = reduce_lcurve(bin_ix, aper_ix, data['t'], len)
    lcurve['flat_counts'] = reduce_lcurve(bin_ix, aper_ix,
                                          1. / data['response'], np.sum)
    lcurve['responses'] = reduce_lcurve(bin_ix, aper_ix, data['response'],
                                        np.mean)
    lcurve['detxs'] = reduce_lcurve(bin_ix, aper_ix, data['col'], np.mean)
    lcurve['detys'] = reduce_lcurve(bin_ix, aper_ix, data['row'], np.mean)
    lcurve['detrad'] = mc.distance(lcurve['detxs'], lcurve['detys'], 400, 400)
    lcurve['racent'] = reduce_lcurve(bin_ix, aper_ix, data['ra'], np.mean)
    lcurve['deccent'] = reduce_lcurve(bin_ix, aper_ix, data['dec'], np.mean)

    skybgmcatdata = dbt.get_mcat_data([ra0, dec0], radius)
    lcurve['mcat_bg'] = lcurve['exptime'] * np.array([
        dbt.mcat_skybg(band, [ra0, dec0],
                       radius,
                       trange=tr,
                       mcat=skybgmcatdata,
                       verbose=verbose)
        for tr in zip(lcurve['t0'], lcurve['t1'])
    ])

    if annulus is not None:
        annu_ix = np.where((angSep > annulus[0]) & (angSep <= annulus[1]))
        lcurve['bg_counts'] = reduce_lcurve(bin_ix, annu_ix, data['t'], len)
        lcurve['bg_flat_counts'] = reduce_lcurve(bin_ix, annu_ix,
                                                 data['response'], np.sum)
        lcurve['bg'] = (mc.area(radius) * lcurve['bg_flat_counts'] /
                        (mc.area(annulus[1]) - mc.area(annulus[0])))
    else:
        lcurve['bg_counts'] = np.zeros(len(lcurve['counts']))
        lcurve['bg_flat_counts'] = np.zeros(len(lcurve['counts']))
        lcurve['bg'] = np.zeros(len(lcurve['counts']))

    lcurve['cps'] = lcurve['flat_counts'] / lcurve['exptime']
    lcurve['cps_err'] = aperture_error(lcurve['flat_counts'],
                                       lcurve['exptime'])
    lcurve['cps_bgsub'] = (lcurve['flat_counts'] -
                           lcurve['bg']) / lcurve['exptime']
    lcurve['cps_bgsub_err'] = aperture_error(lcurve['flat_counts'],
                                             lcurve['exptime'],
                                             bgcounts=lcurve['bg'])
    lcurve['cps_mcatbgsub'] = (lcurve['flat_counts'] -
                               lcurve['mcat_bg']) / lcurve['exptime']
    lcurve['cps_mcatbgsub_err'] = aperture_error(lcurve['flat_counts'],
                                                 lcurve['exptime'],
                                                 bgcounts=lcurve['mcat_bg'])
    lcurve['flux'] = gxt.counts2flux(lcurve['cps'], band)
    lcurve['flux_err'] = gxt.counts2flux(lcurve['cps_err'], band)
    lcurve['flux_bgsub'] = gxt.counts2flux(lcurve['cps_bgsub'], band)
    lcurve['flux_bgsub_err'] = gxt.counts2flux(lcurve['cps_bgsub_err'], band)
    lcurve['flux_mcatbgsub'] = gxt.counts2flux(lcurve['cps_mcatbgsub'], band)
    lcurve['flux_mcatbgsub_err'] = gxt.counts2flux(lcurve['cps_mcatbgsub_err'],
                                                   band)

    # NOTE: These conversions to mag can throw logarithm warnings if the
    # background is brighter than the source, resuling in a negative cps which
    # then gets propagated as a magnitude of NaN.
    lcurve['mag'] = gxt.counts2mag(lcurve['cps'], band)
    lcurve['mag_err_1'] = (
        lcurve['mag'] -
        gxt.counts2mag(lcurve['cps'] + lcurve['cps_err'], band))
    lcurve['mag_err_2'] = (
        gxt.counts2mag(lcurve['cps'] - lcurve['cps_err'], band) -
        lcurve['mag'])
    lcurve['mag_bgsub'] = gxt.counts2mag(lcurve['cps_bgsub'], band)
    lcurve['mag_bgsub_err_1'] = (
        lcurve['mag_bgsub'] -
        gxt.counts2mag(lcurve['cps_bgsub'] + lcurve['cps_bgsub_err'], band))
    lcurve['mag_bgsub_err_2'] = (
        gxt.counts2mag(lcurve['cps_bgsub'] - lcurve['cps_bgsub_err'], band) -
        lcurve['mag_bgsub'])
    lcurve['mag_mcatbgsub'] = gxt.counts2mag(lcurve['cps_mcatbgsub'], band)
    lcurve['mag_mcatbgsub_err_1'] = (lcurve['mag_mcatbgsub'] - gxt.counts2mag(
        lcurve['cps_mcatbgsub'] + lcurve['cps_mcatbgsub_err'], band))
    lcurve['mag_mcatbgsub_err_2'] = (gxt.counts2mag(
        lcurve['cps_mcatbgsub'] - lcurve['cps_mcatbgsub_err'], band) -
                                     lcurve['mag_mcatbgsub'])

    lcurve['photons'] = data

    lcurve['flags'] = getflags(band, bin_ix, lcurve, verbose=verbose)

    return lcurve
Exemple #15
0
import gPhoton.galextools as gt

magrange = np.arange(14,24,1)

expt_ratio = 0.8 # Estimate of ration of effective to raw exposure time
t_raw = np.arange(1,1600,1)
t_eff = expt_ratio*t_raw

for sigma in [1,3]:
    fig = plt.figure(figsize=(8*2,6*2))
    for i,band in enumerate(['FUV','NUV']):
        plt.subplot(2,1,i)
        plt.grid(b=True)
        plt.semilogx()
        plt.xlim(1,1600)
        plt.title('{b} Detection Threshholds'.format(b=band))
        plt.xlabel('Exposure Bin Depth (s)')
        plt.ylabel('{n} Sigma Error (AB Mag)'.format(n=sigma))
        for mag in magrange:
            cps = gt.mag2counts(mag,band)
            cps_err = sigma*np.sqrt(cps*t_eff)/t_eff
            mag_err = mag-gt.counts2mag(cps+cps_err,band)
            plt.plot(t_raw,mag_err,label=mag)
        plt.legend()
    plt.savefig('GALEX {n} Sigma Detection Limits.png'.format(n=sigma))