Example #1
0
def test_token_user_post_and_get_different_systems_flux(
    upload_data_token, public_source, ztf_camera, public_group
):

    status, data = api(
        'POST',
        'photometry',
        data={
            'obj_id': str(public_source.id),
            'mjd': 58000.0,
            'instrument_id': ztf_camera.id,
            'mag': 21.0,
            'magerr': 0.2,
            'limiting_mag': 22.3,
            'magsys': 'vega',
            'filter': 'ztfg',
            'group_ids': [public_group.id],
        },
        token=upload_data_token,
    )
    assert status == 200
    assert data['status'] == 'success'

    photometry_id = data['data']['ids'][0]
    status, data = api(
        'GET',
        f'photometry/{photometry_id}?format=flux&magsys=vega',
        token=upload_data_token,
    )
    assert status == 200
    assert data['status'] == 'success'

    ab = sncosmo.get_magsystem('ab')
    vega = sncosmo.get_magsystem('vega')
    correction = 2.5 * np.log10(vega.zpbandflux('ztfg') / ab.zpbandflux('ztfg'))

    np.testing.assert_allclose(
        data['data']['flux'], 10 ** (-0.4 * (21 - correction - 23.9))
    )
    np.testing.assert_allclose(
        data['data']['fluxerr'], 0.2 / (2.5 / np.log(10)) * data['data']['flux']
    )
    np.testing.assert_allclose(data['data']['zp'], 23.9 + correction)

    status, data = api(
        'GET',
        f'photometry/{photometry_id}?format=flux&magsys=ab',
        token=upload_data_token,
    )
    assert status == 200
    assert data['status'] == 'success'

    np.testing.assert_allclose(
        data['data']['flux'], 10 ** (-0.4 * (21 - correction - 23.9))
    )
    np.testing.assert_allclose(
        data['data']['fluxerr'], 0.2 / (2.5 / np.log(10)) * data['data']['flux']
    )
    np.testing.assert_allclose(data['data']['zp'], 23.9)
Example #2
0
def test_register_loader():
    # Register a loader that returns a MagSystem.
    magsys = sncosmo.get_magsystem('ab')
    sncosmo.register_loader(sncosmo.magsystems.MagSystem,
                            'test_magsystem',
                            basic_loader,
                            args=(magsys, ))

    # make sure that we can get the magnitude system back.
    assert sncosmo.get_magsystem('test_magsystem') is magsys
Example #3
0
def test_token_user_retrieving_source_photometry_and_convert(view_only_token, public_source):
    status, data = api('GET', f'sources/{public_source.id}/photometry?format=flux&magsys=ab',
                       token=view_only_token)
    assert status == 200
    assert data['status'] == 'success'
    assert isinstance(data['data'], list)
    assert 'mjd' in data['data'][0]
    assert 'ra_unc' in data['data'][0]

    mag1_ab = -2.5 * np.log10(data['data'][0]['flux']) + data['data'][0]['zp']
    magerr1_ab = 2.5 / np.log(10) * data['data'][0]['fluxerr']/ data['data'][0]['flux']

    maglast_ab = -2.5 * np.log10(data['data'][-1]['flux']) + data['data'][-1]['zp']
    magerrlast_ab = 2.5 / np.log(10) * data['data'][-1]['fluxerr']/ data['data'][-1]['flux']

    status, data = api('GET', f'sources/{public_source.id}/photometry?format=mag&magsys=ab',
                       token=view_only_token)
    assert status == 200
    assert data['status'] == 'success'

    assert np.allclose(mag1_ab, data['data'][0]['mag'])
    assert np.allclose(magerr1_ab, data['data'][0]['magerr'])

    assert np.allclose(maglast_ab, data['data'][-1]['mag'])
    assert np.allclose(magerrlast_ab, data['data'][-1]['magerr'])


    status, data = api('GET', f'sources/{public_source.id}/photometry?format=flux&magsys=vega',
                       token=view_only_token)

    mag1_vega = -2.5 * np.log10(data['data'][0]['flux']) + data['data'][0]['zp']
    magerr1_vega = 2.5 / np.log(10) * data['data'][0]['fluxerr']/ data['data'][0]['flux']

    maglast_vega = -2.5 * np.log10(data['data'][-1]['flux']) + data['data'][-1]['zp']
    magerrlast_vega = 2.5 / np.log(10) * data['data'][-1]['fluxerr']/ data['data'][-1]['flux']


    assert status == 200
    assert data['status'] == 'success'

    ab = sncosmo.get_magsystem('ab')
    vega = sncosmo.get_magsystem('vega')
    vega_to_ab = {
        filter: 2.5 * np.log10(ab.zpbandflux(filter) / vega.zpbandflux(filter))
        for filter in ['ztfg', 'ztfr', 'ztfi']
    }


    assert np.allclose(mag1_ab, mag1_vega + vega_to_ab[data['data'][0]['filter']])
    assert np.allclose(magerr1_ab, magerr1_vega)

    assert np.allclose(maglast_ab, maglast_vega + vega_to_ab[data['data'][-1]['filter']])
    assert np.allclose(magerrlast_ab, magerrlast_vega)
Example #4
0
def flux_to_mag(table, bandDict, zpsys='AB'):
    """
    Accepts an astropy table of flux data and does the conversion to mags (flux in ergs/s/cm^2/AA)

    :param table: Table containing flux, flux error error, and band columns
    :type table: astropy.Table
    :param bandDict: translates band to sncosmo.Bandpass object (i.e. 'U'-->bessellux)
    :type bandDict: dict
    :param zpsys: magnitude system
    :type zpsys: str,optional
    :returns: astropy.Table object with mag and mag error added
    """
    table = table[table['flux'] > 0]
    ms = sncosmo.get_magsystem(zpsys)
    table[_get_default_prop_name('mag')] = np.asarray(
        map(
            lambda x, y: ms.band_flux_to_mag(x, y),
            table[_get_default_prop_name(
                'flux')],  #/sncosmo.constants.HC_ERG_AA
            np.array(
                [bandDict[z] for z in table[_get_default_prop_name('band')]])))
    table[_get_default_prop_name('magerr')] = np.asarray(
        map(lambda x, y: 2.5 * np.log10(np.e) * y / x,
            table[_get_default_prop_name('flux')],
            table[_get_default_prop_name('fluxerr')]))
    table = table[np.abs(table['mag'] / table['magerr']) > 5]
    return (table)
Example #5
0
def load_filters(FILTER_PREFIX='tophat_'):
    '''
    Load UBVRI tophat filters defined in Pereira (2013) into the sncosmo
    registry.  Also returns a dictionary of zero-point values in Vega system
    flux for each filter.  Flux is given in [photons/s/cm^2].

    Example usage:

        ZP_CACHE = loader.load_filters()
        U_band_zp = ZP_CACHE['U']
    '''
    # dictionary for zero point fluxes of filters
    ZP_CACHE = {'prefix': FILTER_PREFIX}

    for f in 'UBVRI':
        filter_name = FILTER_PREFIX+f
        file_name = dirname+'/data/filters/'+filter_name+'.dat'
        
        try:
            snc.get_bandpass(filter_name)
        except:
            data = np.genfromtxt(file_name)
            bandpass = snc.Bandpass( data[:,0], data[:,1] )
            snc.registry.register(bandpass, filter_name)

        zpsys = snc.get_magsystem('ab')
        zp_phot = zpsys.zpbandflux(filter_name)

        ZP_CACHE[f] = zp_phot

    return ZP_CACHE
Example #6
0
def test_csp_magsystem():
    csp = sncosmo.get_magsystem('csp')

    # filter zeropoints (copied from file)
    zps = {
        "cspu": 13.044,
        "cspg": 15.135,
        "cspr": 14.915,
        "cspi": 14.781,
        "cspb": 14.344,
        "cspv3014": 14.540,
        "cspv3009": 14.493,
        "cspv9844": 14.450,
        "cspys": 13.921,
        "cspjs": 13.836,
        "csphs": 13.510,
        "cspk": 11.967,
        "cspyd": 13.770,
        "cspjd": 13.866,
        "csphd": 13.502
    }

    # The "zero point bandflux" should be the flux that corresponds to
    # magnitude zero. So, 0 = zp - 2.5 log(F)
    for band, zp in zps.items():
        assert abs(2.5 * math.log10(csp.zpbandflux(band)) - zp) < 0.015
Example #7
0
def test_compositemagsystem_band_error():
    """Test that CompositeMagSystem raises an error when band is
    not in system."""

    csp = sncosmo.get_magsystem('csp')
    with pytest.raises(ValueError):
        csp.zpbandflux('desi')
Example #8
0
def test_csp_magsystem():
    csp = sncosmo.get_magsystem('csp')

    # filter zeropoints (copied from
    # http://csp.obs.carnegiescience.edu/data/filters
    # on 13 April 2017)
    zps = {
        "cspu": 12.986,
        "cspg": 15.111,
        "cspr": 14.902,
        "cspi": 14.535,
        "cspb": 14.328,
        "cspv3014": 14.437,
        "cspv3009": 14.388,
        "cspv9844": 14.439,
        "cspys": 13.921,
        "cspjs": 13.836,
        "csphs": 13.510,
        "cspk": 11.968,
        "cspyd": 13.770,
        "cspjd": 13.866,
        "csphd": 13.502
    }

    # The "zero point bandflux" should be the flux that corresponds to
    # magnitude zero. So, 0 = zp - 2.5 log(F)
    for band, zp in zps.items():
        assert abs(2.5 * math.log10(csp.zpbandflux(band)) - zp) < 0.015
Example #9
0
def magnitude_in_band(band: str, spectrum):
    """ """
    bandpassfiles = load_info_json("bandpassfiles")
    zpbandfluxnames = load_info_json("zpbandfluxnames")
    additional_bands = load_info_json("additional_bands")

    # for bandpassfile in bandpassfiles:
    #     full_path_file = os.path.join(CURRENT_FILE_DIR, bandpassfile)
    #     bandpassfiles.update(bandpassfile: full_path_file)

    for bandname in additional_bands.keys():
        fname = additional_bands[bandname]
        b = np.loadtxt(os.path.join(CURRENT_FILE_DIR, fname))
        if "Swift" in fname:
            bandpass = sncosmo.Bandpass(b[:, 0], b[:, 1] / 50, name=bandname)
        else:
            bandpass = sncosmo.Bandpass(b[:, 0], b[:, 1], name=bandname)
        sncosmo.registry.register(bandpass, force=True)

    bp = sncosmo_spectral_v13.read_bandpass(
        os.path.join(CURRENT_FILE_DIR, bandpassfiles[band]))
    ab = sncosmo.get_magsystem("ab")
    zp_flux = ab.zpbandflux(zpbandfluxnames[band])
    bandflux = spectrum.bandflux(bp) / zp_flux
    mag = -2.5 * np.log10(bandflux)

    return mag
Example #10
0
def test_compositemagsystem_band_error():
    """Test that CompositeMagSystem raises an error when band is
    not in system."""

    csp = sncosmo.get_magsystem('csp')
    with pytest.raises(ValueError):
        csp.zpbandflux('desi')
Example #11
0
def mag_to_flux(table, bandDict, zpsys='AB'):
    """
    Accepts an astropy table of magnitude data and does the conversion to fluxes (flux in ergs/s/cm^2/AA)

    :param table: Table containing mag, mag error error, and band columns
    :type table: astropy.Table
    :param bandDict: translates band to sncosmo.Bandpass object (i.e. 'U'-->bessellux)
    :type bandDict: dict
    :param zpsys: magnitude system
    :type zpsys: str,optional
    :returns: astropy.Table object with flux and flux error added (flux in ergs/s/cm^2/AA)
    """
    ms = sncosmo.get_magsystem(zpsys)

    table[_get_default_prop_name('flux')] = asarray(
        list(
            map(
                lambda x, y: ms.band_mag_to_flux(
                    x, y) * sncosmo.constants.HC_ERG_AA,
                asarray(table[_get_default_prop_name('mag')]),
                table[_get_default_prop_name('band')])))
    table[_get_default_prop_name('fluxerr')] = asarray(
        list(
            map(lambda x, y: x * y / (2.5 * log10(e)),
                table[_get_default_prop_name('magerr')],
                table[_get_default_prop_name('flux')])))
    return (table)
Example #12
0
def _getZP(band, zpsys):
    """
    (Private)
    Helper function that calculates the zero-point of a given band
    :param band: filename of band transmission function to get zero-point of 
    """
    ms = sncosmo.get_magsystem(zpsys)
    return (ms.band_flux_to_mag(1 / sncosmo.constants.HC_ERG_AA, band))
