Skip to content

Latest commit

 

History

History
904 lines (495 loc) · 28.4 KB

TESTS.md

File metadata and controls

904 lines (495 loc) · 28.4 KB

Introduction

Automatic test listing generated by testlister.py at 2023-07-10T12:18:49.902047

Package basic

Basic tests.

Module basic/test_datum.py

Tests on basic datum operations such as serialization

Function basic/test_datum.py/test_datum_can_create_and_serialise_img

This ensures that a Datum can serialise and deserialise an image with uncertainty and DQ as well as nominal pixel data. This relies on Value working.

Module basic/test_eval.py

Parser/Evaluator tests - not PCOT specific, just the shunting yard algorithm and VM. This was written with unittest, but you don't need to write every test suite that way - it's just that this was done first.

This has become rather more PCOT specific recently because of Value(), but these functions don't test uncertainty. That's done elsewhere.

Note that there are a lot of tests for how expr nodes manage sources in test_source_principles.py

Test Class basic/test_eval.py/TestCoreBinops

Test the basics of binary operations WITHOUT uncertainty or DQ. All integer operations to make the tests simple (we're working with float32 values).

Method basic/test_eval.py/TestCoreBinops:test_add

addition test, 6+6

Method basic/test_eval.py/TestCoreBinops:test_div

division test, 16/2

Method basic/test_eval.py/TestCoreBinops:test_mul

multiplication test, 8*4

Method basic/test_eval.py/TestCoreBinops:test_sub

subtraction test, 8+2

Test Class basic/test_eval.py/TestPrecedenceAndBrackets

Test that precedence rules are correct and that brackets work

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_1

10*12+4*3

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_2

10*(12+4)*3

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_3

(2+2)*(3+3)

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_4

10/2+9/3

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_5

10/2-9/3

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_6

10*(9-2)*3

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_7

(10-2)*2

Method basic/test_eval.py/TestPrecedenceAndBrackets:test_8

10-2*2

Test Class basic/test_eval.py/TestUnaryMinus

Tests of the syntax for the unary minus operator (and by extension other unary operators that might be defined)

Method basic/test_eval.py/TestUnaryMinus:test_1

-43

Method basic/test_eval.py/TestUnaryMinus:test_2

-43+10

Method basic/test_eval.py/TestUnaryMinus:test_3

43*-1

Method basic/test_eval.py/TestUnaryMinus:test_4

43+-3

Method basic/test_eval.py/TestUnaryMinus:test_5

-4--3

Method basic/test_eval.py/TestUnaryMinus:test_6

(-4)

Method basic/test_eval.py/TestUnaryMinus:test_7

-(-4)

Method basic/test_eval.py/TestUnaryMinus:test_8

-(2*8)

Method basic/test_eval.py/TestUnaryMinus:test_9

-(2*-8)

Test Class basic/test_eval.py/TestVariables

Test simple variable fetches - these are implemented by wiring two Python global values (variable_1 and variable_2) to the var1 and var2 idents.

Method basic/test_eval.py/TestVariables:test_1

Single variable fetch

Method basic/test_eval.py/TestVariables:test_2

var1-var2

Method basic/test_eval.py/TestVariables:test_3

var1-(var2)

Method basic/test_eval.py/TestVariables:test_4

var1-(var2/2)

Test Class basic/test_eval.py/TestNakedIdents

The parser can be set to push strings onto the stack when unrecognised identifiers are found (so-called "naked idents").

Method basic/test_eval.py/TestNakedIdents:test_1

Check that naked idents work when the flag is set in execute()

Method basic/test_eval.py/TestNakedIdents:test_2

Check an assertion is raised when we try to use naked idents without the flag

Test Class basic/test_eval.py/TestFunctions

Test that function calls work. The functions defined are min and max of lists, sqrt, and a function noargs() that returns 100.

Method basic/test_eval.py/TestFunctions:test_1

sqrt(16)

Method basic/test_eval.py/TestFunctions:test_10

max(0,3,2)+min(7,2,45,3)

Method basic/test_eval.py/TestFunctions:test_11

max(min(100,50,200),1,2,4+7,5+1)

Method basic/test_eval.py/TestFunctions:test_12

max(1,2,4+7,5+1,min(100,50,200))

Method basic/test_eval.py/TestFunctions:test_2

min(45,1,56,12,2)

Method basic/test_eval.py/TestFunctions:test_3

max(45,1,56,12,2)

Method basic/test_eval.py/TestFunctions:test_6

10+noargs()

Method basic/test_eval.py/TestFunctions:test_7

max(1,2,4+7,5+1,2*6)

Method basic/test_eval.py/TestFunctions:test_8

max(1,2,4+7,2*6,5+1)

Method basic/test_eval.py/TestFunctions:test_9

max(1,2,4+7,min(100,50,200),5+1)

Module basic/test_geom.py

Tests on basic geometric entities, such as Rect()

Function basic/test_geom.py/test_rect_ctor

Test that Rect constructor gives the right members

Function basic/test_geom.py/test_rect_intersect1

Intersection of two rectangles, one contained entirely within the other. Done both ways.

Function basic/test_geom.py/test_rect_intersect2

More complex rectangle intersection test

Function basic/test_geom.py/test_rect_intersect3

More complex rectangle intersection test

Function basic/test_geom.py/test_rect_intersect4

More complex rectangle intersection test

Function basic/test_geom.py/test_rect_corners

Test the Rect.corners() method for getting rectangle corners

Module basic/test_imagecube.py

Tests on basic imagecube operations

Function basic/test_imagecube.py/test_load_image

Test that we can load a 32x32 solid white image from a PNG. It just does some very basic checks on the image pixels.

Function basic/test_imagecube.py/test_load_image2

A slightly tougher image - a white rect with colour blobs at the corners. Let's make sure the orientation is good, and that we are converting 8bit into 32bit float correctly. Again, it just loads an image from a PNG.

Function basic/test_imagecube.py/test_split_merge

Checks that we can split a colour RGB image and remerge it. Only tests the pixels, not uncertainty or DQ.

Function basic/test_imagecube.py/test_msimage

Just check that we created this image OK, and that we have some kind of mapping in there.

Function basic/test_imagecube.py/test_wavelength

Create an image with some weird bands in it - bands with combined wavelengths - and check that wavelengthBand() works, correctly getting the single wavelength bands.

Function basic/test_imagecube.py/test_wavelength_widest

Create an image with multiple RGB bands (among others) with the same CWL and make sure that wavelengthBand gets the widest one. This gets used in guessing RGB channels.

Function basic/test_imagecube.py/test_imagecube_indexing

test that we can index into an imagecube to get a pixel value for both mono and multichannel image. We don't check limits here but we do check all coords, but all pixels are the same.

Function basic/test_imagecube.py/test_imagecube_indexing2

test that indexing works on a more complex RGB image with coloured corners, so we know the coordinate indexing is correct. Also double checks Value.approxeq.

Function basic/test_imagecube.py/test_imagecube_indexing_bad

Test indexing on coordinates out of range: -ve indices count from the end, but not too -ve or too +ve

Module basic/test_imageshapes.py

Test that images have the correct numpy array shapes (i.e. a single band image is (h,w) and a multiband image is (h,w,d).

Function basic/test_imageshapes.py/test_2dimage

Test a 2D image is OK

Function basic/test_imageshapes.py/test_degenerate2dimage

Should also be possible to create a 2D image from a 3D image with 1 band

Function basic/test_imageshapes.py/test_3dimage

Test a 3D image is OK

Function basic/test_imageshapes.py/test_badshape

A 4D image is right out

Module basic/test_nodes.py

Basic tests on nodes in a document graph

Function basic/test_nodes.py/test_nodes_run

Just make sure all nodes can perform without inputs. This could be made to pass by just having create() do nothing, or having perform() do nothing, but them's the breaks.

Function basic/test_nodes.py/test_node_output_none

Test every XForm type by creating an empty document with one node of that type, and ensure it produces the correct output from its output 0 (if it has one) when unconnected. Generally this is None - not Datum of type NONE (i.e. Datum.null). There are exceptions, such as constant and spectrum.

Function basic/test_nodes.py/test_create_nonexistent_node_type

Try to create a node we know doesn't exist and assert we get a dummy node back.

Function basic/test_nodes.py/test_node_defined_after_usage

We define a simple node type below - but can we still create it in a document? If we couldn't, we should get a dummy node back from the create

Function basic/test_nodes.py/test_simple_node

Create a simple node, wire it up, and make sure it does the thing it should.

Module basic/test_roi.py

It's quite difficult to test ROIs, but we'll try to at least do rect, circle and poly. Some tests here mainly work by performing a change to part of an image selected by an ROI and checking the results are correct. Does not test DQ or uncertainty!

Function basic/test_roi.py/test_nonintersecting_roi

Check that trying to get the subimage for an ROI which doesn't intersect the image throws an exception

Function basic/test_roi.py/test_nonintersecting_negative_roi

As test_nonintersecting_rois, but the ROI starts at negative coords - this should raise an ROIBoundsException

Function basic/test_roi.py/test_rect_clipped

Test a rect ROI that gets clipped to the bottom-right of the image (i.e. ROI is too big)

Function basic/test_roi.py/test_rect_clipped_topleft

Now an ROI that's been clipped at top-left (i.e. xy -ve)

Function basic/test_roi.py/test_rect_change

Test that a rectangular ROI entirely within a black image, when modified, only changes the right number of pixels

Function basic/test_roi.py/test_rect_change_red_to_cyan

Test that a rectangular ROI entirely within a red image, when modified, only changes the right number of pixels to cyan

Function basic/test_roi.py/test_circle_change_masked

change a circle in black image to red, count red pixels.

Function basic/test_roi.py/test_circle_change_masked_red_to_cyan

change a circle in a red image to cyan, count cyan pixels.

Function basic/test_roi.py/test_multi_roi_change

Two circles within an image - we should change the union of those two circles

Function basic/test_roi.py/test_poly_change_red_to_cyan_nopoints

change a polygon in a red image to cyan, count cyan pixels. No points selected, so entire image changes.

Function basic/test_roi.py/test_poly_change_red_to_cyan

Change a polygon in a red image to cyan - rectangle

Function basic/test_roi.py/test_poly_change_red_to_cyan_triangle

Change a polygon in a red image to cyan - triangle

Function basic/test_roi.py/test_poly_change_red_to_cyan_clipped_right_triangle

Change a polygon in a red image to cyan - triangle

Function basic/test_roi.py/test_poly_change_red_to_cyan_clipped_left_bottom_triangle

Change a polygon in a red image to cyan - triangle

Function basic/test_roi.py/test_painted_change_masked_red_to_cyan

Simple test of painted using a single circle

Function basic/test_roi.py/test_painted_change_masked_red_to_cyan_imagesize_not_set

Simple test of painted using a single circle; won't set an ROI because the image size needs to be set

Module basic/test_sources.py

Test low-level source operations. Higher level operations, such as combining in expr nodes, are tested in test_source_principles.py

Function basic/test_sources.py/test_sourcesetctors

Make sure that the different valid forms of SourceSet constructor arguments work

Function basic/test_sources.py/test_getonlyitem

Make sure that getOnlyItem() fails when we try to get the only Source in a SourceSet with more than one item. And that it actually works, of course.

Function basic/test_sources.py/test_sourcesetdunder

Test that for some purposes, a SourceSet can be interacted with directly as if one were interacting with the underlying set (the sourceSet member). SourceSet implements:

  • iter
  • contains
  • len

Function basic/test_sources.py/test_sourcesetunion

Test that source set unions contain union of all subsidiary sets

Function basic/test_sources.py/test_sourcesetbrief

Source set brief description test

Function basic/test_sources.py/test_sourcesetlong

Source set long description test

Function basic/test_sources.py/test_sourcesetstr

str(sourceset) should be the same as sourceset.brief()

Function basic/test_sources.py/test_sourcesetmatches

" "matches" checks to see if any source in a set matches some criterion; in this case we test that the name matches

Function basic/test_sources.py/test_inputsourcenames

Test that input source brief() and long() are correct

Function basic/test_sources.py/test_multibandsourcenames

Test that multiband source brief() is correct

Function basic/test_sources.py/test_multibandsourcedunder

Test that multibands act as an array of SourceSets

Module basic/test_testframework.py

A test for the testing framework itself, and a PCOT-independent template for other tests.

Function basic/test_testframework.py/test_datadir

Check a file exists in the data directory with the same name as the module but with _data added

Function basic/test_testframework.py/test_datadircontents

Test that we can correctly read a file from the data directory

Function basic/test_testframework.py/test_globaldatadir

Check file exists in the global data directory

Function basic/test_testframework.py/test_globaldatadircontents

Check that a file in the global data directory has the correct contents

Module basic/test_values.py

Test the basics principles of the Value type for values with uncertainty - doesn't test the uncertainty parts themselves, that's done in uncertainty/test_ops.py.

For binary operations, each test function is actually a "minisuite" and takes three arguments. Each of these is a function which generates a value, either a scalar or an array. Two functions generate the operands, the other generates the result. Then the main test functions call each of these four times, with combinations of the different types (scalar and array).

More complex tests are done at the node level in uncertainty/test_ops.py, but if those tests fail and these pass then there is a likely to be a problem in the nodes or expression parser.

Function basic/test_values.py/test_approx

Test the "approximately equal" function for both scalars and arrays

Function basic/test_values.py/test_equality

Test the equality operator

Function basic/test_values.py/test_addition

Test addition - see notes for this module

Function basic/test_values.py/test_subtraction

Test subtraction - see notes for this module

Function basic/test_values.py/test_multiplication

Test multiplication - see notes for this module

Function basic/test_values.py/test_division

Test division - see notes for this module

Function basic/test_values.py/test_power

Test exponentiation - see notes for this module

Function basic/test_values.py/test_minmax

Test min and max - see notes for this module

Function basic/test_values.py/test_propagation

Test DQ propagation - see notes for this module

Function basic/test_values.py/test_negate_invert

Test unary operations

Package calibration

Calibration tests (not done)

Module calibration/test_fit.py

Tests of the basic calibration line-fitting technique

Function calibration/test_fit.py/test_fit

Perform some basic tests - we generate some data around a known slope and intercept, and check we recover that slope and intercept correctly

Package input

Test input methods (probably not RGB, that gets tested as part of imagecube tests).

Module input/test_direct.py

Test the direct input method

Function input/test_direct.py/test_direct

Use the special 'direct' input method to bring an ImageCube directly into the graph.

Module input/test_envi.py

Tests of the ENVI input method

Function input/test_envi.py/test_envi_load

Check we can load an ENVI - check the image values and filter names

Module input/test_multifile.py

Multifile input tests

Function input/test_multifile.py/test_multifile_load_with_default_pattern

Load up a set of images using the default filter pattern, which will give duff sources

Function input/test_multifile.py/test_multifile_load_with_bad_pattern

Load up a set of images using a uncompilable pattern

Function input/test_multifile.py/test_multifile_load_with_good_pattern

Here we set up a custom pattern to work out filter positions from file names, assuming that these are PANCAM filters.

Module input/test_pds4_basic.py

Very basic tests for PDS4 input - more work needs to be done on how PDS4 input will work, particularly for HK data (which could be time series) and we need a corpus of known data.

Function input/test_pds4_basic.py/test_pds4_load

Load some PDS4 data, check the channel count in the result, the LIDs, the filter properties but NOT the image pixels (we need a small test image for that)

Module input/test_rgb.py

RGB input tests

Function input/test_rgb.py/test_rgb_load

Test we can load an RGB file (a PNG)

Package principles

Tests of basic operating principles

Module principles/test_ops.py

Test operations - a lot of operations are covered already by things in test_roi_principles, however, and also uncertainty/test_ops.py!

Function principles/test_ops.py/test_scalar_ops

Basic scalar ops, testing precedence and brackets.

Function principles/test_ops.py/test_image_scalar_ops

Smoke test for a basic image+scalar operation, no ROI

Function principles/test_ops.py/test_image_image_ops

Very basic image ops

Function principles/test_ops.py/test_image_stats

Test functions that take an entire image and produce a scalar

Function principles/test_ops.py/test_scalar_div_zero

Test scalar division by zero

Function principles/test_ops.py/test_image_division_by_scalar_zero

Test of dividing an image by scalar zero. Also checks that 0/0 comes out as undefined and divzero.

Function principles/test_ops.py/test_scalar_divide_by_zero_image

Dividing by zero. We're trying to reciprocate an image where two of the bands are zero, which should lead to errors in those bands.

Function principles/test_ops.py/test_pixel_indexing_rgb

Check that we can index into a multichannel ImageCube

Function principles/test_ops.py/test_greyscale_simple

Check that we can index into a 1-channel ImageCube.

Function principles/test_ops.py/test_greyscale_human

now test that greyscaling with human perception of RGB works.

Function principles/test_ops.py/test_all_expr_inputs

Make sure all expr inputs work.

Function principles/test_ops.py/test_unconnected_input_binop

Test that a null input (Datum of type NONE) into a binop produces an appropriate error. The error will actually be thrown before the binop even runs.

Function principles/test_ops.py/test_null_datum_input_binop

Test that a null input (Datum of type None) into a binop produces an appropriate error

Function principles/test_ops.py/test_null_image_input_binop

Test that a null image input (Datum of type Image) into a binop produces an appropriate error

Module principles/test_roi_principles.py

Tests on basic ROI operations. Note that these mostly work by using the ROI control modification of an image and then testing pixels in the result. Only nominal data is checked, not uncertainty or DQ.

Function principles/test_roi_principles.py/test_roi_single_image

Test that a single 'standard operation' - one which uses modifyWithSub - works correctly on an image with a single ROI. ROIs and modifyWithSub are tested at a lower level in basic/test_roi.py; this tests that the layers above use the right code.

Function principles/test_roi_principles.py/test_roi_intersection

Test using expr to intersect two ROIs

Function principles/test_roi_principles.py/test_roi_union_expr

Test that we can union two ROIs correctly with expr and importroi

Function principles/test_roi_principles.py/test_roi_union

Union two ROIs by applying them in series

Function principles/test_roi_principles.py/test_roi_binop_image_lhs

Test image with ROI on LHS of binary operation where RHS is image with no binop. The left image is entirely red, and has a square ROI in the middle. The right image is entirely green. Adding the two images should result in a red image with a yellow square.

Function principles/test_roi_principles.py/test_roi_binop_image_rhs

Test image with ROI on RHS of binary operation where LHS is image with no binop. The left image is entirely green. The right image is entirely blue and has a square ROI in the middle. Adding the two images should result in a green image with a cyan square.

Function principles/test_roi_principles.py/test_rois_on_both_sides_of_binop

Test that operations on two images (e.g. a+b) don't work when there is an ROI on both sides. This test looks overcomplicated, and that's because it is. Originally the principle was that if we had two unions of ROIs being fed into both sides of a binop, that the operation would only modify the intersection - with the LHS being passed through for the rest. This is OK, but really breaks the principle of least astonishment. If the user has fed two images with ROIs into a binary operation it probably means they've done something wrong. Therefore, we should throw an error.

Function principles/test_roi_principles.py/test_rois_same_on_both_sides

It can happen that the ROIs on both sides of a binop are the same ROI, which is fine. This can happen when two channels of the same image are being manipulated.

Function principles/test_roi_principles.py/test_roi_image_plus_scalar

Test that a imageWithROI+scalar uses the ROI

Function principles/test_roi_principles.py/test_roi_intersection_expr

Test that we can intersect two ROIs correctly with expr and importroi

Function principles/test_roi_principles.py/test_roi_diff_expr

Test that we can difference two ROIs correctly with expr and importroi

Function principles/test_roi_principles.py/test_roi_diff_exp2

Test that we can difference two ROIs correctly with expr and importroi

Function principles/test_roi_principles.py/test_roi_neg_expr

Unary negate is not implemented (yet?)

Module principles/test_source_principles.py

Test the basic principles behind how sources are propagated through the graph

Function principles/test_source_principles.py/test_envi_sources

make sure ENVI sources work as expected

Function principles/test_source_principles.py/test_greyscale_sources

Make sure conversion to greyscale using the grey() function works with regard to sources - this will stand in for certain aspects of the sources principles.

Function principles/test_source_principles.py/test_greyscale_sources_expr

Make sure conversion to greyscale using the grey() function works with regard to sources - this will stand in for certain aspects of the sources principles. As test_greyscale_sources(), but uses an actual expr node.

Function principles/test_source_principles.py/test_extract_sources

Make sure that an expression of the form a$n works as expected with sources, this time using an actual expr node

Function principles/test_source_principles.py/test_binop_2images

Make sure that sources work with two images combined in an expr node.

Function principles/test_source_principles.py/test_binop_number_and_number

Make sure that sources work with two images combined in an expr node, but where both images are converted to numbers (using mean). We should get a single source set made up of all the sources.

Function principles/test_source_principles.py/test_binop_image_and_number

Make sure that sources work with two images combined in an expr node, but where both images are converted to numbers (using mean). We should get a single source set made up of all the sources.

Function principles/test_source_principles.py/test_binop_image_and_number2

Similar to test_binop_image_and_number, but we do it the other way around and use a different binop

Function principles/test_source_principles.py/test_binop_image_and_number_literal

Similar to test_binop_image_and_number, but we do it the other way around and use a different binop AND the number is a literal.

Function principles/test_source_principles.py/test_unop_image

Test that sources are propagated correctly through a unary op

Function principles/test_source_principles.py/test_unop_number_from_image

Turn image into number, perform unop on number. Should produce a single source set of all channels in the image.

Module principles/tests/uncertainty/test_create.py

Test the creation of image with uncertainty and DQ bits

Function principles/tests/uncertainty/test_create.py/test_create_unmatched_unc_shape

Test that imagecube ctor throws when unc data is not the same shape as image

Function principles/tests/uncertainty/test_create.py/test_create_wrong_unc_type

Test that an incorrect type passed as uncertainty is not accepted.

Function principles/tests/uncertainty/test_create.py/test_create_unmatched_dq_shape

Test that imagecube ctor throws when DQ data is not the same shape as image

Function principles/tests/uncertainty/test_create.py/test_create_wrong_dq_type_float

Test that a float array passed as DQ is not accepted in imagecube ctor.

Function principles/tests/uncertainty/test_create.py/test_create_wrong_dq_type_int

Test that a int array passed as DQ is not accepted in imagecube ctor.

Function principles/tests/uncertainty/test_create.py/test_create_wrong_dq_type_scalar

Test that a scalar passed as DQ is not accepted in imagecube ctor

Function principles/tests/uncertainty/test_create.py/test_create_unc_2b_ok

Basic test of creating a 2-band image with uncertainty

Function principles/tests/uncertainty/test_create.py/test_default_dq

Test that creating an image with uncertainty creates zero DQ (assuming no other problems)

Function principles/tests/uncertainty/test_create.py/test_nounc_dq

Test that creating an image with no uncertainty data creates NOUNC dq bits

Module principles/tests/uncertainty/test_ops.py

Test binary and unary operators for uncertainty at the top (graph) level. Some of these tests might seem redundant, because we also do them at the lower (Value) level. But it's good to do some basic tests up here too.

If these tests fail, but those tests in basic/test_values.py pass, the problem is probably in the nodes or expression parser.

There's a very handy calculator with uncertainties at https://uncertaintycalculator.com/

Function principles/tests/uncertainty/test_ops.py/test_make_unc

Test that the scalar+uncertainty generator works

Function principles/tests/uncertainty/test_ops.py/test_number_unops

Test that unary operations in expr nodes on numbers with uncertainty work. In the case of unary negation and inverse, (- and !) the uncertainty is passed through unchanged

Function principles/tests/uncertainty/test_ops.py/test_image_unops

Test that unary operations in expr nodes on images with uncertainty work. Also ensure that the operation only acts on areas covered by an ROI and that DQs are passed through.

Function principles/tests/uncertainty/test_ops.py/test_number_number_binops

Test that binary operations in expr nodes on numbers with uncertainty work.

Function principles/tests/uncertainty/test_ops.py/test_number_image_binops

Test than binops in expr nodes on numbers and images work, with the image on the RHS. We want to ensure that the part outside an ROI - and any "bad" parts of the image (with dq.BAD bits) - are unchanged.

Function principles/tests/uncertainty/test_ops.py/test_image_number_binops

Test than binops in expr nodes on images and numbers work, with the image on the LHS. We want to ensure that the part outside an ROI - and any "bad" parts of the image (with dq.BAD bits) - are unchanged.

Function principles/tests/uncertainty/test_ops.py/test_image_image_binops

Test that binops work on image/image pairs, where the LHS image has an ROI on it.

Function principles/tests/uncertainty/test_ops.py/test_image_image_binops_noroi

test image/image operations without a region of interest.

Function principles/tests/uncertainty/test_ops.py/test_dq_propagation_images

Test that DQ is propagated correctly in the binary operators on images