In [4]:
import nbformat as nbf
import re
DEFAULT_FLAGS = ['calib_psfUsed', 'qaBad_flag',
'merge_measurement_i',
'merge_measurement_r',
'merge_measurement_z',
'merge_measurement_y',
'merge_measurement_g',
'base_Footprint_nPix_flag',
'base_PixelFlags_flag_inexact_psfCenter']
DEFAULT_FUNCTORS = (('cmodel', "MagDiff('modelfit_CModel', 'base_PsfFlux')"),
('gauss', "MagDiff('base_GaussianFlux', 'base_PsfFlux')"),
('count', "Column('base_InputCount_value')"),
('seeing', "Seeing()"))
DEFAULT_MATCHED_FUNCTORS = (('gauss', "MagDiff('base_GaussianFlux', 'base_PsfFlux')"),
('seeing', "Seeing()"))
class Cell(object):
params = []
code = ''
def __call__(self, **kwargs):
for p in self.params:
if p not in kwargs:
raise ValueError('Must provide {}'.format(p))
return nbf.v4.new_code_cell(self.code.format(**kwargs))
class CodeCell(Cell):
def __init__(self, code):
self.code = code
class HvImportCell(Cell):
code = """\
import holoviews as hv
hv.notebook_extension('bokeh')"""
class ButlerInitCell(Cell):
params = ('repo',)
code = """\
from lsst.daf.persistence import Butler
butler = Butler('{repo}')"""
class DaskClientCell(Cell):
def __init__(self, scheduler_file):
self.scheduler_file = scheduler_file
@property
def code(self):
code = 'from distributed import Client\n'
code += 'client = Client(scheduler_file={})'.format(self.scheduler_file)
return code
class DefineCoaddCatalogCell(Cell):
params = ('tract', 'filt')
code = """\
from explorer.catalog import CoaddCatalog, VisitCatalog, MultiMatchedCatalog
from explorer.utils import get_visits
tract = {tract}
filt = "{filt}"
dataId = {{'tract':tract, 'filter':filt}}
catalog = CoaddCatalog(butler, dataId)"""
class DefineMatchedCatalogCell(Cell):
params = ('tract', 'filt')
code = """\
from explorer.catalog import CoaddCatalog, VisitCatalog, MultiMatchedCatalog
from explorer.utils import get_visits
tract = {tract}
filt = "{filt}"
dataId = {{'tract':tract, 'filter':filt}}
coaddCat = CoaddCatalog(butler, dataId)
visitCats = [VisitCatalog(butler, {{'tract': tract, 'filter':filt, 'visit':v}}, name=v) for v in get_visits(butler, tract, filt)]
catalog = MultiMatchedCatalog(coaddCat, visitCats, match_registry='QAmatchRegistry.h5')"""
class DefineFunctorsCell(Cell):
def __init__(self, functors=DEFAULT_FUNCTORS):
self.functors = functors
@property
def import_command(self):
to_import = set()
for k, v in self.functors:
m = re.search('(\w+)\(', v)
to_import.add(m.group(1))
return 'from explorer.functors import ' + ','.join(to_import) + '\n'
@property
def code(self):
code = self.import_command
for k, v in self.functors:
code += '{} = {}\n'.format(k,v)
code += '\nfuncs = {{'
for k, v in self.functors:
code += "'{0}':{0},".format(k)
code += '}}'
return code
class DefineDatasetCell(Cell):
def __init__(self, flags=DEFAULT_FLAGS, client=False):
self.flags = flags
self.client = client
@property
def code(self):
code = "from explorer.dataset import QADataset\n"
code += "flags = [" + ',\n'.join(["'{}'".format(f) for f in self.flags]) + ']\n\n'
if self.client:
code += "data = QADataset(catalog, funcs, flags=flags, client=client)"
else:
code += "data = QADataset(catalog, funcs, flags=flags)"
return code
class CalculateDFCell(Cell):
code = """\
# Calculate dataframe; see how long it takes.
%time data.df.head()"""
class MultiScatterskyCell(Cell):
code = """\
from explorer.plots import FilterStream, multi_scattersky
filter_stream = FilterStream()
multi_scattersky(data.ds, filter_stream=filter_stream, width=900, height=300)"""
class FlagSetterCell(Cell):
code ="""\
from explorer.plots import FlagSetter
import parambokeh
flag_setter = FlagSetter(filter_stream=filter_stream, flags=data.flags, bad_flags=data.flags)
parambokeh.Widgets(flag_setter, callback=flag_setter.event, push=False, on_init=True)"""
class ExploreCell(Cell):
def __init__(self, dimension):
self.dimension = dimension
@property
def prefix(self):
raise NotImplementedError('Must define prefix for cell type')
@property
def code(self):
code = """\
%%output max_frames=10000
%%opts Points [width=500, height=500, tools=['hover'], colorbar=True] (cmap='coolwarm', size=4)
# Change dimension to whichever you would like to explore
dimension = '{1}'
{0}_dmap = data.{0}_explore(dimension, filter_stream=filter_stream).relabel(dimension)
tap = hv.streams.Tap(source={0}_dmap, rename={{{{'x':'ra', 'y':'dec'}}}})
{0}_dmap""".format(self.prefix, self.dimension)
return code
class CoaddExploreCell(ExploreCell):
prefix = 'coadd'
class VisitExploreCell(ExploreCell):
prefix = 'visit'
class GingaCell(Cell):
@property
def prefix(self):
raise NotImplementedError('Must define prefix for cell type')
@property
def code(self):
code = """\
import lsst.afw.display
lsst.afw.display.setDefaultBackend("ginga")
from explorer.display import {1}Display
{0}_display = {1}Display(butler, filt, dims=(500,500))
{0}_display.connect_tap(tap)
{0}_display.embed()""".format(self.prefix, self.prefix.capitalize())
return code
class CoaddGingaCell(GingaCell):
prefix = 'coadd'
class VisitGingaCell(GingaCell):
prefix = 'visit'
class CommentCell(Cell):
def __init__(self, comment):
self.comment = comment
@property
def code(self):
return "# {}".format(self.comment)
In [5]:
class QANotebook(object):
def __init__(self, repo, flags=DEFAULT_FLAGS, functors=DEFAULT_FUNCTORS, client=False,
scheduler_file=None, **params):
self.nb = nbf.v4.new_notebook()
self.params = params
self.params.update({'repo':repo})
self.flags = flags
self.functors = functors
self.client = client
self.scheduler_file = scheduler_file
@property
def setup_cells(self):
cells = [HvImportCell(), ButlerInitCell()]
if self.client:
cells.append(DaskClientCell(scheduler_file=self.scheduler_file))
return cells
@property
def define_catalog_cell(self):
return CommentCell('Define `catalog` here')
@property
def definition_cells(self):
return [self.define_catalog_cell,
DefineFunctorsCell(functors=self.functors),
DefineDatasetCell(client=self.client, flags=self.flags), CalculateDFCell()]
@property
def plotting_cells(self):
return [MultiScatterskyCell(), FlagSetterCell()]
@property
def cells(self):
return self.setup_cells + self.definition_cells + self.plotting_cells
def generate_cells(self):
for cell in self.cells:
self.nb.cells.append(cell(**self.params))
def write(self, filename):
self.generate_cells()
with open(filename, 'w') as f:
nbf.write(self.nb, f)
class Coadd_QANotebook(QANotebook):
def __init__(self, repo, tract, filt, **kwargs):
kwargs.update(dict(tract=tract, filt=filt))
super(Coadd_QANotebook, self).__init__(repo=repo, **kwargs)
@property
def define_catalog_cell(self):
return DefineCoaddCatalogCell()
@property
def plotting_cells(self):
return [MultiScatterskyCell(), FlagSetterCell(),
CoaddExploreCell(self.functors[0][0]), CoaddGingaCell()]
class VisitMatch_QANotebook(QANotebook):
def __init__(self, repo, tract, filt, functors=DEFAULT_MATCHED_FUNCTORS, **kwargs):
kwargs.update(dict(tract=tract, filt=filt))
super(VisitMatch_QANotebook, self).__init__(repo=repo, functors=functors, **kwargs)
@property
def define_catalog_cell(self):
return DefineMatchedCatalogCell()
@property
def plotting_cells(self):
return [MultiScatterskyCell(), FlagSetterCell(),
VisitExploreCell(self.functors[0][0]), VisitGingaCell()]
In [6]:
HSC_FILTERS = ['HSC-G', 'HSC-R', 'HSC-I', 'HSC-Z', 'HSC-Y']
In [25]:
DEFAULT_COLOR_FUNCTORS = (('psfmag', "Mag('base_PsfFlux')"),
('cmodel', "Mag('modelfit_CModel')"),
('kron', "Mag('ext_photometryKron_KronFlux')"))
DEFAULT_COLOR_FLAGS = ['calib_psfUsed', 'qaBad_flag', 'base_PixelFlags_flag_inexact_psfCenter']
HSC_FILTERS = ['HSC-G', 'HSC-R', 'HSC-I', 'HSC-Z', 'HSC-Y']
HSC_SHORT_FILTERS = 'GRIZY'
REFERENCE_FILTER = 'HSC-I'
class CodeCell(Cell):
def __init__(self, code):
self.code = code
class DefineColorCatalogCell(Cell):
params = ('tract', 'filters', 'short_filters', 'reference_filter')
code = """\
from explorer.catalog import CoaddCatalog, MultiBandCatalog
tract = 9615
filts = {filters}
short_filts = '{short_filters}'
reference_filt = '{reference_filter}'
catalog = MultiBandCatalog({{filt: CoaddCatalog(butler, {{'tract':tract, 'filter':filt}}, name=filt) for filt in filts}},
short_filters=short_filts, reference_filt=reference_filt)"""
class ColorColor_QANotebook(QANotebook):
def __init__(self, repo, tract,
filters=HSC_FILTERS, short_filters=HSC_SHORT_FILTERS,
reference_filter=REFERENCE_FILTER,
flags=DEFAULT_COLOR_FLAGS, functors=DEFAULT_COLOR_FUNCTORS, **kwargs):
kwargs.update(dict(tract=tract, filters=filters, short_filters=short_filters,
reference_filter=reference_filter))
super(ColorColor_QANotebook, self).__init__(repo=repo, flags=flags, functors=functors, **kwargs)
@property
def define_catalog_cell(self):
return DefineColorCatalogCell()
@property
def plotting_cells(self):
return [CodeCell('data.color_explore()'),
CodeCell('%%opts Points [width=600, height=600]\ndata.color_fit_explore()')]
In [26]:
repo = '/datasets/hsc/repo/rerun/RC/w_2018_04/DM-13256/'
coadd_nb = Coadd_QANotebook(repo, 9615, 'HSC-I')
matched_nb = VisitMatch_QANotebook(repo, 9615, 'HSC-I', client=True, scheduler_file='/scratch/tmorton/dask/scheduler.json')
color_nb = ColorColor_QANotebook(repo, 9615)
In [27]:
coadd_nb.write('test_generate/coadd_HSC-I.ipynb')
matched_nb.write('test_generate/matched_HSC-I.ipynb')
color_nb.write('test_generate/color.ipynb')
In [ ]: