plesty.pow_pl.viz ================= .. py:module:: plesty.pow_pl.viz .. autoapi-nested-parse:: Watch a power-PL run — live, replayed, or rendered to a video. .. code-block:: bash uv run python -m plesty.pow_pl.viz monitor # follow the newest run uv run python -m plesty.pow_pl.viz monitor --replay 2 --record run.mp4 uv run python -m plesty.pow_pl.viz render --run D104-C_QD01_20261012 Everything about *watching* — which run, where the share is mounted, live or replayed, a window of its own or embedded in the bench console — is :class:`plesty.lib.monitor.Viz`'s. The manifest names this module as the experiment's viewer (``viz``), so the bench opens it on the runs it starts. Four views follow the run: the newest spectrum; every spectrum so far against the wave-plate angle, in counts per second so the exposures of one angle compare; the excitation power against the angle; and the integrated emission against the power on log–log axes with its running exponent *k* — the number the analysis after the sweep (:mod:`.analysis`) reports for the whole range. What is this experiment's own is :func:`read_spectrum`: a record names the file the spectrometer wrote, and turning it into columns is the one thing no shared view can do. Watching is passive: the views read committed records and the spectra they point at, and write nothing. Attributes ---------- .. autoapisummary:: plesty.pow_pl.viz.SPIKE_THRESHOLD plesty.pow_pl.viz.MIN_POINTS plesty.pow_pl.viz.viz Classes ------- .. autoapisummary:: plesty.pow_pl.viz.PowerLaw plesty.pow_pl.viz.RateMap Functions --------- .. autoapisummary:: plesty.pow_pl.viz.remove_spikes plesty.pow_pl.viz.read_spectrum plesty.pow_pl.viz._band plesty.pow_pl.viz.integrated Module Contents --------------- .. py:data:: SPIKE_THRESHOLD :value: 20.0 .. py:data:: MIN_POINTS :value: 4 .. py:function:: remove_spikes(counts: numpy.ndarray) -> numpy.ndarray Replace single-pixel spikes (cosmic rays) by the mean of their neighbours. A spike stands more than :data:`SPIKE_THRESHOLD` noise levels above the brighter of its two neighbours *and* more than twice that neighbour; the peak of an emission line fails the second test, so lines pass unchanged. :param counts: One spectrum. :returns: The spectrum with single-pixel spikes replaced. .. py:function:: read_spectrum(row: Any, run: Any) -> dict[str, Any] Turn the file a record names into the columns the views want. Called once per row and cached, so the views load each spectrum once between them. :param row: One committed record. :param run: The run it belongs to; ``run.local`` translates the acquiring host's path onto this machine. :returns: ``wavelength``; ``counts`` as recorded; ``rate``, the spectrum without cosmic rays in counts per second; and ``power_uw``. Nothing for a row that names no spectrum. .. py:function:: _band(wavelength: numpy.ndarray, band: Optional[Sequence[float]]) -> numpy.ndarray Pixels inside *band*, or every pixel when no band is given. .. py:function:: integrated(data: Any) -> tuple[numpy.ndarray, numpy.ndarray] Power (µW) and integrated emission (counts/s) of every spectrum so far. The same reduction as the analysis: each spectrum minus its background (the median of ``analysis.background_nm``, or of the whole spectrum), summed over ``analysis.region_nm`` (or every pixel). :param data: The run's :class:`~plesty.lib.monitor.RunData`. :returns: Two arrays, one value per spectrum that has a power. .. py:class:: PowerLaw(title: str = '', *, name: str = '', weight: Optional[float] = None, area: str = '') Bases: :py:obj:`plesty.lib.monitor.Plot` Integrated emission against power on log–log axes, with the running exponent. Name the view. :param title: Overrides the class attribute. :param name: Layout key; defaults to the title. :param weight: Overrides the class attribute. :param area: Overrides the class attribute. .. py:attribute:: title :value: 'Integrated emission against power' .. py:method:: draw(data: Any) -> list[Any] Every spectrum so far as a point, and the fitted line once there are enough. .. py:class:: RateMap(values: str = 'counts', row: str = '', *, x: str = 'wavelength', title: str = '', name: str = '', weight: Optional[float] = None, area: str = '', color: str = 'violet', scale: str = 'sqrt', x_label: str = 'Wavelength (nm)', y_label: str = '') Bases: :py:obj:`plesty.lib.monitor.common.SpectrumMap` The library's map, of every spectrum in counts per second without cosmic rays. Per second, because each angle may be measured at several exposures; without cosmic rays, because the colour scale runs from the lowest value to the highest and one ray would leave every emission line dark. Stack *values* across rows, against *row*. :param values: Field holding each row's array. :param row: Field holding the swept coordinate, for the axis; empty numbers the rows instead. :param x: Field holding the sample axis, shared by every row — so the map is drawn in the same units as the spectrum above it. ``""``, or a field no row carries, numbers the samples. :param title: What the view is called. :param name: Layout key. :param weight: Relative size. :param area: Which side of the window it starts on. :param color: Palette token the colour map is built from. :param scale: ``"sqrt"`` or ``"linear"``. :param x_label: Axis label of the sample axis. :param y_label: Axis label of the swept axis. .. py:method:: block(data: Any) -> Any Stack the per-second spectra rather than the recorded counts. .. py:data:: viz