autowisp.tests.test_diagnostics_views module

Class Inheritance Diagram

Inheritance diagram of DiagnosticType, DiagnosticsViewTestCase, Image, ImageDiagnostics, ImageType, ObservingSession, PipelineError, SeriesKey, TestAvailableQuantities, TestExpressionAxis, TestImageTypeSplit, TestInitialRow, TestPairOptions, TestQuantileSection, TestSeparateYAxes, TestSharedTimeOffset, datetime

Tests for what the BUI diagnostics views ask of a project.

What the series table offers for a pair of axes – the (session, image type) pairs a row may be drawn for, and the one row the table starts with – what a row reads once the client posts it back, and how the figure below offsets what those rows draw. Every one of them is a question about an observing project, so each needs the throwaway database this builds, following test_error_render.

The rules that need no project – ids, channel columns, section headers and markers – are in test_diagnostics_rules.

class autowisp.tests.test_diagnostics_views.DiagnosticsViewTestCase(methodName='runTest')[source]

Bases: TestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.DiagnosticsViewTestCase

Base creating one throwaway project database holding two nights.

classmethod _fill_database()[source]

Create two observing sessions, the second holding two image types.

Every frame records bg_center in channel R; only object frames record the quantiles, which is the ordinary case of a diagnostic that is not defined for every type. Provenance foreign keys are left dangling, as SQLite does not enforce them and the diagnostics queries only ever join back to observing_session and image_type.

static bind(row, session_id, image_type, *channels)[source]

Return the row as the client posts it with its dropdowns set.

A test asks for a particular series the way the table does – by choosing a pair and a channel per column – rather than by picking a row out of a list, there being one row to start from.

first_row(x_quantity, y_quantity, expressions=None)[source]

Return the row the table starts with, on the earliest session.

images_of = {}

{(night, image_type): [image_id, ...]}, in JD order, so a test can say which images a series is supposed to be built from.

pairs_for(x_quantity, y_quantity, expressions=None)[source]

Return the (session_id, image_type) pairs a row may name.

What the table used to answer with a row each, and now answers with the options of one dropdown.

classmethod setUpClass()[source]

Hook method for setting up class fixture before running tests in the class.

table_for(x_quantity, y_quantity, expressions=None, marker='o')[source]

Return what one section’s table offers for an axis pair.

classmethod tearDownClass()[source]

Hook method for deconstructing the class fixture after running all tests in the class.

