Source code for autowisp.tests.test_photometry_slots

"""Tests for photometry slots in diagnostic expressions.

The second subscript, ``magfit_residual[0][1]``, binding the photometries of
a quantity read per photometry as the first binds its channels. Kept apart
from :mod:`autowisp.tests.test_expressions` only for length; the fixture is
its :class:`~autowisp.tests.test_expressions.SlotTestCase`, with a
per-photometry diagnostic added.
"""

import unittest

import numpy

from autowisp.diagnostics.diagnostic_types import (
    shapefit_photometry,
    time_quantity,
)
from autowisp.diagnostics.expressions import (
    check_expression,
    check_rule,
    get_channel_arity,
    get_indexed_names,
    get_photometry_arity,
    get_photometry_parameters,
)
from autowisp.tests.test_expressions import SlotTestCase


[docs] class TestPhotometrySlots(SlotTestCase): """Photometries, bound through a second subscript as channels are through the first. The library adds to the channel one: two photometries of one channel; one formal photometry against a quoted aperture; an expression passing its photometries on the other way round; one quoting both its channel and its photometry, the shape fit; and a channel-free one taking a photometry, and one reading that. """ library = dict( SlotTestCase.library, apertures="magfit_residual[0][0] - magfit_residual[0][1]", against_ap4="magfit_residual[0][0] - magfit_residual[0]['ap4']", swapped="apertures[1][1, 0] + bg_center[1]", g_shapefit="magfit_residual['G0']['shapefit']", g_residual="magfit_residual['G0'][0]", doubled_g="g_residual[()][0] * 2", ) #: ``magfit_residual`` per channel and photometry, distinct everywhere so #: that reading the wrong one cannot pass by coincidence. residual = { (channel, photometry): numpy.array([1.0, 2.0]) * (10 * index + photometry + 2) for index, channel in enumerate(("B", "R", "G0")) for photometry in (shapefit_photometry, 0, 2, 3, 4) } #: One of each shape above, all wanted at once. wanted = { "swapped": {(("R",), (2, shapefit_photometry))}, "against_ap4": {(("B",), (0,))}, "g_shapefit": {((), ())}, "doubled_g": {((), (3,))}, }
[docs] def fetch(self, wanted): """As for any diagnostic, with ``magfit_residual`` per photometry.""" fetched = super().fetch(wanted) if "magfit_residual" in fetched: fetched["magfit_residual"] = { binding: self.residual[binding[0][0], binding[1][0]] for binding in fetched["magfit_residual"] } return fetched
[docs] def test_parameters_and_arity(self): """Derived from the second subscripts, as channels from the first.""" for name, parameters, arity in ( ("apertures", (0, 1), 2), ("against_ap4", (0,), 1), ("swapped", (0, 1), 2), ("g_shapefit", (), 0), ("g_residual", (0,), 1), ): with self.subTest(name=name): self.assertEqual( get_photometry_parameters(self.library[name]), parameters ) self.assertEqual( get_photometry_arity(name, self.library), arity ) for name, arity in ( ("magfit_residual", 1), ("bg_center", 0), (time_quantity, 0), ): with self.subTest(name=name): self.assertEqual( get_photometry_arity(name, self.library), arity ) self.assertEqual(get_channel_arity("g_residual", self.library), 0)
[docs] def test_reads_carry_their_photometries(self): """The second subscript is part of the read, not a read of its own.""" self.assertEqual( get_indexed_names(self.library["swapped"]), [("apertures", (1,), (1, 0)), ("bg_center", (1,), ())], ) self.assertEqual( get_indexed_names(self.library["doubled_g"]), [("g_residual", (), (0,))], )
[docs] def test_needed_in_every_photometry_read(self): """Formal ones bound, quoted ones read as the ids they spell.""" self.assertEqual( self.needed(self.wanted), { "magfit_residual": { (("R",), (shapefit_photometry,)), (("R",), (2,)), (("B",), (0,)), (("B",), (4,)), (("G0",), (shapefit_photometry,)), (("G0",), (3,)), }, "bg_center": {(("R",), ())}, }, )
[docs] def test_evaluated_in_the_photometries_bound(self): """``swapped`` at ``(2, shapefit)`` is ``apertures`` at the reverse.""" drawn = self.evaluate(self.wanted) for quantity, binding, expected in ( ( "swapped", (("R",), (2, shapefit_photometry)), self.residual["R", shapefit_photometry] - self.residual["R", 2] + self.bg["R"], ), ( "against_ap4", (("B",), (0,)), self.residual["B", 0] - self.residual["B", 4], ), ( "g_shapefit", ((), ()), self.residual["G0", shapefit_photometry], ), ("doubled_g", ((), (3,)), 2 * self.residual["G0", 3]), ): with self.subTest(quantity=quantity): numpy.testing.assert_allclose( drawn[quantity][binding], expected )
[docs] def test_the_library_accepts_them(self): """Every shape above is a valid expression.""" for name in self.wanted: with self.subTest(name=name): self.assertEqual( check_expression(name, self.library[name], self.library), [], )
[docs] def test_a_read_must_match_what_it_reads(self): """A photometry subscript exactly where one is taken, naming one.""" for text in ( "magfit_residual[0]", "bg_center[0][0]", "apertures[0][0]", "magfit_residual[0]['ap']", "g_residual", "g_residual[0][0]", ): with self.subTest(text=text): self.assertTrue(check_expression("bad", text, self.library))
[docs] def test_a_rule_takes_at_most_one_photometry_slot(self): """The other photometries a rule reads are quoted.""" self.assertEqual( check_rule( "magfit_residual[0][0] - magfit_residual[0]['ap4'] > 1", self.library, ), [], ) problems = check_rule("apertures[0][0, 1] > 1", self.library) self.assertEqual(len(problems), 1) self.assertIn("photometry", problems[0])
if __name__ == "__main__": unittest.main()