Skip to content

Commit

Permalink
Initial demo of bokeh plots.
Browse files Browse the repository at this point in the history
  • Loading branch information
ctslater committed Oct 18, 2024
1 parent aa4a6da commit 73e0aa5
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 3 deletions.
7 changes: 4 additions & 3 deletions python/lsst/production/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from flask import Flask, render_template

from . import tractTable, logs
from . import tractTable, logs, bokeh


def create_app():
Expand All @@ -31,12 +31,13 @@ def create_app():

app.register_blueprint(logs.bp)
app.register_blueprint(tractTable.bp)
app.register_blueprint(bokeh.bp)

@app.route("/")
def index():
return render_template("index.html", tools=["metrics", "logs"])
return render_template("index.html", tools=["metrics", "logs", "bokeh"])

return app


__all__ = [tractTable, logs, create_app]
__all__ = [tractTable, logs, bokeh, create_app]
90 changes: 90 additions & 0 deletions python/lsst/production/tools/bokeh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# This file is part of production-tools.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
# (https://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.


from flask import Blueprint, Flask, render_template, url_for
import urllib.parse
bp = Blueprint("bokeh", __name__, url_prefix="/bokeh")

from bokeh.embed import json_item
from bokeh.plotting import figure
from bokeh.resources import CDN

import json
import os


def readFromConsDb(dayObsStart, dayObsEnd):
from lsst.summit.utils import ConsDbClient
with open(os.path.expandvars("${HOME}/.consDB_token"), "r") as f:
token = f.read()
consDbClient = ConsDbClient(f"https://user:{token}@usdf-rsp.slac.stanford.edu/consdb")

dayObsStartInt = int(dayObsStart.replace("-", ""))
dayObsEndInt = int(dayObsEnd.replace("-", ""))
instrument = "lsstcomcamsim"
whereStr = f'''
WHERE obs_start_mjd IS NOT NULL
AND s_ra IS NOT NULL
AND s_dec IS NOT NULL
AND sky_rotation IS NOT NULL
AND ((band IS NOT NULL) OR (physical_filter IS NOT NULL))
AND day_obs >= {dayObsStartInt}
'''

exposure_query = f'''SELECT * FROM cdb_{instrument}.exposure {whereStr}'''
visit1_query = f'''SELECT * FROM cdb_{instrument}.visit1 {whereStr}'''
ccdexposure_quicklook_query = f'''SELECT * FROM cdb_{instrument}.ccdexposure_quicklook'''
ccdvisit1_quicklook_query = f'''SELECT * FROM cdb_{instrument}.ccdvisit1_quicklook JOIN cdb_{instrument}.visit1 ON cdb_{instrument}.ccdvisit1_quicklook.ccdvisit_id = cdb_{instrument}.exposure.ccdvisit_id '''

combinedQuery = f'''
SELECT exposure_id, cdb_{instrument}.visit1_quicklook.psf_sigma_median as psf_sigma_median FROM
cdb_{instrument}.visit1_quicklook
JOIN cdb_{instrument}.exposure ON (cdb_{instrument}.visit1_quicklook.visit_id =cdb_{instrument}.exposure.exposure_id)
WHERE day_obs = {dayObsStartInt}
'''

return consDbClient.query(combinedQuery)


def make_plot(queryTable):
p = figure(title = "Consdb", sizing_mode="fixed", width=500, height=400)
p.xaxis.axis_label = "exposure id"
p.yaxis.axis_label = "Median psf_sigma"
p.scatter(queryTable['exposure_id'], queryTable['psf_sigma_median'], fill_alpha=0.2, size=10)
return p

@bp.route("/")
def index():

debug_text = ""

return render_template("bokeh/index.html", debug_text=debug_text, resources=CDN.render())

@bp.route("/plot1")
def plot1():

table = readFromConsDb("2024-06-18", "2024-06-18")

p = make_plot(table)
return json.dumps(json_item(p, "plotdiv"))


3 changes: 3 additions & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<li class="nav-item">
<a class="nav-link" href="/plot-navigator">Plots</a>
</li>
<li class="nav-item">
<a class="nav-link {{ "active" if active_page=="bokeh" }}" href="{{ url_for('bokeh.index') }}">Bokeh</a>
</li>
</ul>
</nav>
<section class="content">
Expand Down
24 changes: 24 additions & 0 deletions templates/bokeh/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{% extends 'base.html' %}
{% set active_page="bokeh" %}

{% block additional_refs %}
{{ resources |safe }}
{% endblock %}

{% block title %}Live Plots{% endblock %}


{% block header %}Live Plots{% endblock %}

{% block content %}

{{ debug_text }}<br/>

<div id="plotdiv"></div>
<script>
fetch('plot1')
.then(function(response) { return response.json(); })
.then(function(item) { return Bokeh.embed.embed_item(item, "plotdiv"); })
</script>

{% endblock %}

0 comments on commit 73e0aa5

Please sign in to comment.