def synth_image(im, peak_mea, locs, amps, std_xs, std_ys): """ Generate a synthetic image using the Gaussians in the parallel arrays and accumulate into im """ lib = load_lib() n_locs = int(len(locs)) check.array_t(amps, shape=(n_locs,)) check.array_t(std_xs, shape=(n_locs,)) check.array_t(std_ys, shape=(n_locs,)) params = np.zeros((n_locs, Gauss2FitParams.N_FIT_PARAMS)) params[:, Gauss2FitParams.AMP] = amps params[:, Gauss2FitParams.CENTER_Y] = locs[:, 0] params[:, Gauss2FitParams.CENTER_X] = locs[:, 1] params[:, Gauss2FitParams.SIGMA_X] = std_xs params[:, Gauss2FitParams.SIGMA_Y] = std_ys check.array_t(im, ndim=2) params = np.ascontiguousarray(params, dtype=np.float64) im = np.ascontiguousarray(im, dtype=np.float64) im_h, im_w = im.shape error = lib.synth_image(im, im_w, im_h, peak_mea, n_locs, params) if error is not None: raise CException(error)
def do_classify_radrows(nn_v2_context, radrow_start_i, n_radrows): lib = load_lib() n_actual_radrows = nn_v2_context.radmat.n_rows if 0 <= radrow_start_i < n_actual_radrows: n_radrows = min(n_actual_radrows - radrow_start_i, n_radrows) if radrow_start_i + n_radrows <= n_actual_radrows: error = lib.classify_radrows(nn_v2_context, radrow_start_i, n_radrows) if error is not None: raise CException(error)
def _do_radiometry_field_stack_peak_batch(ctx: RadiometryContext, peak_start_i: int, peak_stop_i: int): """ Worker for radiometry_field_stack() zap """ lib = load_lib() error = lib.radiometry_field_stack_peak_batch(ctx, peak_start_i, peak_stop_i) if error is not None: raise CException(error)
def do_field_cycle(ch_ims: np.ndarray, field_i: int, cycle_i: int, reg_psf_samples, peak_mea): lib = load_lib() check.array_t(ch_ims, ndim=3, is_square=True) with context(ch_ims=ch_ims, reg_psf_samples=reg_psf_samples, peak_mea=peak_mea, field_i=field_i) as ctx: error = lib.do_field_cycle(ctx, cycle_i) if error is not None: raise CException(error) return ctx._out_align, ctx._out_locs, ctx._out_radiometry
def context(cy_ims, locs, reg_psf_samples, peak_mea): """ with radiometry.context(...) as ctx: zap.work_orders(do_radiometry, ...) """ lib = load_lib() check.array_t(cy_ims, ndim=3, dtype=np.float64) n_cycles, height, width = cy_ims.shape check.array_t(locs, ndim=2, dtype=np.float64) check.affirm(locs.shape[1] == 2) n_peaks = locs.shape[0] check.array_t(reg_psf_samples, ndim=3) n_divs, n_divs_w, n_params = reg_psf_samples.shape assert n_divs == n_divs_w assert n_params == 3 out_radiometry = np.zeros((n_peaks, n_cycles, 4), dtype=np.float64) ctx = RadiometryContext( cy_ims=F64Arr.from_ndarray(cy_ims), locs=F64Arr.from_ndarray(locs), _locs=locs, n_cycles=n_cycles, n_peaks=n_peaks, n_divs=n_divs, peak_mea=peak_mea, height=height, width=width, reg_psf_samples=F64Arr.from_ndarray(reg_psf_samples), out_radiometry=F64Arr.from_ndarray(out_radiometry), _out_radiometry=out_radiometry, ) error = lib.context_init(ctx) if error is not None: raise CException(error) try: yield ctx finally: lib.context_free(ctx)
def context(ch_ims, reg_psf_samples, peak_mea, field_i): lib = load_lib() check.array_t(ch_ims, ndim=3, dtype=np.uint16) n_channels, height, width = ch_ims.shape check.array_t(reg_psf_samples, ndim=3) n_divs, n_divs_w, n_params = reg_psf_samples.shape assert n_divs == n_divs_w assert n_params == 3 n_max_locs = 10_000 out_align = np.zeros((n_channels, 2), dtype=np.float64) out_locs = np.zeros((n_max_locs, 2), dtype=np.float64) out_radiometry = np.zeros((n_max_locs, n_channels, 4), dtype=np.float64) ctx = SigprocV3Context( field_i=field_i, n_channels=n_channels, ch_ims=U16Arr.fromndarray(ch_ims), reg_psf_samples=F64Arr.from_ndarray(reg_psf_samples), n_divs=n_divs, peak_mea=peak_mea, raw_height=height, raw_width=width, n_max_locs=n_max_locs, out_n_peaks=0, out_align=F64Arr.from_ndarray(out_align), _out_align=out_align, out_locs=F64Arr.from_ndarray(out_locs), _out_locs=out_locs, out_radiometry=F64Arr.from_ndarray(out_radiometry), _out_radiometry=out_radiometry, ) error = lib.context_init(ctx) if error is not None: raise CException(error) try: yield ctx finally: lib.context_free(ctx)
def fit_image(im, locs, guess_params, peak_mea): """ Arguments: im: ndarray single image locs: ndarray (n_locs, 2) guess_params: ndarray (n_locs, AugmentedGauss2Params.N_FULL_PARAMS) peak_mea: measure of peak Returns: fit_params: ndarray(n_locs, AugmentedGauss2Params.N_FULL_PARAMS) The fit parameters std_params: The std of each fit, essentially a quality of fit metric """ lib = load_lib() n_locs = int(len(locs)) check.array_t(im, ndim=2, dtype=np.float64) im = np.ascontiguousarray(im, dtype=np.float64) # assert np.all(~np.isnan(im)) check.array_t(im, ndim=2, dtype=np.float64, c_contiguous=True) check.array_t(locs, ndim=2, shape=(None, 2)) locs_y = np.ascontiguousarray(locs[:, 0], dtype=np.int64) locs_x = np.ascontiguousarray(locs[:, 1], dtype=np.int64) # MARK all nans as negative which fit_array_of_gauss_2d_on_float_image # treats as a sentinel for "DO NOT FIT" locs_y[np.isnan(locs[:, 0])] = -1 locs_x[np.isnan(locs[:, 1])] = -1 fit_fails = np.zeros((n_locs,), dtype=np.int64) check.array_t(fit_fails, dtype=np.int64, c_contiguous=True) check.array_t( guess_params, dtype=np.float64, ndim=2, shape=(n_locs, AugmentedGauss2Params.N_FULL_PARAMS,), ) fit_params = guess_params.copy() fit_params[:, AugmentedGauss2Params.MEA] = peak_mea fit_params = np.ascontiguousarray(fit_params.flatten()) std_params = np.zeros((n_locs, AugmentedGauss2Params.N_FULL_PARAMS)) std_params = np.ascontiguousarray(std_params.flatten()) check.array_t( fit_params, dtype=np.float64, c_contiguous=True, ndim=1, shape=(n_locs * AugmentedGauss2Params.N_FULL_PARAMS,), ) error = lib.gauss2_check() if error is not None: raise CException(error) error = lib.fit_array_of_gauss_2d_on_float_image( im, im.shape[1], # Note inversion of axis (y is primary in numpy) im.shape[0], peak_mea, n_locs, locs_x, locs_y, fit_params, std_params, fit_fails, ) if error is not None: raise CException(error) # RESHAPE fit_params and NAN-out any where the fit failed fit_params = fit_params.reshape((n_locs, AugmentedGauss2Params.N_FULL_PARAMS)) # fit_fails will be 1 both in the case that the fit failed # and the case where it was skipped because "DO NOT FIT" was passed above fit_params[fit_fails == 1, :] = np.nan # After some very basic analysis, it seems that the following # parameters are reasonable guess for out of bound on the # std of fit. # Note, this analysis was done on 11x11 pixels and might # need to be different for other sizes. # BUT! after using this they seemed to knock out everything # so apparently the are not well tuned yet so this block is # temporarily removed. """ std_params = std_params.reshape((n_locs, AugmentedGauss2Params.N_FULL_PARAMS)) param_std_of_fit_limits = np.array((500, 0.18, 0.18, 0.15, 0.15, 0.08, 5,)) out_of_bounds_mask = np.any( std_params[:, 0 : AugmentedGauss2Params.N_FIT_PARAMS] > param_std_of_fit_limits[None, :], axis=1, ) fit_params[out_of_bounds_mask, :] = np.nan """ return fit_params, std_params
def context( train_dyemat, train_dyepeps, radmat, radmat_filter_mask, priors, n_channels, n_neighbors=8, run_row_k_fit=True, run_against_all_dyetracks=False, scoring_verbose=False, scoring_verbose_cc=False, use_row_k_p_val=True, row_k_score_factor=1.0, ): """ with nn_v2.context(...) as ctx: zap.work_orders(do_classify_radrows, ...) """ lib = load_lib() check.t(priors, Priors) output_dtype = NNV2Context.tab_type("output") n_radrows = radmat.shape[0] output = np.zeros((n_radrows, NNV2ContextOutputFields.n_fields), dtype=output_dtype) # This is a possible place to optimize to avoid this conversion to float # But as it is now it is needed because the FLANN needs to lookup by float # so it is easier to convert is all here to RadType. train_fdyemat = train_dyemat.astype(RadType) n_dyts = train_fdyemat.shape[0] assert train_fdyemat.shape[1] == radmat.shape[1] n_cols = train_fdyemat.shape[1] n_channels = n_channels n_cycles = n_cols // n_channels assert n_cycles * n_channels == n_cols illum_model = priors.helper_illum_model(n_channels) # TODO: Cleanup legacy gain_model naming conventions (esp in the C code) row_k_beta = 1.0 row_k_sigma = priors.get_mle(f"row_k_sigma") against_all_dyetracks_output_dtype = None against_all_dyetracks_output = None if run_against_all_dyetracks: against_all_dyetracks_output_dtype = NNV2Context.tab_type( "against_all_dyetracks_output") against_all_dyetracks_output = np.zeros( (n_radrows, 3 * n_dyts), dtype=against_all_dyetracks_output_dtype) scoring_verbose_output_dtype = None scoring_verbose_output = None scoring_verbose_cc_output_dtype = None scoring_verbose_cc_output = None if scoring_verbose: scoring_verbose_output_dtype = NNV2Context.tab_type( "scoring_verbose_output") scoring_verbose_output = np.zeros( (n_radrows * n_neighbors, len(NNV2ScoringVerboseFields.col_names)), dtype=scoring_verbose_output_dtype, ) if scoring_verbose_cc: scoring_verbose_cc_output_dtype = NNV2Context.tab_type( "scoring_verbose_cc_output") n_chcy = train_fdyemat.shape[1] scoring_verbose_cc_output = np.zeros( (n_radrows * n_neighbors * n_chcy, 4), dtype=scoring_verbose_cc_output_dtype) nn_v2_context = NNV2Context( train_fdyemat=Tab.from_mat(train_fdyemat, NNV2Context.tab_type("train_fdyemat")), train_dyepeps=Tab.from_mat(train_dyepeps, NNV2Context.tab_type("train_dyepeps")), radmat=Tab.from_mat(radmat, NNV2Context.tab_type("radmat")), radmat_filter_mask=Tab.from_mat( radmat_filter_mask, NNV2Context.tab_type("radmat_filter_mask")), _radmat_filter_mask=radmat_filter_mask, ch_gain_model=Tab.from_mat(illum_model, NNV2Context.tab_type("ch_gain_model")), row_k_beta=row_k_beta, row_k_sigma=row_k_sigma, row_k_score_factor=row_k_score_factor, n_neighbors=n_neighbors, run_row_k_fit=run_row_k_fit, run_against_all_dyetracks=run_against_all_dyetracks, scoring_verbose=scoring_verbose, scoring_verbose_cc=scoring_verbose_cc, use_row_k_p_val=use_row_k_p_val, n_cols=n_cols, n_channels=n_channels, n_cycles=n_cycles, output=Tab.from_mat(output, output_dtype), _output=output, against_all_dyetracks_output=Tab.from_mat( against_all_dyetracks_output, against_all_dyetracks_output_dtype), _against_all_dyetracks_output=against_all_dyetracks_output, scoring_verbose_output=Tab.from_mat(scoring_verbose_output, scoring_verbose_output_dtype), _scoring_verbose_output=scoring_verbose_output, scoring_verbose_cc_output=Tab.from_mat( scoring_verbose_cc_output, scoring_verbose_cc_output_dtype), _scoring_verbose_cc_output=scoring_verbose_cc_output, ) assert ((-1e5 < radmat) & (radmat < 1e6)).sum( ) > 0.5 * radmat.size, "Too many values are out of bounds for radmat" assert radmat.dtype == RadType error = lib.context_init(nn_v2_context) if error is not None: raise CException(error) try: yield nn_v2_context finally: lib.context_free(nn_v2_context)