Esempio n. 1
0
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
Esempio n. 2
0
 def test_invalid_name(self):
     name = '\'invalid_name\''  # wave cannot contain quotation marks
     array = np.random.randint(0, 100, 10, dtype=np.int32)
     wave = IgorWave(array)
     self.assertRaises(validator.InvalidNameError,
                       wave.rename,
                       name,
                       on_errors='raise')
     wave.rename(name, on_errors='fix')
     self.assertEqual(wave.name, name.replace('\'', '_'))
Esempio n. 3
0
 def test_dimscale(self):
     array = np.random.randint(0, 100, 10, dtype=np.int32)
     wave = IgorWave(array)
     wave.set_dimscale('x', 0, 0.01, 's')
     with TemporaryFile('wb') as fp:
         wave.save(fp)
     with TemporaryFile('wt') as fp:
         wave.save_itx(fp)
Esempio n. 4
0
 def test_pint(self):
     import pint
     ureg = pint.UnitRegistry()
     Q = ureg.Quantity
     a = np.arange(0.0, 10.0, 1.0)
     with self.subTest('short units'):
         wave = IgorWave(Q(a, 's'))
         bunits = wave._wave_header.dataUnits
         expected = 's'.encode(ENCODING)
         self.assertEqual(bunits, expected)
     with self.subTest('long units'):
         q = Q(a, 'kg m / s**2')
         wave = IgorWave(q)
         bunits = wave._extended_data_units
         expected = '{:~}'.format(q.units).encode(ENCODING)
         self.assertEqual(bunits, expected)
Esempio n. 5
0
 def test_datetime(self):
     array = np.arange(np.datetime64('2019-01-01'),
                       np.datetime64('2019-12-31'), np.timedelta64(1, 'D'))
     wave = IgorWave(array)
     self.assertIs(wave._check_array().dtype.type, np.float64)
     with TemporaryFile('wb') as bin, TemporaryFile('wt') as text:
         wave.save(bin)
         wave.save_itx(text)
Esempio n. 6
0
 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
Esempio n. 7
0
def dict_to_ibw(dict_like, prefix, on_errors='fix'):
    """

    :param dict_like: dictionary-like object ({name: array-like, ...})
    :param prefix: file name prefix (each wave is saved as <prefix>_<column>.ibw)
    :param on_errors: behavior when invalid name is given. 'fix': fix errors. 'raise': raise an exception.
    :return: dictionary of generated waves ({name: wave, ...})
    """
    wavelist = [
        IgorWave(array, name, on_errors)
        for (name, array) in dict_like.items()
    ]
    for wave in wavelist:
        wave.save(str(prefix) + '_%s.ibw' % wave.name)
    return {wave.name: wave for wave in wavelist}
Esempio n. 8
0
 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)
Esempio n. 9
0
 def test_array_type(self):
     valid_types = (np.bool_, np.float16, np.int32, np.uint32, np.int64,
                    np.uint64, np.float32, np.float64, np.complex128)
     invalid_types = (object, str)
     for vt in valid_types:
         with self.subTest('type: %r' % vt):
             wave = IgorWave(np.random.randint(0, 100, 10).astype(vt))
             with TemporaryFile('wb') as fp:
                 wave.save(fp)
             with TemporaryFile('wt') as fp:
                 wave.save_itx(fp)
     for it in invalid_types:
         with self.subTest('type: %r' % it):
             wave = IgorWave(np.random.randint(0, 100, 10).astype(it))
             with TemporaryFile('wb') as fp:
                 self.assertRaises(TypeError, wave.save, fp)
             with TemporaryFile('wt') as fp:
                 self.assertRaises(TypeError, wave.save_itx, fp)
Esempio n. 10
0
def make_dos_waves(path_list):
    for rt in path_list:
        print(rt)

        fl = os.listdir(rt)
        fl = [f for f in fl if '.dos' in f]
        fl.sort()

        fm = []
        head = ''
        for f in fl:
            if not f.split('.')[0] == head:
                head = f.split('.')[0]
                fm.append([])
            fm[len(fm) - 1].append(f)

        print(fm)

        for fl in fm:
            ws = {}
            head = fl[0].split('.')[0]
            for f in fl:
                sp = f.split('eV')[1]
                if sp == 'up':
                    r = 1
                elif sp == 'dn':
                    r = -1
                en = 0
                wp = rt + head + '_dos.itx'
                path = rt + f
                dos = load_dos(path)
                for ky in dos.keys():
                    ws[ky + sp] = dos[ky] * r

            print(ws.keys())
            el = ws['ENERGYup']

            e_s = el[0]
            e_n = el.shape[0]
            e_e = el[e_n - 1]
            e_st = (e_e - e_s) / (e_n - 1)

            with open(wp, 'w') as fp:
                for ky in ws.keys():
                    if 'ENERGY' in ky:
                        pass
                    else:
                        wn = head + '_' + ky.replace(':', '_')
                        wn = wn.replace('-', '_')
                        wave = IgorWave(ws[ky], name=wn)
                        wave.set_dimscale('x', e_s, e_st, 'eV')
                        wave.save_itx(fp)
        print(len(fm))
