Registry¶
What is it?¶
The registry (sncosmo.registry
) is responsible for translating
string identifiers to objects, for user convenience. For example, it is
used in sncosmo.get_bandpass
and sncosmo.get_source
to return a
Bandpass
or sncosmo.Model
object based on the name of
the bandpass or model:
>>> sncosmo.get_bandpass('sdssi')
<Bandpass 'sdssi' at 0x28e7c90>
It is also used in methods like bandflux
to
give it the ability to accept either a Bandpass
object or
the name of a bandpass:
>>> model = sncosmo.Model(source='hsiao')
>>> model.bandflux('sdssg', 0.) # works, thanks to registry.
Under the covers, the bandflux
method retrieves the Bandpass
corresponding to 'sdssg'
by calling the
sncosmo.get_bandpass
function.
The registry is actually quite simple: it basically amounts to a dictionary and a few functions for accessing the dictionary. Most of the time, a user doesn’t need to know anything about the registry. However, it is useful if you want to add your own “built-ins” or change the name of existing ones.
Using the registry to achieve custom “built-ins”¶
There are a small set of “built-in” models, bandpasses, and magnitude systems. But what if you want additional ones?
Create a file mydefs.py
that registers all your custom definitions:
# contents of mydefs.py
import numpy as np
import sncosmo
wave = np.array([4000., 4200., 4400., 4600., 4800., 5000.])
trans = np.array([0., 1., 1., 1., 1., 0.])
band = sncosmo.Bandpass(wave, trans, name='tophatg')
sncosmo.registry.register(band)
Make sure mydefs.py
is somewhere in your $PYTHONPATH
or the
directory you are running your main script from. Now in your script
import your definitions at the beginning:
>>> import sncosmo
>>> import mydefs
>>> # ... proceed as normal
>>> # you can now use 'tophatg' as a built-in
Changing the name of built-ins¶
To change the name of the 'sdssg'
band to 'SDSS_G'
:
# contents of mydefs.py
import sncosmo
band = sncosmo.get_bandpass('sdssg')
band.name = 'SDSS_G'
sncosmo.register(band)
Large built-ins¶
What if your built-ins are really big or you have a lot of them? You
might only want to load them as they are needed, rather than having to
load everything into memory when you do import mydefs
. You can use
the sncosmo.registry.register_loader
function. Suppose we have a
bandpass that requires a huge data file (In reality it is unlikely
that loading bandpasses would take a noticeable amount of time, but it
might for models or spectra.):
# contents of mydefs.py
import sncosmo
def load_bandpass(filename, name=None, version=None):
# ...
# read data from filename, create a Bandpass object, "band"
# ...
return band
filename = 'path/to/datafile/for/huge_tophatg'
sncosmo.register_loader(
sncosmo.Bandpass, # class of object returned.
'huge_tophatg', # name
load_bandpass, # function that does the loading
[filename] # arguments to pass to function
)
Now when you import mydefs
the registry will know how to load the
Bandpass
named 'huge_tophatg'
when it is needed. When
loaded, it will be saved in memory so that subsequent operations don’t
need to load it again.