tests.test_events
1import os 2import time 3 4import cv2 5import numpy as np 6import pandas as pd 7 8from csi_images.csi_scans import Scan 9from csi_images.csi_tiles import Tile 10from csi_images.csi_events import Event, EventArray 11from csi_images import csi_images 12 13if os.environ.get("DEBIAN_FRONTEND") == "noninteractive": 14 SHOW_PLOTS = False 15else: 16 # Change this to your preference for local testing, but commit as True 17 SHOW_PLOTS = True 18 19 20def test_getting_event(): 21 scan = Scan.load_txt("tests/data") 22 tile = Tile(scan, 0) 23 event = Event( 24 scan, 25 tile, 26 516, 27 278, 28 ) 29 # Test getting images 30 images = event.extract_images() 31 assert len(images) == 4 32 images = event.extract_images(crop_size=100) 33 assert images[0].shape == (100, 100) 34 images = event.extract_images(crop_size=50) 35 assert images[0].shape == (50, 50) 36 37 if SHOW_PLOTS: 38 for image in images: 39 cv2.imshow("Bright DAPI event in the center", image) 40 cv2.waitKey(0) 41 cv2.destroyAllWindows() 42 43 # Test a corner event 44 event = Event( 45 scan, 46 tile, 47 1346, 48 9, 49 ) 50 images = event.extract_images() 51 assert len(images) == 4 52 images = event.extract_images(crop_size=100) 53 assert images[0].shape == (100, 100) 54 images = event.extract_images(crop_size=200) 55 assert images[0].shape == (200, 200) 56 57 if SHOW_PLOTS: 58 for image in images: 59 cv2.imshow("Events in the top-right corner of a tile", image) 60 cv2.waitKey(0) 61 cv2.destroyAllWindows() 62 63 64def test_getting_many_events(): 65 scan = Scan.load_txt("tests/data") 66 tile = Tile(scan, 1000) 67 tile2 = Tile(scan, 0) 68 events = [ 69 Event(scan, tile, 515, 411), 70 Event(scan, tile2, 2, 1000), 71 Event(scan, tile, 1000, 1000), 72 Event(scan, tile, 87, 126), 73 Event(scan, tile, 1000, 2), 74 Event(scan, tile2, 800, 800), 75 Event(scan, tile, 1000, 662), 76 ] 77 # Test time to extract images sequentially 78 start_time = time.time() 79 images_1 = [] 80 for event in events: 81 images_1.append(event.extract_images()) 82 sequential_time = time.time() - start_time 83 84 # Test time to extract images in parallel 85 start_time = time.time() 86 images_2 = Event.extract_images_for_list(events, crop_size=100) 87 parallel_time = time.time() - start_time 88 assert parallel_time < sequential_time 89 for list_a, list_b in zip(images_1, images_2): 90 assert len(list_a) == len(list_b) 91 for image_a, image_b in zip(list_a, list_b): 92 assert np.array_equal(image_a, image_b) 93 94 # Test that it works after converting to EventArray and back 95 event_array = EventArray.from_events(events) 96 remade_events = event_array.to_events( 97 [scan], ignore_metadata=True, ignore_features=True 98 ) 99 images_3 = Event.extract_images_for_list(remade_events, crop_size=100) 100 for list_a, list_b in zip(images_1, images_3): 101 assert len(list_a) == len(list_b) 102 for image_a, image_b in zip(list_a, list_b): 103 assert np.array_equal(image_a, image_b) 104 105 106def test_event_coordinates_for_bzscanner(): 107 scan = Scan.load_txt("tests/data") 108 # Origin 109 tile = Tile(scan, 0) 110 event = Event(scan, tile, 0, 0) 111 scan_origin = event.get_scan_position() 112 assert 2500 <= scan_origin[0] <= 3500 113 assert 2500 <= scan_origin[1] <= 3500 114 scan_origin_on_slide = event.get_slide_position() 115 assert 71500 <= scan_origin_on_slide[0] <= 72500 116 assert 21500 <= scan_origin_on_slide[1] <= 22500 117 # Within the same tile, "bottom-right corner" 118 event = Event(scan, tile, 1000, 1000) 119 scan_position = event.get_scan_position() 120 assert scan_origin[0] <= scan_position[0] 121 assert scan_origin[1] <= scan_position[1] 122 slide_position = event.get_slide_position() 123 assert slide_position[0] <= scan_origin_on_slide[0] 124 assert slide_position[1] <= scan_origin_on_slide[1] 125 126 # Next row, opposite side 127 tile = Tile(scan, (scan.roi[0].tile_cols - 1, 1)) 128 event = Event(scan, tile, 1000, 1000) 129 scan_position = event.get_scan_position() 130 assert scan_origin[0] <= scan_position[0] 131 assert scan_origin[1] <= scan_position[1] 132 slide_position = event.get_slide_position() 133 assert slide_position[0] <= scan_origin_on_slide[0] 134 assert slide_position[1] <= scan_origin_on_slide[1] 135 136 # Opposite corner 137 tile = Tile(scan, (scan.roi[0].tile_cols - 1, scan.roi[0].tile_rows - 1)) 138 event = Event(scan, tile, 1361, 1003) 139 scan_position = event.get_scan_position() 140 assert 21500 <= scan_position[0] <= 22500 141 assert 58500 <= scan_position[1] <= 60500 142 slide_position = event.get_slide_position() 143 assert 14500 <= slide_position[0] <= 15500 144 assert 2500 <= slide_position[1] <= 3500 145 146 147def test_event_coordinates_for_axioscan(): 148 scan = Scan.load_yaml("tests/data") 149 # Origin 150 tile = Tile(scan, 0) 151 event = Event(scan, tile, 0, 0) 152 scan_position = event.get_scan_position() 153 assert -59000 <= scan_position[0] < -55000 154 assert 0 <= scan_position[1] < 4000 155 slide_position = event.get_slide_position() 156 assert 16000 <= slide_position[0] < 20000 157 assert scan_position[1] == slide_position[1] 158 159 # Opposite corner 160 tile = Tile(scan, (scan.roi[0].tile_cols - 1, scan.roi[0].tile_rows - 1)) 161 event = Event(scan, tile, 2000, 2000) 162 scan_position = event.get_scan_position() 163 assert -4000 <= scan_position[0] <= 0 164 assert 21000 <= scan_position[1] <= 25000 165 slide_position = event.get_slide_position() 166 assert 71000 <= slide_position[0] <= 75000 167 assert scan_position[1] == slide_position[1] 168 169 170def test_eventarray_conversions(): 171 scan = Scan.load_yaml("tests/data") 172 # Origin 173 tile = Tile(scan, 0) 174 event0 = Event(scan, tile, 0, 0) 175 event1 = Event(scan, tile, 1000, 1000) 176 event2 = Event(scan, tile, 2000, 2000) 177 178 event_array = EventArray.from_events([event0, event1, event2]) 179 180 assert len(event_array) == 3 181 assert event_array.metadata is None 182 assert event_array.features is None 183 184 event0.metadata = pd.Series({"event0": 0}) 185 186 try: 187 event_array = EventArray.from_events([event0, event1, event2]) 188 # Should throw error 189 assert False 190 except ValueError: 191 pass 192 193 event1.metadata = pd.Series({"event0": 1}) 194 event2.metadata = pd.Series({"event0": 2}) 195 196 event_array = EventArray.from_events([event0, event1, event2]) 197 198 assert len(event_array) == 3 199 200 events_df = event_array.to_dataframe() 201 202 assert len(events_df) == 3 203 204 assert event_array == EventArray.from_dataframe(events_df) 205 206 # Test adding different dtypes and converting back and forth 207 event_array.features = pd.DataFrame( 208 {"feature1": [1, 2, 3], "feature2": [4.0, 5.0, 6.0]} 209 ) 210 remade_event_list = event_array.to_events([scan]) 211 assert len(remade_event_list) == 3 212 remade_event_array = EventArray.from_events(remade_event_list) 213 assert event_array == remade_event_array 214 # Test saving and loading 215 assert event_array.save_csv("tests/data/events.csv") 216 assert event_array == EventArray.load_csv("tests/data/events.csv") 217 os.remove("tests/data/events.csv") 218 219 assert event_array.save_hdf5("tests/data/events.h5") 220 assert event_array == EventArray.load_hdf5("tests/data/events.h5") 221 os.remove("tests/data/events.h5") 222 223 224def test_ocular_conversions(): 225 scan = Scan.load_txt("tests/data") 226 input_path = "/mnt/HDSCA_Development/DZ/0B58703/ocular" 227 result = EventArray.load_ocular(input_path) 228 # For the purposes of this test, we will manually relabel "clust" == nan to 0 229 # These come from ocular_interesting.rds, which does not have clusters 230 result.metadata["clust"] = result.metadata["clust"].fillna(0) 231 result.metadata["hcpc"] = result.metadata["hcpc"].fillna(0) 232 result.save_ocular("tests/data") 233 new_result = EventArray.load_ocular("tests/data") 234 # # Sort them so that they are in the same order 235 result = result.sort(["tile", "x", "y"]) 236 new_result = new_result.sort(["tile", "x", "y"]) 237 # Note: hcpc method within ocularr and here are different 238 result.metadata["hcpc"] = new_result.metadata["hcpc"].copy() 239 assert result == new_result 240 # Clean up 241 os.remove("tests/data/rc-final.csv") 242 os.remove("tests/data/rc-final.rds") 243 os.remove("tests/data/rc-final1.rds") 244 os.remove("tests/data/rc-final2.rds") 245 os.remove("tests/data/rc-final3.rds") 246 os.remove("tests/data/rc-final4.rds") 247 248 # Try it with "others" files 249 result = EventArray.load_ocular(input_path, event_type="others") 250 result.save_ocular("tests/data", event_type="others") 251 new_result = EventArray.load_ocular("tests/data", event_type="others") 252 result = result.sort(["tile", "x", "y"]) 253 new_result = new_result.sort(["tile", "x", "y"]) 254 # Note: hcpc method within ocularr and here are different 255 result.metadata["hcpc"] = new_result.metadata["hcpc"].copy() 256 assert result == new_result 257 # Clean up 258 os.remove("tests/data/others-final.csv") 259 os.remove("tests/data/others-final.rds") 260 os.remove("tests/data/others-final1.rds") 261 os.remove("tests/data/others-final2.rds") 262 os.remove("tests/data/others-final3.rds") 263 os.remove("tests/data/others-final4.rds") 264 265 266def test_copy_sort_rows_get(): 267 scan = Scan.load_yaml("tests/data") 268 # Origin 269 tile = Tile(scan, 0) 270 events = [ 271 Event(scan, tile, 0, 100), 272 Event(scan, tile, 0, 0), 273 Event(scan, tile, 1000, 1000), 274 Event(scan, tile, 1000, 1), 275 Event(scan, tile, 2000, 2000), 276 ] 277 278 events = EventArray.from_events(events) 279 280 # Copy 281 events_copy = events.copy() 282 events_copy.info["x"] = np.uint16(1) 283 # Check that changes to the copy did not change the original 284 assert events_copy.info["x"].equals(pd.Series([1, 1, 1, 1, 1], dtype=np.uint16)) 285 assert events.info["x"].equals(pd.Series([0, 0, 1000, 1000, 2000], dtype=np.uint16)) 286 287 # Sort 288 events = events.sort(["x", "y"], ascending=[False, True]) 289 assert events.info["x"].equals(pd.Series([2000, 1000, 1000, 0, 0], dtype=np.uint16)) 290 assert events.info["y"].equals(pd.Series([2000, 1, 1000, 0, 100], dtype=np.uint16)) 291 292 # Get 293 events_get = events.get(["x", "y"]) 294 assert events_get["x"].equals(pd.Series([2000, 1000, 1000, 0, 0], dtype=np.uint16)) 295 assert events_get["y"].equals(pd.Series([2000, 1, 1000, 0, 100], dtype=np.uint16)) 296 assert events_get.columns.equals(pd.Index(["x", "y"])) 297 298 # Rows 299 events_get = events.rows([0, 1, 3]) 300 assert len(events_get) == 3 301 assert events_get.info["x"].equals(pd.Series([2000, 1000, 0], dtype=np.uint16)) 302 assert events_get.info["y"].equals(pd.Series([2000, 1, 0], dtype=np.uint16)) 303 events_get = events.rows([True, False, False, True, True]) 304 assert len(events_get) == 3 305 assert events_get.info["x"].equals(pd.Series([2000, 0, 0], dtype=np.uint16)) 306 assert events_get.info["y"].equals(pd.Series([2000, 0, 100], dtype=np.uint16)) 307 308 309def test_event_montages(): 310 scan = Scan.load_txt("tests/data") 311 tile = Tile(scan, 1000) 312 event = Event(scan, tile, 515, 411) 313 images = event.extract_images(crop_size=100) 314 315 # Test different montages 316 montage = csi_images.make_montage(images, [0, 1, 2, 3]) 317 montage_shape = csi_images.get_montage_shape(images[0].shape, 4) 318 assert montage.shape == montage_shape 319 320 if SHOW_PLOTS: 321 cv2.imshow("Horizontal montage with all channels", montage) 322 cv2.waitKey(0) 323 cv2.destroyAllWindows() 324 325 montage = csi_images.make_montage(images, [0, 2]) 326 if SHOW_PLOTS: 327 cv2.imshow("Horizontal montage with DAPI, CD45", montage) 328 cv2.waitKey(0) 329 cv2.destroyAllWindows() 330 331 montage = csi_images.make_montage(images, [0, 2], horizontal=False) 332 if SHOW_PLOTS: 333 cv2.imshow("Vertical montage with DAPI, CD45", montage) 334 cv2.waitKey(0) 335 cv2.destroyAllWindows() 336 337 montage = csi_images.make_montage( 338 images, 339 [0, 2], 340 {0: (0, 0, 1), 2: (0, 1, 0)}, 341 ) 342 if SHOW_PLOTS: 343 cv2.imshow( 344 "Horizontal montage with DAPI+CD45, DAPI, CD45", 345 cv2.cvtColor(montage, cv2.COLOR_RGB2BGR), 346 ) 347 cv2.waitKey(0) 348 cv2.destroyAllWindows() 349 350 montage = csi_images.make_montage( 351 images, 352 [0, 1, 2, 3], 353 {0: (0, 0, 1), 1: (1, 0, 0), 2: (0, 1, 0), 3: (1, 1, 1)}, 354 ) 355 if SHOW_PLOTS: 356 cv2.imshow( 357 "Full, classic montage", 358 cv2.cvtColor(montage, cv2.COLOR_RGB2BGR), 359 ) 360 cv2.waitKey(0) 361 cv2.destroyAllWindows()
def
test_getting_event():
21def test_getting_event(): 22 scan = Scan.load_txt("tests/data") 23 tile = Tile(scan, 0) 24 event = Event( 25 scan, 26 tile, 27 516, 28 278, 29 ) 30 # Test getting images 31 images = event.extract_images() 32 assert len(images) == 4 33 images = event.extract_images(crop_size=100) 34 assert images[0].shape == (100, 100) 35 images = event.extract_images(crop_size=50) 36 assert images[0].shape == (50, 50) 37 38 if SHOW_PLOTS: 39 for image in images: 40 cv2.imshow("Bright DAPI event in the center", image) 41 cv2.waitKey(0) 42 cv2.destroyAllWindows() 43 44 # Test a corner event 45 event = Event( 46 scan, 47 tile, 48 1346, 49 9, 50 ) 51 images = event.extract_images() 52 assert len(images) == 4 53 images = event.extract_images(crop_size=100) 54 assert images[0].shape == (100, 100) 55 images = event.extract_images(crop_size=200) 56 assert images[0].shape == (200, 200) 57 58 if SHOW_PLOTS: 59 for image in images: 60 cv2.imshow("Events in the top-right corner of a tile", image) 61 cv2.waitKey(0) 62 cv2.destroyAllWindows()
def
test_getting_many_events():
65def test_getting_many_events(): 66 scan = Scan.load_txt("tests/data") 67 tile = Tile(scan, 1000) 68 tile2 = Tile(scan, 0) 69 events = [ 70 Event(scan, tile, 515, 411), 71 Event(scan, tile2, 2, 1000), 72 Event(scan, tile, 1000, 1000), 73 Event(scan, tile, 87, 126), 74 Event(scan, tile, 1000, 2), 75 Event(scan, tile2, 800, 800), 76 Event(scan, tile, 1000, 662), 77 ] 78 # Test time to extract images sequentially 79 start_time = time.time() 80 images_1 = [] 81 for event in events: 82 images_1.append(event.extract_images()) 83 sequential_time = time.time() - start_time 84 85 # Test time to extract images in parallel 86 start_time = time.time() 87 images_2 = Event.extract_images_for_list(events, crop_size=100) 88 parallel_time = time.time() - start_time 89 assert parallel_time < sequential_time 90 for list_a, list_b in zip(images_1, images_2): 91 assert len(list_a) == len(list_b) 92 for image_a, image_b in zip(list_a, list_b): 93 assert np.array_equal(image_a, image_b) 94 95 # Test that it works after converting to EventArray and back 96 event_array = EventArray.from_events(events) 97 remade_events = event_array.to_events( 98 [scan], ignore_metadata=True, ignore_features=True 99 ) 100 images_3 = Event.extract_images_for_list(remade_events, crop_size=100) 101 for list_a, list_b in zip(images_1, images_3): 102 assert len(list_a) == len(list_b) 103 for image_a, image_b in zip(list_a, list_b): 104 assert np.array_equal(image_a, image_b)
def
test_event_coordinates_for_bzscanner():
107def test_event_coordinates_for_bzscanner(): 108 scan = Scan.load_txt("tests/data") 109 # Origin 110 tile = Tile(scan, 0) 111 event = Event(scan, tile, 0, 0) 112 scan_origin = event.get_scan_position() 113 assert 2500 <= scan_origin[0] <= 3500 114 assert 2500 <= scan_origin[1] <= 3500 115 scan_origin_on_slide = event.get_slide_position() 116 assert 71500 <= scan_origin_on_slide[0] <= 72500 117 assert 21500 <= scan_origin_on_slide[1] <= 22500 118 # Within the same tile, "bottom-right corner" 119 event = Event(scan, tile, 1000, 1000) 120 scan_position = event.get_scan_position() 121 assert scan_origin[0] <= scan_position[0] 122 assert scan_origin[1] <= scan_position[1] 123 slide_position = event.get_slide_position() 124 assert slide_position[0] <= scan_origin_on_slide[0] 125 assert slide_position[1] <= scan_origin_on_slide[1] 126 127 # Next row, opposite side 128 tile = Tile(scan, (scan.roi[0].tile_cols - 1, 1)) 129 event = Event(scan, tile, 1000, 1000) 130 scan_position = event.get_scan_position() 131 assert scan_origin[0] <= scan_position[0] 132 assert scan_origin[1] <= scan_position[1] 133 slide_position = event.get_slide_position() 134 assert slide_position[0] <= scan_origin_on_slide[0] 135 assert slide_position[1] <= scan_origin_on_slide[1] 136 137 # Opposite corner 138 tile = Tile(scan, (scan.roi[0].tile_cols - 1, scan.roi[0].tile_rows - 1)) 139 event = Event(scan, tile, 1361, 1003) 140 scan_position = event.get_scan_position() 141 assert 21500 <= scan_position[0] <= 22500 142 assert 58500 <= scan_position[1] <= 60500 143 slide_position = event.get_slide_position() 144 assert 14500 <= slide_position[0] <= 15500 145 assert 2500 <= slide_position[1] <= 3500
def
test_event_coordinates_for_axioscan():
148def test_event_coordinates_for_axioscan(): 149 scan = Scan.load_yaml("tests/data") 150 # Origin 151 tile = Tile(scan, 0) 152 event = Event(scan, tile, 0, 0) 153 scan_position = event.get_scan_position() 154 assert -59000 <= scan_position[0] < -55000 155 assert 0 <= scan_position[1] < 4000 156 slide_position = event.get_slide_position() 157 assert 16000 <= slide_position[0] < 20000 158 assert scan_position[1] == slide_position[1] 159 160 # Opposite corner 161 tile = Tile(scan, (scan.roi[0].tile_cols - 1, scan.roi[0].tile_rows - 1)) 162 event = Event(scan, tile, 2000, 2000) 163 scan_position = event.get_scan_position() 164 assert -4000 <= scan_position[0] <= 0 165 assert 21000 <= scan_position[1] <= 25000 166 slide_position = event.get_slide_position() 167 assert 71000 <= slide_position[0] <= 75000 168 assert scan_position[1] == slide_position[1]
def
test_eventarray_conversions():
171def test_eventarray_conversions(): 172 scan = Scan.load_yaml("tests/data") 173 # Origin 174 tile = Tile(scan, 0) 175 event0 = Event(scan, tile, 0, 0) 176 event1 = Event(scan, tile, 1000, 1000) 177 event2 = Event(scan, tile, 2000, 2000) 178 179 event_array = EventArray.from_events([event0, event1, event2]) 180 181 assert len(event_array) == 3 182 assert event_array.metadata is None 183 assert event_array.features is None 184 185 event0.metadata = pd.Series({"event0": 0}) 186 187 try: 188 event_array = EventArray.from_events([event0, event1, event2]) 189 # Should throw error 190 assert False 191 except ValueError: 192 pass 193 194 event1.metadata = pd.Series({"event0": 1}) 195 event2.metadata = pd.Series({"event0": 2}) 196 197 event_array = EventArray.from_events([event0, event1, event2]) 198 199 assert len(event_array) == 3 200 201 events_df = event_array.to_dataframe() 202 203 assert len(events_df) == 3 204 205 assert event_array == EventArray.from_dataframe(events_df) 206 207 # Test adding different dtypes and converting back and forth 208 event_array.features = pd.DataFrame( 209 {"feature1": [1, 2, 3], "feature2": [4.0, 5.0, 6.0]} 210 ) 211 remade_event_list = event_array.to_events([scan]) 212 assert len(remade_event_list) == 3 213 remade_event_array = EventArray.from_events(remade_event_list) 214 assert event_array == remade_event_array 215 # Test saving and loading 216 assert event_array.save_csv("tests/data/events.csv") 217 assert event_array == EventArray.load_csv("tests/data/events.csv") 218 os.remove("tests/data/events.csv") 219 220 assert event_array.save_hdf5("tests/data/events.h5") 221 assert event_array == EventArray.load_hdf5("tests/data/events.h5") 222 os.remove("tests/data/events.h5")
def
test_ocular_conversions():
225def test_ocular_conversions(): 226 scan = Scan.load_txt("tests/data") 227 input_path = "/mnt/HDSCA_Development/DZ/0B58703/ocular" 228 result = EventArray.load_ocular(input_path) 229 # For the purposes of this test, we will manually relabel "clust" == nan to 0 230 # These come from ocular_interesting.rds, which does not have clusters 231 result.metadata["clust"] = result.metadata["clust"].fillna(0) 232 result.metadata["hcpc"] = result.metadata["hcpc"].fillna(0) 233 result.save_ocular("tests/data") 234 new_result = EventArray.load_ocular("tests/data") 235 # # Sort them so that they are in the same order 236 result = result.sort(["tile", "x", "y"]) 237 new_result = new_result.sort(["tile", "x", "y"]) 238 # Note: hcpc method within ocularr and here are different 239 result.metadata["hcpc"] = new_result.metadata["hcpc"].copy() 240 assert result == new_result 241 # Clean up 242 os.remove("tests/data/rc-final.csv") 243 os.remove("tests/data/rc-final.rds") 244 os.remove("tests/data/rc-final1.rds") 245 os.remove("tests/data/rc-final2.rds") 246 os.remove("tests/data/rc-final3.rds") 247 os.remove("tests/data/rc-final4.rds") 248 249 # Try it with "others" files 250 result = EventArray.load_ocular(input_path, event_type="others") 251 result.save_ocular("tests/data", event_type="others") 252 new_result = EventArray.load_ocular("tests/data", event_type="others") 253 result = result.sort(["tile", "x", "y"]) 254 new_result = new_result.sort(["tile", "x", "y"]) 255 # Note: hcpc method within ocularr and here are different 256 result.metadata["hcpc"] = new_result.metadata["hcpc"].copy() 257 assert result == new_result 258 # Clean up 259 os.remove("tests/data/others-final.csv") 260 os.remove("tests/data/others-final.rds") 261 os.remove("tests/data/others-final1.rds") 262 os.remove("tests/data/others-final2.rds") 263 os.remove("tests/data/others-final3.rds") 264 os.remove("tests/data/others-final4.rds")
def
test_copy_sort_rows_get():
267def test_copy_sort_rows_get(): 268 scan = Scan.load_yaml("tests/data") 269 # Origin 270 tile = Tile(scan, 0) 271 events = [ 272 Event(scan, tile, 0, 100), 273 Event(scan, tile, 0, 0), 274 Event(scan, tile, 1000, 1000), 275 Event(scan, tile, 1000, 1), 276 Event(scan, tile, 2000, 2000), 277 ] 278 279 events = EventArray.from_events(events) 280 281 # Copy 282 events_copy = events.copy() 283 events_copy.info["x"] = np.uint16(1) 284 # Check that changes to the copy did not change the original 285 assert events_copy.info["x"].equals(pd.Series([1, 1, 1, 1, 1], dtype=np.uint16)) 286 assert events.info["x"].equals(pd.Series([0, 0, 1000, 1000, 2000], dtype=np.uint16)) 287 288 # Sort 289 events = events.sort(["x", "y"], ascending=[False, True]) 290 assert events.info["x"].equals(pd.Series([2000, 1000, 1000, 0, 0], dtype=np.uint16)) 291 assert events.info["y"].equals(pd.Series([2000, 1, 1000, 0, 100], dtype=np.uint16)) 292 293 # Get 294 events_get = events.get(["x", "y"]) 295 assert events_get["x"].equals(pd.Series([2000, 1000, 1000, 0, 0], dtype=np.uint16)) 296 assert events_get["y"].equals(pd.Series([2000, 1, 1000, 0, 100], dtype=np.uint16)) 297 assert events_get.columns.equals(pd.Index(["x", "y"])) 298 299 # Rows 300 events_get = events.rows([0, 1, 3]) 301 assert len(events_get) == 3 302 assert events_get.info["x"].equals(pd.Series([2000, 1000, 0], dtype=np.uint16)) 303 assert events_get.info["y"].equals(pd.Series([2000, 1, 0], dtype=np.uint16)) 304 events_get = events.rows([True, False, False, True, True]) 305 assert len(events_get) == 3 306 assert events_get.info["x"].equals(pd.Series([2000, 0, 0], dtype=np.uint16)) 307 assert events_get.info["y"].equals(pd.Series([2000, 0, 100], dtype=np.uint16))
def
test_event_montages():
310def test_event_montages(): 311 scan = Scan.load_txt("tests/data") 312 tile = Tile(scan, 1000) 313 event = Event(scan, tile, 515, 411) 314 images = event.extract_images(crop_size=100) 315 316 # Test different montages 317 montage = csi_images.make_montage(images, [0, 1, 2, 3]) 318 montage_shape = csi_images.get_montage_shape(images[0].shape, 4) 319 assert montage.shape == montage_shape 320 321 if SHOW_PLOTS: 322 cv2.imshow("Horizontal montage with all channels", montage) 323 cv2.waitKey(0) 324 cv2.destroyAllWindows() 325 326 montage = csi_images.make_montage(images, [0, 2]) 327 if SHOW_PLOTS: 328 cv2.imshow("Horizontal montage with DAPI, CD45", montage) 329 cv2.waitKey(0) 330 cv2.destroyAllWindows() 331 332 montage = csi_images.make_montage(images, [0, 2], horizontal=False) 333 if SHOW_PLOTS: 334 cv2.imshow("Vertical montage with DAPI, CD45", montage) 335 cv2.waitKey(0) 336 cv2.destroyAllWindows() 337 338 montage = csi_images.make_montage( 339 images, 340 [0, 2], 341 {0: (0, 0, 1), 2: (0, 1, 0)}, 342 ) 343 if SHOW_PLOTS: 344 cv2.imshow( 345 "Horizontal montage with DAPI+CD45, DAPI, CD45", 346 cv2.cvtColor(montage, cv2.COLOR_RGB2BGR), 347 ) 348 cv2.waitKey(0) 349 cv2.destroyAllWindows() 350 351 montage = csi_images.make_montage( 352 images, 353 [0, 1, 2, 3], 354 {0: (0, 0, 1), 1: (1, 0, 0), 2: (0, 1, 0), 3: (1, 1, 1)}, 355 ) 356 if SHOW_PLOTS: 357 cv2.imshow( 358 "Full, classic montage", 359 cv2.cvtColor(montage, cv2.COLOR_RGB2BGR), 360 ) 361 cv2.waitKey(0) 362 cv2.destroyAllWindows()