def save_to_igor_itx(file_path: str, xs: List[np.ndarray], datas: List[np.ndarray], names: List[str], ys: Optional[List[np.ndarray]] = None, x_labels: Optional[Union[str, List[str]]] = None, y_labels: Optional[Union[str, List[str]]] = None): """Save data to a .itx file which can be dropped into Igor""" def check_axis_linear(arr: np.ndarray, axis: str, name: str, current_waves: list) -> bool: if arr.shape[-1] > 1 and not np.all( np.isclose(np.diff(arr), np.diff(arr)[0])): logger.warning( f"{file_path}: Igor doesn't support a non-linear {axis}-axis. Saving as separate wave" ) axis_wave = IgorWave(arr, name=name + f'_{axis}') current_waves.append(axis_wave) return False else: return True if x_labels is None or isinstance(x_labels, str): x_labels = [x_labels] * len(datas) if y_labels is None or isinstance(y_labels, str): y_labels = [y_labels] * len(datas) if ys is None: ys = [None] * len(datas) assert all([ len(datas) == len(list_) for list_ in [xs, names, x_labels, y_labels] ]) waves = [] for x, y, data, name, x_label, y_label in zip(xs, ys, datas, names, x_labels, y_labels): wave = IgorWave(data, name=name) if x is not None: if check_axis_linear(x, 'x', name, waves): wave.set_dimscale('x', x[0], np.mean(np.diff(x)), units=x_label) if y is not None: if check_axis_linear(y, 'y', name, waves): wave.set_dimscale('y', y[0], np.mean(np.diff(y)), units=y_label) elif y_label is not None: wave.set_datascale(y_label) waves.append(wave) with open(file_path, 'w') as fp: for wave in waves: wave.save_itx( fp, image=True ) # Image = True hopefully makes np and igor match in x/y
def test_data_units(self): wavename = 'wave0' unitslist = ('', 'sec', 'second') descs = ('empty units', 'short units', 'long units') for desc, units in zip(descs, unitslist): with self.subTest(desc): com = 'X SetScale d,.*"%s",.*\'%s\'' % (units, wavename) array = np.random.randint(0, 100, 10, dtype=np.int32) wave = IgorWave(array) wave.set_datascale(units) with TemporaryFile('wb') as fp: wave.save(fp) with TemporaryFile('w+t') as fp: wave.save_itx(fp) fp.seek(0) content = fp.read() self.assertRegex(content, com)
def fig_to_igor_itx(f: go.Figure, filepath: str): d = data_from_plotly_fig(f) waves = [] for k in d: if not k.endswith('_x') and not k.endswith('_y'): wave = IgorWave(d[k], name=k) wave.set_datascale(f.layout.yaxis.title.text) for dim in ['x', 'y']: if f'{k}_{dim}' in d: dim_arr = d[f'{k}_{dim}'] wave.set_dimscale('x', dim_arr[0], np.mean(np.diff(dim_arr)), units=f.layout.xaxis.title.text) waves.append(wave) with open(filepath, 'w') as fp: for wave in waves: wave.save_itx( fp, image=True ) # Image = True hopefully makes np and igor match in x/y