Example #13
0
def _param_to_source(source,
                     wave,
                     color_curve=None,
                     band1=None,
                     band2=None,
                     ref_color=False):
    band = None
    for b in np.unique(source.lc['band']):
        temp = sncosmo.get_bandpass(b)
        if temp.minwave() <= min(wave) and temp.maxwave() >= max(wave):
            band = sncosmo.get_bandpass(b)
    if band is None:
        raise RuntimeError(
            "Hmm, your data do not contain the band you want to fit.")
    finalPhase = source._phase
    if color_curve is not None and not ref_color:
        zp1 = source.lc['zp'][source.lc['band'] == band1][0]
        zp2 = source.lc['zp'][source.lc['band'] == band2][0]
        flux1 = sncosmo.Model(source._ts_sources[band1]).bandflux(
            band1, source._phase, zp1,
            source.lc['zpsys'][source.lc['band'] == band1][0])

        temp_flux = flux1 / 10**(-.4 * (color_curve(source._phase) -
                                        (zp1 - zp2)))

    else:
        temp_flux = np.ones(len(finalPhase))
    try:
        zpnorm = 10.**(
            0.4 * source.lc['zp'][source.lc['band'] == band.name.lower()][0])
        band.name = band.name.lower()
    except:
        zpnorm = 10.**(
            0.4 * source.lc['zp'][source.lc['band'] == band.name.upper()][0])
        band.name = band.name.upper()

    wave, dwave = integration_grid(band.minwave(), band.maxwave(),
                                   MODEL_BANDFLUX_SPACING)

    ms = sncosmo.get_magsystem(source.lc['zpsys'][0])
    zpnorm = zpnorm / ms.zpbandflux(band)
    flux = temp_flux * HC_ERG_AA / (dwave * np.sum(wave * band(wave)) * zpnorm)
    finalWave = np.arange(wave[0] - dwave * 10, wave[-1] + dwave * 10, dwave)
    finalFlux = np.zeros((len(finalPhase), len(finalWave)))

    for i in range(len(finalPhase)):
        #if finalPhase[i]>= np.min(timeArr) and finalPhase[i] <= np.max(timeArr):
        for j in range(len(finalWave)):
            if finalWave[j] >= wave[0] and finalWave[j] <= wave[-1]:
                finalFlux[i][j] = flux[i]

    #offset=np.zeros(len(finalPhase))

    out = sncosmo.TimeSeriesSource(np.array(finalPhase),
                                   np.array(finalWave),
                                   np.array(finalFlux),
                                   zero_before=False)
    return (out)
Example #14
0
def test_token_user_post_and_get_different_systems_mag(upload_data_token,
                                                   public_source,
                                                   ztf_camera):

    status, data = api('POST', 'photometry',
                       data={'obj_id': str(public_source.id),
                             'mjd': 58000.,
                             'instrument_id': ztf_camera.id,
                             'mag': 21.,
                             'magerr': 0.2,
                             'limiting_mag': 22.3,
                             'magsys': 'vega',
                             'filter': 'ztfg'
                             },
                       token=upload_data_token)
    assert status == 200
    assert data['status'] == 'success'

    photometry_id = data['data']['ids'][0]
    status, data = api(
        'GET',
        f'photometry/{photometry_id}?format=mag&magsys=vega',
        token=upload_data_token)
    assert status == 200
    assert data['status'] == 'success'

    ab = sncosmo.get_magsystem('ab')
    vega = sncosmo.get_magsystem('vega')
    correction = 2.5 * np.log10(vega.zpbandflux('ztfg') / ab.zpbandflux('ztfg'))

    np.testing.assert_allclose(data['data']['mag'], 21.)
    np.testing.assert_allclose(data['data']['magerr'], 0.2)
    np.testing.assert_allclose(data['data']['limiting_mag'], 22.3)

    status, data = api(
        'GET',
        f'photometry/{photometry_id}?format=mag&magsys=ab',
        token=upload_data_token)
    assert status == 200
    assert data['status'] == 'success'

    np.testing.assert_allclose(data['data']['mag'], 21. - correction)
    np.testing.assert_allclose(data['data']['magerr'], 0.2)
    np.testing.assert_allclose(data['data']['limiting_mag'], 22.3 - correction)
Example #15
0
def register_JLA_magsys():
    #AB_B12
    spec = np.genfromtxt('%s/MagSys/ab-spec.dat' % (os.environ['SNFIT_DATA']))
    wave = spec[:, 0]
    flux = spec[:, 1]
    specsnc = sncosmo.Spectrum(wave,
                               flux,
                               unit=(u.erg / u.s / u.cm**2 / u.AA),
                               wave_unit=u.AA)
    magsys = sncosmo.magsystems.SpectralMagSystem(specsnc)
    sncosmo.registry.register(magsys,
                              'AB_B12',
                              data_class=sncosmo.MagSystem,
                              force=True)
    test = sncosmo.get_magsystem('ab_b12')
    # embed()
    print test

    #vega2
    spec = np.genfromtxt('%s/MagSys/bd_17d4708_stisnic_003.ascii' %
                         (os.environ['SNFIT_DATA']))
    wave = spec[:, 0]
    flux = spec[:, 1]
    specsnc = sncosmo.Spectrum(wave,
                               flux,
                               unit=(u.erg / u.s / u.cm**2 / u.AA),
                               wave_unit=u.AA)
    magsys = sncosmo.magsystems.SpectralMagSystem(specsnc)
    sncosmo.registry.register(magsys,
                              'VEGA2',
                              data_class=sncosmo.MagSystem,
                              force=True)

    #vegahst
    spec = np.genfromtxt('%s/MagSys/alpha_lyr_stis_005.ascii' %
                         (os.environ['SNFIT_DATA']))
    wave = spec[:, 0]
    flux = spec[:, 1]
    specsnc = sncosmo.Spectrum(wave,
                               flux,
                               unit=(u.erg / u.s / u.cm**2 / u.AA),
                               wave_unit=u.AA)
    magsys = sncosmo.magsystems.SpectralMagSystem(specsnc)
    sncosmo.registry.register(magsys,
                              'VEGAHST',
                              data_class=sncosmo.MagSystem,
                              force=True)
Example #16
0
def test_csp_magsystem():
    csp = sncosmo.get_magsystem('csp')

    # filter zeropoints (copied from file)
    zps = {"cspu": 13.044,
           "cspg": 15.135,
           "cspr": 14.915,
           "cspi": 14.781,
           "cspb": 14.344,
           "cspv3014": 14.540,
           "cspv3009": 14.493,
           "cspv9844": 14.450,
           "cspys": 13.921,
           "cspjs": 13.836,
           "csphs": 13.510,
           "cspk": 11.967,
           "cspyd": 13.770,
           "cspjd": 13.866,
           "csphd": 13.502}

    # The "zero point bandflux" should be the flux that corresponds to
    # magnitude zero. So, 0 = zp - 2.5 log(F)
    for band, zp in zps.items():
        assert abs(2.5 * math.log10(csp.zpbandflux(band)) - zp) < 0.015
Example #17
0
def serialize(phot, outsys, format):

    return_value = {
        'obj_id': phot.obj_id,
        'ra': phot.ra,
        'dec': phot.dec,
        'filter': phot.filter,
        'mjd': phot.mjd,
        'instrument_id': phot.instrument_id,
        'instrument_name': phot.instrument.name,
        'ra_unc': phot.ra_unc,
        'dec_unc': phot.dec_unc,
        'origin': phot.origin,
        'id': phot.id,
        'groups': phot.groups,
    }

    filter = phot.filter

    magsys_db = sncosmo.get_magsystem('ab')
    outsys = sncosmo.get_magsystem(outsys)

    relzp_out = 2.5 * np.log10(outsys.zpbandflux(filter))

    # note: these are not the actual zeropoints for magnitudes in the db or
    # packet, just ones that can be used to derive corrections when
    # compared to relzp_out

    relzp_db = 2.5 * np.log10(magsys_db.zpbandflux(filter))
    db_correction = relzp_out - relzp_db

    # this is the zeropoint for fluxes in the database that is tied
    # to the new magnitude system
    corrected_db_zp = PHOT_ZP + db_correction

    if format == 'mag':
        if (phot.original_user_data is not None
                and 'limiting_mag' in phot.original_user_data):
            magsys_packet = sncosmo.get_magsystem(
                phot.original_user_data['magsys'])
            relzp_packet = 2.5 * np.log10(magsys_packet.zpbandflux(filter))
            packet_correction = relzp_out - relzp_packet
            maglimit = phot.original_user_data['limiting_mag']
            maglimit_out = maglimit + packet_correction
        else:
            # calculate the limiting mag
            fluxerr = phot.fluxerr
            fivesigma = 5 * fluxerr
            maglimit_out = -2.5 * np.log10(fivesigma) + corrected_db_zp

        return_value.update({
            'mag':
            phot.mag +
            db_correction if nan_to_none(phot.mag) is not None else None,
            'magerr':
            phot.e_mag if nan_to_none(phot.e_mag) is not None else None,
            'magsys':
            outsys.name,
            'limiting_mag':
            maglimit_out,
        })
    elif format == 'flux':
        return_value.update({
            'flux': nan_to_none(phot.flux),
            'magsys': outsys.name,
            'zp': corrected_db_zp,
            'fluxerr': phot.fluxerr,
        })
    else:
        raise ValueError('Invalid output format specified. Must be one of '
                         f"['flux', 'mag'], got '{format}'.")
    return return_value
Example #18
0
        stack = bolo.LCStack.from_models(model_list)
        ax, sm, dm15 = stack.plot(ax=ax, error=False, color=True, peak=True)
        print dm15
        dm15list.append(dm15)
    sm.set_array(dm15list)
    fig.colorbar(sm, label=r'$\Delta m_{15}(\mathrm{bol})$')
    ax.set_ylim(0, 2.5)
    ax.set_xlim(-20, 80)
    return fig
    

if __name__ == '__main__':    

    files = glob.glob('run/*.out')
    results = map(samples.models, files)
    csp = sncosmo.get_magsystem('csp')
    #fitres = np.genfromtxt('run/fitres.dat', names=True, dtype=None)

    # SNe that had fits that did not fail
    #good = fitres[fitres['status'] == 'OK']['name']

    # keep only successful fits
    #results = filter(lambda tup: tup[0].meta['name'] in good, 
    #                 results)

    # keep only SNe in the hubble flow
    bad = np.genfromtxt('run/bad', dtype=None)
    results = filter(lambda tup: tup[0].meta['zhelio'] >= .01, results)
    results = filter(lambda tup: tup[0].meta['name'][2:] not in bad, results)

    names = [result[0].meta['name'] for result in results]
Example #19
0
#!/usr/bin/env python

__author__ = "Danny Goldstein <*****@*****.**>"
__whatami__ = "Template for test problems."

import numpy as np
import sncosmo
from astropy.table import Table

csp = sncosmo.get_magsystem('csp')
hsiao = sncosmo.get_source('hsiao', version='3.0')
gain = 50000.


class Problem(object):
    def __init__(
            self,
            sedw,
            rv,
            ebv,  # "True parameter values."
            z,
            mwebv,  # "True parameter values."
            dust_type=sncosmo.OD94Dust,
            template=hsiao):

        self.template = template
        p = self.template._phase
        l = self.template._wave
        flux = self.template.flux(p, l)

        try:
Example #20
0
def Plot_Obs_per_filter(data=None, fieldname='',fieldid=0,season=0, flux_name='m5sigmadepth',xfigsize=None, yfigsize=None, figtext=None,figtextsize=1.,ncol=2,color=None,cmap=None, cmap_lims=(3000., 10000.)):
       
    telescope=Telescope(airmass=np.median(1.2))

    transmission=telescope.throughputs
    
    for filtre in 'ugrizy':
        band=sncosmo.Bandpass(transmission.atmosphere[filtre].wavelen,transmission.atmosphere[filtre].sb, name='LSSTPG::'+filtre,wave_unit=u.nm)
        sncosmo.registry.register(band)

    toff=0.
    bands=set(data['band'])
    
    #tmin, tmax = [], []
    if data is not None:
        tmin=np.min(data['mjd']) - 10.
        tmax=np.max(data['mjd']) + 10.
        #tmin.append(np.min(data['mjd']) - 10.)
        #tmax.append(np.max(data['mjd']) + 10.)
    print 'hello',tmin,tmax

        # Calculate layout of figure (columns, rows, figure size). We have to
        # calculate these explicitly because plt.tight_layout() doesn't space the
        # subplots as we'd like them when only some of them have xlabels/xticks.
    wspace = 0.6  # All in inches.
    hspace = 0.3
    lspace = 1.0
    bspace = 0.7
    trspace = 0.2
    nrow = (len(bands) - 1) // ncol + 1
    if xfigsize is None and yfigsize is None:
        hpanel = 2.25
        wpanel = 3.
    elif xfigsize is None:
        hpanel = (yfigsize - figtextsize - bspace - trspace -
                  hspace * (nrow - 1)) / nrow
        wpanel = hpanel * 3. / 2.25
    elif yfigsize is None:
        wpanel = (xfigsize - lspace - trspace - wspace * (ncol - 1)) / ncol
        hpanel = wpanel * 2.25 / 3.
    else:
        raise ValueError('cannot specify both xfigsize and yfigsize')

    figsize = (lspace + wpanel * ncol + wspace * (ncol - 1) + trspace,
               bspace + hpanel * nrow + hspace * (nrow - 1) + trspace +
               figtextsize)  

        # Create the figure and axes.
    fig, axes = plt.subplots(nrow, ncol, figsize=figsize, squeeze=False)
    fig.suptitle(fieldname+' Field '+str(fieldid)+' - Season '+str(season))

    fig.subplots_adjust(left=lspace / figsize[0],
                        bottom=bspace / figsize[1],
                        right=1. - trspace / figsize[0],
                        top=1. - (figtextsize + trspace) / figsize[1],
                        wspace=wspace / wpanel,
                        hspace=hspace / hpanel)
        # Color options.
    if color is None:
        if cmap is None:
            cmap = cm.get_cmap('jet_r')
        # Loop over bands
    bands = list(bands)
    waves = [sncosmo.get_bandpass(b).wave_eff for b in bands]
    waves_and_bands = sorted(zip(waves, bands))

    for axnum in range(ncol * nrow):
        row = axnum // ncol
        col = axnum % ncol
        ax = axes[row, col]
        
        if axnum >= len(waves_and_bands):
            ax.set_visible(False)
            ax.set_frame_on(False)
            continue

        wave, band = waves_and_bands[axnum]

        bandname_coords = (0.92, 0.92)
        bandname_ha = 'right'
        if color is None:
            bandcolor = cmap((cmap_lims[1] - wave) /
                                 (cmap_lims[1] - cmap_lims[0]))
        else:
            bandcolor = color

        if data is not None:
            mask = data['band'] == band
            time = data['mjd'][mask]
            flux = data[flux_name][mask]
            ax.errorbar(time, flux, ls='None',
                        color=bandcolor, marker='.', markersize=10.)    
            # Band name in corner
            ax.text(bandname_coords[0], bandname_coords[1], band,
                    color='k', ha=bandname_ha, va='top', transform=ax.transAxes)

            ax.axhline(y=0., ls='--', c='k')  # horizontal line at flux = 0.
            ax.set_xlim((tmin, tmax))
            ax.set_ylim((np.min(flux)-1.,np.max(flux)+1.))
            if (len(bands) - axnum - 1) < ncol:
                ax.set_xlabel('time')
               
            else:
                for l in ax.get_xticklabels():
                    l.set_visible(False)
            if col == 0:
                if flux_name == 'flux':
                    ax.set_ylabel('flux ($ZP_{{{0}}} = {1}$)'
                                  .format(sncosmo.get_magsystem(zpsys).name.upper(), zp))
                if flux_name == 'flux_e_sec':
                   ax.set_ylabel('flux (e/sec)')
                
                if flux_name == 'm5sigmadepth':
                    ax.set_ylabel('$m_{5\sigma}$ [mag]')

    plt.gcf().savefig('Obs_Plots/m5_vs_filter_'+fieldname+'_'+str(fieldid)+'_season_'+str(season)+'.png')
#Make 0.8 Ia, 0.15 Ia-91T, 0.05 Ia-91bg, and split in different types of Ia using numbers from Li et al 2011c.

redshifts_91bg=random.sample(redshifts,int(num_Ia*0.05))
bg_idx=np.isin(redshifts,redshifts_91bg,invert=True)
redshifts_91bg=random.sample(redshifts_91bg,int(len(redshifts_91bg)*0.4545))

redshifts=redshifts[bg_idx]

redshifts_91T=random.sample(redshifts,int(num_Ia*0.15))
T_idx=np.isin(redshifts,redshifts_91T,invert=True)
redshifts_91T=random.sample(redshifts_91T,int(len(redshifts_91T)*0.882))

redshifts_Ia=redshifts[T_idx]
redshifts_Ia=random.sample(redshifts_Ia,int(len(redshifts_Ia)*0.407))

ab = sncosmo.get_magsystem('ab')
snid=0

#-------------------------------------------------------------------------------------------
#Create Ia parameters
#-------------------------------------------------------------------------------------------

sn_type='SNIa'
model=sncosmo.Model(source='salt2')
start_phase=-20.

params=[dict() for x in range(len(redshifts_Ia))]
for j in range (len(redshifts_Ia)):
	#We want absolute magnitude to be varied about -19.1 with some scatter on the hubble diagram
	mabs=np.random.normal(-19.1,0.2)
	model.set(z=redshifts_Ia[j])
Example #22
0
def createMultiplyImagedSN(
        sourcename, snType, redshift, z_lens=None, telescopename='telescope',
        objectName='object', time_delays=[10., 50.], magnifications=[2., 1.], sn_params={}, av_dists={},
        numImages=2, cadence=5, epochs=30, clip_time=[-30, 150], bands=['F105W', 'F160W'], start_time=None,
        gain=200., skynoiseRange=(1, 1.1), timeArr=None, zpsys='ab', zp=None, hostr_v=3.1, lensr_v=3.1,
        microlensing_type=None, microlensing_params=[], ml_loc=[None, None],
        dust_model='CCM89Dust', av_host=.3, av_lens=0, fix_luminosity=False,
        minsnr=0.0, scatter=True, snrFunc=None):
    """
    Generate a multiply-imaged SN light curve set, with user-specified time
    delays and magnifications.

    Parameters
    ----------
    sourcename: :class:`~sncosmo.Source` or str
        The model for the spectral evolution of the source. If a string
        is given, it is used to retrieve a :class:`~sncosmo.Source` from
        the registry.
    snType : str
        The classification of the supernova
    redshift : float
        Redshift of the source
    z_lens : float
        Redshift of the lens
    telescopename : str
        The name of the telescope used for observations
    objectName : str
        The name of the simulated supernova
    time_delays : :class:`~list` of :class:`~float`
        The relative time delays for the multiple images of the supernova. Must
        be same length as numImages
    magnifications : :class:`~list` of :class:`~float`
        The relative magnifications for the multiple images of hte supernova. Must
        be same length as numImages
    sn_params: :class:`~dict`
        A dictionary with SN model parameters as keys, and some sort of pdf or
        other callable function that returns the model parameter.
    av_dists: :class:`~dict`
        A dictionary with 'host' or 'lens' as keys, and some sort of pdf or
        other callable function that returns the relevant av parameter.
    numImages : int
        The number of images to simulate
    cadence : float
        The cadence of the simulated observations (if timeArr is not defined)
    epochs : int
        The number of simulated observations (if timeArr is not defined)
    clip_time: :class:`~list`
        Rest frame phase start and end time, will clip output table to these values.
    bands : :class:`~list` of :class:`~sncosmo.Bandpass` or :class:`~str`
        The bandpass(es) used for simulated observations
    start_time: float
        Start time for the leading image. If None, start will be the first value in 
        the time array, and the peak will be this ± the 
        relative time delay for the leading image. 
    gain : float
        Gain of the telescope "obtaining" the simulated observations (if snrFunc
        not defined)
    skynoiseRange : :class:`~list` of :class:`~float`
        The left and right bounds of sky noise used to define observational noise
        (if snrFunc not defined)
    timeArr : :class:`~list` of :class:`~float`
        A list of times that define the simulated observation epochs
    zpsys : str or :class:`~sncosmo.MagSystem`
        The zero-point system used to define the photometry
    zp : float or :class:`~list` of :class:`~float`
        The zero-point used to define the photometry, list if simulating multiple
        bandpasses. Then this list must be the same length as bands
    hostr_v: float
        The r_v parameter for the host.
    lensr_v: float
        The r_v parameter for the lens.
    microlensing_type : str
        If microlensing is to be included, defines whether it is
        "AchromaticSplineMicrolensing" or "AchromaticMicrolensing"
    microlensing_params: :class:`~numpy.array` or :class:`~list` of :class:`~int`
        If using AchromaticSplineMicrolensing, then this params list must give
        three values for [nanchor, sigmadm, nspl]. If using AchromaticMicrolensing,
        then this must be a microcaustic defined by a 2D numpy array
    ml_loc: :class:`~list`
        List containing tuple locations of SN on microlensing map (random if Nones)
    dust_model : str
        The dust model to be used for simulations, see sncosmo documentation for options
    av_host : float
        The A<sub>V</sub> parameter for the simulated dust effect in the source plane
    av_lens : float
        The A<sub>V</sub> parameter for the simulated dust effect in the lens plane
    fix_luminosity: bool
        Set the luminosity of every SN to be the peak of the distribution
    minsnr : float
        A minimum SNR threshold for observations when defining uncertainty
    scatter : bool
        Boolean that decides whether Gaussian scatter is applied to simulated
        observations
    snrFunc : :class:`~scipy.interpolate.interp1d` or :class:`~dict`
        An interpolation function that defines the signal to noise ratio (SNR)
        as a function of magnitude in the AB system. Used to define the
        observations instead of telescope parameters like gain and skynoise.
        This can be a dictionary, so that it's different for each filter with
        filters as keys and interpolation functions as values.

    Returns
    -------
    MISN: :class:`~sntd.MISN`
        A MISN object containing each of the multiply-imaged SN light curves
        and the simulation parameters.
    Examples
    --------
    >>> myMISN = sntd.createMultiplyImagedSN('salt2', 'Ia', 1.33,z_lens=.53, bands=['F110W'],
        zp=[26.8], cadence=5., epochs=35.,skynoiseRange=(.001,.005),gain=70. , time_delays=[10., 78.],
        magnifications=[7,3.5], objectName='My Type Ia SN', telescopename='HST',minsnr=5.0)
    """

    if timeArr is not None:
        times = timeArr
    else:
        times = np.linspace(0, int(cadence*epochs), int(epochs))
        if start_time is not None:
            times += start_time
    leading_peak = times[0]
    bandList = np.array([np.tile(b, len(times)) for b in bands]).flatten()
    ms = sncosmo.get_magsystem(zpsys)

    if zp is None:
        zpList = [ms.band_flux_to_mag(1, b) for b in bandList]
    elif isinstance(zp, (list, tuple)):
        zpList = np.array([np.tile(z, len(times)) for z in zp]).flatten()
    else:
        zpList = [zp for i in range(len(bandList))]

    # set up object to be filled by simulations
    curve_obj = MISN(telescopename=telescopename, object_name=objectName)
    curve_obj.bands = set(bandList)

    # make sncosmo obs table
    obstable = Table({'time': np.tile(times, len(bands)), 'band': bandList,
                      'zpsys': [zpsys.upper() for i in range(len(bandList))],
                      'zp': zpList,
                      'skynoise': np.random.uniform(
                          skynoiseRange[0], skynoiseRange[1], len(bandList)),
                      'gain': [gain for i in range(len(bandList))]})
    absolutes = _getAbsoluteDist()

    # Set up the dust_model extinction effects in the host galaxy and lens plane
    # TODO allow additional dust screens, not in the host or lens plane?
    # TODO sample from a prior for host and lens-plane dust A_V?
    # TODO : allow different lens-plane dust_model for each image?
    RV_lens = lensr_v
    RV_host = hostr_v
    dust_frames = []
    dust_names = []
    dust_effect_list = []
    if dust_model and (av_lens or av_host or len(av_dists) > 0):
        dust_effect = {'CCM89Dust': sncosmo.CCM89Dust,
                       'OD94Dust': sncosmo.OD94Dust,
                       'F99Dust': sncosmo.F99Dust}[dust_model]()
        if av_host or 'host' in av_dists.keys():
            dust_frames.append('rest')
            dust_names.append('host')
            dust_effect_list.append(dust_effect)
        if av_lens or 'lens' in av_dists.keys():
            dust_frames.append('free')
            dust_names.append('lens')
            dust_effect_list.append(dust_effect)

    # The following is not needed, but may be resurrected when we allow user
    # to provide additional dust screens.
    # if not isinstance(dust_names, (list, tuple)):
    #    dust_names=[dust_names]
    # if not isinstance(dust_frames, (list, tuple)):
    #    dust_frames=[dust_frames]

    # The sncosmo Model is initially set up with only dust effects, because
    # as currently constructed, dust has the same effect on all images.
    # Microlensing effects are added separately for each SN image below.

    model = sncosmo.Model(source=sourcename, effects=dust_effect_list,
                          effect_names=dust_names, effect_frames=dust_frames)
    model.set(z=redshift)
    # set absolute magnitude in b or r band based on literature
    if snType in ['IIP', 'IIL', 'IIn']:
        absBand = 'bessellb'
    else:
        absBand = 'bessellr'
    if model.param_names[2] not in sn_params.keys():
        if fix_luminosity:
            model.set_source_peakabsmag(absolutes[snType]['dist'][0],
                                        absBand, zpsys)
        else:
            model.set_source_peakabsmag(_getAbsFromDist(absolutes[snType]['dist']),
                                        absBand, zpsys)
    else:
        model.parameters[2] = sn_params[model.param_names[2]]()

    t0 = leading_peak
    if snType == 'Ia':
        x0 = model.get('x0')
        params = {'z': redshift, 't0': t0, 'x0': x0}
        if 'x1' not in sn_params.keys():
            params['x1'] = np.random.normal(0., 1.)
        else:
            params['x1'] = sn_params['x1']()
        if 'c' not in sn_params.keys():
            params['c'] = np.random.normal(0., .1)
        else:
            params['c'] = sn_params['c']()
    else:
        amp = model.get('amplitude')
        params = {'z': redshift, 't0': t0, 'amplitude': amp}
    model.set(**params)
    if av_host or 'host' in av_dists.keys():
        if 'host' in av_dists.keys():
            av_host = av_dists['host']()
        ebv_host = av_host/RV_host
        model.set(hostebv=ebv_host, hostr_v=RV_host)
    else:
        ebv_host = 0
    if av_lens or 'lens' in av_dists.keys():
        if z_lens is None:
            print('No z_lens set, assuming half of source z...')
            z_lens = redshift / 2.
        if 'lens' in av_dists.keys():
            av_lens = av_dists['lens']()
        ebv_lens = av_lens/RV_lens
        model.set(lensz=z_lens, lensebv=ebv_lens, lensr_v=RV_lens)
    else:
        ebv_lens = 0

    # Step through each of the multiple SN images, adding time delays,
    # macro magnifications, and microlensing effects.
    for imnum, td, mu in zip(range(numImages), time_delays, magnifications):
        # Make a separate model_i for each SN image, so that lensing effects
        # can be reflected in the model_i parameters and propagate correctly
        # into realize_lcs for flux uncertainties
        model_i = deepcopy(model)
        model_i._flux = _mlFlux
        params_i = deepcopy(params)
        if snType == 'Ia':
            params_i['x0'] *= mu
        else:
            params_i['amplitude'] *= mu
        params_i['t0'] += td

        if microlensing_type is not None:
            # add microlensing effect
            if 'spline' in microlensing_type.lower():
                # Initiate a spline-based mock ml effect (at this point,
                # a set of random splines is generated and the microlensing
                # magnification curve is fixed)
                nanchor, sigmadm, nspl = microlensing_params
                if microlensing_type.lower().startswith('achromatic'):
                    ml_spline_func = sncosmo.AchromaticSplineMicrolensing
                else:
                    ml_spline_func = ChromaticSplineMicrolensing
                ml_effect = ml_spline_func(nanchor=nanchor, sigmadm=sigmadm,
                                           nspl=nspl)
            else:
                # get magnification curve from the defined microcaustic
                mlTime = np.arange(
                    0, times[-1]/(1+redshift)-model_i._source._phase[0]+5, .1)
                time, dmag = microcaustic_field_to_curve(
                    microlensing_params, mlTime, z_lens, redshift, loc=ml_loc[imnum])
                dmag /= np.mean(dmag)  # to remove overall magnification

                ml_effect = AchromaticMicrolensing(
                    time+model_i._source._phase[0], dmag, magformat='multiply')

            model_i.add_effect(ml_effect, 'microlensing', 'rest')
        else:
            ml_effect = None

        # Generate the simulated SN light curve observations, make a `curve`
        # object, and store the simulation metadata
        model_i.set(**params_i)

        table_i = realize_lcs(
            obstable, model_i, [params_i],
            trim_observations=True, scatter=scatter, thresh=minsnr, snrFunc=snrFunc)
        tried = 0
        while (len(table_i) == 0 or len(table_i[0]) < numImages) and tried < 50:
            table_i = realize_lcs(
                obstable, model_i, [params_i],
                trim_observations=True, scatter=scatter, thresh=minsnr, snrFunc=snrFunc)
            tried += 1
        if tried == 50:
            # this arbitrary catch is here in case your minsnr and observation parameters
            # result in a "non-detection"
            print("Your survey parameters detected no supernovae.")
            return None
        table_i = table_i[0]
        if timeArr is None:
            table_i = table_i[table_i['time'] < model_i.get(
                't0')+clip_time[1]*(1+model_i.get('z'))]
            table_i = table_i[table_i['time'] > model_i.get(
                't0')+clip_time[0]*(1+model_i.get('z'))]
        # create is curve with all parameters and add it to the overall MISN object from above
        curve_i = image_lc()
        curve_i.object_name = None
        curve_i.zpsys = zpsys
        curve_i.table = deepcopy(table_i)
        curve_i.bands = list(set(table_i['band']))
        curve_i.simMeta = deepcopy(table_i.meta)
        curve_i.simMeta['sourcez'] = redshift
        curve_i.simMeta['model'] = copy(model_i)
        curve_i.simMeta['hostebv'] = ebv_host
        curve_i.simMeta['lensebv'] = ebv_lens
        curve_i.simMeta['lensz'] = z_lens
        curve_i.simMeta['mu'] = mu
        curve_i.simMeta['td'] = td
        curve_i.simMeta['microlensing'] = ml_effect
        curve_i.simMeta['microlensing_type'] = microlensing_type

        if microlensing_type == 'AchromaticSplineMicrolensing':
            curve_i.simMeta['microlensing_params'] = microlensing_params
        elif microlensing_type is not None:
            curve_i.simMeta['microlensing_params'] = interp1d(
                time+model_i._source._phase[0], dmag, fill_value=1,bounds_error=False)

        curve_obj.add_image_lc(curve_i)

    # Store the un-lensed model as a component of the lensed SN object.
    model.set(**params)
    curve_obj.model = model

    return(curve_obj)
