Esempio n. 1
0
def plot_on_single_pmt_array(c,
                             array_name='top',
                             r=straxen.tpc_r * 1.1,
                             pmt_label_size=7,
                             pmt_label_color='white',
                             log_scale=False,
                             vmin=None,
                             vmax=None,
                             **kwargs):
    """Plot one of the PMT arrays and color it by c.

    :param c: Array of colors to use. Must be len(straxen.n_tpc_pmts)
    :param label: Label for the color bar
    :param pmt_label_size: Fontsize for the PMT number labels.
    Set to 0 to disable.
    :param pmt_label_color: Text color of the PMT number labels.
    :param log_scale: If True, use a logarithmic color scale
    :param extend: same as plt.colorbar(extend=...)
    :param vmin: Minimum of color scale
    :param vmax: maximum of color scale

    Other arguments are passed to plt.scatter.
    """
    assert len(c) == straxen.n_tpc_pmts, \
        f"Need array of {straxen.n_tpc_pmts} values, got {len(c)}"
    if vmin is None:
        vmin = c.min()
    if vmax is None:
        vmax = c.max()

    pmt_positions = straxen.pmt_positions().to_records()

    plt.gca().set_aspect('equal')
    plt.xlim(-r, r)
    plt.ylim(-r, r)

    mask = pmt_positions['array'] == array_name
    pos = pmt_positions[mask]

    kwargs.setdefault('s', 230)
    result = plt.scatter(
        pos['x'],
        pos['y'],
        c=c[mask],
        vmin=vmin,
        vmax=vmax,
        norm=matplotlib.colors.LogNorm() if log_scale else None,
        **kwargs)

    if pmt_label_size:
        for p in pos:
            plt.text(p['x'],
                     p['y'],
                     str(p['i']),
                     horizontalalignment='center',
                     verticalalignment='center',
                     fontsize=pmt_label_size,
                     color=pmt_label_color)
    return result
Esempio n. 2
0
def hvdisp_plot_pmt_pattern(*, config, records, to_pe, array='bottom'):
    """Plot a PMT array, with colors showing the intensity
    of light observed in the time range
    :param array: 'top' or 'bottom', array to show
    """
    import holoviews as hv

    pmts = straxen.pmt_positions(xenon1t=config['n_tpc_pmts'] < 300)
    areas = np.bincount(records['channel'],
                        weights=records['area'] * to_pe[records['channel']],
                        minlength=len(pmts))

    # Which PMTs should we include?
    m = pmts['array'] == array
    pmts = pmts[m].copy()
    pmts['area'] = areas[m]

    f = 1.08
    pmts = hv.Dataset(pmts,
                      kdims=[
                          hv.Dimension('x',
                                       unit='cm',
                                       range=(-straxen.tpc_r * f,
                                              straxen.tpc_r * f)),
                          hv.Dimension('y',
                                       unit='cm',
                                       range=(-straxen.tpc_r * f,
                                              straxen.tpc_r * f)),
                          hv.Dimension('i',
                                       range=(0, config['n_tpc_pmts']),
                                       label='PMT number'),
                          hv.Dimension('area', label='Area', unit='PE')
                      ])
    pmts = pmts.to(hv.Points,
                   vdims=['area', 'i'],
                   group='PMTPattern',
                   label=array.capitalize()).opts(plot=dict(color_index=2,
                                                            tools=['hover'],
                                                            show_grid=False),
                                                  style=dict(size=17,
                                                             cmap='plasma'))

    return pmts
Esempio n. 3
0
def plot_on_single_pmt_array(
        c,
        array_name='top',
        xenon1t=False,
        r=straxen.tpc_r * 1.03,
        pmt_label_size=8,
        pmt_label_color='white',
        show_tpc=True,
        log_scale=False, vmin=None, vmax=None,
        dead_pmts=None, dead_pmt_color='gray',
        **kwargs):
    """Plot one of the PMT arrays and color it by c.

    :param c: Array of colors to use. Must be len() of the number of TPC PMTs
    :param label: Label for the color bar
    :param pmt_label_size: Fontsize for the PMT number labels.
    Set to 0 to disable.
    :param pmt_label_color: Text color of the PMT number labels.
    :param log_scale: If True, use a logarithmic color scale
    :param extend: same as plt.colorbar(extend=...)
    :param vmin: Minimum of color scale
    :param vmax: maximum of color scale

    Other arguments are passed to plt.scatter.
    """
    if vmin is None:
        vmin = c.min()
    if vmax is None:
        vmax = c.max()

    pmt_positions = straxen.pmt_positions(xenon1t=xenon1t).to_records()

    ax = plt.gca()
    ax.set_aspect('equal')
    plt.xlim(-r, r)
    plt.ylim(-r, r)

    mask = pmt_positions['array'] == array_name
    pos = pmt_positions[mask]

    kwargs.setdefault('s', 280)
    if log_scale:
        kwargs.setdefault('norm',
                          matplotlib.colors.LogNorm(vmin=vmin,
                                                    vmax=vmax))
    else:
        kwargs.setdefault('vmin', vmin)
        kwargs.setdefault('vmax', vmax)
    result = plt.scatter(
        pos['x'],
        pos['y'],
        c=c[mask],
        **kwargs)

    if show_tpc:
        ax.set_facecolor('lightgrey')
        ax.add_artist(plt.Circle(
            (0, 0),
            straxen.tpc_r,
            edgecolor='k',
            facecolor='w',
            zorder=-5,
            linewidth=1))
    else:
        ax.set_axis_off()
    if dead_pmts is not None:
        _dead_mask = [pi in dead_pmts for pi in pos['i']]
        result = plt.scatter(
            pos[_dead_mask]['x'],
            pos[_dead_mask]['y'],
            c=dead_pmt_color,
            **kwargs)

    if pmt_label_size:
        for p in pos:
            plt.text(p['x'], p['y'], str(p['i']),
                     horizontalalignment='center',
                     verticalalignment='center',
                     fontsize=pmt_label_size,
                     color=pmt_label_color)
    return result
