def load_qa(self): cam = self.selected_arm + str(self.selected_spectrograph) mergedqa = QLFModels().get_output(self.selected_process_id, cam) gen_info = mergedqa['GENERAL_INFO'] flavor = mergedqa['FLAVOR'] if flavor == "science": ra = gen_info['RA'] dec = gen_info['DEC'] check_ccds = mergedqa['TASKS']['CHECK_CCDs'] xwsigma = check_ccds['METRICS']['XWSIGMA'] xw_amp = check_ccds['METRICS']['XWSIGMA_AMP'] xw_fib = check_ccds['METRICS']['XWSIGMA_FIB'] nrg = check_ccds['PARAMS']['XWSIGMA_NORMAL_RANGE'] wrg = check_ccds['PARAMS']['XWSIGMA_WARN_RANGE'] obj_type = sort_obj(gen_info) # [""]*500 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'] xsigma = xw_fib[0] wsigma = xw_fib[1] delta_rg = wrg[1] - wrg[0] hist_rg = (wrg[0] - 0.1 * delta_rg, wrg[1] + 0.1 * delta_rg) my_palette = get_palette("RdYlBu_r") xfiber = np.arange(len(xsigma)) wfiber = np.arange(len(wsigma)) if mergedqa['FLAVOR'].upper() != 'SCIENCE': ra = np.full(500, np.nan) dec = np.full(500, np.nan) source = ColumnDataSource( data={ 'x1': ra, 'y1': dec, 'xsigma': xsigma, 'wsigma': wsigma, 'delta_xsigma': np.array(xsigma) - xw_ref[0], 'delta_wsigma': np.array(wsigma) - xw_ref[1], 'xref': [xw_ref[0]] * len(xsigma), 'wref': [xw_ref[1]] * len(xsigma), 'xfiber': xfiber, 'wfiber': wfiber, 'OBJ_TYPE': obj_type, 'left': np.arange(0, 500) - 0.4, 'right': np.arange(0, 500) + 0.4, 'bottom': [0] * 500 }) 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;">Reference: </span> <span style="font-size: 1vw; color: #515151">@xref</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> """ wsigma_tooltip = """ <div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">WSigma: </span> <span style="font-size: 1vw; color: #515151">@wsigma</span> </div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">Reference: </span> <span style="font-size: 1vw; color: #515151">@wref</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;">@wfiber</span> </div> </div> """ url = "http://legacysurvey.org/viewer?ra=@ra&dec=@dec&zoom=16&layer=decals-dr5" # determining the position of selected cam fibers: obj_type = sort_obj(gen_info) # --------------------------------- if flavor == "science": # axes limit xmin, xmax = [min(ra[:]), max(ra[:])] ymin, ymax = [min(dec[:]), max(dec[:])] xfac, yfac = [(xmax - xmin) * 0.06, (ymax - ymin) * 0.06] left, right = xmin - xfac, xmax + xfac bottom, top = ymin - yfac, ymax + yfac low, high = wrg xmapper = LinearColorMapper(palette=my_palette, low=low, high=high, nan_color="darkgrey") wmapper = LinearColorMapper(palette=my_palette, low=low, high=high, nan_color="darkgrey") # ============ # XSIGMA WEDGE radius = 0.0165 radius_hover = 0.02 # 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) 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='delta_xsigma', mapper=xmapper, colorbar_title='xsigma').plot taptool = wedge_plot_x.select(type=TapTool) taptool.callback = OpenURL(url=url) # ============ # WSIGMA WEDGE wedge_plot_w = Plot2d(x_range=xrange_wedge, y_range=yrange_wedge, x_label="RA", y_label="DEC", tooltip=wsigma_tooltip, title="WSIGMA", width=500, height=380, yscale="auto").wedge( source, x='x1', y='y1', field='delta_wsigma', mapper=wmapper, colorbar_title='wsigma').plot taptool = wedge_plot_w.select(type=TapTool) taptool.callback = OpenURL(url=url) # ================================ # Stat histogram # x_fiber_hist 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="", width=600, height=300, yscale="auto", hover_mode="vline", ).quad( source, top='xsigma', ) # w_fiber_hist d_yplt = (max(wsigma) - min(wsigma)) * 0.1 yrange = [0, max(wsigma) + d_yplt] whist = Plot2d( yrange, x_label="Fiber number", y_label="W std dev (number of pixels)", tooltip=xsigma_tooltip, title="", width=600, height=300, yscale="auto", hover_mode="vline", ).quad( source, top='wsigma', ) # ================================ # Stat histogram def histpar(yscale, hist): if yscale == 'log': ylabel = "Frequency + 1" yrange = (1, 11**(int(np.log10(max(hist))) + 1)) bottomval = 'bottomplusone' histval = 'histplusone' else: ylabel = "Frequency" yrange = (0.0 * max(hist), 1.1 * max(hist)) bottomval = 'bottom' histval = 'hist' return [ylabel, yrange, bottomval, histval] xhistlabel = "XSIGMA" yscale = "auto" 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> """ hist, edges = np.histogram(xsigma, 'sqrt') source_hist = ColumnDataSource( data={ 'hist': hist, 'histplusone': hist + 1, 'bottom': [0] * len(hist), 'bottomplusone': [1] * len(hist), 'left': edges[:-1], 'right': edges[1:] }) ylabel, yrange, bottomval, histval = histpar(yscale, hist) p_hist_x = Plot2d( x_label=xhistlabel, y_label=ylabel, tooltip=hist_tooltip_x, title="", width=600, height=300, yscale="auto", y_range=yrange, x_range=(hist_rg[0] + xw_ref[0], hist_rg[1] + xw_ref[0]), hover_mode="vline", ).quad( source_hist, top=histval, bottom=bottomval, line_width=0.4, ) # Histogram 2 xhistlabel = "WSIGMA" hist_tooltip_w = """ <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;">WSIGMA: </span> <span style="font-size: 1vw; color: #515151;">[@left, @right]</span> </div> </div> """ hist, edges = np.histogram(wsigma, 'sqrt') source_hist = ColumnDataSource( data={ 'hist': hist, 'histplusone': hist + 1, 'bottom': [0] * len(hist), 'bottomplusone': [1] * len(hist), 'left': edges[:-1], 'right': edges[1:] }) ylabel, yrange, bottomval, histval = histpar(yscale, hist) yrangew = yrange p_hist_w = Plot2d( x_label=xhistlabel, y_label=ylabel, tooltip=hist_tooltip_w, title="", width=600, height=300, yscale="auto", y_range=yrange, x_range=(hist_rg[0] + xw_ref[1], hist_rg[1] + xw_ref[1]), hover_mode="vline", ).quad( source_hist, top=histval, bottom=bottomval, line_width=0.8, ) # -------------------------------------------------------------- # vlines ranges: bname = 'XWSIGMA' for ialert in nrg: # par[bname+'_NORMAL_RANGE']: spans = Span(location=ialert + xw_ref[0], dimension='height', line_color='green', line_dash='dashed', line_width=2) p_hist_x.add_layout(spans) my_label = 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(my_label) for ialert in wrg: # par[bname+'_WARN_RANGE']: spans = Span(location=ialert + xw_ref[0], dimension='height', line_color='tomato', line_dash='dotdash', line_width=2) p_hist_x.add_layout(spans) my_label = 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(my_label) for ialert in nrg: # par[bname+'_NORMAL_RANGE']: spans = Span(location=ialert + xw_ref[1], dimension='height', line_color='green', line_dash='dashed', line_width=2) p_hist_w.add_layout(spans) my_label = Label(x=ialert + xw_ref[1], y=yrangew[-1] / 2.2, y_units='data', text='Normal Range', text_color='green', angle=np.pi / 2.) p_hist_w.add_layout(my_label) for ialert in wrg: # par[bname+'_WARN_RANGE']: spans = Span(location=ialert + xw_ref[1], dimension='height', line_color='tomato', line_dash='dotdash', line_width=2) p_hist_w.add_layout(spans) my_label = Label(x=ialert + xw_ref[1], y=yrangew[-1] / 2.2, y_units='data', text='Warning Range', text_color='tomato', angle=np.pi / 2.) p_hist_w.add_layout(my_label) # amp 1 xamp = Patch().plot_amp( dz=xw_amp[0], refexp=[xw_ref[0]] * 4, name="XSIGMA AMP", description="X standard deviation per Amp (number of pixels)", wrg=wrg) # amp 2 wamp = Patch().plot_amp( dz=xw_amp[1], refexp=[xw_ref[1]] * 4, name="WSIGMA AMP", description="W standard deviation per Amp (number of pixels)", wrg=wrg) # ------------------------------------------------------------------------- info_col = Title().write_description('xwsigma') current_exposures = check_ccds['METRICS']['XWSIGMA'] alert_x = Table().alert_table(nrg, wrg) alert_w = Table().alert_table(nrg, wrg) if flavor == 'science': program = gen_info['PROGRAM'].upper() reference_exposures = check_ccds['PARAMS']['XWSIGMA_' + program + '_REF'] keynames = ["XSIGMA"] x_metric = Table().reference_table(keynames, [current_exposures[0]], [reference_exposures[0]]) keynames = ["WSIGMA"] w_metric = Table().reference_table(keynames, [current_exposures[1]], [reference_exposures[1]]) layout = column( info_col, widgetbox(Div(), css_classes=["tableranges"]), widgetbox( Div(text= '<h2 align=center style="text-align:center;"> XSIGMA </h2>' )), widgetbox( Div(text= '<h2 align=center style="text-align:center;"> WSIGMA </h2>' )), x_metric, w_metric, alert_x, alert_w, column(wedge_plot_x, sizing_mode='scale_both'), column(wedge_plot_w, sizing_mode='scale_both'), column(xhist, sizing_mode='scale_both'), column(whist, sizing_mode='scale_both'), column(p_hist_x, sizing_mode='scale_both'), column(p_hist_w, sizing_mode='scale_both'), column(xamp, sizing_mode='scale_both'), column(wamp, sizing_mode='scale_both'), css_classes=["display-grid"], sizing_mode='scale_width') else: reference_exposures = check_ccds['PARAMS']['XWSIGMA_REF'] keynames = ["XSIGMA"] x_metric = Table().reference_table(keynames, [current_exposures[0]], [reference_exposures[0]]) keynames = ["WSIGMA"] w_metric = Table().reference_table(keynames, [current_exposures[1]], [reference_exposures[1]]) layout = column( info_col, widgetbox(Div(), css_classes=["tableranges"]), widgetbox( Div(text= '<h2 align=center style="text-align:center;"> XSIGMA </h2>' )), widgetbox( Div(text= '<h2 align=center style="text-align:center;"> WSIGMA </h2>' )), x_metric, w_metric, alert_x, alert_w, column(xhist, sizing_mode='scale_both'), column(whist, sizing_mode='scale_both'), column(p_hist_x, sizing_mode='scale_both'), column(p_hist_w, sizing_mode='scale_both'), column(xamp, sizing_mode='scale_both'), column(wamp, sizing_mode='scale_both'), css_classes=["display-grid"], sizing_mode='scale_width') return file_html(layout, CDN, "XWSIGMA")
def load_qa(self): cam = self.selected_arm + str(self.selected_spectrograph) mergedqa = QLFModels().get_output(self.selected_process_id, cam) # list of available object in petal objlist = mergedqa["TASKS"]["CHECK_SPECTRA"]["METRICS"]["OBJLIST"] if 'SKY' in objlist: objlist.remove('SKY') gen_info = mergedqa['GENERAL_INFO'] ra = gen_info['RA'] dec = gen_info['DEC'] check_spectra = mergedqa['TASKS']['CHECK_SPECTRA'] snr = check_spectra['METRICS'] nrg = check_spectra['PARAMS']['FIDSNR_TGT_NORMAL_RANGE'] wrg = check_spectra['PARAMS']['FIDSNR_TGT_WARN_RANGE'] # Object identification in fibers: obj_fiber = sort_obj(gen_info) qlf_obj = ['ELG', 'LRG', 'QSO', 'STAR'] avobj = ['STAR' if x == 'STD' else x for x in objlist] obj_idx = {} for o in qlf_obj: try: obj_idx.update({o: avobj.index(o)}) except: obj_idx.update({o: None}) try: exptime = gen_info['EXPTIME'] name_warn = '' except: exptime = 1000 name_warn = ' (exptime fixed)' # Sort objects for QLF: obj_idx = {} for o in qlf_obj: try: obj_idx.update({o: avobj.index(o)}) except: obj_idx.update({o: None}) def good_idx(mag, snr): # Filtering measurements with good SNR & good MAG # Treating None (inf and Nan already treated in db) mag_2 = np.array([-9998 if x is None else x for x in mag]) snr_2 = np.array([-9998 if x is None else x for x in snr]) idx = np.arange(len(snr_2)) # Filtering values with good mag AND snr return list(idx[(mag_2 > -999) & (snr_2 > 0)]) # Treating bad snr and mag mag_snr = {} for o in avobj: snr_ql, mag_ql = snr['SNR_MAG_TGT'][obj_idx[o]] idx = good_idx(mag_ql, snr_ql) x = [mag_ql[i] for i in idx] y = [snr_ql[i] for i in idx] mag_snr.update({o: [y, x]}) # Preparing xy_plot data: if obj_idx['ELG'] is not None: elg_snr = mag_snr['ELG'] if obj_idx['LRG'] is not None: lrg_snr = mag_snr['LRG'] if obj_idx['QSO'] is not None: qso_snr = mag_snr['QSO'] if obj_idx['STAR'] is not None: star_snr = mag_snr['STAR'] #lrg_snr = mag_snr['LRG'] def fit_func(xdata, coeff): """ astro fit """ r1 = 0.0 # read noise a, b = coeff x = np.linspace(min(xdata), max(xdata), 1000) Flux = 10**(-0.4 * (x - 22.5)) y = a * Flux * exptime / np.sqrt(a * Flux * exptime + b * exptime + r1**2) return x, y data_model = { 'x': [], 'y': [], 'y2': [], 'fiber_id': [], 'ra': [], 'dec': [], } elg = ColumnDataSource(data=data_model.copy()) lrg = ColumnDataSource(data=data_model.copy()) qso = ColumnDataSource(data=data_model.copy()) star = ColumnDataSource(data=data_model.copy()) data_fit = { 'x': [], 'y': [], 'y2': [], 'fiber_id': [], 'ra': [], 'dec': [] } elg_fit = ColumnDataSource(data=data_fit.copy()) lrg_fit = ColumnDataSource(data=data_fit.copy()) qso_fit = ColumnDataSource(data=data_fit.copy()) star_fit = ColumnDataSource(data=data_fit.copy()) if obj_idx['ELG'] is not None: elg.data['x'] = elg_snr[1] elg.data['y'] = np.array(elg_snr[0]) elg.data['y2'] = np.array(elg_snr[0])**2 elg.data['fiber_id'] = gen_info['ELG_FIBERID'] elg.data['ra'] = [ra[i % 500] for i in gen_info['ELG_FIBERID']] elg.data['dec'] = [dec[i % 500] for i in gen_info['ELG_FIBERID']] xfit, yfit = fit_func(elg_snr[1], snr['FITCOEFF_TGT'][obj_idx['ELG']]) elg_fit.data['x'] = xfit elg_fit.data['y'] = np.array(yfit) elg_fit.data['y2'] = np.array(yfit)**2 for key in ['fiber_id', 'ra', 'dec']: elg_fit.data[key] = [''] * len(yfit) if obj_idx['LRG'] is not None: lrg.data['x'] = lrg_snr[1] lrg.data['y'] = np.array(lrg_snr[0]) lrg.data['y2'] = np.array(lrg_snr[0])**2 lrg.data['fiber_id'] = gen_info['LRG_FIBERID'] lrg.data['ra'] = [ra[i % 500] for i in gen_info['LRG_FIBERID']] lrg.data['dec'] = [dec[i % 500] for i in gen_info['LRG_FIBERID']] xfit, yfit = fit_func(lrg_snr[1], snr['FITCOEFF_TGT'][obj_idx['LRG']]) lrg_fit.data['x'] = xfit lrg_fit.data['y'] = np.array(yfit) lrg_fit.data['y2'] = np.array(yfit)**2 for key in ['fiber_id', 'ra', 'dec']: lrg_fit.data[key] = [''] * len(yfit) if obj_idx['QSO'] is not None: qso.data['x'] = qso_snr[1] qso.data['y'] = np.array(qso_snr[0]) qso.data['y2'] = np.array(qso_snr[0])**2 qso.data['fiber_id'] = gen_info['QSO_FIBERID'] qso.data['ra'] = [ra[i % 500] for i in gen_info['QSO_FIBERID']] qso.data['dec'] = [dec[i % 500] for i in gen_info['QSO_FIBERID']] xfit, yfit = fit_func(qso_snr[1], snr['FITCOEFF_TGT'][obj_idx['QSO']]) qso_fit.data['x'] = xfit qso_fit.data['y'] = np.array(yfit) qso_fit.data['y2'] = np.array(yfit)**2 for key in ['fiber_id', 'ra', 'dec']: qso_fit.data[key] = [''] * len(yfit) if obj_idx['STAR'] is not None: star.data['x'] = star_snr[1] star.data['y'] = np.array(star_snr[0]) star.data['y2'] = np.array(star_snr[0])**2 star.data['fiber_id'] = gen_info['STAR_FIBERID'] star.data['ra'] = [ra[i % 500] for i in gen_info['STAR_FIBERID']] star.data['dec'] = [dec[i % 500] for i in gen_info['STAR_FIBERID']] xfit, yfit = fit_func(star_snr[1], snr['FITCOEFF_TGT'][obj_idx['STAR']]) star_fit.data['x'] = xfit star_fit.data['y'] = np.array(yfit) star_fit.data['y2'] = np.array(yfit)**2 for key in ['fiber_id', 'ra', 'dec']: star_fit.data[key] = [''] * len(yfit) html_tooltip = """ <div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">SNR: </span> <span style="font-size: 1vw; color: #515151;">@y</span> </div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">DECAM_{}: </span> <span style="font-size: 1vw; color: #515151;">@x</span> </div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">Fiber ID: </span> <span style="font-size: 1vw; color: #515151;">@fiber_id</span> </div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">RA: </span> <span style="font-size: 1vw; color: #515151;">@ra</span> </div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">Dec: </span> <span style="font-size: 1vw; color: #515151">@dec</span> </div> </div> """.format(str(self.selected_arm).upper()) url = "http://legacysurvey.org/viewer?ra=@ra&dec=@dec&zoom=16&layer=decals-dr5" elg_plot = Plot2d( x_label="DECAM_{}".format(str(self.selected_arm).upper()), y_label="MEDIAN SNR^2", tooltip=html_tooltip, title="ELG", width=500, height=380, yscale="log", ).line( source=elg_fit, y='y2', ).circle( source=elg, size=8, y='y2', fill_color="blue", ).plot taptool = elg_plot.select(type=TapTool) taptool.callback = OpenURL(url=url) lrg_plot = Plot2d(x_label="DECAM_{}".format( str(self.selected_arm).upper()), y_label="MEDIAN SNR^2", tooltip=html_tooltip, title="LRG", width=500, height=380, yscale="log").line( source=lrg_fit, y='y2', ).circle( source=lrg, size=8, y='y2', fill_color="red", ).plot taptool = lrg_plot.select(type=TapTool) taptool.callback = OpenURL(url=url) qso_plot = Plot2d(x_label="DECAM_{}".format( str(self.selected_arm).upper()), y_label="MEDIAN SNR^2", tooltip=html_tooltip, title="QSO", width=500, height=380, yscale="log").line( source=qso_fit, y='y2', ).circle( source=qso, size=8, y='y2', fill_color="green", ).plot taptool = qso_plot.select(type=TapTool) taptool.callback = OpenURL(url=url) star_plot = Plot2d( x_label="DECAM_{}".format(str(self.selected_arm).upper()), y_label="MEDIAN SNR^2", tooltip=html_tooltip, title="STAR", width=500, height=380, yscale="log", ).line(source=star_fit, y='y2').circle( source=star, size=8, y='y2', fill_color="yellow", ).plot taptool = star_plot.select(type=TapTool) taptool.callback = OpenURL(url=url) # infos info_col = Title().write_description('snr') # ----------------- # WEDGES snr_tooltip = """ <div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">Resid: </span> <span style="font-size: 1vw; color: #515151">@resid_snr</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;">@QLF_FIBERID</span> </div> </div> """ median = snr['MEDIAN_SNR'] resid = snr['SNR_RESID'] qlf_fiberid = range(0, 500) my_palette = get_palette('bwr') fibersnr_tgt = [] for i in avobj: fibersnr_tgt.append(gen_info[i + '_FIBERID']) fibersnr = [] for i in list(range(len(fibersnr_tgt))): fibersnr = fibersnr + fibersnr_tgt[i] source = ColumnDataSource( data={ 'x1': [ra[i % 500] for i in fibersnr], 'y1': [dec[i % 500] for i in fibersnr], 'resid_snr': resid, 'QLF_FIBERID': fibersnr, 'OBJ_TYPE': [obj_fiber[i % 500] for i in fibersnr], 'median': median }) ra_not = [] dec_not = [] obj_not = [] fiber_not = [] fiber_mod = [] for fiber in fibersnr: fiber_mod.append(fiber % 500) for i in range(500): if i not in fiber_mod: ra_not.append(ra[i]) dec_not.append(dec[i]) fiber_not.append(i) obj_not.append(obj_fiber[i]) source_not = ColumnDataSource( data={ 'x1': ra_not, 'y1': dec_not, 'resid_snr': [''] * len(dec_not), 'QLF_FIBERID': fiber_not, 'OBJ_TYPE': obj_not }) rmax, rmin = np.nanmax(resid), np.nanmin(resid) if np.isnan(rmax) or np.isnan(rmin): fill_color = 'lightgray' else: dy = (rmax - rmin) * 0.1 mapper = LinearColorMapper(palette=my_palette, nan_color='darkgray', low=rmin - dy, high=rmax + dy) fill_color = {'field': 'resid_snr', 'transform': mapper} radius = 0.0165 radius_hover = 0.02 # 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) # axes limit xmin, xmax = [min(ra[:]), max(ra[:])] ymin, ymax = [min(dec[:]), max(dec[:])] xfac, yfac = [(xmax - xmin) * 0.06, (ymax - ymin) * 0.06] left, right = xmin - xfac, xmax + xfac bottom, top = ymin - yfac, ymax + yfac # WEDGE RESIDUAL plots wedge_plot = Plot2d(x_range=xrange_wedge, y_range=yrange_wedge, x_label="RA", y_label="DEC", tooltip=snr_tooltip, title='Residual SNR' + name_warn, width=500, height=380, yscale="auto").wedge( source, x='x1', y='y1', field='resid_snr', mapper=mapper, ).wedge( source_not, x='x1', y='y1', ).plot taptool = wedge_plot.select(type=TapTool) taptool.callback = OpenURL(url=url) # ------------------- # Median plot median_tooltip = """ <div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">MEDIAN: </span> <span style="font-size: 1vw; color: #515151">@median</span> </div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">Resid: </span> <span style="font-size: 1vw; color: #515151">@resid_snr</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;">@QLF_FIBERID</span> </div> </div> """ mediam_plot = Plot2d( x_label="Fiber", y_label='Median SNR', tooltip=median_tooltip, title="", width=600, height=400, yscale="auto", hover_mode="vline", ).vbar( source, y="median", x="QLF_FIBERID", line_width=0.4, ) # Prepare tables current_exposures = check_spectra['METRICS']['FIDSNR_TGT'] program = gen_info['PROGRAM'].upper() reference_exposures = check_spectra['PARAMS']['FIDSNR_TGT_' + program + '_REF'] keynames = ["FIDSNR_TGT" + " ({})".format(i) for i in objlist] metric = Table().reference_table(keynames, current_exposures, reference_exposures) alert = Table().alert_table(nrg, wrg) layout = column(info_col, Div(), metric, alert, column(elg_plot, sizing_mode='scale_both'), column(lrg_plot, sizing_mode='scale_both'), column(qso_plot, sizing_mode='scale_both'), column(star_plot, sizing_mode='scale_both'), column(mediam_plot, sizing_mode='scale_both'), column(wedge_plot, sizing_mode='scale_both'), css_classes=["display-grid"]) return file_html(layout, CDN, "MEDIAN SNR")
def load_qa(self): cam = self.selected_arm+str(self.selected_spectrograph) mergedqa = QLFModels().get_output(self.selected_process_id, cam) check_spectra = mergedqa['TASKS']['CHECK_SPECTRA'] gen_info = mergedqa['GENERAL_INFO'] ra = gen_info['RA'] dec = gen_info['DEC'] nrg = check_spectra['PARAMS']['PEAKCOUNT_NORMAL_RANGE'] wrg = check_spectra['PARAMS']['PEAKCOUNT_WARN_RANGE'] current_exposures = [check_spectra['METRICS']['PEAKCOUNT']] program = gen_info['PROGRAM'].upper() reference_exposures = check_spectra['PARAMS']['PEAKCOUNT_' + program + '_REF'] obj_type = sort_obj(gen_info) my_palette = get_palette("RdYlBu_r") peak_tooltip = """ <div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">PEAKCOUNT: </span> <span style="font-size: 1vw; color: #515151">@peakcount_fib</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;">Obj Type: </span> <span style="font-size: 1vw; color: #515151;">@OBJ_TYPE</span> </div> </div> """ url = "http://legacysurvey.org/viewer?ra=@ra&dec=@dec&zoom=16&layer=decals-dr5" qlf_fiberid = np.arange(0, 500) peak_hover = HoverTool(tooltips=peak_tooltip) peakcount_fib = check_spectra['METRICS']['PEAKCOUNT_FIB'] source = ColumnDataSource(data={ 'x1': ra, 'y1': dec, 'peakcount_fib': peakcount_fib, 'delta_peakcount_fib': np.array(peakcount_fib)-reference_exposures, 'QLF_FIBERID': qlf_fiberid, 'OBJ_TYPE': obj_type, }) low, high = wrg mapper = LinearColorMapper(palette=my_palette, low=low, #0.98*np.min(peakcount_fib), high=high, #1.02*np.max(peakcount_fib)) nan_color='darkgrey') radius = 0.0165 radius_hover = 0.02 # 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) # axes limit xmin, xmax = [min(gen_info['RA'][:]), max(gen_info['RA'][:])] ymin, ymax = [min(gen_info['DEC'][:]), max(gen_info['DEC'][:])] xfac, yfac = [(xmax-xmin)*0.06, (ymax-ymin)*0.06] left, right = xmin - xfac, xmax+xfac bottom, top = ymin-yfac, ymax+yfac wedge_plot = Plot2d( x_range=xrange_wedge, y_range=yrange_wedge, x_label="RA", y_label="DEC", tooltip=peak_tooltip, title="PEAKCOUNT", width=500, height=380, ).wedge( source, x='x1', y='y1', field='delta_peakcount_fib', mapper=mapper, ).plot info_col = Title().write_description('skypeak') # ================================ # histogram hist_tooltip = """ <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;">Peakcount: </span> <span style="font-size: 1vw; color: #515151;">[@left, @right]</span> </div> </div> """ hist, edges = np.histogram(peakcount_fib, bins="sqrt") source_hist = ColumnDataSource(data={ 'hist': hist, 'histplusone': hist+1, 'bottom': [0] * len(hist), 'bottomplusone': [1]*len(hist), 'left': edges[:-1], 'right': edges[1:] }) p_hist = Plot2d( y_range=(1, 11**(int(np.log10(max(hist)))+1)), x_label='PEAKCOUNT', y_label='Frequency + 1', tooltip=hist_tooltip, title="", width=550, height=300, yscale="log", hover_mode="vline", ).quad( source_hist, top='histplusone', bottom='bottomplusone', line_width=1, ) # Prepare tables keynames = ["PEAKCOUNT" for i in range(len(current_exposures))] metric = Table().reference_table(keynames, current_exposures, reference_exposures) alert = Table().alert_table(nrg, wrg) layout = column(info_col, Div(), metric, alert, column(wedge_plot, sizing_mode='scale_both'), column(p_hist, sizing_mode='scale_both'), css_classes=["display-grid"]) return file_html(layout, CDN, "SKYPEAK")
def load_qa(self): cam = self.selected_arm + str(self.selected_spectrograph) mergedqa = QLFModels().get_output(self.selected_process_id, cam) check_fibers = mergedqa['TASKS']['CHECK_FIBERS'] gen_info = mergedqa['GENERAL_INFO'] flavor = mergedqa["FLAVOR"] countbins = check_fibers['METRICS'] nrg = check_fibers['PARAMS']['NGOODFIB_NORMAL_RANGE'] wrg = check_fibers['PARAMS']['NGOODFIB_WARN_RANGE'] if flavor == "science": ra = gen_info['RA'] dec = gen_info['DEC'] else: ra = [''] * 500 dec = [''] * 500 qlf_fiberid = np.arange(0, 500) # the fiber id is giving by petal obj_type = sort_obj(mergedqa['GENERAL_INFO']) hist_tooltip = """ <div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">FIBER STATUS: </span> <span style="font-size: 1vw; color: #515151;">@status</span> </div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">FIBER ID: </span> <span style="font-size: 1vw; color: #515151;">@fiberid</span> </div> </div> """ y = np.array(countbins['GOOD_FIBERS']) fibers = list(countbins['GOOD_FIBERS']) colors = ['#319b5c' if i == 1 else '#282828' for i in fibers] x = np.array(range(len(fibers))) hist_source = ColumnDataSource( data={ 'goodfiber': y, 'fiberid': x, 'segx0': x - 0.4, 'segx1': x + 0.4, 'segy0': y, 'segy1': y, 'status': ['GOOD' if i == 1 else 'BAD' for i in y], 'x1': ra, 'y1': dec, 'QLF_FIBERID': qlf_fiberid, 'OBJ_TYPE': obj_type, 'color': colors }) p = Plot2d( y_range=Range1d(-.1, 1.1), x_label="Fiber", y_label="Fiber Status", tooltip=hist_tooltip, title="Status", width=550, height=350, yscale="auto", hover_mode="vline", ).segment(hist_source).plot # ---------------- # Wedge if flavor == "science": if ra is None or dec is None: return 'Missing RA and DEC' count_tooltip = """ <div> <div> <span style="font-size: 1vw; font-weight: bold; color: #303030;">FIBER STATUS: </span> <span style="font-size: 1vw; color: #515151">@status</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;">Obj Type: </span> <span style="font-size: 1vw; color: #515151;">@OBJ_TYPE</span> </div> </div> """ radius = 0.0165 radius_hover = 0.02 # 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) p2 = Plot2d(x_range=xrange_wedge, y_range=yrange_wedge, x_label="RA", y_label="DEC", tooltip=count_tooltip, title="Fiber Status", width=400, height=350, yscale="auto").wedge( hist_source, x='x1', y='y1', field='color', ).plot else: p2 = Div() ngood = countbins['NGOODFIB'] fracgood = ngood / 500. - 1. info_col = Title().write_description('countbins') # Prepare tables current_exposures = [check_fibers['METRICS']['NGOODFIB']] if flavor == 'science': program = gen_info['PROGRAM'].upper() reference_exposures = check_fibers['PARAMS']['NGOODFIB_' + program + '_REF'] else: reference_exposures = check_fibers['PARAMS']['NGOODFIB_REF'] keynames = ["NGOODFIB"] metric = Table().reference_table(keynames, current_exposures, reference_exposures) alert = Table().alert_table(nrg, wrg) layout = column(info_col, Div(), metric, alert, column(p, sizing_mode='scale_both'), column(p2, sizing_mode='scale_both'), css_classes=["display-grid"]) return file_html(layout, CDN, "COUNTBINS")