Example #23
0
                               model,
                               params,
                               bounds=bounds,
                               verbose=False)
    return ((res, fit))


def _snFitWrap(args):
    try:
        return (_snFit(args))
    except:
        return (None)


files = glob.glob('*clipped.dat')
zpMag = sncosmo.get_magsystem('Vega')
sne = []
times = []
#plt.figure()
for f in files:
    if f not in ['lc_2009kn_clipped.dat', 'lc_2010bq_clipped.dat']:
        continue
    print(f)
    t0 = 0
    lc = sncosmo.read_lc(f)
    f = f[:-8]
    if len(lc[lc['Band'] == 'U']) == 0 and len(
            lc[lc['Band'] == 'u']) == 0 and len(lc[lc['Band'] == 'J']) == 0:
        #os.remove(f)
        continue
Example #24
0
def test_builtin_magsystem(name):
    sncosmo.get_magsystem(name)
Example #25
0
def _extrapolate_ir(band,
                    vArea,
                    color,
                    xTrans,
                    xWave,
                    d,
                    f,
                    w,
                    niter,
                    log,
                    index,
                    doneIR,
                    bandDict,
                    zpsys,
                    model,
                    bandsDone,
                    IRoverwrite,
                    accuracy=1e-12):
    """
    (Private)
    Algorithm for extrapolation of SED into the IR
    """
    wavestep = w[1] - w[0]
    idx, val = _find_nearest(
        w, xWave[0])  #closest wavelength in the sed to the start of the band
    idx2, val2 = _find_nearest(
        w, xWave[-1])  #closest wavelength in the sed to the end of the band
    overlapMag = 0
    temp1 = xTrans[xWave <= w[-1]]
    temp = xWave[xWave <= w[-1]]
    if xWave[0] - val > wavestep:  #then need to extrapolate between end of SED and left edge of band
        Nstep = len(arange(val, xWave[0], wavestep))
        wextRed = sorted([val + (j + 1) * wavestep for j in range(Nstep)])
        fextRed = array([
            max(0, f[idx]) for wave in wextRed
        ])  #just a flat slope from the end of the SED to the edge of the band
        w2 = append(w[:idx + 1], wextRed)
        f2 = append(f[:idx + 1], fextRed)
    else:  #if the SED extends to the band:
        if not IRoverwrite:
            return (w, f)
        if not any([
                _checkBandOverlap(bandDict[x], bandDict[band])
                for x in bandsDone
        ]):  #  then cut it off at the band for new extrapolation
            w2 = w[:idx + 1]
            f2 = f[:idx + 1]
        else:  #calculate the area for the overlap between bands, then subtract that from what is necessary and begin extrapolation at the right edge of the last extrapolation
            w2 = w
            f2 = f
            bandIdx, bandVal = _find_nearest(xWave, w[-1])
            tempIdx, tempVal = _find_nearest(w, xWave[0])
            if xWave[0] < w[-1]:
                if bandVal < w[-1]:
                    xTrans = xTrans[bandIdx + 1:]
                    xWave = xWave[bandIdx + 1:]
                else:
                    xTrans = xTrans[bandIdx:]
                    xWave = xWave[bandIdx:]

    w = w2
    f = f2
    ms = sncosmo.get_magsystem(zpsys)

    try:
        overlapArea = sum(f[tempIdx:] * temp * temp1 * gradient(temp))
    except:
        overlapArea = 0

    bArea = ms.band_mag_to_flux(
        vArea - color, bandDict[band]
    ) * sncosmo.constants.HC_ERG_AA - overlapArea  #area in the band we are extrapolating into (mag to flux), everything should be in ergs at this point
    x2 = xWave[-1]
    x1 = w[-1]
    interpFunc = scint.interp1d(append(x1, x2), append(f[-1], 0))

    area = sum(interpFunc(xWave) * xTrans * xWave * gradient(xWave))
    i = 1
    extra = False
    if area > bArea:  #then we need flux=0, but slope of line steeper

        i = 0
        while area > bArea:
            i -= 1
            x2 = xWave[i]
            interpFunc = scint.interp1d(append(w[-1], x2), append(f[-1], 0))
            idx = list(xWave).index(x2)
            area = sum(
                interpFunc(arange(w[-1], x2 + wavestep / 10, wavestep)) *
                xTrans[:idx + 1] *
                arange(w[-1], x2 + wavestep / 10, wavestep) *
                gradient(arange(w[-1], x2 + wavestep / 10, wavestep)))
        i = 1
        x3 = x2 + wavestep
        idx2 = list(xWave).index(x2)
        idx3 = idx2 + 1
        while (
                abs(area - bArea) / (area + bArea) > accuracy and i <= niter
        ):  #this loop runs if necessary accuracy wasn't reached because of wavelength binning, it changes the starting flux slightly
            if i == 1:
                y3 = f[-1] / 2
                while area < bArea:
                    y3 *= 2
                    interpFunc1 = scint.interp1d(append(w[-1], x2),
                                                 append(f[-1], y3))
                    interpFunc2 = scint.interp1d(append(x2, x3), append(y3, 0))
                    area1 = sum(
                        interpFunc1(arange(w[-1], x2 + wavestep / 10,
                                           wavestep)) * xTrans[:idx2 + 1] *
                        arange(w[-1], x2 + wavestep / 10, wavestep) *
                        gradient(arange(w[-1], x2 + wavestep / 10, wavestep)))
                    area2 = sum(
                        interpFunc2(arange(x2, x3 + wavestep / 10, wavestep)) *
                        xTrans[idx2:idx3 + 1] *
                        arange(x2, x3 + wavestep / 10, wavestep) *
                        gradient(arange(x2, x3 + wavestep / 10, wavestep)))
                    area = area1 + area2
                y1 = 0
                y2 = y3
            if area > bArea:
                y3 = y2
            else:
                y1 = y2
            y2 = (y3 + y1) / 2
            interpFunc1 = scint.interp1d(append(w[-1], x2), append(f[-1], y2))
            interpFunc2 = scint.interp1d(append(x2, x3), append(y3, 0))
            area1 = sum(
                interpFunc1(arange(w[-1], x2 + wavestep / 10, wavestep)) *
                xTrans[0:idx2 + 1] *
                arange(w[-1], x2 + wavestep / 10, wavestep) *
                gradient(arange(w[-1], x2 + wavestep / 10, wavestep)))
            area2 = sum(
                interpFunc2(arange(x2, x3 + wavestep / 10, wavestep)) *
                xTrans[idx2:idx3 + 1] *
                arange(x2, x3 + wavestep / 10, wavestep) *
                gradient(arange(x2, x3 + wavestep / 10, wavestep)))
            area = area1 + area2
            i += 1
        y1 = f[-1]
        extra = True

    elif area < bArea:  #then the flux at the right edge of the band must be greater than 0
        y1 = 0
        y3 = max(f)  #initial upper bound is max of SED
        y2 = y3
        x2 = xWave[-1]
        tried = False
        while (abs(area - bArea) / (area + bArea) > accuracy and i <= niter):
            if area > bArea:
                y3 = y2
            else:
                if not tried:
                    while area < bArea:  #this will increase the upper bound until the area is greater than the necessary area
                        y3 *= 2
                        interpFunc = scint.interp1d(append(w[-1], x2),
                                                    append(f[-1], y3))
                        area = sum(
                            interpFunc(xWave) * xTrans * xWave *
                            gradient(xWave))
                    tried = True
                else:
                    y1 = y2
            y2 = (y3 + y1) / 2

            interpFunc = scint.interp1d(append(w[-1], x2), append(f[-1], y2))
            area = sum(interpFunc(xWave) * xTrans * xWave * gradient(xWave))
            i += 1
        y1 = f[-1]
    else:
        y1 = f[-1]
        y2 = 0
    if abs(area - bArea) > .001 * bArea:
        log.write(
            'WARNING: The parameters you chose led to an integration in the %s-Band of %e instead of %e for index %i \n'
            % (band, vArea - ms.band_flux_to_mag(
                (area + overlapArea) / sncosmo.constants.HC_ERG_AA,
                bandDict[band]), color, index))
    (a, b, rval, pval, stderr) = stats.linregress(append(w[-1], x2),
                                                  append(y1, y2))

    if extra:
        Nstep1 = len(arange(w[-1], x2, wavestep))
        wextRed1 = sorted([w[-1] + (j + 1) * wavestep for j in range(Nstep1)])
        fextRed1 = array([max(0, a * wave + b) for wave in wextRed1])
        (a, b, rval, pval, stderr) = stats.linregress(append(x2, x3),
                                                      append(y2, 0))
        Nstep2 = len(arange(x2, x3, wavestep))
        wextRed2 = sorted([x2 + (j + 1) * wavestep for j in range(Nstep2)])
        fextRed2 = array([max(0, a * wave + b) for wave in wextRed2])
        if x3 < xWave[-1]:
            Nstep3 = len(arange(x3, xWave[-1], wavestep))
            wextRed3 = sorted([x3 + (j + 1) * wavestep for j in range(Nstep3)])
            fextRed3 = array([0 for wave in wextRed3])
        else:
            wextRed3 = []
            fextRed3 = []
        wextRed = append(wextRed1, append(wextRed2, wextRed3))
        fextRed = append(fextRed1, append(fextRed2, fextRed3))
    else:
        Nstep = len(arange(w[-1], xWave[-1], wavestep))
        wextRed = sorted([w[-1] + (j + 1) * wavestep for j in range(Nstep)])

        fextRed = array([
            max(0, a * wave +
                b) if wave <= xWave[-1] else max(0, a * xWave[-1] + b)
            for wave in wextRed
        ])

    w = append(w, wextRed)
    f = append(f, fextRed)
    return (w, f)
