def get_task_data(self): sigshape = tuple(self.meta.partition_shape.sig) rad_in = self.params.rad_in rad_out = self.params.rad_out real_center = self.params.real_center real_rad = self.params.real_rad if not (real_center is None or real_rad is None): real_mask = 1 - 1 * _make_circular_mask( real_center[1], real_center[0], sigshape[1], sigshape[0], real_rad) else: real_mask = None fourier_mask_out = 1 * _make_circular_mask( sigshape[1] * 0.5, sigshape[0] * 0.5, sigshape[1], sigshape[0], rad_out) fourier_mask_in = 1 * _make_circular_mask( sigshape[1] * 0.5, sigshape[0] * 0.5, sigshape[1], sigshape[0], rad_in) fourier_mask = np.fft.fftshift(fourier_mask_out - fourier_mask_in) half_fourier_mask = fourier_mask[:, :int(fourier_mask.shape[1] * 0.5) + 1] kwargs = { 'real_mask': real_mask, 'half_fourier_mask': half_fourier_mask, } return kwargs
def get_cluster_udf(self, sd_udf_results): from skimage.feature import peak_local_max center = (self.parameters["cy"], self.parameters["cx"]) rad_in = self.parameters["ri"] rad_out = self.parameters["ro"] n_peaks = self.parameters["n_peaks"] min_dist = self.parameters["min_dist"] sstd = sd_udf_results['std'] sshape = sstd.shape if not (center is None or rad_in is None or rad_out is None): mask_out = 1*_make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_out) mask_in = 1*_make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_in) mask = mask_out - mask_in masked_sstd = sstd*mask else: masked_sstd = sstd coordinates = peak_local_max(masked_sstd, num_peaks=n_peaks, min_distance=min_dist) y = coordinates[..., 0] x = coordinates[..., 1] z = range(len(y)) mask = sparse.COO( shape=(len(y), ) + tuple(self.dataset.shape.sig), coords=(z, y, x), data=1. ) udf = ApplyMasksUDF( # float32 for cupy support mask_factories=lambda: mask, mask_count=len(y), mask_dtype=np.float32, use_sparse=True ) return udf
def init(partition, center, rad_in, rad_out): mask_out = 1 * _make_circular_mask( center[1], center[0], partition.shape.sig[1], partition.shape.sig[0], rad_out) mask_in = 1 * _make_circular_mask( center[1], center[0], partition.shape.sig[1], partition.shape.sig[0], rad_in) mask = mask_out - mask_in kwargs = { 'mask': mask, } return kwargs
def get_task_data(self): center = self.params.center sig_shape = tuple(self.meta.partition_shape.sig) rad_out, rad_in = self.params.rad_out, self.params.rad_in mask_out = 1 * _make_circular_mask(center[1], center[0], sig_shape[1], sig_shape[0], rad_out) mask_in = 1 * _make_circular_mask(center[1], center[0], sig_shape[1], sig_shape[0], rad_in) mask = mask_out - mask_in kwargs = { 'mask': mask, } return kwargs
def get_udf_results(self, udf_results, roi, damage): from libertem.viz import visualize_simple sum_results = np.array(udf_results['intensity']) real_rad = self.parameters.get("real_rad") real_center = (self.parameters.get("real_centery"), self.parameters.get("real_centerx")) if not (real_center is None or real_rad is None): sigshape = sum_results.shape real_mask = 1 - 1 * _make_circular_mask( real_center[1], real_center[0], sigshape[1], sigshape[0], real_rad) fft_result = np.log( abs(np.fft.fftshift(np.fft.fft2(sum_results * real_mask))) + 1) else: fft_result = np.log( abs(np.fft.fftshift(np.fft.fft2(sum_results))) + 1) return AnalysisResultSet([ AnalysisResult(raw_data=sum_results, visualized=visualize_simple(fft_result, damage=True), key="intensity", title="intensity", desc="fft of sum of all frames"), ])
def get_results(self, job_results): data, coords = self.get_results_base(job_results) real_rad = self.parameters.get("real_rad") real_center = (self.parameters.get("real_centery"), self.parameters.get("real_centerx")) if data.dtype.kind == 'c': return AnalysisResultSet( self.get_complex_results( job_results, key_prefix="intensity", title="intensity", desc="the frame at %s" % (coords, ), )) if not (real_center is None or real_rad is None): sigshape = job_results.shape real_mask = 1 - 1 * _make_circular_mask( real_center[1], real_center[0], sigshape[1], sigshape[0], real_rad) visualized = visualize_simple(np.fft.fftshift( abs(np.fft.fft2(data * real_mask))), logarithmic=True) else: visualized = visualize_simple(np.fft.fftshift( abs(np.fft.fft2(data))), logarithmic=True) return AnalysisResultSet([ AnalysisResult(raw_data=data, visualized=visualized, key="intensity", title="intensity", desc="the frame at %s" % (coords, )), ])
def init_fft(partition, rad_in, rad_out, real_center, real_rad): sigshape = partition.shape.sig if not (real_center is None or real_rad is None): real_mask = 1 - 1 * _make_circular_mask( real_center[1], real_center[0], sigshape[1], sigshape[0], real_rad) else: real_mask = None fourier_mask_out = 1 * _make_circular_mask( sigshape[1] * 0.5, sigshape[0] * 0.5, sigshape[1], sigshape[0], rad_out) fourier_mask_in = 1 * _make_circular_mask( sigshape[1] * 0.5, sigshape[0] * 0.5, sigshape[1], sigshape[0], rad_in) fourier_mask = fourier_mask_out - fourier_mask_in kwargs = { 'real_mask': real_mask, 'fourier_mask': fourier_mask, } return kwargs
def get_udf_results(self, udf_results, roi): data = udf_results['intensity'].data[0] real_rad = self.parameters.get("real_rad") real_center = (self.parameters.get("real_centery"), self.parameters.get("real_centerx")) if data.dtype.kind == 'c': return self.get_generic_results(data) if not (real_center is None or real_rad is None): sigshape = data.shape real_mask = 1-1*_make_circular_mask( real_center[1], real_center[0], sigshape[1], sigshape[0], real_rad ) fft_data = np.fft.fftshift(abs(np.fft.fft2(data*real_mask))) else: fft_data = np.fft.fftshift(abs(np.fft.fft2(data))) return self.get_generic_results(fft_data)
def test_pick_fft_masked(lt_ctx): data = _mk_random([3 * 3, 8, 8], dtype=np.float32) dataset = MemoryDataSet(data=data, tileshape=(1, 8, 8), num_partitions=2, sig_dims=2) analysis = PickFFTFrameAnalysis(dataset=dataset, parameters={ 'x': 1, 'real_rad': 1, 'real_centerx': 1, 'real_centery': 1, }) real_mask = np.invert( _make_circular_mask(centerX=1, centerY=1, imageSizeX=8, imageSizeY=8, radius=1)) fft_data = np.fft.fftshift(abs(np.fft.fft2(data[1] * real_mask))) res = lt_ctx.run(analysis) assert np.allclose(res.intensity.raw_data, fft_data)
def make_feature_vec(ctx, dataset, delta, n_peaks, min_dist=None, center=None, rad_in=None, rad_out=None, roi=None): """ Creates a feature vector for each frame in ROI based on non-zero order diffraction peaks positions Parameters ---------- ctx : libertem.api.Context dataset : libertem.io.dataset.DataSet A dataset with 1- or 2-D scan dimensions and 2-D frame dimensions num : int Number of possible peak positions to detect (better put higher value, the output is limited to the number of peaks the algorithm could find) delta : float Relative intensity difference between current frame and reference image for decision making for feature vector value (delta = (x-ref)/ref, so, normally, value should be in range [0,1]) rad_in : int, optional Inner radius in pixels of a ring to mask region of interest of SD image to delete outliers for peak finding rad_out : int, optional Outer radius in pixels of a ring to mask region of interest of SD image to delete outliers for peak finding center : tuple, optional (y,x) - pixels, coordinates of a ring to mask region of interest of SD image to delete outliers for peak finding roi : numpy.ndarray, optional boolean array which limits the elements the UDF is working on. Has a shape of dataset_shape.nav Returns ------- pass_results: dict Returns a feature vector for each frame. "1" - denotes presence of peak for current frame for given possible peak position, "0" - absence of peak for current frame for given possible peak position, To return 2-D array use pass_results['feature_vec'].data coordinates: numpy array of int Returns array of coordinates of possible peaks positions """ res_stat = run_stddev(ctx, dataset, roi) savg = res_stat['mean'] sstd = res_stat['std'] sshape = sstd.shape if not (center is None or rad_in is None or rad_out is None): mask_out = 1 * _make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_out) mask_in = 1 * _make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_in) mask = mask_out - mask_in masked_sstd = sstd * mask else: masked_sstd = sstd if min_dist is None: min_dist = 1 coordinates = peak_local_max(masked_sstd, num_peaks=n_peaks, min_distance=min_dist) udf = FeatureVecMakerUDF(delta=delta, savg=savg, coordinates=coordinates) pass_results = ctx.run_udf(dataset=dataset, udf=udf, roi=roi) return (pass_results, coordinates)
async def controller(self, cancel_id, executor, job_is_cancelled, send_results): stddev_udf = StdDevUDF() roi = self.get_sd_roi() result_iter = UDFRunner(stddev_udf).run_for_dataset_async( self.dataset, executor, roi=roi, cancel_id=cancel_id) async for sd_udf_results in result_iter: pass if job_is_cancelled(): raise JobCancelledError() sd_udf_results['var'].data sd_udf_results['num_frame'].data sd_udf_results = dict(sd_udf_results.items()) sd_udf_results['var'] = sd_udf_results['var'].data / sd_udf_results[ 'num_frame'].data sd_udf_results['std'] = np.sqrt(sd_udf_results['var'].data) sd_udf_results['mean'] = sd_udf_results[ 'sum_frame'].data / sd_udf_results['num_frame'].data sd_udf_results['num_frame'] = sd_udf_results['num_frame'].data sd_udf_results['sum_frame'] = sd_udf_results['sum_frame'].data center = (self.parameters["cy"], self.parameters["cx"]) rad_in = self.parameters["ri"] rad_out = self.parameters["ro"] delta = self.parameters["delta"] n_peaks = self.parameters["n_peaks"] min_dist = self.parameters["min_dist"] savg = sd_udf_results['mean'] sstd = sd_udf_results['std'] sshape = sstd.shape if not (center is None or rad_in is None or rad_out is None): mask_out = 1 * _make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_out) mask_in = 1 * _make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_in) mask = mask_out - mask_in masked_sstd = sstd * mask else: masked_sstd = sstd coordinates = peak_local_max(masked_sstd, num_peaks=n_peaks, min_distance=min_dist) udf = feature.FeatureVecMakerUDF(delta=delta, savg=savg, coordinates=coordinates) result_iter = UDFRunner(udf).run_for_dataset_async(self.dataset, executor, cancel_id=cancel_id) async for udf_results in result_iter: pass if job_is_cancelled(): raise JobCancelledError() results = await run_blocking( self.get_udf_results, udf_results=udf_results, roi=roi, ) await send_results(results, True)
async def controller(self, cancel_id, executor, job_is_cancelled, send_results): stddev_udf = StdDevUDF() roi = self.get_sd_roi() result_iter = UDFRunner(stddev_udf).run_for_dataset_async( self.dataset, executor, roi=roi, cancel_id=cancel_id) async for sd_udf_results in result_iter: pass if job_is_cancelled(): raise JobCancelledError() sd_udf_results = consolidate_result(sd_udf_results) center = (self.parameters["cy"], self.parameters["cx"]) rad_in = self.parameters["ri"] rad_out = self.parameters["ro"] n_peaks = self.parameters["n_peaks"] min_dist = self.parameters["min_dist"] sstd = sd_udf_results['std'] sshape = sstd.shape if not (center is None or rad_in is None or rad_out is None): mask_out = 1 * _make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_out) mask_in = 1 * _make_circular_mask(center[1], center[0], sshape[1], sshape[0], rad_in) mask = mask_out - mask_in masked_sstd = sstd * mask else: masked_sstd = sstd coordinates = peak_local_max(masked_sstd, num_peaks=n_peaks, min_distance=min_dist) y = coordinates[..., 0] x = coordinates[..., 1] z = range(len(y)) mask = sparse.COO(shape=(len(y), ) + tuple(self.dataset.shape.sig), coords=(z, y, x), data=1) udf = ApplyMasksUDF(mask_factories=lambda: mask, mask_count=len(y), mask_dtype=np.uint8, use_sparse=True) result_iter = UDFRunner(udf).run_for_dataset_async(self.dataset, executor, cancel_id=cancel_id) async for udf_results in result_iter: pass if job_is_cancelled(): raise JobCancelledError() results = await run_blocking( self.get_udf_results, udf_results=udf_results, roi=roi, ) await send_results(results, True)