Source code for libvhc.html.communication

# Virus Health Check: a validation tool for HETDEX/VIRUS data
# Copyright (C) 2016, 2017  "The HETDEX collaboration"
#
# 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/>.
"""Interface for the html renderer
The relevant parts are imported into html/__init__.py

"""
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import contextlib

from libvhc.html import fplane
from libvhc.html import queue

HTML_RECAP = "{{recipe}}_recap_{}.html"
"""Template name for the html recap files"""

# _manager = multiprocessing.Manager()
# Private container for the fplane object
# key: recipe; value: fplane.FPlane instance
_listeners = dict()
_queues = dict()


[docs]class HtmlRecipeError(KeyError): """The html render for the recipe has not been initialised""" pass
[docs]def get_listener(name): """Return the queue listener Parameters ---------- name : string name of the logger Returns ------- :class:`libvhc.html.queue.SetupQueueListener` can be used once in a :keyword:`with` Raises ------ KeyError if the ``name`` listener is not found """ return _listeners[name]
[docs]def get_queue(name): """Returns the queue saved under the ``name``. If it does not exist, create it first Parameters ---------- path : string path of the two above files Returns ------- :class:`libvhc.html.queue.HTMLQueue` """ try: return _queues[name] except KeyError: q = queue.HTMLQueue() _queues[name] = q return q
[docs]@contextlib.contextmanager def html_context(name): """Yield the listener and the queue associated with ``name`` from within a :keyword:`with` statement Parameters ---------- name : string name of the listener and the queue Yields ------ queue-like instance :class:`~pyhetdex.tools.logging_helper.SetupQueueListener` """ try: with get_queue(name) as q, get_listener(name) as l: yield q, l finally: clear_html(name)
[docs]def clear_html(name): """Remove the queue and the listener Parameters ---------- name : string name of the queue and logger """ _queues.pop(name, None) _listeners.pop(name, None)
[docs]def init_renderer(recipe, fplane_file, use_process=True): """Initialize the renderer for the HTML file and the :class:`fplane.FPlane` Parameters ---------- recipe : string name of the recipe fplane_file : string name of the file describing the focal plane. use_process : bool, optional run the listener in a process or in a thread """ q = get_queue(recipe) listener = queue.SetupQueueListener(q, fplane.FPlane, recipe, fplane_file, use_process=use_process) _listeners[recipe] = listener
[docs]def _mkmessage(vcheck, message): """Prepend the string from ``vcheck`` to the ``message`` Parameters ---------- vcheck : instance of :class:`~libvhc.VCheck` store the recipe name and the check currently executing message : string message of the test Returns ------- string """ return str(vcheck) + "; " + message
[docs]def add_fplane_test(vcheck, message, success): """Append a new :class:`TestResults` to the focal plane tests The name of the recipe and driver are prepended to the message. Parameters ---------- vcheck : instance of :class:`~libvhc.VCheck` store the recipe name and the check currently executing message : string message of the test success : string or bool success status of the test; must be one of the accepted values of :class:`TestResults` Raises ------ HtmlRecipeError if the ``recipe`` renderer has not been initialized """ get_queue(vcheck.recipe).put(['add_test', (_mkmessage(vcheck, message), success)])
[docs]def add_ifu_test(vcheck, ifuslot, message, success): """Append a new :class:`TestResults` to the ifu tests The name of the recipe and driver are prepended to the message. Parameters ---------- vcheck : instance of :class:`~libvhc.VCheck` store the recipe name and the check currently executing ifuslot : string id of the ifu slot, if the IFU does not exists, add the message to the global messages marking it as a failure. Use a non existing ``ifuslot`` (e.g. ``None``) to add it to the orphaned tests message : string message of the test success : string or bool success status of the test; must be one of the accepted values of :class:`TestResults` Raises ------ HtmlRecipeError if the ``recipe`` renderer has not been initialized """ get_queue(vcheck.recipe).put(['add_ifu_test', (ifuslot, _mkmessage(vcheck, message), success)])
[docs]def add_ntests(vcheck, new_tests): """Add ``new_tests`` to the number of tests Parameters ---------- vcheck : instance of :class:`~libvhc.VCheck` store the recipe name and the check currently executing new_tests : int number on tests to add Raises ------ HtmlRecipeError if the ``recipe`` renderer has not been initialized """ get_queue(vcheck.recipe).put(['add_ntests', (new_tests,)])
[docs]def render_html(recipe, fnames, path, xmin=-450, ymin=-550, xscale=1, yscale=1, open_html=False): """Render the html and save it into ``outpath``. The name of the output html is ``recipe_recap.html``. If it already exists, a counter is added: ``recipe_recap_n.html`` Parameters ---------- recipe : string name of the recipe fnames : :class:`libvhc.utils.FileNameRotator` object containing the file names. It expects the html file on :attr:`fnames.html_recap`, the log file on :attr:`fnames.logfile` and the result file on :attr:`fnames.result_file`. The html recap file name is expected to contain a placeholder ``{recipe}`` path : string path given to vhc xmin, ymin : float minimum ``x`` and ``y`` coordinate to rescale the ifu positions scale : float divide the ``x`` and ``y`` by this value after subtracting the minima. See :func:`fplane.IFU.rescale` for further details open_html : bool open the new html in the default browser """ q = get_queue(recipe) # rescale the IFU to fit them into the html frame q.put(['ifu_rescale', (xmin, ymin, xscale, yscale)]) # post process the ifus to get the ifu statuses in place q.put('postprocess_ifus') # set the template into the fplane object q.put('load_template') # render the template q.put(['render', (path, fnames.logfile, fnames.result_file, fnames.driver_file)]) # build the output file name and save the rendered template fname = fnames.html_recap.format(recipe=recipe) write_html(recipe, fname, open_html=open_html)
[docs]def write_html(recipe, fname, open_html=False): '''Send the command to write the html recap file. Parameters ---------- recipe : string name of the recipe fname : string name of the file open_html : bool open the new html in the default browser ''' q = get_queue(recipe) q.put(['write_recap', (fname, ), {'auto_open': open_html}])