Example #26
0
def _extrapolate_uv(band,
                    rArea,
                    color,
                    xTrans,
                    xWave,
                    f,
                    w,
                    niter,
                    log,
                    index,
                    bandDict,
                    zpsys,
                    UVoverwrite,
                    accuracy=1e-9):
    """
    (Private)
    Algorithm to extrapolate an SED into the UV
    """
    wavestep = w[1] - w[0]
    idx, val = _find_nearest(w, xWave[-1])
    idx2, val2 = _find_nearest(w, xWave[0])
    if val - xWave[
            -1] > wavestep:  #then need to extrapolate between end of SED and left edge of band
        Nstep = len(arange(xWave[-1], val, wavestep))
        wextRed = sorted(
            [xWave[-1] + (j + 1) * wavestep for j in range(Nstep)])
        fextRed = array([
            max(0, f[idx]) for wave in wextRed
        ])  #just a flat slope from the end of the SED to the edge of the band
        w2 = append(wextRed, w[idx:])
        f2 = append(fextRed, f[idx:])

    else:
        if UVoverwrite:  #if the SED extends to the band, then cut it off at the band for new extrapolation
            w2 = w[idx:]
            f2 = f[idx:]
        else:  #don't extrapolate
            return (w, f)
    if idx > idx2:
        w1 = w[:idx2]
        f1 = f[:idx2]
    else:
        w1 = []
        f1 = []
    w = w2
    f = f2
    ms = sncosmo.get_magsystem(zpsys)
    bArea = ms.band_mag_to_flux(
        rArea + color, bandDict[band]
    ) * sncosmo.constants.HC_ERG_AA  #area in the band we are extrapolating into (mag to flux)
    x1 = w[0]
    x2 = xWave[0]
    interpFunc = scint.interp1d(append(x2, x1), append(0, f[0]))
    area = sum(interpFunc(xWave) * xTrans * xWave *
               gradient(xWave))  #this is the flux calculation done by sncosmo
    i = 1
    extra = False
    if area > bArea:  #then we need flux=0, but slope of line steeper
        i = -1
        while area > bArea:
            i += 1
            x2 = xWave[i]
            interpFunc = scint.interp1d(append(x2, w[0]), append(0, f[0]))
            idx = list(xWave).index(x2)
            area = sum(
                interpFunc(arange(x2, w[0] + wavestep / 10, wavestep)) *
                xTrans[idx:] * arange(x2, w[0] + wavestep / 10, wavestep) *
                gradient(arange(x2, w[0] + wavestep / 10, wavestep)))
        i = 1
        x3 = x2 - wavestep
        idx2 = list(xWave).index(x2)
        idx3 = idx2 - 1
        while (
                abs(area - bArea) / (area + bArea) > accuracy and i <= niter
        ):  #this loop runs if necessary accuracy wasn't reached because of wavelength binning, it changes the starting flux slightly
            if i == 1:
                y3 = f[0] / 2
                while area < bArea:
                    y3 *= 2
                    interpFunc1 = scint.interp1d(append(x2, w[0]),
                                                 append(y3, f[0]))
                    interpFunc2 = scint.interp1d(append(x3, x2), append(0, y3))
                    area1 = sum(
                        interpFunc1(arange(x2, w[0] + wavestep / 10,
                                           wavestep)) * xTrans[idx:] *
                        arange(x2, w[0] + wavestep / 10, wavestep) *
                        gradient(arange(x2, w[0] + wavestep / 10, wavestep)))
                    area2 = sum(
                        interpFunc2(arange(x3, x2 + wavestep / 10, wavestep)) *
                        xTrans[idx3:idx2 + 1] *
                        arange(x3, x2 + wavestep / 10, wavestep) *
                        gradient(arange(x3, x2 + wavestep / 10, wavestep)))
                    area = area1 + area2
                y1 = 0
                y2 = y3
            if area > bArea:
                y3 = y2
            else:
                y1 = y2
            y2 = (y3 + y1) / 2
            interpFunc1 = scint.interp1d(append(x2, w[0]), append(y2, f[0]))
            interpFunc2 = scint.interp1d(append(x3, x2), append(0, y2))
            area1 = sum(
                interpFunc1(arange(x2, w[0] + wavestep / 10, wavestep)) *
                xTrans[idx:] * arange(x2, w[0] + wavestep / 10, wavestep) *
                gradient(arange(x2, w[0] + wavestep / 10, wavestep)))
            area2 = sum(
                interpFunc2(arange(x3, x2 + wavestep / 10, wavestep)) *
                xTrans[idx3:idx2 + 1] *
                arange(x3, x2 + wavestep / 10, wavestep) *
                gradient(arange(x3, x2 + wavestep / 10, wavestep)))
            area = area1 + area2
            i += 1
        y1 = f[0]
        extra = True

    elif area < bArea:  #then the flux at the left edge of the band must be greater than 0
        y1 = 0
        y3 = max(f)  #initial upper bound is max of SED
        y2 = y3
        x2 = xWave[0]
        tried = False
        while (abs(area - bArea) / (area + bArea) > accuracy and i <= niter):
            if area > bArea:
                y3 = y2
            else:
                if not tried:
                    while area < bArea:  #this will increase the upper bound until the area is greater than the necessary area
                        y3 *= 2
                        interpFunc = scint.interp1d(append(x2, w[0]),
                                                    append(y3, f[0]))
                        area = sum(
                            interpFunc(xWave) * xTrans * xWave *
                            gradient(xWave))
                    tried = True
                else:
                    y1 = y2
            y2 = (y3 + y1) / 2

            interpFunc = scint.interp1d(append(x2, w[0]), append(y2, f[0]))
            area = sum(interpFunc(xWave) * xTrans * xWave * gradient(xWave))
            i += 1
        y1 = f[0]
    else:
        y1 = f[0]
        y2 = 0
    if abs(area - bArea) > .001 * bArea:
        log.write(
            'WARNING: The parameters you chose led to an integration in the %s-Band of %e instead of %e for index %i \n'
            % (band, vArea / area, color, index))
    (a, b, rval, pval, stderr) = stats.linregress(append(x2, w[0]),
                                                  append(y2, y1))
    if extra:

        Nstep3 = len(arange(x2, w[0], wavestep))
        wextRed3 = sorted([x2 + (j + 1) * wavestep for j in range(Nstep3)])
        fextRed3 = array([max(0, a * wave + b) for wave in wextRed3])
        if x3 > xWave[0]:
            Nstep1 = len(arange(xWave[0], x3, wavestep))
            wextRed1 = sorted(
                [xWave[0] + (j + 1) * wavestep for j in range(Nstep1)])
            fextRed1 = array([0 for wave in wextRed1])
        else:
            wextRed1 = []
            fextRed1 = []

        (a, b, rval, pval, stderr) = stats.linregress(append(x3, x2),
                                                      append(0, y2))
        Nstep2 = len(arange(x3, x2, wavestep))
        wextRed2 = sorted([x3 + (j + 1) * wavestep for j in range(Nstep2)])
        fextRed2 = array([max(0, a * wave + b) for wave in wextRed2])

        wextRed = append(wextRed1, append(wextRed2, wextRed3))
        fextRed = append(fextRed1, append(fextRed2, fextRed3))
    else:
        Nstep = len(arange(xWave[0], w[0], wavestep))
        wextRed = sorted([xWave[0] + (j) * wavestep for j in range(Nstep)])
        fextRed = array([
            max(0, a * wave +
                b) if wave >= xWave[0] else max(0, a * xWave[0] + b)
            for wave in wextRed
        ])

    w = append(w1, append(wextRed, w))
    f = append(f1, append(fextRed, f))

    return (w, f)
Example #27
0
def test_builtins_magsys_ab():
    sncosmo.get_magsystem('ab')
Example #28
0
def test_register_magsystem():
    magsys = sncosmo.get_magsystem('ab')
    sncosmo.register(magsys, name='test_magsys')
    assert sncosmo.get_magsystem('test_magsys') is magsys
    def plot_lc(self, indice, plot_in_dir='default', plot_orig_template=True, **kwargs):
        """

        Plot the data and fit results

        :param indice: int, indice of the event in the data
        :param plot_in_dir: str, the directory where to save the plot, defaults to self.lc_dir
        :param plot_orig_template: bool, if True the original temaplet will be plottes
        :param kwargs: to be passed self.to plot_lc_with_mosfit_fit

        """

        if plot_in_dir == 'default':
            plot_in_dir = self.lc_dir

        if not os.path.isdir(plot_in_dir):
            logger.info(f'making directory {plot_in_dir}')
            os.mkdir(plot_in_dir)

        with open(self.dhandler.get_data('sncosmo'), 'rb') as f:
            data = pickle.load(f, encoding='latin1')

        original_id = data['meta']['idx_orig'][indice]
        neutrino_time = data['meta']['neutrino_time'][indice] if 'neutrino_time' in data['meta'] else None

        logger.debug(f'plotting {original_id}')

        fig, ax = plt.subplots()
        plt.gca().invert_yaxis()

        if 'sncosmo' in self.rhandler.method:
            raise DeprecationWarning
            # self.plot_lc_with_sncosmo_fit(indice, ax)
        elif 'mosfit' in self.rhandler.method:
            self.plot_lc_with_mosfit_fit(indice, ax, **kwargs)
        else:
            raise PlotterError('Jesus, what\'s that method, you crazy dog?! You\'re a dog, man!')

        if not isinstance(self.rhandler.collected_data, type(None)):
            collected_data = self.rhandler.collected_data[indice]

            t_exp_true = collected_data['t_exp_true']
            t_exp_fit = collected_data['t_exp_fit']
            t_exp_ic = collected_data['t_exp_dif_0.9']
            tdif = collected_data['t_exp_dif']

            ax.axvline(t_exp_fit, color='red', label='fitted $t_{{exp}}=$' + f'{t_exp_fit:.2f}')

            if not np.isnan(t_exp_true):
                ax.plot([], [], ' ', label=r'$t_{dif} = $' + '{:.1f}'.format(tdif))
                ax.axvline(t_exp_true, color='red', linestyle='--', label='true $t_{exp}$')
                ic = np.array(t_exp_ic) + t_exp_true
            else:
                ic = t_exp_ic
            ax.fill_between(ic,
                            y1=30, color='red', alpha=0.2,
                            label=r'IC$_{90\%}=$' + f'[{ic[0]:.2f}, {ic[1]:.2f}]')

            if neutrino_time:
                ax.axvline(neutrino_time, color='gold', linestyle='--', label=r't$_{\nu}$=' + f'{neutrino_time:.2f}')

        else:
            logger.info('Data from fits has not been collected! Can\'t draw explosion time estimate ...')

        if plot_orig_template:
            peak_band, peak_mag = self.dhandler.get_peak_band(indice, meta_data=data['meta'])
            _ = get_explosion_time(self.dhandler.get_spectral_time_evolution_file(indice),
                                   peak_band=peak_band,
                                   peak_mjd=data['meta']['t_peak'][indice],
                                   redshift=data['meta']['z'][indice],
                                   full_output=True)

            time, flux = _[1], _[2]

            magsys = sncosmo.get_magsystem('AB')
            mags = np.array([magsys.band_flux_to_mag(f, peak_band) if f > 0 else np.nan for f in flux])
            mags += peak_mag - min(mags)

            ax.plot(time, mags, ls='-.', color=bandcolors(peak_band), label=f'original template {peak_band}')

            ax.plot(data['meta']['t_peak'][indice], peak_mag,
                    color=bandcolors(peak_band), marker='x', label=f'peak')

        ax.set_title(original_id)
        ax.set_xlabel('Phase in MJD')
        ax.set_ylabel('Apparent Magnitude')

        plt.legend()
        plt.tight_layout()
        fn = f'{plot_in_dir}/{indice}.pdf'
        logger.debug(f'saving to {fn}')
        plt.savefig(fn)
        plt.close()
Example #30
0
def generate_buckets(low, high, n, inverse_microns=False):
    '''
    function to generate [n] tophat filters within the
    range of [low, high] (given in Angrstroms), with one 'V' filter centered at
    the BESSEL-V filter's effective wavelength (5417.2 Angstroms).
    '''
    V_EFF = 5417.2

    if inverse_microns:
        V_EFF = 10000./V_EFF
        temp = low
        low = 10000./high
        high = 10000./temp
        STEP_SIZE = .01
        prefix = 'bucket_invmicron_'
    else:
        STEP_SIZE = 2
        prefix = 'bucket_angstrom_'

    zp_cache = {'prefix':prefix}

    hi_cut, lo_cut = high-V_EFF, V_EFF-low
    a = (n-1)/(1+(hi_cut/lo_cut))
    A, B = np.round(a), np.round(n-1-a)

    lo_bw, hi_bw = lo_cut/(A+0.5), hi_cut/(B+0.5)
    lo_diff = lo_cut-(A+0.5)*hi_bw
    hi_diff = hi_cut-(B+0.5)*lo_bw

    idx = np.argmin((lo_diff,hi_diff))
    BW = (lo_bw,hi_bw)[idx]
    LOW = (low,low+lo_diff)[idx]

    toregister = {}
    for i in xrange(n):
        start = LOW+i*BW
        end = LOW+(i+1)*BW

        wave = np.arange(start, end, STEP_SIZE)
        trans = np.ones(wave.shape[0])
        trans[0]=trans[-1]=0

        index = (str(i),'V')[ abs(V_EFF-(start+end)/2) < 1e-5 ]

        if inverse_microns:
            wave = sorted(10000./wave)

        toregister[index] = {'wave':wave, 'trans':trans}

    filters = []
    zpsys = snc.get_magsystem('vega')
    for index, info in toregister.items():
        wave, trans = info['wave'], info['trans']
        bandpass = snc.Bandpass(wave, trans)
        
        snc.registry.register(bandpass, prefix+index, force=True)
        zp_phot = zpsys.zpbandflux(prefix+index)
        zp_cache[index] = zp_phot

        filters.append(index)
    
    
    
    return filters, zp_cache
Example #31
0
def test_retrieve_cases():
    for name in ['ab', 'Ab', 'AB']:  # Should work regardless of case.
        sncosmo.get_magsystem(name)
Example #32
0
def createMultiplyImagedSN(sourcename,
                           snType,
                           redshift,
                           telescopename='telescope',
                           objectName='object',
                           time_delays=[10., 50.],
                           magnifications=[2., 1.],
                           numImages=2,
                           cadence=5,
                           epochs=30,
                           bands=['F105W', 'F125W', 'F160W'],
                           gain=200.,
                           skynoiseRange=(1, 1.1),
                           timeArr=None,
                           zpsys='ab',
                           zp=None,
                           microlensing_type=None,
                           microlensing_params=[],
                           dust_model='CCM89Dust',
                           av_host=.3,
                           av_lens=None,
                           z_lens=None,
                           minsnr=0.0,
                           scatter=True,
                           snrFunc=None):
    """Generate a multiply-imaged SN light curve set, with user-specified time
    delays and magnifications.

    Parameters
    ----------
    sourcename : `~sncosmo.Source` or str
        The model for the spectral evolution of the source. If a string
        is given, it is used to retrieve a `~sncosmo.Source` from
        the registry.
    snType : str
        The classification of the supernova
    redshift : float
        Redshift of the source
    z_lens : float
        Redshift of the lens
    telescopename : str
        The name of the telescope used for observations
    objectName : str
        The name of the simulated supernova
    numImages : int
        The number of images to simulate
    time_delays : list of float
        The relative time delays for the multiple images of the supernova. Must
        be same length as numImages
    magnifications : list of float
        The relative magnifications for the multiple images of hte supernova. Must
        be same length as numImages
    timeArr : list of float
        A list of times that define the simulated observation epochs
    cadence : float
        The cadence of the simulated observations (if timeArr is not defined)
    epochs : int
        The number of simulated observations (if timeArr is not defined)
    bands : list of `~sncosmo.Bandpass` or str
        The bandpass(es) used for simulated observations
    snrFunc : `~scipy.interpolate.interp1d`
        An interpolation function that defines the signal to noise ratio (SNR)
        as a function of magnitude in the AB system. Used to define the
        observations instead of telescope parameters like gain and skynoise
    gain : float
        Gain of the telescope "obtaining" the simulated observations (if snrFunc
        not defined)
    skynoiseRange : list of float
        The left and right bounds of sky noise used to define observational noise
        (if snrFunc not defined)
    minsnr : float
        A minimum SNR threshold for observations when defining uncertainty
    scatter : bool
        Boolean that decides whether Gaussian scatter is applied to simulated
        observations
    zpsys : str or `~sncosmo.MagSystem`
        The zero-point system used to define the photometry
    zp : float or list of float
        The zero-point used to define the photometry, list if simulating multiple
        bandpasses. Then this list must be the same length as bands
    microlensing_type : str
        If microlensing is to be included, defines whether it is
        "AchromaticSplineMicrolensing" or "AchromaticMicrolensing"
    microlensing_params : `~numpy.array` or list of int
        If using AchromaticSplineMicrolensing, then this params list must give
        three values for [nanchor, sigmadm, nspl]. If using AchromaticMicrolensing,
        then this must be a microcaustic defined by a 2D numpy array
    dust_model : str
        The dust model to be used for simulations, see sncosmo documentation for options
    av_host : float
        The A<sub>V</sub> parameter for the simulated dust effect in the source plane
    av_lens : float
        The A<sub>V</sub> parameter for the simulated dust effect in the lens plane


    Returns
    -------
    MISN : `~sntd.curveDict`
        A curveDict object containing each of the multiply-imaged SN light curves
        and the simulation parameters.
    Examples
    --------
    >>> myMISN = sntd.createMultiplyImagedSN('salt2', 'Ia', 1.33,z_lens=.53, bands=['F110W'],
        zp=[26.8], cadence=5., epochs=35.,skynoiseRange=(.001,.005),gain=70. , time_delays=[10., 78.],
        magnifications=[7,3.5], objectName='My Type Ia SN', telescopename='HST',minsnr=5.0)
    """

    if timeArr is not None:
        times = timeArr
    else:
        times = np.linspace(0, int(cadence * epochs), int(epochs))

    bandList = np.array([np.tile(b, len(times)) for b in bands]).flatten()
    ms = sncosmo.get_magsystem(zpsys)

    if zp is None:
        zpList = [ms.band_flux_to_mag(1, b) for b in bandList]
    elif isinstance(zp, (list, tuple)):
        zpList = np.array([np.tile(z, len(times)) for z in zp]).flatten()
    else:
        zpList = [zp for i in range(len(bandList))]

    #set up object to be filled by simulations
    curve_obj = curveDict(telescopename=telescopename, object=objectName)
    curve_obj.bands = set(bandList)

    #make sncosmo obs table
    obstable = Table({
        'time':
        np.tile(times, len(bands)),
        'band':
        bandList,
        'zpsys': [zpsys.upper() for i in range(len(bandList))],
        'zp':
        zpList,
        'skynoise':
        np.random.uniform(skynoiseRange[0], skynoiseRange[1], len(bandList)),
        'gain': [gain for i in range(len(bandList))]
    })

    absolutes = _getAbsoluteDist()

    # Set up the dust_model extinction effects in the host galaxy and lens plane
    # TODO allow additional dust screens, not in the host or lens plane?
    # TODO sample from a prior for host and lens-plane dust A_V?
    # TODO : allow different lens-plane dust_model for each image?
    R_V = 3.1  # TODO: allow user-specified alternate dust R_V
    RV_lens = R_V
    RV_host = R_V
    dust_frames = []
    dust_names = []
    dust_effect_list = []
    if dust_model and (av_lens or av_host):
        dust_effect = {
            'CCM89Dust': sncosmo.CCM89Dust,
            'OD94Dust': sncosmo.OD94Dust,
            'F99Dust': sncosmo.F99Dust
        }[dust_model]()
        if av_host:
            dust_frames.append('rest')
            dust_names.append('host')
            dust_effect_list.append(dust_effect)
        if av_lens:
            dust_frames.append('free')
            dust_names.append('lens')
            dust_effect_list.append(dust_effect)

    # The following is not needed, but may be resurrected when we allow user
    # to provide additional dust screens.
    #if not isinstance(dust_names, (list, tuple)):
    #    dust_names=[dust_names]
    #if not isinstance(dust_frames, (list, tuple)):
    #    dust_frames=[dust_frames]

    # The sncosmo Model is initially set up with only dust effects, because
    # as currently constructed, dust has the same effect on all images.
    # Microlensing effects are added separately for each SN image below.

    model = sncosmo.Model(source=sourcename,
                          effects=dust_effect_list,
                          effect_names=dust_names,
                          effect_frames=dust_frames)
    model.set(z=redshift)
    #set absolute magnitude in b or r band based on literature
    if snType in ['IIP', 'IIL', 'IIn']:
        absBand = 'bessellb'
    else:
        absBand = 'bessellr'
    model.set_source_peakabsmag(_getAbsFromDist(absolutes[snType]['dist']),
                                absBand, zpsys)
    # TODO: allow user to specify parameters like x1, c, t0 if desired.

    t0 = 0
    if snType == 'Ia':
        x0 = model.get('x0')
        params = {
            'z': redshift,
            't0': t0,
            'x0': x0,
            'x1': np.random.normal(0., 1.),
            'c': np.random.normal(0., .1)
        }
    else:
        amp = model.get('amplitude')
        params = {'z': redshift, 't0': t0, 'amplitude': amp}
    model.set(**params)
    if av_host:
        ebv_host = av_host / RV_host
        model.set(hostebv=ebv_host, hostr_v=RV_host)
    else:
        ebv_host = 0
    if av_lens:
        if z_lens is None:
            z_lens = redshift / 2.  # TODO : Warn user about missing z_lens
        ebv_lens = av_lens / RV_lens
        model.set(lensz=z_lens, lensebv=ebv_lens, lensr_v=RV_lens)
    else:
        ebv_lens = 0

    # Step through each of the multiple SN images, adding time delays,
    # macro magnifications, and microlensing effects.
    for imnum, td, mu in zip(range(numImages), time_delays, magnifications):
        # Make a separate model_i for each SN image, so that lensing effects
        # can be reflected in the model_i parameters and propagate correctly
        # into realize_lcs for flux uncertainties
        model_i = deepcopy(model)
        model_i._flux = _mlFlux
        params_i = deepcopy(params)
        if snType == 'Ia':
            params_i['x0'] *= mu
        else:
            params_i['amplitude'] *= mu
        params_i['t0'] += td

        if microlensing_type is not None:
            # add microlensing effect
            if 'spline' in microlensing_type.lower():
                # Initiate a spline-based mock ml effect (at this point,
                # a set of random splines is generated and the microlensing
                # magnification curve is fixed)
                nanchor, sigmadm, nspl = microlensing_params
                if microlensing_type.lower().startswith('achromatic'):
                    ml_spline_func = sncosmo.AchromaticSplineMicrolensing
                else:
                    ml_spline_func = ChromaticSplineMicrolensing
                ml_effect = ml_spline_func(nanchor=nanchor,
                                           sigmadm=sigmadm,
                                           nspl=nspl)
            else:
                #get magnification curve from the defined microcaustic
                mlTime = np.arange(
                    0,
                    times[-1] / (1 + redshift) - model_i._source._phase[0] + 5,
                    1)

                time, dmag = microcaustic_field_to_curve(
                    microlensing_params, mlTime, z_lens, redshift)
                dmag /= np.mean(dmag)  #to remove overall magnification

                ml_effect = AchromaticMicrolensing(time +
                                                   model_i._source._phase[0],
                                                   dmag,
                                                   magformat='multiply')
                # time=np.arange(-10,5,.5)
                # lc1=model_i.bandflux('bessellb',time,zp=26.8,zpsys='ab')
                # lc2=model_i.bandflux('bessellb',time-.5,zp=26.8,zpsys='ab')
                # lc1/=np.max(lc1)
                # lc2/=np.max(lc2)
                # dmag=lc2/lc1
                # dmag/=np.mean(dmag)
                # import matplotlib.pyplot as plt
                # fig=plt.figure()
                # ax=fig.gca()
                # ax.plot(time,dmag)
                #ml_effect=AchromaticMicrolensing(time,dmag)
            model_i.add_effect(ml_effect, 'microlensing', 'rest')
        else:
            ml_effect = None

        # Generate the simulated SN light curve observations, make a `curve`
        # object, and store the simulation metadata
        model_i.set(**params_i)

        table_i = realize_lcs(obstable,
                              model_i, [params_i],
                              trim_observations=True,
                              scatter=scatter,
                              thresh=minsnr,
                              snrFunc=snrFunc)
        tried = 0
        while (len(table_i) == 0
               or len(table_i[0]) < numImages) and tried < 50:
            table_i = realize_lcs(obstable,
                                  model_i, [params_i],
                                  trim_observations=True,
                                  scatter=scatter,
                                  thresh=minsnr,
                                  snrFunc=snrFunc)
            tried += 1
        if tried == 50:
            #this arbitrary catch is here in case your minsnr and observation parameters
            #result in a "non-detection"
            print("Your survey parameters detected no supernovae.")
            return None
        table_i = table_i[0]
        if timeArr is None:
            table_i = table_i[table_i['time'] < td + 60]
            table_i = table_i[table_i['time'] > td - 30]
        #create is curve with all parameters and add it to the overall curveDict object from above
        curve_i = curve()
        curve_i.object = None
        curve_i.zpsys = zpsys
        curve_i.table = deepcopy(table_i)
        curve_i.bands = list(set(table_i['band']))
        curve_i.simMeta = deepcopy(table_i.meta)
        curve_i.simMeta['sourcez'] = redshift
        curve_i.simMeta['model'] = model_i
        curve_i.simMeta['hostebv'] = ebv_host
        curve_i.simMeta['lensebv'] = ebv_lens
        curve_i.simMeta['lensz'] = z_lens
        curve_i.simMeta['mu'] = mu
        curve_i.simMeta['td'] = td
        curve_i.simMeta['microlensing'] = ml_effect
        curve_i.simMeta['microlensing_type'] = microlensing_type

        if microlensing_type == 'AchromaticSplineMicrolensing':
            curve_i.simMeta['microlensing_params'] = microlensing_params
        elif microlensing_type is not None:
            curve_i.simMeta['microlensing_params'] = interp1d(
                time + model_i._source._phase[0], dmag)

        curve_obj.add_curve(curve_i)

    # Store the un-lensed model as a component of the lensed SN object.
    model.set(**params)
    curve_obj.model = model

    return (curve_obj)
