def test_scatter_geometry(): file_path = test_utils.download_sampledata("CT-chest") volume = deepdrr.Volume.from_nrrd(file_path) carm = deepdrr.MobileCArm(isocenter=volume.center_in_world) print(f"volume center in world: {volume.center_in_world}") print(f"volume spacing: {volume.spacing}") print(f"volume ijk_from_world\n{volume.ijk_from_world}") with deepdrr.Projector( volume=volume, carm=carm, step=0.1, mode="linear", max_block_index=200, spectrum="90KV_AL40", photon_count=100000, scatter_num=10e7, threads=8, neglog=True, ) as projector: image = projector.project() image = (image * 255).astype(np.uint8) #Image.fromarray(image).save("output/test_multivolume.png") output_dir = test_utils.get_output_dir()
def test_kwire(): output_dir = test_utils.get_output_dir() data_dir = test_utils.download_sampledata("CTPelvic1K_sample") volume = deepdrr.Volume.from_nifti(data_dir / "dataset6_CLINIC_0001_data.nii.gz", use_thresholding=True) volume.rotate(Rotation.from_euler("xz", [90, -90], degrees=True)) # load the line annotation for the trajectory annotation_path = sorted(list(data_dir.glob("*.mrk.json")))[1] annotation = deepdrr.LineAnnotation.from_markup(annotation_path, volume) # define the simulated C-arm carm = deepdrr.MobileCArm( annotation.startpoint_in_world.lerp(annotation.endpoint_in_world, 0.3), ) # first, just do the CT volume on its own with deepdrr.Projector(volume, carm=carm) as projector: image = projector() image_utils.save(output_dir / "test_kwire_empty.png", image) # Then add a kwire kwire = deepdrr.vol.KWire.from_example() kwire.align(annotation.startpoint_in_world, annotation.endpoint_in_world, 1) # Then, do them both # with deepdrr.Projector([volume, kwire], carm=carm) as projector: # image = projector() # image_utils.save(output_dir / "test_kwire.png", image) # screenshot = vis.show( # volume, carm, annotation, kwire, full=[True, True, True, True] # ) # image_utils.save(output_dir / "test_kwire_screenshot.png", screenshot) output_dir = output_dir / "test_kwire" output_dir.mkdir(exist_ok=True) i = 0 with deepdrr.Projector([volume, kwire], carm=carm) as projector: for alpha in [-30, -15, 0, 15, 30, 45, 60, 75, 90]: carm.move_to(alpha=alpha, degrees=True) for progress in np.arange(0, 1, 0.2): kwire.align( annotation.startpoint_in_world, annotation.endpoint_in_world, progress, ) image = projector() image_utils.save( output_dir / f"{i:03d}_test_kwire_only_alpha={alpha}_progress={int(100 * progress)}.png", image, ) log.info i += 1
def main(): output_dir = test_utils.get_output_dir() data_dir = test_utils.download_sampledata("CTPelvic1K_sample") patient = deepdrr.Volume.from_nifti( data_dir / "dataset6_CLINIC_0001_data.nii.gz", use_thresholding=True ) patient.faceup() # define the simulated C-arm carm = deepdrr.MobileCArm(patient.center_in_world) # project in the AP view with Projector(patient, carm=carm) as projector: carm.move_to(alpha=0, beta=-15) image = projector() path = output_dir / "example_projector.png" image_utils.save(path, image) log.info(f"saved example projection image to {path.absolute()}")
def test_scatter_single_volume_aligned(): """A single volume, aligned with the world XYZ planes""" file_path = test_utils.download_sampledata("CT-chest") volume = deepdrr.Volume.from_nrrd(file_path) carm = deepdrr.MobileCArm(isocenter=volume.center_in_world) with deepdrr.Projector( volume=volume, carm=carm, step=0.1, mode="linear", max_block_index=1024, spectrum="90KV_AL40", photon_count=100000, scatter_num=10e7, threads=8, neglog=True, ) as projector: image = projector.project() image = (image * 255).astype(np.uint8) Image.fromarray(image).save("output/test_scatter.png") output_dir = test_utils.get_output_dir()
def test_mcgpu(): file_path = test_utils.download_sampledata("CT-chest") volume = deepdrr.Volume.from_nrrd(file_path) # Steps in the test # # 1. check that MCGPU is installed in correct location. If not, automatically pass the test # 2. load volume and specify test's geometry # 3. Convert to MCGPU format and write out to file in proper location # 4. Run DeepDRR # 5. Run MCGPU # 6. Compare in intelligent ways # 1. check that MCGPU is installed in correct location. If not, automatically pass the test tests_dir = Path(__file__).resolve().parent # deepdrr/tests ancestor = tests_dir.parent.parent mcgpu_dir = ancestor / "MCGPU" if not mcgpu_dir.is_dir(): log.info(f"MCGPU not installed in proper location for {__file__}") return mcgpu_exe = mcgpu_dir / "MC-GPU_v1.3.x" if not mcgpu_exe.is_file(): log.info( f"MC-GPU_v1.3.x file not installed in proper location for {__file__}" ) return mcgpu_test_dir = mcgpu_dir / "DeepDRR_testing" if not mcgpu_test_dir.exists(): os.mkdir(mcgpu_test_dir) # 2. load volume and specify test's geometry carm = deepdrr.MobileCArm(isocenter=volume.center_in_world) projector = deepdrr.Projector( volume=volume, carm=carm, step=0.1, mode="linear", max_block_index=200, spectrum="90KV_AL40", photon_count=100000, scatter_num=10e7, threads=8, neglog=False, ) # 3. Convert to MCGPU format and write out to file in proper location source_world_cm = carm.get_camera_projection().get_center_in_world( ) * 0.1 # convert to [cm] _detector_ctr = np.array( [carm.sensor_width / 2, carm.sensor_height / 2, 1]) src_dir = np.array( carm.get_camera_projection().world_from_index) @ _detector_ctr mag2 = (src_dir[0] * src_dir[0]) + (src_dir[1] * src_dir[1]) + (src_dir[2] * src_dir[2]) source_direction = src_dir / np.sqrt(mag2) detector_shape = (carm.sensor_width, carm.sensor_height) detector_size_cm = ( carm.sensor_width * carm.pixel_size * 0.1, # convert to [cm] carm.sensor_height * carm.pixel_size * 0.1 # convert to [cm] ) src_to_iso_cm = (np.array(carm.isocenter) * 0.1) - np.array(source_world_cm) source_to_isocenter_dist_cm = np.sqrt(np.dot(src_to_iso_cm, src_to_iso_cm)) FILENAME = "DeepDRR_test_mcgpu" log.info("Starting conversion to MCGPU format") conv_to_mcgpu.make_mcgpu_inputs( volume, FILENAME, mcgpu_test_dir, projector.scatter_num, 12345, projector.threads * projector.threads, projector.histories_per_thread, "90KV_AL40", source_world_cm, source_direction, detector_shape, detector_size_cm, carm.source_to_detector_distance * 0.1, # convert to [cm] source_to_isocenter_dist_cm) log.info("Done with conversion to MCGPU format") # 4. Run DeepDRR projector.initialize() deepdrr_image = projector.project() #deepdrr_image = (deepdrr_image * 255).astype(np.uint8) # only if using neglog Image.fromarray(deepdrr_image).save("output/test_mcgpu_deepdrr.png") projector.free() output_dir = test_utils.get_output_dir() # 5. Run MCGPU mcgpu_infile = mcgpu_test_dir / f"{FILENAME}.in" mcgpu_outfile = mcgpu_test_dir / f"{FILENAME}.out" args = [ mcgpu_exe.as_posix(), mcgpu_infile.as_posix(), "|", "tee", mcgpu_outfile.as_posix() ] print("args to subprocess call:") for arg in args: print(arg) #subprocess.call(args) # TODO: figure out how to use this cwd_str = os.getcwd() print(f"TEMP: current working directory before call: {cwd_str}") os.chdir(f"{mcgpu_test_dir.as_posix()}") print(f"TEMP: changed directory to {os.getcwd()}") os.system( f"{mcgpu_exe.as_posix()} {mcgpu_infile.as_posix()} | tee {mcgpu_outfile.as_posix()}" ) os.chdir(f"{cwd_str}") print(f"TEMP: current working directory after call: {os.getcwd()}") # 6. Compare in intelligent ways dat_file_path = mcgpu_test_dir / f"mcgpu_image_{FILENAME}.dat" mcgpu_results_raw = mcgpu_raw_to_ndarray_helper(dat_file_path.as_posix(), carm.sensor_width, carm.sensor_height) # Convert from [eV/cm^2 per history] to [eV] on each pixel pixel_area_cm = (carm.pixel_size * 0.1) * (carm.pixel_size * 0.1) mcgpu_results_eV = mcgpu_results_raw * pixel_area * projector.scatter_num