class autowisp.tests.test_diagnostics_views.TestAvailableQuantities(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestAvailableQuantities

What the two axis selectors offer, given what this project holds.

Availability rather than validity: every stored expression is valid in every project, so the only question a selector can usefully ask is whether the diagnostics an expression reaches have actually been recorded here.

_recorded()[source]

Return the raw in-use diagnostic names.

test_a_broken_expression_is_hidden_rather_than_raised()[source]

A stored cycle must not stop the plot page rendering.

Saying what is wrong with it belongs to the management page; here the only sane answer is not to offer it.

test_a_concrete_quantile_is_judged_against_the_raw_names()[source]

Which is why the family collapse happens after this check.

Against the collapsed list pixel_q999 would look unrecorded and a perfectly drawable expression would go missing from the selector.

test_a_dependency_makes_its_dependents_unavailable()[source]

Availability follows the whole subtree, not the direct names.

test_a_jd_only_expression_is_always_available()[source]

jd exists for every image of the canonical list.

test_an_unknown_name_is_hidden_too()[source]

A typo no version of AutoWISP defines, rather than a cycle.

test_every_recorded_name_is_offered()[source]

Including each quantile, which is what an expression is judged against and what a section may now draw.

test_expression_hidden_where_an_input_is_not_recorded()[source]

Not an error – astrom_residual is real, merely unrecorded.

The distinction the whole design rests on: this expression is valid here and would be offered in a project that had run plate solving.

test_expression_offered_where_its_inputs_are_recorded()[source]

The ordinary case, and the composed one behind it.

test_expressions_join_the_same_flat_list()[source]

Not a second list beside it.

An axis reads one name, and a recorded diagnostic is an expression of itself as far as everything downstream is concerned – which is the same flat name space that stops an expression taking a diagnostic’s name.

test_the_selector_offers_each_quantile_and_no_family()[source]

A pixel_q* is an ordinary quantity with a section of its own.

The family name stood for all of them on one plot, which is what sections do for any quantity – so it earned its keep no longer, and drawing one quantile against another needed an expression while it existed.

class autowisp.tests.test_diagnostics_views.TestExpressionAxis(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestExpressionAxis

An expression selected for an axis, as a diagnostic would be.

The library is passed in rather than stored, which is the arrangement that lets these run against a project database alone: what the view does with an expression does not depend on where it was kept.

library = {'q_ratio': 'pixel_q999[1] / pixel_q99[1]', 'rel_bg': 'bg_center[1] - nanmedian(bg_center[1])', 'scaled_bg': 'rel_bg[1] * 10'}

Referenced by every test here; bg_center is recorded for both image types, so the availability answer is interesting.

test_a_composed_expression_reaches_through()[source]

scaled_bg needs what rel_bg needs, transitively.

test_an_expression_against_a_diagnostic()[source]

Both axes at once, one of each kind, sharing a query.

test_an_unknown_name_is_refused()[source]

Neither a diagnostic nor an expression, so nothing to plot.

test_offered_wherever_its_diagnostics_are()[source]

Availability follows what the expression reaches, not its name.

Nothing records a diagnostic called rel_bg; the series it can be drawn for are those recording the bg_center it is built from.

test_restricted_to_the_types_recording_its_inputs()[source]

Only object frames record the quantiles, so only they are offered.

test_the_values_are_the_expression_evaluated()[source]

End to end: an expression axis produces its own numbers.

class autowisp.tests.test_diagnostics_views.TestImageTypeSplit(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestImageTypeSplit

A session holding several image types yields a series per type.

test_a_type_without_the_diagnostic_is_absent()[source]

Only object frames record the quantiles, so only they appear.

test_canonical_list_holds_only_its_own_type()[source]

The alignment the whole design rests on is per type.

Every array is padded onto this list, so if it mixed types then so would every quantity built against it.

test_each_type_is_offered_separately()[source]

The mixed night offers object and flat as two pairs, not one.

test_the_type_is_shown_in_the_table()[source]

Otherwise two pairs of the mixed night would read identically.

test_values_are_not_taken_across_types()[source]

The point of the split: an aggregate sees one population.

A series covering the whole night would hand nanmedian all five frames and return the object median, since the objects outnumber the flats – silently, and wrongly.

class autowisp.tests.test_diagnostics_views.TestInitialRow(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestInitialRow

The one row a table starts with, so the page draws without a click.

test_exactly_one_row()[source]

The table lists nothing; the rest are built by the user.

test_it_names_the_quantity_it_draws()[source]

Which is what lets the figure read a y per row rather than a page.

test_on_the_first_pair_offered()[source]

The earliest session, that being how the options are ordered.

test_one_channel_recorded_arrives_bound()[source]

A column with one channel to offer is no choice at all.

The fixture records R alone, so the row is bound and counted at render and draws the moment the page loads.

class autowisp.tests.test_diagnostics_views.TestPairOptions(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestPairOptions

The (session, image type) pairs a row may be drawn for.

What the table answered with a row each when it listed them, and now answers with the options of one dropdown.

test_a_pair_needs_every_column_to_have_a_channel()[source]

Only object frames record the quantiles, so only they are offered.

test_an_option_names_its_session_and_type()[source]

Otherwise the two rows of the mixed night would read alike.

test_listed_by_session_start_time()[source]

Labels are free-form, so the times are what orders them.

test_the_times_sort_as_text()[source]

Which is why they are formatted rather than left as datetimes.

class autowisp.tests.test_diagnostics_views.TestQuantileSection(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestQuantileSection

A pixel_q* draws like any other recorded diagnostic.

Which is the whole of what replaced the family: a quantile is named, bound, counted and read exactly as bg_center is, and several of them share a plot by being several sections rather than by one name expanding into them.

test_a_quantile_reads_its_own_values()[source]

No family stands between the name and the numbers.

test_a_quantile_section_starts_with_a_row()[source]

Built from the same pairs, since only object frames record it.

test_one_quantile_against_another()[source]

What the family made impossible without an expression.

class autowisp.tests.test_diagnostics_views.TestSeparateYAxes(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestSeparateYAxes

Quantities in different units sharing an x but not a y scale.

Only reverse is mocked, so the artists, the labels and the legend are the real ones: the per-point click-through URL needs Django settings and is not what any of this is about.

drawn_labels()[source]

Return the rows the figure draws, in the order it draws them.

figure_for(y_axes)[source]

Draw bg_center and pixel_q99 with the given assignment.

test_separate_numbers_draw_an_axis_each()[source]

A twin per further axis, each labelled for what it carries.

test_sharing_one_axis_draws_one()[source]

Both quantities on the same scale, named on the same label.

test_the_legend_sits_on_the_topmost_axis()[source]

Naming every series, wherever it was drawn.

On the host it would be painted under the twin’s points, and each axis on its own would name only what it drew.

test_the_x_axis_and_grid_stay_on_the_host()[source]

Twin grids interleave into a mesh saying nothing about either.

class autowisp.tests.test_diagnostics_views.TestSharedTimeOffset(methodName='runTest')[source]

Bases: DiagnosticsViewTestCase

Inheritance diagram of autowisp.tests.test_diagnostics_views.TestSharedTimeOffset

The x-offset is one value for the whole figure, not per series.

_plotted_x_values()[source]

Return the x arrays that reach the per-series plotting call.

plot_image_diagnostic_series is mocked out, which both captures the offset values and avoids reverse() needing Django settings.

_series_starts()[source]

Return where each plotted series begins on the shared x axis.

test_offset_is_not_per_series()[source]

Guard the exact regression the merge could introduce.

Zeroing each series on its own would start every one of them at 0, collapsing the day between the two nights. The second night’s series keep that day, wherever in the night each one begins.

test_only_the_earliest_series_starts_at_zero()[source]

One offset for the figure, so exactly one series lands on 0.

autowisp.tests.test_diagnostics_views._diagnostic_names = ('bg_center', 'pixel_q99', 'pixel_q999')

the lazy database initialization behind set_project_home creates the schema but seeds no diagnostic_type rows, and depending on that would couple these tests to project-creation behaviour they are not about.

Type:

Every diagnostic the fixture records. All are created explicitly

autowisp.tests.test_diagnostics_views._first_bg_center = {'flat': 500.0, 'object': 100.0}

bg_center of the first frame of each type. Far enough apart that a median over one type cannot be confused with a median over the mixture.

autowisp.tests.test_diagnostics_views._first_jd = 2460000.5

JD of the first image of the first night.

autowisp.tests.test_diagnostics_views._frames_per_night = ({'object': 3}, {'flat': 2, 'object': 3})

Frames of each type per night. Only the second night is mixed, which is what lets these tests tell a per-type series from one that lumps a whole session together; leaving the first night single-type keeps the plain one-series-per-night cases readable.

autowisp.tests.test_diagnostics_views._night_separation = 1.0

Nights are one day apart, so their JD ranges cannot overlap.

autowisp.tests.test_diagnostics_views._quantile_names = ('pixel_q99', 'pixel_q999')

Recorded for object frames alone, which is what makes them the case of a diagnostic that is not drawable for every image type.