XSIGMA Plots Example

This is an example on how to make xsigma plots using Jupyter Notebook. This notebook contains:

  1. How to connect to the api to get mergedQA data
  2. Wedge plot
  3. Simple Histogram
  4. Histogram with labels
  5. Patch plot

1. How to connect to the api to get mergedQA data

1.1 Connecting to a QLF API

The following cell connect to the api running in the same Docker environment as the Jupyter Notebook docker container.

http://app:8000/dashboard/api/job/?process=2

But it can be used by any other QLF accessible api such as:

http://qltest.linea.gov.br/dashboard/api/job/?process=8

In [ ]:
import urllib.request
import json
job = urllib.request.urlopen("http://ql.linea.gov.br/dashboard/api/job/?process=1").read()
api = json.loads(job)
mergedqa = api['results'][0]['output']
print('mergedQA loaded!')

1.2 Loading Bokeh and adding QLF ploting code to the python path


In [ ]:
import sys
sys.path.append('/app/qlf/backend/framework/qlf')
from bokeh.io import show, output_notebook
output_notebook()

2. Wedge Plot

2.1 Preparing mergedQA data to be displayed


In [ ]:
from bokeh.models import ColumnDataSource, Range1d
import numpy as np
from dashboard.bokeh.helper import get_palette, sort_obj
from bokeh.models import LinearColorMapper

check_ccds = mergedqa['TASKS']['CHECK_CCDs']

gen_info = mergedqa['GENERAL_INFO']
flavor= mergedqa['FLAVOR']

ra = gen_info['RA']
dec = gen_info['DEC']
xw_fib = check_ccds['METRICS']['XWSIGMA_FIB']
xsigma = xw_fib[0]
xfiber = np.arange(len(xsigma))
obj_type = sort_obj(gen_info)

source = ColumnDataSource(data={
    'x1': ra,  
    'y1': dec, 
    'xsigma': xsigma,
    'xfiber': xfiber,
    'OBJ_TYPE': obj_type,
    'left': np.arange(0, 500)-0.4,
    'right': np.arange(0, 500)+0.4,
    'bottom': [0]*500
    })

# centralize wedges in plots:
ra_center=0.5*(max(ra)+min(ra))
dec_center=0.5*(max(dec)+min(dec))
xrange_wedge = Range1d(start=ra_center + .95, end=ra_center-.95)
yrange_wedge = Range1d(start=dec_center+.82, end=dec_center-.82)

my_palette = get_palette("viridis")
xmapper = LinearColorMapper(palette=my_palette,
                            low=0.98*np.min(xsigma),
                            high=1.02*np.max(xsigma))
print('Data Ready!')

2.2 Creating tooltip format


In [ ]:
xsigma_tooltip = """
    <div>
        <div>
            <span style="font-size: 1vw; font-weight: bold; color: #303030;">XSigma: </span>
            <span style="font-size: 1vw; color: #515151">@xsigma</span>
        </div>
        <div>
            <span style="font-size: 1vw; font-weight: bold; color: #303030;">Obj Type: </span>
            <span style="font-size: 1vw; color: #515151;">@OBJ_TYPE</span>
        </div>
        <div>
            <span style="font-size: 1vw; font-weight: bold; color: #303030;">RA: </span>
            <span style="font-size: 1vw; color: #515151;">@x1</span>
        </div>
        <div>
            <span style="font-size: 1vw; font-weight: bold; color: #303030;">DEC: </span>
            <span style="font-size: 1vw; color: #515151;">@y1</span>
        </div>

        <div>
            <span style="font-size: 1vw; font-weight: bold; color: #303030;">FIBER ID: </span>
            <span style="font-size: 1vw; color: #515151;">@xfiber</span>
        </div>

        </div>
    """
print('Tooltip Created!')

2.3 Showing a Wedge Plot


In [ ]:
from dashboard.bokeh.plots.plot2d.main import Plot2d

wedge_plot_x = Plot2d(
    x_range=xrange_wedge,
    y_range=yrange_wedge,
    x_label="RA",
    y_label="DEC",
    tooltip=xsigma_tooltip,
    title="XSIGMA",
    width=500,
    height=380,
    yscale="auto"
).wedge(
    source,
    x='x1',
    y='y1',
    field='xsigma',
    mapper=xmapper,
    colorbar_title='xsigma'
).plot

