tests.test_scans API documentation

# tests.test_scans

View Source

      1import os
      2
      3from csi_images.csi_scans import Scan
      4
      5
      6def test_from_yaml():
      7    scan = Scan.load_yaml("tests/data")
      8    # Assert that the scan is valid
      9    assert scan.slide_id != ""
     10    assert scan.exists
     11    assert scan.path != ""
     12    assert scan.start_datetime != ""
     13    assert scan.end_datetime != ""
     14    assert scan.scan_time_s > 0
     15    assert scan.scanner_id != ""
     16    assert scan.tray_pos != ""
     17    assert scan.slide_pos != ""
     18    assert scan.camera != ""
     19    assert scan.objective != ""
     20    assert scan.pixel_size_um > 0
     21    assert scan.tile_width_px > 0
     22    assert scan.tile_height_px > 0
     23    assert scan.tile_x_offset_px >= 0
     24    assert scan.tile_y_offset_px >= 0
     25    assert scan.tile_overlap_proportion >= 0
     26    assert len(scan.channels) > 0
     27    for channel in scan.channels:
     28        assert channel.name != ""
     29        assert channel.exposure_ms > 0
     30        assert channel.intensity > 0
     31        assert channel.gain_applied
     32    assert len(scan.roi) > 0
     33    for roi in scan.roi:
     34        assert roi.origin_x_um != -1
     35        assert roi.origin_y_um != -1
     36        assert roi.width_um > 0
     37        assert roi.height_um > 0
     38        assert roi.tile_rows > 0
     39        assert roi.tile_cols > 0
     40        assert roi.focus_points is not None
     41
     42    # Should be able to read and autopopulate scan.yaml component
     43    assert scan == Scan.load_yaml("tests/data/scan.yaml")
     44
     45    # Write, read, then delete the scan.yaml
     46    scan.save_yaml("tests/data/temp.yaml")
     47    assert scan == Scan.load_yaml("tests/data/temp.yaml")
     48    os.remove("tests/data/temp.yaml")
     49
     50    # If we change the name, it's no longer equal but has the same profile
     51    scan2 = Scan.load_yaml("tests/data")
     52    scan2.slide_id = "DIFFERENT"
     53    assert scan != scan2
     54    assert scan.has_same_profile(scan2)
     55
     56    # If we change the tile size, it no longer has the same profile
     57    scan2 = Scan.load_yaml("tests/data")
     58    scan2.tile_width_px = 1
     59    assert scan != scan2
     60    assert not scan.has_same_profile(scan2)
     61
     62
     63def test_from_txt():
     64    scan = Scan.load_txt("tests/data")
     65    # Assert that the scan is valid
     66    assert scan.slide_id != ""
     67    assert scan.exists
     68    assert scan.path != ""
     69    assert scan.start_datetime != ""
     70    assert scan.end_datetime != ""
     71    assert scan.scan_time_s > 0
     72    assert scan.scanner_id != ""
     73    assert scan.tray_pos != ""
     74    assert scan.slide_pos != ""
     75    # assert scan.camera != ""  # Unclear
     76    assert scan.objective != ""
     77    assert scan.pixel_size_um > 0
     78    assert scan.tile_width_px > 0
     79    assert scan.tile_height_px > 0
     80    assert scan.tile_x_offset_px >= 0
     81    assert scan.tile_y_offset_px >= 0
     82    assert scan.tile_overlap_proportion >= 0
     83    assert len(scan.channels) > 0
     84    for channel in scan.channels:
     85        assert channel.name != ""
     86        assert channel.exposure_ms > 0
     87        assert channel.intensity > 0
     88        # assert channel.gain_applied  # Not necessarily clear
     89    assert len(scan.roi) > 0
     90    for roi in scan.roi:
     91        assert roi.origin_x_um != -1
     92        assert roi.origin_y_um != -1
     93        assert roi.width_um > 0
     94        assert roi.height_um > 0
     95        assert roi.tile_rows > 0
     96        assert roi.tile_cols > 0
     97        assert roi.focus_points is not None
     98
     99    # Should be able to read and autopopulate scan.txt component
    100    assert scan == Scan.load_txt("tests/data/slideinfo.txt")
    101
    102
    103def test_dict():
    104    scan = Scan.load_txt("tests/data")
    105    # Should be the same back and forth from dictionary
    106    assert scan == Scan.from_dict(scan.to_dict())
    107
    108
    109def test_names_and_indices():
    110    # Should be able to get the correct indices for the channels
    111    scan = Scan.load_txt("tests/data")
    112    correct_channel_order = ["DAPI", "TRITC", "CY5", "BF", "FITC"]
    113    assert scan.get_channel_indices(correct_channel_order) == [0, 1, 2, 3, 4]
    114
    115    # Should return -1 for None
    116    assert scan.get_channel_indices([None]) == [-1]
    117
    118    # Should raise an error if the channel is not found
    119    try:
    120        scan.get_channel_indices(["DAPI", "TRITC", "CY5", "FITC", "INVALID"])
    121        assert False
    122    except ValueError:
    123        assert True
    124
    125
    126def test_image_size():
    127    scan = Scan.load_yaml("tests/data")
    128    assert scan.get_image_size() == (2020, 2020)

def test_from_yaml(): View Source

     7def test_from_yaml():
     8    scan = Scan.load_yaml("tests/data")
     9    # Assert that the scan is valid
    10    assert scan.slide_id != ""
    11    assert scan.exists
    12    assert scan.path != ""
    13    assert scan.start_datetime != ""
    14    assert scan.end_datetime != ""
    15    assert scan.scan_time_s > 0
    16    assert scan.scanner_id != ""
    17    assert scan.tray_pos != ""
    18    assert scan.slide_pos != ""
    19    assert scan.camera != ""
    20    assert scan.objective != ""
    21    assert scan.pixel_size_um > 0
    22    assert scan.tile_width_px > 0
    23    assert scan.tile_height_px > 0
    24    assert scan.tile_x_offset_px >= 0
    25    assert scan.tile_y_offset_px >= 0
    26    assert scan.tile_overlap_proportion >= 0
    27    assert len(scan.channels) > 0
    28    for channel in scan.channels:
    29        assert channel.name != ""
    30        assert channel.exposure_ms > 0
    31        assert channel.intensity > 0
    32        assert channel.gain_applied
    33    assert len(scan.roi) > 0
    34    for roi in scan.roi:
    35        assert roi.origin_x_um != -1
    36        assert roi.origin_y_um != -1
    37        assert roi.width_um > 0
    38        assert roi.height_um > 0
    39        assert roi.tile_rows > 0
    40        assert roi.tile_cols > 0
    41        assert roi.focus_points is not None
    42
    43    # Should be able to read and autopopulate scan.yaml component
    44    assert scan == Scan.load_yaml("tests/data/scan.yaml")
    45
    46    # Write, read, then delete the scan.yaml
    47    scan.save_yaml("tests/data/temp.yaml")
    48    assert scan == Scan.load_yaml("tests/data/temp.yaml")
    49    os.remove("tests/data/temp.yaml")
    50
    51    # If we change the name, it's no longer equal but has the same profile
    52    scan2 = Scan.load_yaml("tests/data")
    53    scan2.slide_id = "DIFFERENT"
    54    assert scan != scan2
    55    assert scan.has_same_profile(scan2)
    56
    57    # If we change the tile size, it no longer has the same profile
    58    scan2 = Scan.load_yaml("tests/data")
    59    scan2.tile_width_px = 1
    60    assert scan != scan2
    61    assert not scan.has_same_profile(scan2)

def test_from_txt(): View Source

     64def test_from_txt():
     65    scan = Scan.load_txt("tests/data")
     66    # Assert that the scan is valid
     67    assert scan.slide_id != ""
     68    assert scan.exists
     69    assert scan.path != ""
     70    assert scan.start_datetime != ""
     71    assert scan.end_datetime != ""
     72    assert scan.scan_time_s > 0
     73    assert scan.scanner_id != ""
     74    assert scan.tray_pos != ""
     75    assert scan.slide_pos != ""
     76    # assert scan.camera != ""  # Unclear
     77    assert scan.objective != ""
     78    assert scan.pixel_size_um > 0
     79    assert scan.tile_width_px > 0
     80    assert scan.tile_height_px > 0
     81    assert scan.tile_x_offset_px >= 0
     82    assert scan.tile_y_offset_px >= 0
     83    assert scan.tile_overlap_proportion >= 0
     84    assert len(scan.channels) > 0
     85    for channel in scan.channels:
     86        assert channel.name != ""
     87        assert channel.exposure_ms > 0
     88        assert channel.intensity > 0
     89        # assert channel.gain_applied  # Not necessarily clear
     90    assert len(scan.roi) > 0
     91    for roi in scan.roi:
     92        assert roi.origin_x_um != -1
     93        assert roi.origin_y_um != -1
     94        assert roi.width_um > 0
     95        assert roi.height_um > 0
     96        assert roi.tile_rows > 0
     97        assert roi.tile_cols > 0
     98        assert roi.focus_points is not None
     99
    100    # Should be able to read and autopopulate scan.txt component
    101    assert scan == Scan.load_txt("tests/data/slideinfo.txt")

def test_dict(): View Source

    104def test_dict():
    105    scan = Scan.load_txt("tests/data")
    106    # Should be the same back and forth from dictionary
    107    assert scan == Scan.from_dict(scan.to_dict())

def test_names_and_indices(): View Source

    110def test_names_and_indices():
    111    # Should be able to get the correct indices for the channels
    112    scan = Scan.load_txt("tests/data")
    113    correct_channel_order = ["DAPI", "TRITC", "CY5", "BF", "FITC"]
    114    assert scan.get_channel_indices(correct_channel_order) == [0, 1, 2, 3, 4]
    115
    116    # Should return -1 for None
    117    assert scan.get_channel_indices([None]) == [-1]
    118
    119    # Should raise an error if the channel is not found
    120    try:
    121        scan.get_channel_indices(["DAPI", "TRITC", "CY5", "FITC", "INVALID"])
    122        assert False
    123    except ValueError:
    124        assert True

def test_image_size(): View Source

    127def test_image_size():
    128    scan = Scan.load_yaml("tests/data")
    129    assert scan.get_image_size() == (2020, 2020)