Example #1
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
Example #2
0
def calculate_ideal_flare_energy(model,
                                 quiescence,
                                 distance,
                                 band='NUV',
                                 effective_widths={
                                     'NUV': 729.94,
                                     'FUV': 255.45
                                 },
                                 quiet=True):
    """ Because it's an 'ideal flare,' we can make assumptions that improve
    runtime. """
    q = quiescence

    distance_cm = distance * 3.086e+18  # convert from parsecs to cm
    # NOTE: This does not interpolate over small gaps.
    flare_flux = np.array(model['flux'].values) - counts2flux(q, band)
    flare_flux = np.array([0 if f < 0 else f for f in flare_flux])
    tbins = np.array(model['t1']) - np.array(model['t0'])
    integrated_flux = (tbins * flare_flux).sum()
    """
    GALEX effective widths from
    http://svo2.cab.inta-csic.es/svo/theory/fps3/index.php?id=GALEX/GALEX.NUV:
    729.94 Angstroms
    http://svo2.cab.inta-csic.es/svo/theory/fps3/index.php?id=GALEX/GALEX.FUV:
    255.45 Angstroms
    """
    fluence = integrated_flux * effective_widths[band]
    energy = (4 * np.pi * (distance_cm**2) * fluence)
    return energy
Example #3
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
Example #4
0
def fake_a_flare(
    band='NUV',
    quiescent_mag=18,
    fpeak_mags=[17],  # peak flux of flares
    stepsz=30.,  # integration depth in seconds
    trange=[0, 1600],  # visit length in seconds
    tpeaks=[250],  # peak time of flares
    fwidths=[60],  # "fwhm" of flares
    resolution=0.05,  # normal photon time resolution
    flat_err=0.15  # 15% error in the NUV flat field
):

    quiescent_cps = mag2counts(quiescent_mag, band)
    t = np.arange(trange[0], trange[1], resolution)
    tbins = np.arange(trange[0], trange[1], stepsz)
    models = []

    for ii, fpeak_mag, tpeak, fwidth in zip(range(len(fpeak_mags)), fpeak_mags,
                                            tpeaks, fwidths):
        fpeak_cps = mag2counts(fpeak_mag, band)
        flare = (aflare(t, [tpeak, fwidth,
                            max(fpeak_cps - quiescent_cps, 0)]) +
                 quiescent_cps)

        flare_binned = []
        for t0 in tbins:
            ix = np.where((t >= t0) & (t < t0 + stepsz))
            flare_binned += [np.array(flare)[ix].sum() / len(ix[0])]

        flare_binned_counts = np.array(flare_binned) * stepsz
        flare_obs = np.array([
            np.random.normal(loc=counts, scale=np.sqrt(counts)) / stepsz
            for counts in flare_binned_counts
        ])
        flare_obs_err = np.array(
            [np.sqrt(counts) / stepsz for counts in flare_binned_counts])

        model_dict = {
            't0': t,
            't1': t + resolution,
            'cps': flare,
            'cps_err': np.zeros(len(flare)),
            'flux': counts2flux(flare, band),
            'flux_err': np.zeros(len(flare)),
            'flags': np.zeros(len(flare))
        }
        models.append(pd.DataFrame(model_dict))

        # Construct a simulated lightcurve dataframe.
        # NOTE: Since we don't need to worry about aperture corrections, we
        # copy the cps and cps_err into those so the paper's pipeline can run on
        # this simulated light curve too.  We assume no missing time coverage in
        # the time bins, since those with bad coverage are avoided in our paper's
        # pipeline anyways, and thus set the 'expt' to be the same as the
        # requested bin size.
        if ii == 0:
            # First flare in visit, setup the entire light curve.
            lc_dict = {
                't0': tbins,
                't1': tbins + stepsz,
                'cps': flare_obs,
                'cps_err': flare_obs_err,
                'cps_apcorrected': flare_obs,
                'counts': flare_binned_counts,
                'flux': counts2flux(flare_obs, band),
                'flux_err': counts2flux(flare_obs_err, band),
                'expt': np.full(len(tbins), stepsz),
                'flags': np.zeros(len(tbins))
            }
        else:
            # More flares in this light curve, only need to adjust the fluxes.
            lc_dict['cps'] += flare_obs
            lc_dict['cps_err'] = ((lc_dict['cps_err'])**2. +
                                  (flare_obs_err)**2.)**0.5
            lc_dict['cps_apcorrected'] += flare_obs
            lc_dict['counts'] += flare_binned_counts
            lc_dict['flux'] += counts2flux(flare_obs, band)
            lc_dict['flux_err'] = ((lc_dict['flux_err'])**2. +
                                   (counts2flux(flare_obs_err, band))**2.)**0.5

    # "TRUTH" + simulated lightcurve dataframe
    return models, pd.DataFrame(lc_dict)