Example #33
0
    def Plot_LC_Points(self,data=None, flux_name='flux',xfigsize=None, yfigsize=None, figtext=None,figtextsize=1.,ncol=2,color=None,cmap=None, cmap_lims=(3000., 10000.),zp=25., zpsys='ab',):
       
        

        toff=data.meta['DayMax']
        bands=set(data['band'])

        tmin, tmax = [], []
        if data is not None:
            tmin.append(np.min(data['time']) - 10.)
            tmax.append(np.max(data['time']) + 10.)

        # Calculate layout of figure (columns, rows, figure size). We have to
        # calculate these explicitly because plt.tight_layout() doesn't space the
        # subplots as we'd like them when only some of them have xlabels/xticks.
        wspace = 0.6  # All in inches.
        hspace = 0.3
        lspace = 1.0
        bspace = 0.7
        trspace = 0.2
        nrow = (len(bands) - 1) // ncol + 1
        if xfigsize is None and yfigsize is None:
            hpanel = 2.25
            wpanel = 3.
        elif xfigsize is None:
            hpanel = (yfigsize - figtextsize - bspace - trspace -
                      hspace * (nrow - 1)) / nrow
            wpanel = hpanel * 3. / 2.25
        elif yfigsize is None:
            wpanel = (xfigsize - lspace - trspace - wspace * (ncol - 1)) / ncol
            hpanel = wpanel * 2.25 / 3.
        else:
            raise ValueError('cannot specify both xfigsize and yfigsize')

        figsize = (lspace + wpanel * ncol + wspace * (ncol - 1) + trspace,
               bspace + hpanel * nrow + hspace * (nrow - 1) + trspace +
               figtextsize)  

        # Create the figure and axes.
        fig, axes = plt.subplots(nrow, ncol, figsize=figsize, squeeze=False)
        
        fig.subplots_adjust(left=lspace / figsize[0],
                            bottom=bspace / figsize[1],
                            right=1. - trspace / figsize[0],
                            top=1. - (figtextsize + trspace) / figsize[1],
                            wspace=wspace / wpanel,
                            hspace=hspace / hpanel)
        # Color options.
        if color is None:
            if cmap is None:
                cmap = cm.get_cmap('jet_r')
        # Loop over bands
        bands = list(bands)
        waves = [sncosmo.get_bandpass(b).wave_eff for b in bands]
        waves_and_bands = sorted(zip(waves, bands))

        for axnum in range(ncol * nrow):
            row = axnum // ncol
            col = axnum % ncol
            ax = axes[row, col]
 
            if axnum >= len(waves_and_bands):
                ax.set_visible(False)
                ax.set_frame_on(False)
                continue

            wave, band = waves_and_bands[axnum]

            bandname_coords = (0.92, 0.92)
            bandname_ha = 'right'
            if color is None:
                bandcolor = cmap((cmap_lims[1] - wave) /
                                 (cmap_lims[1] - cmap_lims[0]))
            else:
                bandcolor = color

            if data is not None:
                mask = data['band'] == band
                time = data['time'][mask]
                flux = data[flux_name][mask]
                fluxerr = data['fluxerr'][mask]/data['flux'][mask]*data[flux_name][mask]
                ax.errorbar(time - toff, flux, fluxerr, ls='None',
                            color=bandcolor, marker='.', markersize=10.)    
            # Band name in corner
            ax.text(bandname_coords[0], bandname_coords[1], band,
                    color='k', ha=bandname_ha, va='top', transform=ax.transAxes)

            ax.axhline(y=0., ls='--', c='k')  # horizontal line at flux = 0.
            ax.set_xlim((tmin-toff, tmax-toff))

            if (len(bands) - axnum - 1) < ncol:
                if toff == 0.:
                    ax.set_xlabel('time')
                else:
                    ax.set_xlabel('time - {0:.2f}'.format(toff))
            else:
                for l in ax.get_xticklabels():
                    l.set_visible(False)
            if col == 0:
                if flux_name == 'flux':
                    ax.set_ylabel('flux ($ZP_{{{0}}} = {1}$)'
                                  .format(sncosmo.get_magsystem(zpsys).name.upper(), zp))
                if flux_name == 'flux_e_sec':
                   ax.set_ylabel('flux (e/sec)') 
Example #34
0
def generate_buckets(low, high, n, inverse_microns=False):
    '''
    function to generate [n] tophat filters within the
    range of [low, high] (given in Angrstroms), with one 'V' filter centered at
    the BESSEL-V filter's effective wavelength (5417.2 Angstroms).
    '''
    #V_EFF = 5417.2
    V_EFF = 5413.5  # To be consistent with mag_spect_fitting.py.


    if inverse_microns:
        V_EFF = 10000./V_EFF
        temp = low
        low = 10000./high
        high = 10000./temp
        STEP_SIZE = .01         # this number may be the reason why it's difficult to go to more than 80 bands. -XH
        prefix = 'bucket_invmicron_'
    else:
        STEP_SIZE = 2      # becaues the finest wavelength resolution (for 11fe) is 2A.  -XH
        prefix = 'bucket_angstrom_'

    zp_cache = {'prefix':prefix}

    hi_cut, lo_cut = high-V_EFF, V_EFF-low
    print 'hi_cut, lo_cut', hi_cut, lo_cut
    a = (n-1)/(1+(hi_cut/lo_cut))   # this is to figure out the relative portion of the number of red bands vs. blue bands (boundaried on V_EFF).  -XH
    print 'a, n', a, n


    A, B = np.round(a), np.round(n-1-a)  # A and B are the number of band for the blue and red parts of the spectrum (relative to V_eff), respectively.
                                         # It's better to give them more descriptive names.  -XH

    lo_bw, hi_bw = lo_cut/(A+0.5), hi_cut/(B+0.5)  # looks like bw stands for bandwidth.  They added 0.5, probably to make sure, one doesn't run out of room on either end of
                                                   # the spectrum.  Note at this point, the bandwidths for the blue and red parts constructed this way are close to each
                                                   # other, but not identical.   -XH

    print 'lo_bw, hi_bw',lo_bw, hi_bw

    ## The next few lines is to determine which of the two bw's is lower and that will be used as the bandwidth, BW.  -XH
    lo_diff = lo_cut-(A+0.5)*hi_bw
    hi_diff = hi_cut-(B+0.5)*lo_bw

    idx = np.argmin((lo_diff,hi_diff))
    #print 'idx', idx
    BW = (lo_bw,hi_bw)[idx]      # the lower of the two bandwidths is selected.  -XH
    LOW_wave = (low,low+lo_diff)[idx] # not sure what this accomplishes.  LOw ends up being 3300, which was the input, low.  -XH
    HIGH_wave = LOW_wave + n*BW              # This is actual upper wavelength limit.
    #print 'HIGH_wave', HIGH_wave
#exit(1)

    toregister = {}
    for i in xrange(n):
        start = LOW_wave+i*BW
        end = LOW_wave+(i+1)*BW  # will replace this with: end = start + BW.  -XH

        wave = np.arange(start, end, STEP_SIZE)
        trans = np.ones(wave.shape[0])
        trans[0]=trans[-1]=0

        index = (str(i),'V')[ abs(V_EFF-(start+end)/2) < 1e-5 ]   # This selects either i or V for index.  -XH

        if inverse_microns:
            wave = sorted(10000./wave)

        toregister[index] = {'wave':wave, 'trans':trans}

    filters = []
    zpsys = snc.get_magsystem('ab')
    for index, info in toregister.items():
        wave, trans = info['wave'], info['trans']
        bandpass = snc.Bandpass(wave, trans)
        
        snc.registry.register(bandpass, prefix+index, force=True)
        zp_phot = zpsys.zpbandflux(prefix+index)
        zp_cache[index] = zp_phot

        filters.append(index)
    
    
    
    return filters, zp_cache, LOW_wave, HIGH_wave
Example #35
0
#                 'r': (6289., 7607.),
#                 'i': (7607., 8585.)}
filter_edges = {
    'u': (3300., 4102.),
    'b': (4102., 5100.),
    'v': (5200., 6289.),
    'r': (6289., 7607.),
    'i': (7607., 9200.)
}
SNF_BANDS = {}
for fname, edges in filter_edges.items():
    wave = [edges[0] - 1., edges[0], edges[1], edges[1] + 1.]
    trans = [0., 1., 1., 0.]
    SNF_BANDS[fname] = sncosmo.Bandpass(wave, trans, name='snf' + fname)

MAGSYS = sncosmo.get_magsystem('vega')
SUBSET_NAMES = ['training', 'validation', 'auxiliary', 'bad']


class Dataset(object):
    def __init__(self, subset=None, data_dir=IDR_dir):
        self.data_dir = data_dir
        with open(os.path.join(data_dir, 'META.pkl'), 'rb') as meta:
            data = pickle.load(meta)
        self.data = {}
        if subset is not None:
            # Convert to list
            if type(subset) is str:
                subset = [subset]
            # Check for bad subset names
            cleaned_subset_names = []
