def align_ims(ims, bounds=None): """ Align a stack of ims by generating simplified fiducials for each image. These ims might be from a single channel over many cycles or one cycle over many channels. If bounds, do not allow alignment > bounds Returns: aln_offsets: ndarray(n_cycles, 2); where 2 is (y, x) """ approx_psf = approximate_psf() with prof("convolve"): fiducial_ims = np.zeros_like(ims) for i, im in enumerate(ims): im = im.astype(np.float64) if not np.all(np.isnan(im)): med = float(np.nanmedian(im)) else: med = 0 im = np.nan_to_num(im, nan=med) fid_im = imops.convolve(im, approx_psf - np.mean(approx_psf)) fid_im -= np.median(fid_im) # The edges often end up with artifacts that will cause # the convolution grief so we simply zero them out as they # are unlikely to contribute much to the alignment imops.edge_fill(fid_im, approx_psf.shape[0] * 2) fiducial_ims[i, :, :] = fid_im return _sub_pixel_align_cy_ims(fiducial_ims, bounds=bounds)
def cpu_test(self): mat = np.random.uniform(size=(5000, 5000)) with prof( "cpu_tests_matrix_invert", mega_elems=(mat.shape[0] * mat.shape[1]) / 1e6, _tell=True, ): np.linalg.inv(mat)
def profile_aligns(): true_aln_offsets, chcy_ims = _synth(1024, 10) profile.prof_start_record_capture() with prof("alignment"): with prof("find_offsets"): pred_cy_offsets = align_ims(chcy_ims[0]) pred_chcy_offsets = pred_cy_offsets.reshape(1, *pred_cy_offsets.shape) assert np.all(np.abs(pred_chcy_offsets - true_aln_offsets) < 0.06) with prof("resample"): resample_aligned_ims(chcy_ims, pred_chcy_offsets) profile_records = profile.prof_stop_record_capture() assert profile_records[-1].name == "alignment" assert profile_records[-1].elapsed < 10.0
def fileio_test(self, jobs_folder): job_name = f"_profile/_{int(time.time()):08x}" large_random = np.random.uniform(size=1024**3 // 8) # 8 because floats are 8 bytes def write_to(write_path): # import shutil # total, used, free = shutil.disk_usage(write_path.dirname) # print(f"Free disk at {write_path}: {free / gb:2.2f}GB ({free / total:2.1f}%)") write_path.dirname.mkdir() with open(write_path, "wb") as f: f.write(large_random) # PROFILE write to jobs_folder job_folder_write_path = jobs_folder / job_name try: with prof( "fileio_to_jobs_folder", gbs=large_random.nbytes / self.gb, _tell=True, ): write_to(job_folder_write_path) finally: job_folder_write_path.delete() # PROFILE write to plaster_tmp with tmp_file() as plaster_tmp_folder_write_path: with prof( "fileio_to_plaster_tmp", gbs=large_random.nbytes / self.gb, _tell=True, ): write_to(plaster_tmp_folder_write_path) # PROFILE write to /tmp tmp_folder_write_path = local.path(tempfile.mkstemp()) try: with prof("fileio_to_tmp", gbs=large_random.nbytes / self.gb, _tell=True): write_to(tmp_folder_write_path) finally: tmp_folder_write_path.delete()
def _sub_pixel_align_cy_ims(cy_ims, bounds=None): """ Align image stack with sub-pixel precision. As an optimization, this will subdivide into a number of smaller random subregions and then average the offset. However, this optimization can fail when the image is very sparse. And that failure mode is trapped and then the stack is re-run without the subregion optimization. I tried to go down to 64 pixels sub-regions but could only get to 0.1 of a pixel which might be enough but decided to stay at 128 where I can get 0.05 I found that i needed 8 samples for stability and each is taking about 1 sec on 100 cycles. """ # ALIGN within one pixel with prof("pixel_align"): pixel_offsets, pixel_aligned_cy_ims = imops.align( cy_ims, return_shifted_ims=True, bounds=bounds) # IMPROVE with sub-pixel precision with prof("subpixel_align"): try: sub_pixel_offset = _subsize_sub_pixel_align_cy_ims( pixel_aligned_cy_ims, subsize=128, n_samples=8) except AlignmentError: # The subsize parameter is merely an optimization but in very sparse images # the aligner can fail to find enough peaks in an subregion to align so in # that case we try again but with the subsize optimization disabled. try: sub_pixel_offset = _subsize_sub_pixel_align_cy_ims( pixel_aligned_cy_ims, subsize=None, n_samples=1) except AlignmentError: # This is a true failure. There was no alignment even using the entire # image so we jam in an impossible shift of the entire image. im_mea = pixel_aligned_cy_ims.shape[-1] far_away = np.full(pixel_offsets.shape, im_mea, dtype=float) far_away[0, :] = 0.0 sub_pixel_offset = far_away return pixel_offsets + sub_pixel_offset
def mem_test(self): gb = 1024**3 rnd = np.random.uniform(size=(1_000, 500_000)) with prof("mem_tests_copy", gbs=rnd.nbytes / gb, _tell=True): rnd.copy()