-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathutil.py
251 lines (198 loc) · 6.58 KB
/
util.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
import os
import pickle as pkl
import tkinter as tk
from CaImaging.util import get_data_paths, search_for_folders
tkroot = tk.Tk()
tkroot.withdraw()
from tkinter import filedialog
import pandas as pd
def make_pattern_dict():
"""
Makes the dictionary that tells get_data_paths() where each data
file lives.
:return:
---
pattern_dict: dict
Dictionary where fields are
"""
pattern_dict = {
"Arduino": "^H\d{2}_M\d{2}_S\d{2}.\d{4} \d{4}.txt$",
"BehaviorVideo": "Merged.avi",
"DLC": ".*DLC_resnet.*.h5",
"BehaviorData": ".*_LocationOutput.csv",
"timestamps": "^time[s,S]tamp",
"PreprocessedBehavior": "PreprocessedBehavior.csv",
"minian": "^minian$",
}
return pattern_dict
def grab_paths(session_folder=None):
"""
Get the data paths for a session minian_folder.
:param session_folder:
:return:
"""
pattern_dict = make_pattern_dict()
if session_folder is None:
session_folder = filedialog.askdirectory()
paths = get_data_paths(session_folder, pattern_dict)
return paths
def find_timestamp_file(timestamp_paths, camera_type):
"""
Looks for the miniscope timestamp file or the behavior camera's
timestamp file.
:parameters
---
timestamp_paths: list of strs (usually 2)
Paths to csvs, usually one each for behavior or miniscope.
camera_type: 'Miniscope' or 'BehavCam'
Camera type whose timestamp you want.
"""
n_paths = len(timestamp_paths)
assert n_paths == 2, f'Unusual number of paths entered: {n_paths}'
assert camera_type in ['BehavCam', 'Miniscope'], 'Unusual camera type entered'
files = [path for path in timestamp_paths if
camera_type in path]
n_files_found = len(files)
assert n_files_found==1, f'Unusual number of paths found: {n_files_found}'
return files[0]
class Session_Metadata:
def __init__(self, session_folder=None, overwrite=False):
"""
Locate the metadata in a session. This will typically
include things like minian output minian_folder, behavior
tracking csvs, timestamps, etc. The files found
are defined by the pattern dict in the function
make_pattern_dict().
:parameters
---
session_folder: str
Full path to the minian_folder you want to extract
metadata from.
overwrite: bool
Whether or not to overwrite the existing
metadata csv.
"""
# If minian_folder is not specified, open a dialog box.
if session_folder is None:
self.session_folder = filedialog.askdirectory()
else:
self.session_folder = session_folder
# Get full file path to the metadata csv.
self.full_path = os.path.join(session_folder, "metadata.pkl")
if overwrite:
self.build()
self.save()
self.meta_dict = self.load()
else:
try:
self.meta_dict = self.load()
except:
self.build()
self.save()
self.meta_dict = self.load()
def build(self):
"""
Gather all the paths.
"""
self.filepaths = grab_paths(self.session_folder)
def save(self):
"""
Pickle the dict to disk. .
"""
with open(self.full_path, "wb") as file:
pkl.dump(self.filepaths, file)
def load(self):
"""
Load pickled dict.
:return:
"""
with open(self.full_path, "rb") as file:
meta_dict = pkl.load(file)
return meta_dict
class Metadata_CSV:
def __init__(
self,
folder=None,
mouse=-3,
date=-2,
session=-1,
filename="Metadata.csv",
overwrite=False,
):
"""
Makes a CSV file containing the metadata of all the sessions
for a particular project. This includes session minian_folder
locations as well as individual files within those folders.
For example, ezTrack outputs or timestamps.dat.
:param folder:
"""
if folder is None:
self.project_folder = filedialog.askdirectory()
else:
self.project_folder = folder
self.filename = filename
self.path_levels = {
"mouse": mouse,
"date": date,
"session": session,
}
fname = os.path.join(self.project_folder, filename)
if overwrite:
self.build()
self.save()
self.df = pd.read_csv(fname)
else:
try:
self.df = pd.read_csv(fname)
except:
self.build()
self.save()
self.df = pd.read_csv(fname)
def build(self):
self.session_folders = search_for_folders(
self.project_folder, "^H?[0-9]+_M?[0-9]+_S?[0-9]+$"
)
for folder in self.session_folders:
Session_Metadata(folder, overwrite=True)
mouse_names = self.get_metadata("mouse")
master_dict = {
"Mouse": mouse_names,
"Group": None, # to do
"Session": self.get_metadata("date"),
"Session_Type": self.get_session_type(),
"Path": self.session_folders,
"CellRegPath": [
os.path.join(
self.project_folder, mouse, "SpatialFootprints", "CellRegResults"
)
for mouse in mouse_names
], # to do
"Metadata": [
os.path.join(folder, "metadata.pkl") for folder in self.session_folders
],
}
self.df = pd.DataFrame(master_dict)
def save(self):
self.df.to_csv(os.path.join(self.project_folder, self.filename), index=False)
def get_session_type(self):
session_types = [
folder.split(os.sep)[self.path_levels["date"]].split("_")[-1]
for folder in self.session_folders
]
return session_types
def get_metadata(self, path_level):
"""
Get the metadata associated with each path.
:parameter
---
path_level: str
'mouse', 'date', or 'session'
"""
mice = [
session.split(os.sep)[self.path_levels[path_level]]
for session in self.session_folders
]
return mice
if __name__ == "__main__":
# paths = grab_paths(r'Z:\Will\Drift\Data\Castor_Scope05\09_06_2020_CircleTrackShaping1\17_11_36')
Metadata_CSV(r"Z:\Will\Drift\Data", overwrite=True)