Esempio n. 11
0
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
Esempio n. 12
0
def dict_to_itx(dict_like, path_or_buf, on_errors='fix'):
    """

    :param dict_like: dictionary-like object ({name: array-like, ...})
    :param path_or_buf: filename or file-like object
    :param on_errors: behavior when invalid name is given. 'fix': fix errors. 'raise': raise an exception.
    :return: dictionary of generated waves ({name: wave, ...})
    """
    fp = path_or_buf if hasattr(path_or_buf, 'write') else open(
        path_or_buf, 'w', encoding=igorwriter.ENCODING)
    wavelist = [
        IgorWave(array, name, on_errors)
        for (name, array) in dict_like.items()
    ]
    try:
        for wave in wavelist:
            wave.save_itx(fp)
    finally:
        if fp is not path_or_buf:
            fp.close()
    return {wave.name: wave for wave in wavelist}
Esempio n. 13
0
def make_3Dband_ibw(npypath, savepath, name, e_s, e_e):
    ch = np.load(npypath)
    print('npy data loaded')
    dims = len(ch.shape) - 1
    ky_s = -1
    ky_e = 1
    kz_s = -1
    kz_e = 1

    sp.call(['mkdir', '-p', savepath])
    if dims == 2:
        ch = np.transpose(ch, (1, 2, 0))
        print(ch.shape)
        ch = np.concatenate([np.flip(ch, 1), np.delete(ch, 0, 1)], 1)
        ch = np.concatenate([np.flip(ch, 2), np.delete(ch, 0, 2)], 2)
    elif dims == 3:
        ch = np.transpose(ch, (2, 3, 1, 0))
        ch = np.concatenate([np.flip(ch, 1), np.delete(ch, 0, 1)], 1)
        ch = np.concatenate([np.flip(ch, 2), np.delete(ch, 0, 2)], 2)
        ch = np.concatenate([np.flip(ch, 3), np.delete(ch, 0, 3)], 3)
        kz_n = ch.shape[3]
        kz_st = (kz_e - kz_s) / (kz_n - 1)
    print('concatenate end')
    ky_n = ch.shape[1]
    ky_st = (ky_e - ky_s) / (ky_n - 1)

    for ba in range(ch.shape[0]):
        out = savepath + name + '_Band' + str(ba + 1) + '.ibw'
        if (np.amax(ch[ba]) >= e_s and np.amin(ch[ba]) <= e_e):
            wave = IgorWave(ch[ba], name=name + '_Band' + str(ba + 1))
            wave.set_dimscale('x', ky_s, ky_st, '2pi/a')
            wave.set_dimscale('y', ky_s, ky_st, '2pi/a')
            if dims == 3:
                wave.set_dimscale('z', kz_s, kz_st, '2pi/a')
            wave.save(out)
            print('save : ' + out)
Esempio n. 14
0
    def test_file_io(self):
        array = np.random.randint(0, 100, 10, dtype=np.int32)
        wave = IgorWave(array)
        with TemporaryDirectory() as datadir:
            itx = datadir + '/wave0.itx'
            ibw = datadir + '/wave0.ibw'
            wave.save_itx(itx)
            with open(itx, 'w') as fp:
                wave.save_itx(fp)

            wave.save(ibw)
            with self.subTest('save in a new binary file'):
                with open(ibw, 'wb') as fp:
                    wave.save(fp)
            with self.subTest('append to a binary should fail'):
                with open(ibw, 'wb') as fp:
                    fp.write(b'something')
                    self.assertRaises(ValueError, wave.save, fp)
                with open(ibw, 'ab') as fp:
                    self.assertRaises(ValueError, wave.save, fp)
            with self.subTest('save in a truncated binary file'):
                with open(ibw, 'wb') as fp:
                    wave.save(fp)