Example #36
0
def curveToColor(lc,
                 colors,
                 bandFit=None,
                 snType='II',
                 bandDict=_filters,
                 color_bands=_opticalBands,
                 zpsys='AB',
                 model=None,
                 singleBand=False,
                 verbose=True,
                 **kwargs):
    """
    Function takes a lightcurve file and creates a color table for it.

    :param lc: Name of lightcurve file you want to read, or astropy Table containing data
    :type lc: str or astropy.Table
    :param colors: Colors you want to calculate for the given SN (i.e U-B, r'-J)
    :type colors: str or list of strings
    :param bandFit: If there is a specific band you would like to fit instead of default
    :type bandFit: str,optional
    :param snType: Classification of SN
    :type snType: str,optional
    :param bandDict: sncosmo bandpass for each band used in the fitting/table generation
    :type bandDict: dict,optional
    :param color_bands: bands making up the known component of chosen colors
    :type color_bands: list,optional
    :param zpsys: magnitude system (i.e. AB or Vega)
    :type zpsys: str,optional
    :param model: If there is a specific sncosmo model you would like to fit with, otherwise all models mathcing the SN classification will be tried
    :type model: str,optional
    :param singleBand: If you would like to only fit the bands in the color
    :type singleBand: Boolean,optional
    :param verbose: If you would like printing information to be turned on/off
    :type verbose: Boolean,optional
    :param kwargs: Catches all SNCOSMO fitting parameters here
    :returns: colorTable: Astropy Table object containing color information
    """

    bands = append([col[0] for col in colors], [col[-1] for col in colors])
    for band in _filters:
        if band not in bandDict.keys() and band in bands:
            bandDict[band] = sncosmo.get_bandpass(_filters[band])
    if not isinstance(colors, (tuple, list)):
        colors = [colors]
    zpMag = sncosmo.get_magsystem(zpsys)

    if isinstance(lc, str):
        curve = _standardize(sncosmo.read_lc(lc))
    else:
        try:
            curve = _standardize(lc)
        except:
            raise RuntimeError("Can't understand your lightcurve.")
    if _get_default_prop_name('zpsys') not in curve.colnames:
        curve[_get_default_prop_name('zpsys')] = zpsys
    colorTable = Table(masked=True)
    colorTable.add_column(Column(data=[], name=_get_default_prop_name('time')))

    for band in bandDict:
        if not isinstance(bandDict[band], sncosmo.Bandpass):
            bandDict = _bandCheck(bandDict, band)
    t0 = None
    if verbose:
        print('Getting best fit for: ' + ','.join(colors))

    args = []
    for p in _fittingParams:
        args.append(kwargs.get(p, _fittingParams[p]))

        if p == 'method':
            try:
                importlib.import_module(_fittingPackages[args[-1]])
            except RuntimeError:
                sys.exit()
    for color in colors:  #start looping through desired colors
        if bandDict[color[
                0]].wave_eff < _UVrightBound:  #then extrapolating into the UV from optical
            if not bandFit:
                bandFit = color[-1]
            if singleBand:
                color_bands = [color[-1]]
            blue = curve[curve[_get_default_prop_name('band')] ==
                         color[0]]  #curve on the blue side of current color
            red = curve[[
                x in color_bands for x in curve[_get_default_prop_name('band')]
            ]]  #curve on the red side of current color
        else:  #must be extrapolating into the IR
            if not bandFit:
                bandFit = color[0]
            if singleBand:
                color_bands = [color[0]]
            blue = curve[[
                x in color_bands for x in curve[_get_default_prop_name('band')]
            ]]
            red = curve[curve[_get_default_prop_name('band')] == color[-1]]
        if len(blue) == 0 or len(red) == 0:
            if verbose:
                print('Asked for color %s but missing necessary band(s)' %
                      color)
            bandFit = None
            continue

        btemp = [
            bandDict[blue[_get_default_prop_name('band')][i]].name
            for i in range(len(blue))
        ]
        rtemp = [
            bandDict[red[_get_default_prop_name('band')][i]].name
            for i in range(len(red))
        ]
        blue.remove_column(_get_default_prop_name('band'))
        blue[_get_default_prop_name('band')] = btemp
        red.remove_column(_get_default_prop_name('band'))
        red[_get_default_prop_name('band')] = rtemp
        #now make sure we have zero-points and fluxes for everything
        if _get_default_prop_name('zp') not in blue.colnames:
            blue[_get_default_prop_name('zp')] = [
                zpMag.band_flux_to_mag(1 / sncosmo.constants.HC_ERG_AA,
                                       blue[_get_default_prop_name('band')][i])
                for i in range(len(blue))
            ]
        if _get_default_prop_name('zp') not in red.colnames:
            red[_get_default_prop_name('zp')] = [
                zpMag.band_flux_to_mag(1 / sncosmo.constants.HC_ERG_AA,
                                       red[_get_default_prop_name('band')][i])
                for i in range(len(red))
            ]
        if _get_default_prop_name('flux') not in blue.colnames:
            blue = mag_to_flux(blue, bandDict, zpsys)
        if _get_default_prop_name('flux') not in red.colnames:
            red = mag_to_flux(red, bandDict, zpsys)

        if not t0:  #this just ensures we only run the fitting once
            if not model:
                if verbose:
                    print('No model provided, running series of models.')

                mod, types = loadtxt(os.path.join(__dir__, 'data', 'sncosmo',
                                                  'models.ref'),
                                     dtype='str',
                                     unpack=True)
                modDict = {mod[i]: types[i] for i in range(len(mod))}
                if snType != 'Ia':
                    mods = [
                        x for x in sncosmo.models._SOURCES._loaders.keys()
                        if x[0] in modDict.keys()
                        and modDict[x[0]][:len(snType)] == snType
                    ]
                elif snType == 'Ia':
                    mods = [
                        x for x in sncosmo.models._SOURCES._loaders.keys()
                        if 'salt2' in x[0]
                    ]

                mods = {
                    x[0] if isinstance(x, (tuple, list)) else x
                    for x in mods
                }
                if bandFit == color[0] or len(blue) > len(red):
                    args[0] = blue
                    if len(blue) > 60:
                        fits = []
                        for mod in mods:
                            fits.append(_snFit([mod] + args))
                    else:
                        fits = pyParz.foreach(mods, _snFit, args)
                    fitted = blue
                    notFitted = red
                    fit = color[0]
                elif bandFit == color[-1] or len(blue) < len(red):
                    args[0] = red
                    '''
                    data,temp= sncosmo_fitting.cut_bands(photometric_data(red), sncosmo.Model(tempMod),
                                                             z_bounds=all_bounds.get('z', None),
                                                             warn=True)
                    print(data.fluxerr)
                    cov = diag(data.fluxerr**2) if data.fluxcov is None else data.fluxcov
                    invcov = linalg.pinv(cov)

                    args.append(invcov)
                    
                    sys.exit()
                    
                    fits=pyParz.foreach(mods,_snFit,args)
                    args.pop()
                    '''
                    if len(red) > 60:
                        fits = []
                        for mod in mods:
                            fits.append(_snFit([mod] + args))
                    else:
                        fits = pyParz.foreach(mods, _snFit, args)
                    fitted = red
                    notFitted = blue
                    fit = color[-1]
                else:
                    raise RuntimeError(
                        'Neither band "%s" nor band "%s" has more points, and you have not specified which to fit.'
                        % (color[0], color[-1]))
                bestChisq = inf
                for f in fits:
                    if f:
                        res, mod = f
                        if res.chisq < bestChisq:
                            bestChisq = res.chisq
                            bestFit = mod
                            bestRes = res
                if verbose:
                    print('Best fit model is "%s", with a Chi-squared of %f' %
                          (bestFit._source.name, bestChisq))
            elif bandFit == color[0] or len(blue) > len(red):
                args[0] = blue
                bestRes, bestFit = _snFit(append(model, args))
                fitted = blue
                notFitted = red
                fit = color[0]
                if verbose:
                    print(
                        'The model you chose (%s) completed with a Chi-squared of %f'
                        % (model, bestRes.chisq))
            elif bandFit == color[-1] or len(blue) < len(red):
                args[0] = red
                bestRes, bestFit = _snFit(append(model, args))
                fitted = red
                notFitted = blue
                fit = color[-1]
                if verbose:
                    print(
                        'The model you chose (%s) completed with a Chi-squared of %f'
                        % (model, bestRes.chisq))
            else:
                raise RuntimeError(
                    'Neither band "%s" nor band "%s" has more points, and you have not specified which to fit.'
                    % (color[0], color[-1]))

            t0 = _getBandMaxTime(bestFit, fitted, bandDict, 'B',
                                 zpMag.band_flux_to_mag(1, bandDict['B']),
                                 zpsys)
            if len(t0) == 1:
                t0 = t0[0]
            else:
                raise RuntimeError('Multiple global maxima in best fit.')
        else:
            if len(blue) > len(red) or bandFit == color[0]:
                fitted = blue
                notFitted = red
                fit = color[0]
            elif len(blue) < len(red) or bandFit == color[-1]:
                fitted = red
                notFitted = blue
                fit = color[-1]
            else:
                raise RuntimeError(
                    'Neither band "%s" nor band "%s" has more points, and you have not specified which to fit.'
                    % (color[0], color[-1]))

        #return(bestFit,bestRes,t0,fitted,notFitted)
        tGrid, bestMag = _snmodel_to_mag(bestFit, fitted, zpsys, bandDict[fit])

        ugrid, UMagErr, lgrid, LMagErr = _getErrorFromModel(
            append([bestFit._source.name, fitted], args[1:]), zpsys,
            bandDict[fit])
        tempTable = Table(
            [tGrid - t0, bestMag, bestMag * .1],
            names=(_get_default_prop_name('time'),
                   _get_default_prop_name('mag'),
                   _get_default_prop_name('magerr')
                   ))  #****RIGHT NOW THE ERROR IS JUST SET TO 10%*****
        interpFunc = scint.interp1d(
            array(tempTable[_get_default_prop_name('time')]),
            array(tempTable[_get_default_prop_name('mag')]))
        minterp = interpFunc(
            array(notFitted[_get_default_prop_name('time')] - t0))
        interpFunc = scint.interp1d(ugrid - t0, UMagErr)
        uinterp = interpFunc(
            array(notFitted[_get_default_prop_name('time')] - t0))
        interpFunc = scint.interp1d(lgrid - t0, LMagErr)
        linterp = interpFunc(
            array(notFitted[_get_default_prop_name('time')] - t0))
        magerr = mean([minterp - uinterp, linterp - minterp], axis=0)

        for i in range(len(minterp)):
            colorTable.add_row(append(
                notFitted[_get_default_prop_name('time')][i] - t0,
                [1 for j in range(len(colorTable.colnames) - 1)]),
                               mask=[
                                   True if j > 0 else False
                                   for j in range(len(colorTable.colnames))
                               ])
        if fit == color[0]:
            colorTable[color] = MaskedColumn(
                append([1 for j in range(len(colorTable) - len(minterp))],
                       minterp -
                       array(notFitted[_get_default_prop_name('mag')])),
                mask=[
                    True if j < (len(colorTable) - len(minterp)) else False
                    for j in range(len(colorTable))
                ])
        else:
            colorTable[color] = MaskedColumn(
                append([1 for j in range(len(colorTable) - len(minterp))],
                       array(notFitted[_get_default_prop_name('mag')]) -
                       minterp),
                mask=[
                    True if j < (len(colorTable) - len(minterp)) else False
                    for j in range(len(colorTable))
                ])
        colorTable[color[0] + color[-1] + '_err'] = MaskedColumn(
            append([1 for j in range(len(colorTable) - len(magerr))], magerr +
                   array(notFitted[_get_default_prop_name('magerr')])),
            mask=[
                True if j < (len(colorTable) - len(magerr)) else False
                for j in range(len(colorTable))
            ])
        #colorTable['V-r']=MaskedColumn(append([1 for j in range(len(colorTable)-len(magerr))],[bestFit.color('bessellv','sdss::r',zpsys,t0) for i in range(len(linterp))]),mask=[True if j<(len(colorTable)-len(magerr)) else False for j in range(len(colorTable))])
        tempVRCorr = 0
        for name in bestFit.effect_names:
            magCorr = _unredden(
                color, bandDict,
                bestRes.parameters[bestRes.param_names.index(name + 'ebv')],
                bestRes.parameters[bestRes.param_names.index(name + 'r_v')])
            colorTable[color] -= magCorr
            tempVRCorr += _unredden(
                'V-R', bandDict,
                bestRes.parameters[bestRes.param_names.index(name + 'ebv')],
                bestRes.parameters[bestRes.param_names.index(name + 'r_v')])
            corr1 = _ccm_extinction(
                sncosmo.get_bandpass('besselli').wave_eff,
                bestRes.parameters[bestRes.param_names.index(name + 'ebv')],
                r_v=3.1)
            corr2 = _ccm_extinction(
                sncosmo.get_bandpass('bessellr').wave_eff,
                bestRes.parameters[bestRes.param_names.index(name + 'ebv')],
                r_v=3.1)
            corr3 = _ccm_extinction(
                sncosmo.get_bandpass('bessellb').wave_eff,
                bestRes.parameters[bestRes.param_names.index(name + 'ebv')],
                r_v=3.1)
            corr4 = _ccm_extinction(
                sncosmo.get_bandpass('bessellv').wave_eff,
                bestRes.parameters[bestRes.param_names.index(name + 'ebv')],
                r_v=3.1)
        vr = [
            x - tempVRCorr
            for x in bestFit.color('bessellv', 'bessellr', zpsys,
                                   arange(t0 - 20, t0 + 100, 1))
        ]
        #vr=(bestFit.bandmag('bessellr',zpsys,arange(t0-20,t0+100,1))-bestFit.bandmag('besselli',zpsys,arange(t0-20,t0+100,1))-(corr2-corr1))/(bestFit.bandmag('bessellb',zpsys,arange(t0-20,t0+100,1))-bestFit.bandmag('bessellv',zpsys,arange(t0-20,t0+100,1))-(corr3-corr4))
        bandFit = None
    colorTable.sort(_get_default_prop_name('time'))

    return (colorTable, vr)