-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpicasso2srx.py
166 lines (131 loc) · 5.54 KB
/
picasso2srx.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
# Specific script name.
SCRIPT_NAME = 'picasso2srx.py'
# Specify script version.
VERSION = 1.0
from glob import glob
import argparse
import pandas as pd
import os
import locsutil as lu
import time
MESSAGE = f"""
%s version %s. Requires a path to DNA-PAINT localization file (HDF5) or a directory containing
localization files. Optionally takes in other parameters.
Returns SRX compatible CSV files.
""" % (SCRIPT_NAME, VERSION)
# SRX .csv file format
SRX_COL = [
'image-ID', 'time-point', 'cycle', 'z-step', 'frame', 'accum', 'probe',
'photon-count', 'photon-count11', 'photon-count12', 'photon-count21', 'photon-count22',
'psfx', 'psfy', 'psfz', 'psf-photon-count', 'x', 'y', 'z', 'stdev', 'amp',
'background11', 'background12', 'background21', 'background22', 'maxResidualSlope',
'chisq', 'log-likelihood', 'llr', 'accuracy', 'fiducial', 'valid',
'precisionx', 'precisiony', 'precisionz', 'cluster-ID'
]
def main():
"""
Converts DNA-PAINT localization files to SRX readable CSV files.
Parameters (user input)
-------
input : str
frames : int
pixel : int, optional
segmented : bool, optional
decoded : bool, optional
Returns
-------
None
"""
# Allow user to input parameters on command line.
user_input = argparse.ArgumentParser(description=MESSAGE)
# Input file name.
required_named = user_input.add_argument_group('required arguments')
required_named.add_argument('-f', '--input', required=True, action='store',
type=str, help='Input file name or directory name which includes input files.')
required_named.add_argument('-a', '--frames', required=True, action='store',
type=int, help='Number of frames per section acquired.')
# Take in optional parameters.
user_input.add_argument('-p', '--pixel', action='store', type=int,
default=65.0, help='Pixel size in nm scale. Default = 65 nm.')
user_input.add_argument('-s', '--segmented', action='store_true',
default=False, help='Whether file was segmented. Default = disabled.')
user_input.add_argument('-d', '--decoded', action='store_true',
default=False, help='Whether file was decoded. Default = disabled.')
args = user_input.parse_args()
input_path = args.input
pixel_size = args.pixel
frames_per_section = args.frames
segmented = args.segmented
decoded = args.decoded
# Starts a timer.
start = time.time()
# Performs conversion iteratively if input is a path to a directory.
if os.path.isdir(input_path):
query = os.path.join(input_path, '*.hdf5')
locs_files = glob(query)
for file in locs_files:
print('Converting...' + file)
picasso_to_srx(file, pixel_size, frames_per_section, segmented, decoded)
else:
picasso_to_srx(input_path, pixel_size, frames_per_section, segmented, decoded)
print(f'Total_time: {time.time() - start} [sec]')
def picasso_to_srx(input_file: str,
pixel_size: float,
frames_per_section: int,
segmented: bool,
decoded: bool
) -> None:
# Converts format
converted = convert_to_srx(input_file, pixel_size, frames_per_section, segmented, decoded)
# Makes an output directory.
work_dir = os.path.dirname(input_file)
out_path = os.path.join(work_dir, 'srx')
if not os.path.exists(out_path):
os.makedirs(out_path)
# Generates output file name prefix
file_base = os.path.basename(input_file)
file_stem = lu.clean_filename(file_base)
out_name = f'{file_stem}.csv'
out_name = os.path.join(out_path, out_name)
# Outputs a converted file.
converted.to_csv(out_name, index=False)
def convert_to_srx(input_file: str,
pixel_size: float,
frames_per_section: int,
segmented: bool,
decoded: bool
) -> pd.DataFrame:
locs_data = lu.read_locs(input_file)
locs_data = locs_data.reset_index()
converted = pd.DataFrame(columns=SRX_COL)
if segmented:
if 'hdbscan' in locs_data.columns:
locs_data = locs_data[locs_data['hdbscan'] != -1]
converted['cluster-ID'] = locs_data['hdbscan']
else:
locs_data = locs_data[locs_data['dbscan'] != -1]
converted['cluster-ID'] = locs_data['dbscan']
locs_data = lu.convert_xy(locs_data, pixel_size)
converted['image-ID'] = locs_data['index']
converted['z-step'] = locs_data['frame'] // frames_per_section
converted['frame'] = locs_data['frame'] % frames_per_section
if 'n' in locs_data.columns:
converted['accum'] = locs_data['n']
converted['photon-count'] = locs_data['photons']
converted['photon-count11'] = locs_data['photons'] / 2.0
converted['photon-count12'] = locs_data['photons'] / 2.0
converted['x'] = locs_data['x_nm']
converted['y'] = locs_data['y_nm']
converted['z'] = locs_data['z']
converted['background11'] = locs_data['bg'] / 2.0
converted['background12'] = locs_data['bg'] / 2.0
converted['valid'] = 1
converted['precisionx'] = locs_data['lpx_nm']
converted['precisiony'] = locs_data['lpy_nm']
converted['precisionz'] = locs_data['d_zcalib']
if decoded:
converted['probe'] = locs_data['id']
converted.fillna(0, inplace=True)
return converted
if __name__ == '__main__':
main()