-
Notifications
You must be signed in to change notification settings - Fork 0
/
BatchSaveAsPNG.py
122 lines (83 loc) · 4.21 KB
/
BatchSaveAsPNG.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# -*- coding: utf-8 -*-
"""
Created on Fri May 22 11:14:03 2020
@author: Sylvain Rama
This script will convert csv or abf files to PNG, save a direct file and a transposed copy and log the file sizes in a Pandas dataframe.
pyPNG is quite a pain with Numpy arrays, crashing with the error "TypeError: can't set bytearray slice from numpy.ndarray"
As a result, signal entropy of abf file is on the transposed value. Noise entropy is on the direct value. This is reversed when using csv file.
From the Materials & Methods in:
A quick and easy way to estimate entropy and mutual information for neuroscience
Mickael Zbili(1), Sylvain Rama(2)*
1, Blue Brain Project, École polytechnique fédérale de Lausanne (EPFL) Biotech Campus, Geneva, Switzerland.
2, UCL Queen Square Institute of Neurology, University College London, London, United Kingdom.
*, Correspondence: Sylvain Rama, s.rama@ucl.ac.uk
"""
#%% Imports
import pyabf
import numpy as np
import os
import pandas as pd
import png
import tkinter as tk
from tkinter import filedialog
#%% TKinter GUI for Selecting files.
root = tk.Tk()
root.overrideredirect(True)
root.geometry('0x0+0+0')
root.focus_force()
initial_folder = "E:/"
FT = [("All files", "*.*"), ("Abf files", "*.abf"),
("Excel files", "*.xlsx"), ("CSV files", "*.csv")]
ttl = 'Select Files'
file_paths = filedialog.askopenfilenames(parent=root, title=ttl, filetypes=FT, initialdir = initial_folder )
root.withdraw()
# Preparing names for the dataframe.
rates_values = np.zeros((2, len(file_paths)))
rates_df = pd.DataFrame(rates_values)
names = []
size = 1 # Default length of the signal is 1, to prevent divide-by-zero error.
for paths in file_paths:
names.append(os.path.basename(os.path.normpath(paths)))
rates_df.columns = names
rates_df.index = ['PNG Rate 1', 'PNG Rate 2']
#%% Main loop for each selected file.
for i in range(len(file_paths)):
split = os.path.split(file_paths[i])
file_extension = os.path.splitext(split[1])[1][1:]
# Extracting the signals according to type of files
if file_extension == 'abf':
file = pyabf.ABF(file_paths[i])
test=file.data[0]
noisy_signals=np.reshape(test, (file.sweepCount, file.sweepPointCount))
# This will give column-wise sweeps, so the standard size is actually the value for the noise.
# The transposed value is for the signal entropy rate.
# We cannot transpose it here to have the direct value, as it crashes pyPNG.
# Binning the signals to U8 if it is an abf.
noisy_signals = noisy_signals - np.min(noisy_signals)
noisy_signals = noisy_signals / np.max(noisy_signals)
noisy_signals = np.uint8(noisy_signals * 255)
# We suppose the csv files are not above U8.
if file_extension == 'csv':
file=pd.read_csv(file_paths[i], dtype='float')
noisy_signals = file.to_numpy()
noisy_signals = noisy_signals.T
# Transposing here
# /!\ PyPNG is a pain with Numpy and crashes when transposing the arrays.
# See https://github.com/drj11/pypng/issues/91
# https://github.com/drj11/pypng/commit/c4935f49d4ab1a66983e33ede232ca2f79d34a60
noisy_signals_transposed = noisy_signals.transpose().copy()
size = np.prod(np.shape(noisy_signals))
name = os.path.splitext(split[1])[0]
png_name = os.path.join(split[0], name +'.png')
# 2 elements to save: standard and transposed arrays
to_save = [noisy_signals, noisy_signals_transposed]
# Saving each array as PNG, getting the size of the file and putting it in a Pandas dataframe.
for j in [0,1]:
png_array = np.array(to_save[j], dtype=np.uint8)
png.from_array(png_array, mode="L").save(png_name)
# size = os.path.getsize(png_name)
rates_df.iloc[j, i] = os.path.getsize(png_name) / size
#%% Saving the final results as ax Excel sheet
xls_name = os.path.join(split[0], 'File_png_rates.xlsx')
with pd.ExcelWriter(xls_name) as writer:
rates_df.to_excel(writer, sheet_name='PNG Rates', index=True)