show(wedge_plot_x)

3. Simple Histogram


In [ ]:
d_yplt = (max(xsigma) - min(xsigma))*0.1
yrange = [0, max(xsigma) + d_yplt]

xhist = Plot2d(
    yrange,
    x_label="Fiber number",
    y_label="X std dev (number of pixels)",
    tooltip=xsigma_tooltip,
    title="Histogram",
    width=600,
    height=300,
    yscale="auto",
    hover_mode="vline",
).quad(
    source,
    top='xsigma',
)
show(xhist)

4. Histogram with labels

4.1 Preparing mergedQA data to be displayed


In [ ]:
wrg = check_ccds['PARAMS']['XWSIGMA_WARN_RANGE']
delta_rg = wrg[1] - wrg[0]
hist_rg = (wrg[0] - 0.1*delta_rg, wrg[1]+0.1*delta_rg)

if mergedqa['FLAVOR'].upper() == 'SCIENCE':
    program = mergedqa['GENERAL_INFO']['PROGRAM'].upper()
    program_prefix = '_'+program
else:
    program_prefix = ''
xw_ref = check_ccds['PARAMS']['XWSIGMA'+program_prefix+'_REF']

hist, edges = np.histogram(xsigma, 'sqrt')

source_hist = ColumnDataSource(data={
    'hist': hist,
    'bottom': [0] * len(hist),
    'left': edges[:-1],
    'right': edges[1:]
})
print('Done!')

4.2 Creating new tooltip format


In [ ]:
hist_tooltip_x = """
    <div>
        <div>
            <span style="font-size: 1vw; font-weight: bold; color: #303030;">Frequency: </span>
            <span style="font-size: 1vw; color: #515151">@hist</span>
        </div>
        <div>
            <span style="font-size: 1vw; font-weight: bold; color: #303030;">XSIGMA: </span>
            <span style="font-size: 1vw; color: #515151;">[@left, @right]</span>
        </div>
    </div>
"""
print('Tooltip Created!')

4.3 Plotting a simple histogram


In [ ]:
p_hist_x = Plot2d(
    x_label="XSIGMA",
    y_label="Frequency",
    tooltip=hist_tooltip_x,
    title="Histogram",
    width=600,
    height=300,
    yscale="auto",
    y_range=(0.0*max(hist), 1.1*max(hist)),
    x_range=(hist_rg[0]+xw_ref[0],
             hist_rg[1]+xw_ref[0]),
    hover_mode="vline",
).quad(
    source_hist,
    top='hist',
    bottom='bottom',
    line_width=0.4,
)

show(p_hist_x)

4.4 Creating normal and warning divisors/labels


In [ ]:
nrg = check_ccds['PARAMS']['XWSIGMA_NORMAL_RANGE']

from bokeh.models import Span, Label

for ialert in nrg:
    normal_divisors = Span(location=ialert+xw_ref[0], 
                dimension='height',
                line_color='green',
                line_dash='dashed', line_width=2)
    p_hist_x.add_layout(normal_divisors)

    normal_labels = Label(x=ialert+xw_ref[0], 
                    y= yrange[-1]/2.2,
                    y_units='data',
                    text='Normal Range',
                    text_color='green', angle=np.pi/2.)
    p_hist_x.add_layout(normal_labels)
    

for ialert in wrg:
    warning_divisors = Span(location=ialert+xw_ref[0], dimension='height', line_color='tomato',
                 line_dash='dotdash', line_width=2)
    p_hist_x.add_layout(warning_divisors)
    
    warning_labels = Label(x=ialert+xw_ref[0], y=yrange[-1]/2.2, y_units='data',
                     text='Warning Range', text_color='tomato', angle=np.pi/2.)
    p_hist_x.add_layout(warning_labels)

p_hist_x.title.text  = "Histogram with labels"
show(p_hist_x)

5. Patch plot


In [ ]:
from dashboard.bokeh.plots.patch.main import Patch

xw_amp = check_ccds['METRICS']['XWSIGMA_AMP']

xamp = Patch().plot_amp(
    dz=xw_amp[0],
    refexp=[xw_ref[0]]*4,
    name="XSIGMA AMP",
    description="X std deviation per Amp (number of pixels)",
    wrg=wrg
)

show(xamp)

In [ ]: