def test_build_spec_table_not_copy(self): """build_spec_table should not copy tables if not neccessary""" xs = np.arange(3) # float32 table will force a copy because Orange X is float64 X = np.ones([4, 3], dtype=np.float32) data = build_spec_table(xs, X) self.assertFalse(np.may_share_memory(data.X, X)) # float64 will not force a copy X = np.ones([4, 3], dtype=np.float64) data = build_spec_table(xs, X) self.assertTrue(np.may_share_memory(data.X, X))
def process_stack(data, xat, yat, upsample_factor=100, use_sobel=False, ref_frame_num=0): hypercube, lsx, lsy = get_hypercube(data, xat, yat) if bn.anynan(hypercube): raise NanInsideHypercube(True) calculate_shift = RegisterTranslation(upsample_factor=upsample_factor) filterfn = sobel if use_sobel else lambda x: x shifts, aligned_stack = alignstack(hypercube.T, shiftfn=calculate_shift, ref_frame_num=ref_frame_num, filterfn=filterfn) xmin, ymin = shifts[:, 0].min(), shifts[:, 1].min() xmax, ymax = shifts[:, 0].max(), shifts[:, 1].max() xmin, xmax = int(round(xmin)), int(round(xmax)) ymin, ymax = int(round(ymin)), int(round(ymax)) shape = hypercube.shape slicex = slice(max(xmax, 0), min(shape[1], shape[1] + xmin)) slicey = slice(max(ymax, 0), min(shape[0], shape[0] + ymin)) cropped = np.array(aligned_stack).T[slicey, slicex] # transform numpy array back to Orange.data.Table return shifts, build_spec_table( *_spectra_from_image(cropped, getx(data), np.linspace(*lsx)[slicex], np.linspace(*lsy)[slicey]))
def process_stack(data, xat, yat, upsample_factor=100, use_sobel=False, ref_frame_num=0): hypercube, lsx, lsy = get_hypercube(data, xat, yat) calculate_shift = RegisterTranslation(upsample_factor=upsample_factor) filterfn = sobel if use_sobel else lambda x: x shifts, aligned_stack = alignstack(hypercube.T, shiftfn=calculate_shift, ref_frame_num=ref_frame_num, filterfn=filterfn) xmin, ymin = shifts[:, 0].min(), shifts[:, 1].min() xmax, ymax = shifts[:, 0].max(), shifts[:, 1].max() xmin, xmax = int(round(xmin)), int(round(xmax)) ymin, ymax = int(round(ymin)), int(round(ymax)) shape = hypercube.shape slicex = slice(max(xmax, 0), min(shape[1], shape[1]+xmin)) slicey = slice(max(ymax, 0), min(shape[0], shape[0]+ymin)) cropped = np.array(aligned_stack).T[slicey, slicex] # transform numpy array back to Orange.data.Table return shifts, build_spec_table(*_spectra_from_image(cropped, getx(data), np.linspace(*lsx)[slicex], np.linspace(*lsy)[slicey]))
def orange_table_from_3d(image3d): info = _spectra_from_image(image3d, range(5), range(image3d[:, :, 0].shape[1]), range(image3d[:, :, 0].shape[0])) data = build_spec_table(*info) return data
def test_image_computation(self): spectra = [[[0, 0, 2, 0], [0, 0, 1, 0]], [[1, 2, 2, 0], [0, 1, 1, 0]]] wns = [0, 1, 2, 3] x_locs = [0, 1] y_locs = [0, 1] data = build_spec_table(*_spectra_from_image(spectra, wns, x_locs, y_locs)) def last_called_array(m): arrays = [a[0][0] for a in m.call_args_list if a and a[0] and isinstance(a[0][0], np.ndarray)] return arrays[-1] wrap = self.widget.imageplot.img # integrals from zero; default self.send_signal("Data", data) with patch.object(wrap, 'setImage', wraps=wrap.setImage) as m: wait_for_image(self.widget) called = last_called_array(m) target = [[2, 1], [4.5, 2]] np.testing.assert_equal(called.squeeze(), target) # peak from zero self.widget.integration_method = \ self.widget.integration_methods.index(IntegrateFeaturePeakSimple) self.widget._change_integral_type() with patch.object(wrap, 'setImage', wraps=wrap.setImage) as m: wait_for_image(self.widget) called = last_called_array(m) target = [[2, 1], [2, 1]] np.testing.assert_equal(called.squeeze(), target) # single wavenumber (feature) self.widget.controls.value_type.buttons[1].click() self.widget.attr_value = data.domain.attributes[1] self.widget.update_feature_value() with patch.object(wrap, 'setImage', wraps=wrap.setImage) as m: wait_for_image(self.widget) called = last_called_array(m) target = [[0, 0], [2, 1]] np.testing.assert_equal(called.squeeze(), target) # RGB self.widget.controls.value_type.buttons[2].click() self.widget.rgb_red_value = data.domain.attributes[0] self.widget.rgb_green_value = data.domain.attributes[1] self.widget.rgb_blue_value = data.domain.attributes[2] self.widget.update_rgb_value() with patch.object(wrap, 'setImage', wraps=wrap.setImage) as m: wait_for_image(self.widget) called = last_called_array(m) # first three wavenumbers (features) should be passed to setImage target = [data.X[0, :3], data.X[1, :3]], [data.X[2, :3], data.X[3, :3]] np.testing.assert_equal(called, target)
def process_stack(data, xat, yat, upsample_factor=100, use_sobel=False, ref_frame_num=0): ndom = Domain([xat, yat]) datam = Table(ndom, data) coorx = datam.X[:, 0] coory = datam.X[:, 1] lsx = values_to_linspace(coorx) lsy = values_to_linspace(coory) lsz = data.X.shape[1] if lsx is None: raise InvalidAxisException("x") if lsy is None: raise InvalidAxisException("y") # set data hypercube = np.ones((lsy[2], lsx[2], lsz)) * np.nan xindex = index_values(coorx, lsx) yindex = index_values(coory, lsy) hypercube[yindex, xindex] = data.X if np.any(np.isnan(hypercube)): raise NanInsideHypercube(np.sum(np.isnan(hypercube))) calculate_shift = RegisterTranslation(upsample_factor=upsample_factor) filterfn = sobel if use_sobel else lambda x: x shifts, aligned_stack = alignstack(hypercube.T, shiftfn=calculate_shift, ref_frame_num=ref_frame_num, filterfn=filterfn) xmin, ymin = shifts[:, 0].min(), shifts[:, 1].min() xmax, ymax = shifts[:, 0].max(), shifts[:, 1].max() xmin, xmax = int(round(xmin)), int(round(xmax)) ymin, ymax = int(round(ymin)), int(round(ymax)) shape = hypercube.shape slicex = slice(max(xmax, 0), min(shape[1], shape[1] + xmin)) slicey = slice(max(ymax, 0), min(shape[0], shape[0] + ymin)) cropped = np.array(aligned_stack).T[slicey, slicex] # transform numpy array back to Orange.data.Table return shifts, build_spec_table( *_spectra_from_image(cropped, getx(data), np.linspace(*lsx)[slicex], np.linspace(*lsy)[slicey]))
def test_hypercube_roundtrip(self): d = self.mosaic xat = [v for v in d.domain.metas if v.name == "map_x"][0] yat = [v for v in d.domain.metas if v.name == "map_y"][0] hypercube, lsx, lsy = get_hypercube(d, xat, yat) features = getx(d) ndom = Orange.data.Domain([xat, yat]) datam = Orange.data.Table(ndom, d) coorx = datam.X[:, 0] coory = datam.X[:, 1] coords = np.ones((lsx[2], lsy[2], 2)) coords[index_values(coorx, lsx), index_values(coory, lsy)] = datam.X x_locs = coords[:, 0, 0] y_locs = coords[0, :, 1] features, spectra, data = _spectra_from_image(hypercube, features, x_locs, y_locs) nd = build_spec_table(features, spectra, data) np.testing.assert_equal(d.X, nd.X) np.testing.assert_equal(d.Y, nd.Y) np.testing.assert_equal(d.metas, nd.metas) self.assertEqual(d.domain, nd.domain)
def calculateFFT(self): """ Calculate FFT from input interferogram(s). This is a handler method for - bad data / data shape - splitting the array in the case of two interferogram sweeps per dataset. - multiple input interferograms Based on mertz module by Eric Peach, 2014 """ wavenumbers = None spectra = [] phases = [] zpd_fwd = [] zpd_back = [] # Reset info, error and warning dialogs self.Error.clear() self.Warning.clear() fft_single = irfft.IRFFT( dx=self.dx, apod_func=self.apod_func, zff=2**self.zff, phase_res=self.phase_resolution if self.phase_res_limit else None, phase_corr=self.phase_corr, peak_search=self.peak_search, ) ifg_data = self.data.X stored_phase = self.stored_phase stored_zpd_fwd, stored_zpd_back = None, None # Only use first row stored phase for now if stored_phase is not None: stored_phase = stored_phase[0] try: stored_zpd_fwd = int(stored_phase["zpd_fwd"].value) except ValueError: stored_zpd_fwd = None try: stored_zpd_back = int(stored_phase["zpd_back"].value) except ValueError: stored_zpd_back = None stored_phase = stored_phase.x # lowercase x for RowInstance # Use manual zpd value(s) if specified and enable batch processing elif not self.peak_search_enable: stored_zpd_fwd = self.zpd1 stored_zpd_back = self.zpd2 chunks = max(1, len(self.data) // CHUNK_SIZE) ifg_data = np.array_split(self.data.X, chunks, axis=0) fft_single = irfft.MultiIRFFT( dx=self.dx, apod_func=self.apod_func, zff=2**self.zff, phase_res=self.phase_resolution if self.phase_res_limit else None, phase_corr=self.phase_corr, peak_search=self.peak_search, ) if self.reader == 'NeaReaderGSF': fft_single = irfft.ComplexFFT( dx=self.dx, apod_func=self.apod_func, zff=2**self.zff, phase_res=self.phase_resolution if self.phase_res_limit else None, phase_corr=self.phase_corr, peak_search=self.peak_search, ) full_data = self.data.X[::2] * np.exp(self.data.X[1::2] * 1j) for row in full_data: spectrum_out, phase_out, wavenumbers = fft_single( row, zpd=stored_zpd_fwd) spectra.append(spectrum_out) spectra.append(phase_out) spectra = np.vstack(spectra) if self.limit_output is True: wavenumbers, spectra = self.limit_range(wavenumbers, spectra) self.spectra_table = build_spec_table(wavenumbers, spectra, additional_table=self.data) self.Outputs.spectra.send(self.spectra_table) return for row in ifg_data: if self.sweeps in [2, 3]: # split double-sweep for forward/backward # forward: 2-2 = 0 , backward: 3-2 = 1 try: row = np.hsplit(row, 2)[self.sweeps - 2] except ValueError as e: self.Error.ifg_split_error(e) return if self.sweeps in [0, 2, 3]: try: spectrum_out, phase_out, wavenumbers = fft_single( row, zpd=stored_zpd_fwd, phase=stored_phase) zpd_fwd.append(fft_single.zpd) except ValueError as e: self.Error.fft_error(e) return elif self.sweeps == 1: # Double sweep interferogram is split, solved independently and the # two results are averaged. try: data = np.hsplit(row, 2) except ValueError as e: self.Error.ifg_split_error(e) return fwd = data[0] # Reverse backward sweep to match fwd sweep back = data[1][::-1] # Calculate spectrum for both forward and backward sweeps try: spectrum_fwd, phase_fwd, wavenumbers = fft_single( fwd, zpd=stored_zpd_fwd, phase=stored_phase) zpd_fwd.append(fft_single.zpd) spectrum_back, phase_back, wavenumbers = fft_single( back, zpd=stored_zpd_back, phase=stored_phase) zpd_back.append(fft_single.zpd) except ValueError as e: self.Error.fft_error(e) return # Calculate the average of the forward and backward sweeps spectrum_out = np.mean(np.array([spectrum_fwd, spectrum_back]), axis=0) phase_out = np.mean(np.array([phase_fwd, phase_back]), axis=0) else: return spectra.append(spectrum_out) phases.append(phase_out) spectra = np.vstack(spectra) phases = np.vstack(phases) self.phases_table = build_spec_table(wavenumbers, phases, additional_table=self.data) if not self.peak_search_enable: # All zpd values are equal by definition zpd_fwd = zpd_fwd[:1] self.phases_table = add_meta_to_table( self.phases_table, ContinuousVariable.make("zpd_fwd"), zpd_fwd) if zpd_back: if not self.peak_search_enable: zpd_back = zpd_back[:1] self.phases_table = add_meta_to_table( self.phases_table, ContinuousVariable.make("zpd_back"), zpd_back) if self.limit_output is True: wavenumbers, spectra = self.limit_range(wavenumbers, spectra) self.spectra_table = build_spec_table(wavenumbers, spectra, additional_table=self.data) self.Outputs.spectra.send(self.spectra_table) self.Outputs.phases.send(self.phases_table)
def calculateFFT(self): """ Calculate FFT from input interferogram(s). This is a handler method for - bad data / data shape - splitting the array in the case of two interferogram sweeps per dataset. - multiple input interferograms Based on mertz module by Eric Peach, 2014 """ self.wavenumbers = None self.spectra = None self.phases = None # Reset info, error and warning dialogs self.error(1) # FFT ValueError, usually wrong sweep number self.error(2) # vsplit ValueError, odd number of data points self.warning(4) # Phase resolution limit too low for row in self.data.X: # Check to see if interferogram is single or double sweep if self.sweeps == 0: try: spectrum_out, phase_out, self.wavenumbers = self.fft_single( row) except ValueError as e: self.error(1, "FFT error: %s" % e) return elif self.sweeps == 1: # Double sweep interferogram is split, solved independently and the # two results are averaged. try: data = np.hsplit(row, 2) except ValueError as e: self.error(2, "%s" % e) return fwd = data[0] # Reverse backward sweep to match fwd sweep back = data[1][::-1] # Calculate spectrum for both forward and backward sweeps try: spectrum_fwd, phase_fwd, self.wavenumbers = self.fft_single( fwd) spectrum_back, phase_back, self.wavenumbers = self.fft_single( back) except ValueError as e: self.error(1, "FFT error: %s" % e) return # Calculate the average of the forward and backward sweeps spectrum_out = np.mean(np.array([spectrum_fwd, spectrum_back]), axis=0) phase_out = np.mean(np.array([phase_fwd, phase_back]), axis=0) else: return if self.spectra is not None: self.spectra = np.vstack((self.spectra, spectrum_out)) self.phases = np.vstack((self.phases, phase_out)) else: self.spectra = spectrum_out self.phases = phase_out if self.limit_output is True: limits = np.searchsorted(self.wavenumbers, [self.out_limit1, self.out_limit2]) self.wavenumbers = self.wavenumbers[limits[0]:limits[1]] # Handle 1D array if necessary if self.spectra.ndim == 1: self.spectra = self.spectra[None, limits[0]:limits[1]] self.phases = self.phases[None, limits[0]:limits[1]] else: self.spectra = self.spectra[:, limits[0]:limits[1]] self.phases = self.phases[:, limits[0]:limits[1]] self.spectra_table = build_spec_table(self.wavenumbers, self.spectra) self.phases_table = build_spec_table(self.wavenumbers, self.phases) self.Outputs.spectra.send(self.spectra_table) self.Outputs.phases.send(self.phases_table)
def calculateFFT(self): """ Calculate FFT from input interferogram(s). This is a handler method for - bad data / data shape - splitting the array in the case of two interferogram sweeps per dataset. - multiple input interferograms Based on mertz module by Eric Peach, 2014 """ wavenumbers = None spectra = [] phases = [] zpd_fwd = [] zpd_back = [] # Reset info, error and warning dialogs self.Error.clear() self.Warning.clear() fft_single = irfft.IRFFT(dx=self.dx, apod_func=self.apod_func, zff=2**self.zff, phase_res=self.phase_resolution if self.phase_res_limit else None, phase_corr=self.phase_corr, peak_search=self.peak_search, ) stored_phase = self.stored_phase stored_zpd_fwd, stored_zpd_back = None, None # Only use first row stored phase for now if stored_phase is not None: stored_phase = stored_phase[0] try: stored_zpd_fwd = int(stored_phase["zpd_fwd"].value) except ValueError: stored_zpd_fwd = None try: stored_zpd_back = int(stored_phase["zpd_back"].value) except ValueError: stored_zpd_back = None stored_phase = stored_phase.x # lowercase x for RowInstance for row in self.data.X: if self.sweeps in [2, 3]: # split double-sweep for forward/backward # forward: 2-2 = 0 , backward: 3-2 = 1 try: row = np.hsplit(row, 2)[self.sweeps - 2] except ValueError as e: self.Error.ifg_split_error(e) return if self.sweeps in [0, 2, 3]: try: spectrum_out, phase_out, wavenumbers = fft_single( row, zpd=stored_zpd_fwd, phase=stored_phase) zpd_fwd.append(fft_single.zpd) except ValueError as e: self.Error.fft_error(e) return elif self.sweeps == 1: # Double sweep interferogram is split, solved independently and the # two results are averaged. try: data = np.hsplit(row, 2) except ValueError as e: self.Error.ifg_split_error(e) return fwd = data[0] # Reverse backward sweep to match fwd sweep back = data[1][::-1] # Calculate spectrum for both forward and backward sweeps try: spectrum_fwd, phase_fwd, wavenumbers = fft_single( fwd, zpd=stored_zpd_fwd, phase=stored_phase) zpd_fwd.append(fft_single.zpd) spectrum_back, phase_back, wavenumbers = fft_single( back, zpd=stored_zpd_back, phase=stored_phase) zpd_back.append(fft_single.zpd) except ValueError as e: self.Error.fft_error(e) return # Calculate the average of the forward and backward sweeps spectrum_out = np.mean(np.array([spectrum_fwd, spectrum_back]), axis=0) phase_out = np.mean(np.array([phase_fwd, phase_back]), axis=0) else: return spectra.append(spectrum_out) phases.append(phase_out) spectra = np.vstack(spectra) phases = np.vstack(phases) self.phases_table = build_spec_table(wavenumbers, phases, additional_table=self.data) self.phases_table = add_meta_to_table(self.phases_table, ContinuousVariable.make("zpd_fwd"), zpd_fwd) if zpd_back: self.phases_table = add_meta_to_table(self.phases_table, ContinuousVariable.make("zpd_back"), zpd_back) if self.limit_output is True: limits = np.searchsorted(wavenumbers, [self.out_limit1, self.out_limit2]) wavenumbers = wavenumbers[limits[0]:limits[1]] # Handle 1D array if necessary if spectra.ndim == 1: spectra = spectra[None, limits[0]:limits[1]] else: spectra = spectra[:, limits[0]:limits[1]] self.spectra_table = build_spec_table(wavenumbers, spectra, additional_table=self.data) self.Outputs.spectra.send(self.spectra_table) self.Outputs.phases.send(self.phases_table)
def calculateFFT(self): """ Calculate FFT from input interferogram(s). This is a handler method for - bad data / data shape - splitting the array in the case of two interferogram sweeps per dataset. - multiple input interferograms Based on mertz module by Eric Peach, 2014 """ self.wavenumbers = None self.spectra = None self.phases = None # Reset info, error and warning dialogs self.error(1) # FFT ValueError, usually wrong sweep number self.error(2) # vsplit ValueError, odd number of data points self.warning(4) # Phase resolution limit too low for row in self.data.X: # Check to see if interferogram is single or double sweep if self.sweeps == 0: try: spectrum_out, phase_out, self.wavenumbers = self.fft_single(row) except ValueError as e: self.error(1, "FFT error: %s" % e) return elif self.sweeps == 1: # Double sweep interferogram is split, solved independently and the # two results are averaged. try: data = np.hsplit(row, 2) except ValueError as e: self.error(2, "%s" % e) return fwd = data[0] # Reverse backward sweep to match fwd sweep back = data[1][::-1] # Calculate spectrum for both forward and backward sweeps try: spectrum_fwd, phase_fwd, self.wavenumbers = self.fft_single(fwd) spectrum_back, phase_back, self.wavenumbers = self.fft_single(back) except ValueError as e: self.error(1, "FFT error: %s" % e) return # Calculate the average of the forward and backward sweeps spectrum_out = np.mean( np.array([spectrum_fwd, spectrum_back]), axis=0) phase_out = np.mean(np.array([phase_fwd, phase_back]), axis=0) else: return if self.spectra is not None: self.spectra = np.vstack((self.spectra, spectrum_out)) self.phases = np.vstack((self.phases, phase_out)) else: self.spectra = spectrum_out self.phases = phase_out if self.limit_output is True: limits = np.searchsorted(self.wavenumbers, [self.out_limit1, self.out_limit2]) self.wavenumbers = self.wavenumbers[limits[0]:limits[1]] # Handle 1D array if necessary if self.spectra.ndim == 1: self.spectra = self.spectra[None,limits[0]:limits[1]] self.phases = self.phases[None,limits[0]:limits[1]] else: self.spectra = self.spectra[:,limits[0]:limits[1]] self.phases = self.phases[:,limits[0]:limits[1]] self.spectra_table = build_spec_table(self.wavenumbers, self.spectra) self.phases_table = build_spec_table(self.wavenumbers, self.phases) self.Outputs.spectra.send(self.spectra_table) self.Outputs.phases.send(self.phases_table)