Esempio n. 4
0
def plot_pmt_array(
    peak,
    array_type,
    to_pe,
    plot_all_pmts=False,
    log=False,
    xenon1t=False,
    fig=None,
    label='',
):
    """
    Plots top or bottom PMT array for given peak.

    :param peak: Peak for which the hit pattern should be plotted.
    :param array_type: String which specifies if "top" or "bottom"
        PMT array should be plotted
    :param to_pe: PMT gains.
    :param log: If true use a log-scale for the color scale.
    :param plot_all_pmts: If True colors all PMTs instead of showing
        swtiched off PMTs as gray dots.
    :param xenon1t: If True plots 1T array.
    :param fig: Instance of bokeh.plotting.figure if None one will be
        created via straxen.bokeh.utils.default_figure().
    :param label: Label of the peak which should be used for the
        plot legend

    :returns: Tuple containing a bokeh figure, glyph and transform
        instance.
    """
    if peak.shape:
        raise ValueError(
            'Can plot PMT array only for a single peak at a time.')

    tool_tip = [('Plot', '$name'), ('Channel', '@pmt'),
                ('X-Position [cm]', '$x'), ('Y-Position [cm]', '$y'),
                ('area [pe]', '@area')]

    array = ('top', 'bottom')
    if array_type not in array:
        raise ValueError('"array_type" must be either top or bottom.')

    if not fig:
        fig = straxen.bokeh_utils.default_fig(title=f'{array_type} array')

    # Creating TPC axis and title
    fig = _plot_tpc(fig)

    # Plotting PMTs:
    pmts = straxen.pmt_positions(xenon1t)
    if plot_all_pmts:
        mask_pmts = np.zeros(len(pmts), dtype=np.bool_)
    else:
        mask_pmts = to_pe == 0
    pmts_on = pmts[~mask_pmts]
    pmts_on = pmts_on[pmts_on['array'] == array_type]

    if np.any(mask_pmts):
        pmts_off = pmts[mask_pmts]
        pmts_off = pmts_off[pmts_off['array'] == array_type]
        fig = _plot_off_pmts(pmts_off, fig)

    area_per_channel = peak['area_per_channel'][pmts_on['i']]

    if log:
        area_plot = np.log10(area_per_channel)
        # Manually set infs to zero since cmap cannot handle it.
        area_plot = np.where(area_plot == -np.inf, 0, area_plot)
    else:
        area_plot = area_per_channel

    mapper = bokeh.transform.linear_cmap(field_name='area_plot',
                                         palette="Viridis256",
                                         low=min(area_plot),
                                         high=max(area_plot))

    source_on = bklt.ColumnDataSource(
        data={
            'x': pmts_on['x'],
            'y': pmts_on['y'],
            'area': area_per_channel,
            'area_plot': area_plot,
            'pmt': pmts_on['i']
        })

    p = fig.scatter(
        source=source_on,
        radius=straxen.tpc_pmt_radius,
        fill_color=mapper,
        fill_alpha=1,
        line_color='black',
        legend_label=label,
        name=label + '_pmt_array',
    )
    fig.add_tools(
        bokeh.models.HoverTool(names=[label + '_pmt_array'],
                               tooltips=tool_tip))
    fig.legend.location = 'top_left'
    fig.legend.click_policy = "hide"
    fig.legend.orientation = "horizontal"
    fig.legend.padding = 0
    fig.toolbar_location = None
    return fig, p, mapper
Esempio n. 5
0
def test_pmt_pos_nt():
    """
    Test if we can get the nT PMT positions
    """
    pandas.DataFrame(straxen.pmt_positions(False))
Esempio n. 6
0
def test_pmt_pos_1t():
    """
    Test if we can get the 1T PMT positions
    """
    pandas.DataFrame(straxen.pmt_positions(True))