def test_eq(self, trafo): """multicolor.Registrator: Test equality operator""" r1 = multicolor.Registrator() r1.parameters1 = trafo r1.parameters2 = trafo * 2 r2 = multicolor.Registrator() r2.parameters1 = trafo r2.parameters2 = trafo * 3 assert r1 == r1 assert r1 != r2 assert r1 != "bla"
def test_save_load(self, save_fmt, trafo, tmp_path): """multicolor.Registrator: save to/load from binary file""" cc = multicolor.Registrator() cc.parameters1 = trafo cc.parameters2 = np.linalg.inv(trafo) data_keys = ("c1", "c2") # Test with file object with open(tmp_path / f"save.{save_fmt}", "w+b") as f: cc.save(f, fmt=save_fmt, key=data_keys) f.seek(0) cc_loaded_file = multicolor.Registrator.load(f, fmt=save_fmt, key=data_keys) np.testing.assert_allclose(cc_loaded_file.parameters1, trafo) np.testing.assert_allclose(cc_loaded_file.parameters2, np.linalg.inv(trafo)) # Test with file name fname = tmp_path / f"bla.{save_fmt}" cc.save(fname, fmt=save_fmt, key=data_keys) cc_loaded_fname = multicolor.Registrator.load(fname, fmt=save_fmt, key=data_keys) np.testing.assert_allclose(cc_loaded_fname.parameters1, trafo) np.testing.assert_allclose(cc_loaded_fname.parameters2, np.linalg.inv(trafo))
def test_determine_parameters(self, dataframes, dataframe_pairs, trafo): """multicolor.Registrator.determine_parameters""" cc = multicolor.Registrator(dataframes[0], dataframes[1]) cc.determine_parameters() res = cc.pairs.sort_values(("channel1", "x")).reset_index(drop=True) pd.testing.assert_frame_equal(res, dataframe_pairs) np.testing.assert_allclose(cc.parameters1, trafo) np.testing.assert_allclose(cc.parameters2, np.linalg.inv(trafo))
def test_find_pairs_multi_file(self, dataframes, dataframe_pairs): """multicolor.Registrator.find_pairs, list of input features""" cc = multicolor.Registrator([dataframes[0]] * 2, [dataframes[1]] * 2) cc.find_pairs() res = cc.pairs.sort_values(("channel1", "x")).reset_index(drop=True) exp = pd.concat([dataframe_pairs] * 2) exp = exp.sort_values(("channel1", "x")).reset_index(drop=True) pd.testing.assert_frame_equal(res, exp)
def __init__(self, parent=None): super().__init__(parent) self._channels = {} self._frameSel = multicolor.FrameSelector("") self._registrator = multicolor.Registrator() self.channelsChanged.connect(self._imageDataChanged) self.registratorChanged.connect(self._imageDataChanged) self.excitationSeqChanged.connect(self._imageDataChanged)
def test_call_img(self): """multicolor.Registrator.__call__: image arg""" cc = multicolor.Registrator(None, None) img = np.arange(50)[:, np.newaxis] + np.arange(100)[np.newaxis, :] cc.parameters1 = np.array([[-1, 0, img.shape[1] - 1], [0, 1, 0], [0, 0, 1]]) cc.parameters2 = np.linalg.inv(cc.parameters1) img_corr = cc(img, channel=1) np.testing.assert_allclose(img_corr, img[:, ::-1])
def test_yaml(self, trafo): """multicolor.Registrator: save to/load from YAML""" cc = multicolor.Registrator() cc.parameters1 = trafo cc.parameters2 = np.linalg.inv(trafo) sio = StringIO() io.yaml.safe_dump(cc, sio) sio.seek(0) cc_loaded = io.yaml.safe_load(sio) np.testing.assert_allclose(cc_loaded.parameters1, trafo) np.testing.assert_allclose(cc_loaded.parameters2, np.linalg.inv(trafo))
def test_call_img_callable_cval(self): """multicolor.Registrator.__call__: image arg with callable `cval`""" cc = multicolor.Registrator(None, None) img = np.arange(50)[:, np.newaxis] + np.arange(100)[np.newaxis, :] cc.parameters1 = np.array([[-1, 0, img.shape[1] // 2 - 1], [0, 1, 0], [0, 0, 1]]) cc.parameters2 = np.linalg.inv(cc.parameters1) img_corr = cc(img, channel=1, cval=lambda x: -10) exp = np.empty_like(img) exp[:, :exp.shape[1] // 2] = img[:, img.shape[1] // 2 - 1::-1] exp[:, exp.shape[1] // 2:] = -10 np.testing.assert_allclose(img_corr, exp)
def calc_registration(self, plot: bool = True, max_frame: Optional[int] = None, params: Optional[Dict[str, Any]] = None ) -> Optional[mpl.figure.FigureCanvasBase]: """Calculate transformation between color channels Localize beads using the options set with :py:meth:`set_bead_loc_opts`, find pairs and fit transformation. Store result in :py:attr:`self.tracker.registrator`. Parameters ---------- plot If True, plot the fit results and return the figure canvas. max_frame Maximum frame number to consider. Useful if beads defocused in later frames. If `None` use all frames. params Passed to :py:meth:`multicolor.Registrator.determine_parameters`. Returns ------- If ``plot=True``, return the figure canvas which can be displayed in Jupyter notebooks. """ label = ipywidgets.Label(value="Starting…") display(label) n_files = len(self.special_sources["registration"]) locs = {"donor": [], "acceptor": []} for n, img_file in enumerate( self.special_sources["registration"].values()): label.value = f"Locating beads (file {n+1}/{n_files})" im_seq, to_close = self._open_image_sequence(img_file) for chan in "donor", "acceptor": locator = self.locators[f"reg_{chan}"] lo = locator.batch_func(im_seq[chan][:max_frame], **locator.options) locs[chan].append(lo) label.layout = ipywidgets.Layout(display="none") cc = multicolor.Registrator(locs["donor"], locs["acceptor"]) cc.determine_parameters(**params or {}) self.tracker.registrator = cc if plot: fig, ax = plt.subplots(1, 2) cc.test(ax=ax) return fig.canvas
def test_fit_parameters(self, dataframe_pairs, trafo): """multicolor.Registrator.fit_parameters""" cc = multicolor.Registrator(None, None) # Add outlier dataframe_pairs.loc[dataframe_pairs.index.max() + 1] = \ [10., 12., -70., -110.] cc.pairs = dataframe_pairs cc.fit_parameters() # Check whether ambiguous outlier pairs were removed res = cc.pairs.sort_values(("channel1", "x")).reset_index(drop=True) pd.testing.assert_frame_equal(res, dataframe_pairs.iloc[:-1]) # Check transforms np.testing.assert_allclose(cc.parameters1, trafo) np.testing.assert_allclose(cc.parameters2, np.linalg.inv(trafo))
def test_find_pairs_multi_frame(self, dataframes, dataframe_pairs): """multicolor.Registrator.find_pairs, multiple frames""" dfs = [] for d in dataframes: d1 = d.copy() d["frame"] = 0 d1["frame"] = 1 dfs.append(pd.concat([d, d1], ignore_index=True)) cc = multicolor.Registrator(dfs[0], dfs[1]) cc.find_pairs() res = cc.pairs.sort_values(("channel1", "x")).reset_index(drop=True) exp = pd.concat([dataframe_pairs] * 2) exp = exp.sort_values(("channel1", "x")).reset_index(drop=True) pd.testing.assert_frame_equal(res, exp)
def test_call_dataframe(self, dataframes): """multicolor.Registrator.__call__: DataFrame arg""" cc = multicolor.Registrator(*dataframes) cc.determine_parameters() res = cc.pairs["channel1"].copy() res["frame"] = 0 exp = cc.pairs["channel2"].copy() exp["frame"] = res["frame"] res2 = cc(res, channel=1, inplace=False) cc(res, channel=1, inplace=True) pd.testing.assert_frame_equal(res, exp) pd.testing.assert_frame_equal(res2, exp)
def test_determine_parameters_mirrored(self, dataframes, dataframe_pairs, trafo): """multicolor.Registrator.determine_parameters, mirrored 1st axis""" mirror_x = dataframes[0]["x"].max() dataframes[0]["x"] = mirror_x - dataframes[0]["x"] dataframe_pairs["channel1", "x"] = \ mirror_x - dataframe_pairs["channel1", "x"] cc = multicolor.Registrator(dataframes[0], dataframes[1]) cc.determine_parameters() res = cc.pairs.sort_values(("channel1", "x"), ascending=False) res = res.reset_index(drop=True) pd.testing.assert_frame_equal(res, dataframe_pairs) trafo = trafo @ np.array([[-1, 0, mirror_x], [0, 1, 0], [0, 0, 1]]) np.testing.assert_allclose(cc.parameters1, trafo) np.testing.assert_allclose(cc.parameters2, np.linalg.inv(trafo))
def __init__(self, parent=None): super().__init__(parent) self.dataRoles = [ "display", "key", "ddImg", "daImg", "aaImg", "particles" ] self._channels = { "acceptor": { "source_id": 0, "roi": None }, "donor": { "source_id": 0, "roi": None } } self._excitationSeq = "" self._registrator = multicolor.Registrator() self._trackLengthRange = [0, np.inf] self.propagateProperty("channels") self.propagateProperty("excitationSeq") self.propagateProperty("registrator")
def test_find_pairs_no_frame(self, dataframes, dataframe_pairs): """multicolor.Registrator.find_pairs, no "frame" column""" cc = multicolor.Registrator(dataframes[0], dataframes[1]) cc.find_pairs() res = cc.pairs.sort_values(("channel1", "x")).reset_index(drop=True) pd.testing.assert_frame_equal(res, dataframe_pairs)