Example #5
0
 def test_counts2flux_NUV(self):
     self.assertAlmostEqual(gt.counts2flux(10,'NUV'),2.06e-16* 10)
Example #6
0
 def test_counts2flux_FUV(self):
     self.assertAlmostEqual(gt.counts2flux(10,'FUV'),1.4e-15 * 10)
Example #7
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
Example #8
0
def make_lightcurve(photon_file,
                    band,
                    stepsz=30.,
                    skypos=(24.76279, -17.94948),
                    aper=gt.aper2deg(7),
                    fixed_t0=False,
                    makefile=False,
                    quiet=False,
                    filetag='',
                    lc_filename=None):
    """ Generate a light curve of a specific target. """
    if lc_filename is None:
        lc_filename = photon_file.replace(
            '.csv', '-{stepsz}s{filetag}.csv'.format(stepsz=int(stepsz),
                                                     filetag=filetag))
    if os.path.exists(lc_filename) and not makefile:
        if not quiet:
            print_inline('    Pre-exists, reading in file...')
        return pd.read_csv(lc_filename)
    else:
        if not quiet:
            print_inline('Generating {fn}'.format(fn=lc_filename))
    events = calibrate_photons(photon_file, band)
    # Below is a calculation of the re-centering, if desired.
    skypos_recentered = recenter(events, skypos=skypos)
    c1 = SkyCoord(ra=skypos[0] * u.degree, dec=skypos[1] * u.degree)
    c2 = SkyCoord(ra=skypos_recentered[0] * u.degree,
                  dec=skypos_recentered[1] * u.degree)
    if not quiet:
        print('Recentering aperture on [{ra}, {dec}]'.format(
            ra=skypos_recentered[0], dec=skypos_recentered[1]))
        print("Recenter shift (arcsec): " + str(c1.separation(c2).arcsec))
    ix = aper_photons(events, skypos=skypos_recentered, aper=aper)
    if len(ix[0]) == 0:
        return [], [], [], []
    trange = [
        np.floor(np.array(events['t'])[ix].min()),
        np.ceil(np.array(events['t'])[ix].max())
    ]
    if fixed_t0:
        # Use this to force NUV and FUV to have the same bins
        trange[0] = fixed_t0
    expt = compute_exptime_array(np.array(events['t'].values), band, trange,
                                 stepsz, np.array(events['flags'].values))
    counts, tbins, detrads = [], [], []
    col, row = np.array(events['col']), np.array(events['row'])
    detrad = np.sqrt((col - 400)**2 + (row - 400)**2)
    for t0 in np.arange(trange[0], trange[1], stepsz):
        tix = np.where((np.array(events['t'])[ix] >= t0)
                       & (np.array(events['t']) < t0 + stepsz)[ix]
                       & (np.array(events['flags'], dtype='int16')[ix] == 0))
        tbins += [t0]
        detrads += [detrad[ix][tix].mean()]
        if len(tix[0]) == 0:
            counts += [0.]
        else:
            counts += [np.array(events['response'])[ix][tix].sum()]
    cps = np.array(counts) / np.array(expt)
    cps_err = np.sqrt(counts) / np.array(expt)
    lc = pd.DataFrame({
        't0': tbins,
        't1': list(np.array(tbins) + stepsz),
        'cps': cps,
        'cps_err': cps_err,
        'flux': gt.counts2flux(cps, band),
        'flux_err': gt.counts2flux(cps_err, band),
        'counts': counts,
        'expt': expt,
        'detrad': detrads
    })
    lc['cps_apcorrected'] = apcorrect_cps(lc, band, aper=aper)
    lc['flux_apcorrected'] = gt.counts2flux(lc['cps_apcorrected'], band)
    lc.to_csv(lc_filename)
    return lc