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)
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
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)
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)
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
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
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')
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
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
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)
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))
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)
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)
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)
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
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
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]
#!/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:
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])
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)
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
def test_builtin_magsystem(name): sncosmo.get_magsystem(name)
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)
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)
def test_builtins_magsys_ab(): sncosmo.get_magsystem('ab')
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()
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
def test_retrieve_cases(): for name in ['ab', 'Ab', 'AB']: # Should work regardless of case. sncosmo.get_magsystem(name)
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)
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)')
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
# '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 = []
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)