Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docs #298

Merged
merged 10 commits into from Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/_helpers/bandpass_page.py
Expand Up @@ -10,8 +10,8 @@
ASCII_LETTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

bandpass_meta = _BANDPASSES.get_loaders_metadata()
table_delim = " ".join([15 * '=', 80 * '=', 24 * '=', 8 * '=', 12 * '='])
table_colnames = ("{0:15} {1:80} {2:24} {3:8} {4:12}"
table_delim = " ".join([15 * '=', 120 * '=', 24 * '=', 8 * '=', 12 * '='])
table_colnames = ("{0:15} {1:120} {2:24} {3:8} {4:12}"
.format('Name', 'Description', 'Reference', 'Data URL',
'Retrieved'))
urlnums = {}
Expand Down Expand Up @@ -50,7 +50,7 @@ def bandpass_table(setname):
if 'retrieved' in m:
retrieved = m['retrieved']

lines.append("{0!r:15} {1:80} {2:24} {3:8} {4:12}".format(
lines.append("{0!r:15} {1:120} {2:24} {3:8} {4:12}".format(
m['name'], m['description'], reflink, urllink, retrieved))

lines.append(table_delim)
Expand Down
6 changes: 3 additions & 3 deletions docs/_helpers/source_page.py
Expand Up @@ -9,8 +9,8 @@

lines = [
'',
' '.join([20*'=', 7*'=', 10*'=', 27*'=', 30*'=', 7*'=', 20*'=']),
'{0:20} {1:7} {2:10} {3:27} {4:30} {5:7} {6:50}'.format(
' '.join([30*'=', 7*'=', 10*'=', 27*'=', 30*'=', 7*'=', 20*'=']),
'{0:30} {1:7} {2:10} {3:27} {4:30} {5:7} {6:50}'.format(
'Name', 'Version', 'Type', 'Subclass', 'Reference', 'Website', 'Notes')
]
lines.append(lines[1])
Expand Down Expand Up @@ -44,7 +44,7 @@
urlnums[url] = max(urlnums.values()) + 1
urllink = '`{0}`_'.format(string.ascii_letters[urlnums[url]])

lines.append("{0!r:20} {1!r:7} {2:10} {3:27} {4:30} {5:7} {6:50}"
lines.append("{0!r:30} {1!r:7} {2:10} {3:27} {4:30} {5:7} {6:50}"
.format(m['name'], m['version'], m['type'], m['subclass'],
reflink, urllink, notelink))

Expand Down
11 changes: 11 additions & 0 deletions docs/reference.rst
Expand Up @@ -61,6 +61,7 @@ maps, and more.*
write_lc
read_bandpass
load_example_data
load_example_spectrum_data
read_snana_ascii
read_snana_fits
read_snana_simlib
Expand All @@ -69,6 +70,16 @@ maps, and more.*
write_griddata_ascii
write_griddata_fits

Spectra
=======

.. autosummary::
:toctree: api

Spectrum



.. _fitting-api:

Fitting Photometric Data
Expand Down
85 changes: 44 additions & 41 deletions docs/spectrum.rst
Expand Up @@ -2,21 +2,17 @@
Spectra
*******

Spectroscopic observations are supported in `sncosmo` with the `~sncosmo.Spectrum`
class. A spectrum object can be created from a list of wavelengths and flux values:
Spectroscopic observations are supported in `sncosmo` with the
`~sncosmo.Spectrum` class. A spectrum object can be created from a list of
wavelengths and flux values:

.. code:: python

>>> wave = np.arange(3000, 9000)
>>> model = sncosmo.Model(source='hsiao-subsampled')
>>> model.set(z=0.1, amplitude=1e-5, t0=56000.)
>>> sample_time = model['t0'] + 2.
>>> flux = model.flux(time=sample_time, wave=wave)

>>> spectrum = sncosmo.Spectrum(wave, flux, time=sample_time)
>>> wave, flux, fluxerr = sncosmo.load_example_spectrum_data()
>>> spectrum = sncosmo.Spectrum(wave, flux)

By default, the wavelengths are assumed to be in angstroms and the flux values as a
spectral flux density (erg / s / cm^2 / A).
By default, the wavelengths are assumed to be in angstroms and the flux
values as a spectral flux density (erg / s / cm^2 / A).

Uncertainties
-------------
Expand All @@ -26,15 +22,14 @@ uncertainties for each spectral element:

.. code:: python

>>> fluxerr = 0.1 * flux
>>> spectrum = sncosmo.Spectrum(wave, flux, fluxerr, time=sample_time)
>>> spectrum = sncosmo.Spectrum(wave, flux, fluxerr)

or a full covariance matrix:

.. code:: python

>>> fluxcov = np.diag(fluxerr**2) + 1e-5 * np.max(flux)**2
>>> spectrum = sncosmo.Spectrum(wave, flux, fluxcov=fluxcov, time=sample_time)
>>> spectrum = sncosmo.Spectrum(wave, flux, fluxcov=fluxcov)

All operations will take these uncertanties into account.

Expand All @@ -47,39 +42,40 @@ available in sncosmo:
.. code:: python

>>> spectrum.bandflux('sdssg')
6.336874516839506
6.417843339246818

Synthetic photometry can be calculated on multiple bands simultaneously:

.. code:: python

>>> spectrum.bandflux(['sdssg', 'sdssr', 'sdssi'])
array([6.33687452, 5.33348909, 2.86301428])
array([6.41784334, 5.37683496, 2.8626649 ])

If a zeropoint and magnitude system are specified, then the bandflux is returned in that
system (otherwise it is in photons / s / cm^2 by default).
If a zeropoint and magnitude system are specified, then the bandflux is
returned in that system (otherwise it is in photons / s / cm^2 by default).

.. code:: python

>>> spectrum.bandflux(['sdssg', 'sdssr', 'sdssi'], zp=25., zpsys='ab')
array([115932.40764299, 108077.89453051, 79602.18806937])
array([117413.72315598, 108956.25581652, 79592.47424074])

Optionally, the full covariance matrix between the bandfluxes can also be calculated:
Optionally, the full covariance matrix between the bandfluxes can also be
calculated:

.. code:: python

>>> spectrum.bandfluxcov(['sdssg', 'sdssr', 'sdssi'], zp=25., zpsys='ab')
(array([115932.40764299, 108077.89453051, 79602.18806937]),
array([[ 436626.04457069, 574161.2530974 , 845566.99897734],
[ 574161.2530974 , 1088219.30397941, 1460106.55463119],
[ 845566.99897734, 1460106.55463119, 2203060.35600117]]))
(array([117413.72315598, 108956.25581652, 79592.47424074]),
array([[1546972.78077853, 874550.34470817, 1287550.14818921],
[ 874550.34470817, 2479812.26652077, 2226272.0481113 ],
[1287550.14818921, 2226272.0481113 , 3805168.84485814]]))

A band magnitude can be evaluated in a specific magnitude system:

.. code:: python

>>> spectrum.bandmag(['sdssg', 'sdssr', 'sdssi'], magsys='ab')
array([12.33948786, 12.41565781, 12.74768749])
array([12.32570285, 12.40686957, 12.74781999])



Expand All @@ -93,38 +89,45 @@ A spectrum can be rebinned with arbitrary wavelength bins. This returns a new

>>> binned_spectrum = spectrum.rebin(np.arange(3500, 6000, 100))

Rebinning introduces covariance between adjacent spectral elements if the bin edges
in the original spectrum don't line up with the bin edges in the rebinned spectrum. This
covariance is properly propagated.
Rebinning introduces covariance between adjacent spectral elements if the bin
edges in the original spectrum don't line up with the bin edges in the
rebinned spectrum. This covariance is properly propagated.


Fitting with spectra
--------------------

Spectra can be used in fits. Any combination of spectra and photometry is allowed. For
example, to fit a single spectrum:
Spectra can be used in fits. Any combination of spectra and photometry is
allowed. To fit spectra, the times at which the spectra were taken must be
specified. For example, to fit a single spectrum:

.. code:: python

>>> model.set(z=0., amplitude=1., t0=0.)
>>> sncosmo.fit_lc(model=model, spectra=binned_spectrum,
Create the spectrum object, and specify the time at which it was taken.
kboone marked this conversation as resolved.
Show resolved Hide resolved
>>> spectrum = sncosmo.Spectrum(wave, flux, fluxerr, time=20.)

Fit a model to the spectrum.
>>> model = sncosmo.Model(source='hsiao-subsampled')
>>> sncosmo.fit_lc(model=model, spectra=spectrum,
... vparam_names=['amplitude', 't0', 'z'],
... bounds={'z': (0., 0.3)})
( success: True
message: 'Minimization exited successfully.'
ncall: 86
chisq: 1.1072097164403554e-05
ndof: 22
ncall: 108
chisq: 576.7111360163605
ndof: 597
param_names: ['z', 't0', 'amplitude']
parameters: array([9.99999822e-02, 5.60000000e+04, 9.99997056e-06])
parameters: array([9.96571945e-02, 1.80278503e+01, 1.00650322e-05])
vparam_names: ['z', 't0', 'amplitude']
covariance: array([[ 4.60410999e-08, 7.84028630e-06, -1.39915254e-12],
[ 7.84028630e-06, 6.28193143e-03, -1.47231576e-09],
[-1.39915254e-12, -1.47231576e-09, 2.86156520e-15]])
errors: OrderedDict([('z', 0.0002145718167298541), ('t0', 0.07925860166142229), ('amplitude', 5.3493599593407034e-08)])
covariance: array([[ 1.17946556e-07, 1.64336679e-05, -5.21279026e-12],
[ 1.64336679e-05, 1.70047614e-02, -4.60755668e-09],
[-5.21279026e-12, -4.60755668e-09, 2.91915780e-15]])
errors: OrderedDict([('z', 0.00034343314287464677),
('t0', 0.13040215158608248),
('amplitude', 5.4029230945864686e-08)])
nfit: 1
data_mask: None,
<sncosmo.models.Model at 0x7fb8d498c110>)
<sncosmo.models.Model at 0x7fa30159a6d0>)

Other valid signatures are:

Expand Down
14 changes: 14 additions & 0 deletions misc/gen_example_spectrum.py
@@ -0,0 +1,14 @@
#!/usr/bin/env python
import numpy as np
import sncosmo

wave = np.arange(3000, 9000, 10)
model = sncosmo.Model(source='hsiao-subsampled')
model.set(z=0.1, amplitude=1e-5, t0=0.)
sample_time = model['t0'] + 2.
flux = model.flux(time=sample_time, wave=wave)
fluxerr = 0.1 * flux
flux = flux + np.random.normal(scale=fluxerr)

np.savetxt('example_spectrum.dat', np.array([wave, flux, fluxerr]).T,
header="wave flux fluxerr")
10 changes: 5 additions & 5 deletions sncosmo/builtins.py
Expand Up @@ -922,10 +922,10 @@ def load_2011fe(relpath, name=None, version=None):
('v19-iptf13bvn', '1.0', 'SN Ib', 'V19_iPTF13bvn_noHostExtCorr.SED')
]

note = """Templates from Vincenzi et al. 19. Each template is extended in the
ultraviolet (1600AA) and in the near infrared (10000AA). Each template can be
used in its original version (v19-sn-name) or in its host dust extinction
corrected version (v19-sn-name-corr)."""
note = "Templates from Vincenzi et al. 19. Each template is extended in the " \
"ultraviolet (1600AA) and in the near infrared (10000AA). Each template " \
"can be used in its original version (v19-sn-name) or in its host dust " \
"extinction corrected version (v19-sn-name-corr)."

for name, vrs, sntype, fn in V19_CC_models:
relpath = os.path.join('models', 'vincenzi', fn)
Expand Down Expand Up @@ -1009,7 +1009,7 @@ def load_sugarmodel(relpath, name=None, version=None):
meta = {'type': 'SN Ia', 'subclass': '`~sncosmo.SUGARSource`',
'url': 'http://supernovae.in2p3.fr/sugar_template/',
'reference': ('Leget20',
'Leget et al. 2020',
'Leget et al. 2020 '
'<https://doi.org/10.1051/0004-6361/201834954>')}

_SOURCES.register_loader(name, load_sugarmodel,
Expand Down