def save_ht_outs(h5_gp, tfp, shift): """ Save processed Hilbert Transform outputs""" # Error check if isinstance(h5_gp, h5py.Dataset): raise ValueError('Must pass an h5Py group') # Filter bad pixels tfp_fixed, _ = badpixels.fix_array(tfp, threshold=2) tfp_fixed = np.array(tfp_fixed) # write data; note that this is all actually deprecated and should be fixed # grp_name = h5_gp.name # grp_tr = px.io.VirtualGroup(grp_name) # tfp_px = px.io.VirtualDataset('tfp', tfp, parent = h5_gp) # shift_px = px.io.VirtualDataset('shift', shift, parent = h5_gp) # tfp_fixed_px = px.io.VirtualDataset('tfp_fixed', tfp_fixed, parent = h5_gp) # # grp_tr.attrs['timestamp'] = get_time_stamp() # grp_tr.add_children([tfp_px]) # grp_tr.add_children([shift_px]) # grp_tr.add_children([tfp_fixed_px]) # write data using current pyUSID implementations # grp_tr = h5_file.create_group(h5_gp.name) tfp_px = h5_gp.create_dataset('tfp', data=tfp, dtype=np.float32) shift_px = h5_gp.create_dataset('shift', data=shift, dtype=np.float32) tfp_fixed_px = h5_gp.create_dataset('tfp_fixed', data=tfp_fixed, dtype=np.float32) h5_gp.attrs['timestamp'] = get_time_stamp() return tfp_px, shift_px, tfp_fixed_px
def save_CSV_from_file(h5_file, h5_path='/', append='', mirror=False): """ Saves the tfp, shift, and fixed_tfp as CSV files Parameters ---------- h5_file : H5Py file of FFtrEFM class Reminder you can always type: h5_svd.file or h5_avg.file for this h5_path : str, optional specific folder path to search for the tfp data. Usually not needed. append : str, optional text to append to file name """ h5_ff = h5_file if isinstance(h5_file, ffta.hdf_utils.process.FFtrEFM): print('Saving from FFtrEFM Class') h5_ff = h5_file.h5_main.file h5_path = h5_file.h5_results_grp.name elif not isinstance(h5_file, h5py.File): print('Saving from pyUSID object') h5_ff = h5_file.file tfp = usid.hdf_utils.find_dataset(h5_ff[h5_path], 'tfp')[0][()] # tfp_fixed = usid.hdf_utils.find_dataset(h5_file[h5_path], 'tfp_fixed')[0][()] shift = usid.hdf_utils.find_dataset(h5_ff[h5_path], 'shift')[0][()] tfp_fixed, _ = badpixels.fix_array(tfp, threshold=2) tfp_fixed = np.array(tfp_fixed) print(usid.hdf_utils.find_dataset(h5_ff[h5_path], 'shift')[0].parent.name) path = h5_ff.file.filename.replace('\\', '/') path = '/'.join(path.split('/')[:-1]) + '/' os.chdir(path) if mirror: np.savetxt('tfp-' + append + '.csv', np.fliplr(tfp).T, delimiter=',') np.savetxt('shift-' + append + '.csv', np.fliplr(shift).T, delimiter=',') np.savetxt('tfp_fixed-' + append + '.csv', np.fliplr(tfp_fixed).T, delimiter=',') else: np.savetxt('tfp-' + append + '.csv', tfp.T, delimiter=',') np.savetxt('shift-' + append + '.csv', shift.T, delimiter=',') np.savetxt('tfp_fixed-' + append + '.csv', tfp_fixed.T, delimiter=',') return
def plot_tfp(ffprocess, scale_tfp=1e6, scale_shift=1, threshold=2, **kwargs): ''' Quickly plots the tfp and shift data. If there's a height image in the h5_file associated with ffprocess, will plot that as well Parameters ---------- ffprocess : FFtrEFM class object (inherits Process) Returns ------- fig, a : figure and axes objects ''' fig, a = plt.subplots(nrows=2, ncols=2, figsize=(13, 6)) tfp_ax = a[0][1] shift_ax = a[1][1] img_length = ffprocess.parm_dict['FastScanSize'] img_height = ffprocess.parm_dict['SlowScanSize'] kwarg = {'origin': 'lower', 'x_vec': img_length * 1e6, 'y_vec': img_height * 1e6, 'num_ticks': 5, 'stdevs': 3, 'show_cbar': True} for k, v in kwarg.items(): if k not in kwargs: kwargs.update({k: v}) num_cols = ffprocess.parm_dict['num_cols'] num_rows = ffprocess.parm_dict['num_rows'] try: ht = ffprocess.h5_main.file['/height/Raw_Data'][:, 0] ht = np.reshape(ht, [num_cols, num_rows]).transpose() ht_ax = a[0][0] ht_image, cbar = usid.viz.plot_utils.plot_map(ht_ax, ht * 1e9, cmap='gray', **kwarg) cbar.set_label('Height (nm)', rotation=270, labelpad=16) except: pass tfp_ax.set_title('tFP Image') shift_ax.set_title('Shift Image') tfp_fixed, _ = badpixels.fix_array(ffprocess.h5_tfp[()], threshold=threshold) tfp_image, cbar_tfp = usid.viz.plot_utils.plot_map(tfp_ax, tfp_fixed * scale_tfp, cmap='inferno', **kwargs) shift_image, cbar_sh = usid.viz.plot_utils.plot_map(shift_ax, ffprocess.h5_shift[()] * scale_shift, cmap='inferno', **kwargs) cbar_tfp.set_label('Time (us)', rotation=270, labelpad=16) cbar_sh.set_label('Frequency Shift (Hz)', rotation=270, labelpad=16) text = tfp_ax.text(num_cols / 2, num_rows + 3, '') return fig, a
def save_CSV_from_file(h5_file, h5_path='/', append='', mirror=False): """ Saves the Q, Amp, as CSV files :param h5_file: Reminder you can always type: h5_svd.file or h5_avg.file for this :type h5_file: H5Py file :param h5_path: specific folder path to search for the tfp data. Usually not needed. :type h5_path: str, optional :param append: text to append to file name (e.g. RD01 or something related to the file) :type append: str, optional :param mirror: Flips the ibw signal if acquired during a retrace, so data match the topography pixel-to-pixel :type mirror: bool, optional """ Q = usid.hdf_utils.find_dataset(h5_file[h5_path], 'Q')[-1][()] A = usid.hdf_utils.find_dataset(h5_file[h5_path], 'Amplitude')[-1][()] Q_fixed, _ = badpixels.fix_array(Q, threshold=2) print(usid.hdf_utils.find_dataset(h5_file[h5_path], 'Q')[-1].parent.name) path = h5_file.file.filename.replace('\\', '/') path = '/'.join(path.split('/')[:-1]) + '/' os.chdir(path) if mirror: np.savetxt('Q-' + append + '.csv', np.fliplr(Q).T, delimiter=',') np.savetxt('Qfixed-' + append + '.csv', np.fliplr(Q_fixed).T, delimiter=',') np.savetxt('Amp-' + append + '.csv', np.fliplr(A).T, delimiter=',') else: np.savetxt('Q' + append + '.csv', Q.T, delimiter=',') np.savetxt('Qfixed-' + append + '.csv', Q_fixed.T, delimiter=',') np.savetxt('Amp-' + append + '.csv', A.T, delimiter=',') return
def save_ht_outs(h5_gp, tfp, shift): """ Save processed Hilbert Transform outputs :param h5_gp: :type h5_gp: :param tfp: :type tfp: :param shift: :type shift: :returns: tuple (tfp_px, shift_px, tfp_fixed_px) WHERE [type] tfp_px is... [type] shift_px is... [type] tfp_fixed_px is... """ # Error check if isinstance(h5_gp, h5py.Dataset): raise ValueError('Must pass an h5Py group') # Filter bad pixels tfp_fixed, _ = badpixels.fix_array(tfp, threshold=2) tfp_fixed = np.array(tfp_fixed) # grp_tr = h5_file.create_group(h5_gp.name) tfp_px = h5_gp.create_dataset('tfp', data=tfp, dtype=np.float32) shift_px = h5_gp.create_dataset('shift', data=shift, dtype=np.float32) tfp_fixed_px = h5_gp.create_dataset('tfp_fixed', data=tfp_fixed, dtype=np.float32) # h5_gp.attrs['timestamp'] = write_book_keeping_attrs() return tfp_px, shift_px, tfp_fixed_px
def plot_ringdown(h5_file, h5_path='/', append='', savefig=True, stdevs=2): """ Plots the relevant tfp, inst_freq, and shift values as separate image files Parameters ---------- h5_file : h5Py File h5_path : str, optional Location of the relevant datasets to be saved/plotted. e.g. h5_rb.name append : str, optional A string to include in the saved figure filename savefig : bool, optional Whether or not to save the image stdevs : int, optional Number of standard deviations to display """ # h5_rd = usid.hdf_utils.find_dataset(h5_file[h5_path], 'Ringdown')[0] if 'Dataset' in str(type(h5_file[h5_path])): h5_path = h5_file[h5_path].parent.name Q = usid.hdf_utils.find_dataset(h5_file[h5_path], 'Q')[0][()] A = usid.hdf_utils.find_dataset(h5_file[h5_path], 'Amplitude')[0][()] Q_fixed, _ = badpixels.fix_array(Q, threshold=2) A_fixed, _ = badpixels.fix_array(A, threshold=2) parm_dict = usid.hdf_utils.get_attributes(h5_file[h5_path]) if 'FastScanSize' not in parm_dict: parm_dict = usid.hdf_utils.get_attributes(h5_file[h5_path].parent) xs = parm_dict['FastScanSize'] ys = parm_dict['SlowScanSize'] asp = ys / xs if asp != 1: asp = asp * 2 fig, a = plt.subplots(nrows=2, figsize=(8, 9)) _, cbar_t = usid.viz.plot_utils.plot_map(a[0], Q_fixed, x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) _, cbar_s = usid.viz.plot_utils.plot_map(a[1], A_fixed * 1e9, x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) cbar_t.set_label('Q (a.u.)', rotation=270, labelpad=16) a[0].set_title('Q', fontsize=12) cbar_s.set_label('Amplitude (nm)', rotation=270, labelpad=16) a[1].set_title('Amplitude', fontsize=12) fig.tight_layout() if savefig: path = h5_file.file.filename.replace('\\', '/') path = '/'.join(path.split('/')[:-1]) + '/' os.chdir(path) fig.savefig('Q_Amp_' + append + '_.tif', format='tiff') return fig, a
def plot_tfps(h5_file, h5_path='/', append='', savefig=True, stdevs=2): """ Plots the relevant tfp, inst_freq, and shift values as separate image files Parameters ---------- h5_file : h5Py File h5_path : str, optional Location of the relevant datasets to be saved/plotted. e.g. h5_rb.name append : str, optional A string to include in the saved figure filename savefig : bool, optional Whether or not to save the image stdevs : int, optional Number of standard deviations to display """ h5_file = px.io.HDFwriter(h5_file).file try: h5_if = usid.hdf_utils.find_dataset(h5_file[h5_path], 'Inst_Freq')[0] except: h5_if = usid.hdf_utils.find_dataset(h5_file[h5_path], 'inst_freq')[0] parm_dict = get_utils.get_params(h5_if) # parm_dict = usid.hdf_utils.get_attributes(h5_file[h5_path]) if 'Dataset' in str(type(h5_file[h5_path])): h5_path = h5_file[h5_path].parent.name tfp = usid.hdf_utils.find_dataset(h5_file[h5_path], 'tfp')[0][()] shift = usid.hdf_utils.find_dataset(h5_file[h5_path], 'shift')[0][()] if tfp.shape[1] == 1: # Forgot to reconvert and/or needs to be converted [ysz, xsz] = h5_if.pos_dim_sizes tfp = np.reshape(tfp, [ysz, xsz]) shift = np.reshape(shift, [ysz, xsz]) try: tfp_fixed = usid.hdf_utils.find_dataset(h5_file[h5_path], 'tfp_fixed')[0][()] except: tfp_fixed, _ = badpixels.fix_array(tfp, threshold=2) tfp_fixed = np.array(tfp_fixed) xs = parm_dict['FastScanSize'] ys = parm_dict['SlowScanSize'] asp = ys / xs if asp != 1: asp = asp * 2 fig, a = plt.subplots(nrows=3, figsize=(8, 9)) [vmint, vmaxt] = np.mean(tfp) - 2 * np.std(tfp), np.mean(tfp) - 2 * np.std(tfp) [vmins, vmaxs ] = np.mean(shift) - 2 * np.std(shift), np.mean(shift) - 2 * np.std(shift) _, cbar_t = usid.viz.plot_utils.plot_map(a[0], tfp_fixed * 1e6, x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) _, cbar_r = usid.viz.plot_utils.plot_map(a[1], 1 / (1e3 * tfp_fixed), x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) _, cbar_s = usid.viz.plot_utils.plot_map(a[2], shift, x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) cbar_t.set_label('tfp (us)', rotation=270, labelpad=16) a[0].set_title('tfp', fontsize=12) cbar_r.set_label('Rate (kHz)', rotation=270, labelpad=16) a[1].set_title('1/tfp', fontsize=12) cbar_s.set_label('shift (Hz)', rotation=270, labelpad=16) a[2].set_title('shift', fontsize=12) fig.tight_layout() if savefig: path = h5_file.file.filename.replace('\\', '/') path = '/'.join(path.split('/')[:-1]) + '/' os.chdir(path) fig.savefig('tfp_shift_' + append + '_.tif', format='tiff') return
def plot_tfps(h5_file, h5_path='/', append='', savefig=True, stdevs=2, scale=None): """ Plots the relevant tfp, inst_freq, and shift values as separate image files :param h5_file: :type h5_file: h5Py File :param h5_path: Location of the relevant datasets to be saved/plotted. e.g. h5_rb.name :type h5_path: str, optional :param append: A string to include in the saved figure filename :type append: str, optional :param savefig: Whether or not to save the image :type savefig: bool, optional :param stdevs: Number of standard deviations to display :type stdevs: int, optional :param scale: Scale bar size, in microns :type scale: float, optional :returns: tuple (fig, ax) WHERE [type] fig is... [type] ax is... """ try: h5_if = usid.hdf_utils.find_dataset(h5_file[h5_path], 'Inst_Freq')[0] except: h5_if = usid.hdf_utils.find_dataset(h5_file[h5_path], 'inst_freq')[0] parm_dict = get_utils.get_params(h5_if) # parm_dict = usid.hdf_utils.get_attributes(h5_file[h5_path]) if 'Dataset' in str(type(h5_file[h5_path])): h5_path = h5_file[h5_path].parent.name tfp = usid.hdf_utils.find_dataset(h5_file[h5_path], 'tfp')[0][()] shift = usid.hdf_utils.find_dataset(h5_file[h5_path], 'shift')[0][()] if tfp.shape[1] == 1: # Forgot to reconvert and/or needs to be converted [ysz, xsz] = h5_if.pos_dim_sizes tfp = np.reshape(tfp, [ysz, xsz]) shift = np.reshape(shift, [ysz, xsz]) try: tfp_fixed = usid.hdf_utils.find_dataset(h5_file[h5_path], 'tfp_fixed')[0][()] except: tfp_fixed, _ = badpixels.fix_array(tfp, threshold=2) tfp_fixed = np.array(tfp_fixed) xs = parm_dict['FastScanSize'] ys = parm_dict['SlowScanSize'] asp = ys / xs if asp != 1: asp = asp * 2 fig, ax = plt.subplots(nrows=3, figsize=(8, 9), facecolor='white') [vmint, vmaxt] = np.mean(tfp) - 2 * np.std(tfp), np.mean(tfp) - 2 * np.std(tfp) [vmins, vmaxs ] = np.mean(shift) - 2 * np.std(shift), np.mean(shift) - 2 * np.std(shift) _, cbar_t = usid.viz.plot_utils.plot_map(ax[0], tfp_fixed * 1e6, x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) _, cbar_r = usid.viz.plot_utils.plot_map(ax[1], 1 / (1e3 * tfp_fixed), x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) _, cbar_s = usid.viz.plot_utils.plot_map(ax[2], shift, x_vec=xs * 1e6, y_vec=ys * 1e6, aspect=asp, cmap='inferno', stdevs=stdevs) cbar_t.set_label('tfp (us)', rotation=270, labelpad=16) ax[0].set_title('tfp', fontsize=12) if scale: sz = np.floor(xs * 1e6 / scale) ratio = int(tfp_fixed.shape[1] / sz) if scale > 1: sz = str(scale) + ' $\mu m$' else: sz = str(int(scale * 1000)) + ' nm' fontprops = fm.FontProperties(size=14, weight='bold') bar1 = AnchoredSizeBar(ax[0].transData, ratio, sz, frameon=False, loc='lower right', size_vertical=2, pad=0.2, color='white', fontproperties=fontprops) ax[0].add_artist(bar1) cbar_r.set_label('Rate (kHz)', rotation=270, labelpad=16) ax[1].set_title('1/tfp', fontsize=12) if scale: bar1 = AnchoredSizeBar(ax[0].transData, ratio, sz, frameon=False, loc='lower right', size_vertical=2, pad=0.2, color='white', fontproperties=fontprops) ax[1].add_artist(bar1) cbar_s.set_label('shift (Hz)', rotation=270, labelpad=16) ax[2].set_title('shift', fontsize=12) if scale: bar1 = AnchoredSizeBar(ax[0].transData, ratio, sz, frameon=False, loc='lower right', size_vertical=2, pad=0.2, color='white', fontproperties=fontprops) ax[2].add_artist(bar1) fig.tight_layout() if savefig: path = h5_file.file.filename.replace('\\', '/') path = '/'.join(path.split('/')[:-1]) + '/' os.chdir(path) fig.savefig('tfp_shift_' + append + '_.tif', format='tiff') return fig, ax
def plot_tfp(ffprocess, scale_tfp=1e6, scale_shift=1, threshold=2, **kwargs): ''' Quickly plots the tfp and shift data. If there's a height image in the h5_file associated with ffprocess, will plot that as well :param ffprocess: :type ffprocess: FFtrEFM class object (inherits Process) or the parent Group :param scale_tfp: :type scale_tfp: :param scale_shift: :type scale_shift: :param threshold: :type threshold: :param kwargs: :type kwargs: :returns: tuple (fig, a) WHERE fig is figure object ax is axes object ''' fig, a = plt.subplots(nrows=2, ncols=2, figsize=(13, 6)) tfp_ax = a[0][1] shift_ax = a[1][1] tfp_cal_ax = a[1][0] if isinstance(ffprocess, ffta.hdf_utils.process.FFtrEFM): img_length = ffprocess.parm_dict['FastScanSize'] img_height = ffprocess.parm_dict['SlowScanSize'] num_cols = ffprocess.parm_dict['num_cols'] num_rows = ffprocess.parm_dict['num_rows'] tfp = ffprocess.h5_tfp[()] shift = ffprocess.h5_shift[()] if 'tfp_cal' in ffprocess.h5_tfp.parent: tfp_cal = ffprocess.h5_tfp.parent['tfp_cal'][()] tfp_cal_fixed, _ = badpixels.fix_array(tfp_cal, threshold=threshold) else: tfp_cal_fixed = tfp_cal = np.ones(tfp.shape) elif isinstance(ffprocess, h5py.Group): attr = get_attributes(ffprocess['Inst_Freq']) img_length = attr['FastScanSize'] img_height = attr['SlowScanSize'] num_cols = attr['num_cols'] num_rows = attr['num_rows'] tfp = ffprocess['tfp'] shift = ffprocess['shift'] if 'tfp_cal' in ffprocess: tfp_cal = ffprocess['tfp_cal'][()] tfp_cal_fixed, _ = badpixels.fix_array(tfp_cal, threshold=threshold) else: tfp_cal_fixed = tfp_cal = np.ones(tfp.shape) kwarg = { 'origin': 'lower', 'x_vec': img_length * 1e6, 'y_vec': img_height * 1e6, 'num_ticks': 5, 'stdevs': 3, 'show_cbar': True } for k, v in kwarg.items(): if k not in kwargs: kwargs.update({k: v}) try: ht = ffprocess.h5_main.file['/height_000/Raw_Data'][:, 0] ht = np.reshape(ht, [num_cols, num_rows]).transpose() ht_ax = a[0][0] ht_image, cbar = plot_utils.plot_map(ht_ax, ht * 1e9, cmap='gray', **kwarg) cbar.set_label('Height (nm)', rotation=270, labelpad=16) except: pass tfp_ax.set_title('tFP Image') shift_ax.set_title('Shift Image') tfp_fixed, _ = badpixels.fix_array(tfp, threshold=threshold) tfp_image, cbar_tfp = plot_utils.plot_map(tfp_ax, tfp_fixed * scale_tfp, cmap='inferno', **kwargs) shift_image, cbar_sh = plot_utils.plot_map(shift_ax, shift * scale_shift, cmap='inferno', **kwargs) try: tfp_cal_image, cbar_tfp_cal = plot_utils.plot_map(tfp_cal_ax, tfp_cal_fixed * scale_tfp, cmap='inferno', **kwargs) cbar_tfp_cal.set_label('Time Calib. (us)', rotation=90, labelpad=16) except: tfp_cal_image = tfp_cal_ax.imshow(tfp_cal_fixed * scale_tfp, cmap='inferno', origin='lower') cbar_tfp.set_label('Time (us)', rotation=270, labelpad=16) cbar_sh.set_label('Frequency Shift (Hz)', rotation=270, labelpad=16) text = tfp_ax.text(num_cols / 2, num_rows + 3, '') return fig, a
def save_CSV_from_file(h5_file, h5_path='/', append='', mirror=False, offset=0): """ Saves the tfp, shift, and fixed_tfp as CSV files :param h5_file: Reminder you can always type: h5_svd.file or h5_avg.file for this :type h5_file: H5Py file of FFtrEFM class :param h5_path: specific folder path to search for the tfp data. Usually not needed. :type h5_path: str, optional :param append: text to append to file name :type append: str, optional :param mirror: :type mirror: bool, optional :param offset: if calculating tFP with a fixed offset for fitting, this subtracts it out :type offset: float """ h5_ff = h5_file if isinstance(h5_file, ffta.hdf_utils.process.FFtrEFM): print('Saving from FFtrEFM Class') h5_ff = h5_file.h5_main.file h5_path = h5_file.h5_results_grp.name elif not isinstance(h5_file, h5py.File): print('Saving from pyUSID object') h5_ff = h5_file.file tfp = find_dataset(h5_ff[h5_path], 'tfp')[0][()] shift = find_dataset(h5_ff[h5_path], 'shift')[0][()] try: tfp_cal = find_dataset(h5_ff[h5_path], 'tfp_cal')[0][()] except: tfp_cal = None tfp_fixed, _ = badpixels.fix_array(tfp, threshold=2) tfp_fixed = np.array(tfp_fixed) if isinstance(tfp_cal, np.ndarray): tfp_cal_fixed, _ = badpixels.fix_array(tfp_cal, threshold=2) tfp_cal_fixed = np.array(tfp_cal_fixed) print(find_dataset(h5_ff[h5_path], 'shift')[0].parent.name) path = h5_ff.file.filename.replace('\\', '/') path = '/'.join(path.split('/')[:-1]) + '/' os.chdir(path) if mirror: np.savetxt('tfp-' + append + '.csv', np.fliplr(tfp - offset).T, delimiter=',') np.savetxt('shift-' + append + '.csv', np.fliplr(shift).T, delimiter=',') np.savetxt('tfp_fixed-' + append + '.csv', np.fliplr(tfp_fixed - offset).T, delimiter=',') else: np.savetxt('tfp-' + append + '.csv', (tfp - offset).T, delimiter=',') np.savetxt('shift-' + append + '.csv', shift.T, delimiter=',') np.savetxt('tfp_fixed-' + append + '.csv', (tfp_fixed - offset).T, delimiter=',') if isinstance(tfp_cal, np.ndarray): if mirror: np.savetxt('tfp_cal-' + append + '.csv', np.fliplr(tfp_cal - offset).T, delimiter=',') np.savetxt('tfp_cal_fixed-' + append + '.csv', np.fliplr(tfp_cal_fixed - offset).T, delimiter=',') else: np.savetxt('tfp_cal-' + append + '.csv', (tfp_cal - offset).T, delimiter=',') np.savetxt('tfp_cal_fixed-' + append + '.csv', (tfp_cal_fixed - offset).T, delimiter=',') return