batoolset 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- batoolset/GUI/__init__.py +0 -0
- batoolset/GUI/list_gui.py +513 -0
- batoolset/GUI/multi_image_display.py +989 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1345 -0
- batoolset/GUI/scrollablepaint.py +1152 -0
- batoolset/IJ_ROIs/__init__.py +0 -0
- batoolset/IJ_ROIs/tools.py +40 -0
- batoolset/PATH/__init__.py +0 -0
- batoolset/PATH/tools.py +79 -0
- batoolset/SQLite_tools/__init__.py +0 -0
- batoolset/SQLite_tools/tools.py +840 -0
- batoolset/__init__.py +0 -0
- batoolset/binary/__init__.py +0 -0
- batoolset/binary/tools.py +123 -0
- batoolset/binarytools/__init__.py +0 -0
- batoolset/binarytools/cell_center_detector.py +290 -0
- batoolset/clipboard_tools/__init__.py +0 -0
- batoolset/clipboard_tools/tools.py +7 -0
- batoolset/colors/__init__.py +0 -0
- batoolset/colors/colorgen.py +193 -0
- batoolset/colors/tools.py +22 -0
- batoolset/command_line/__init__.py +0 -0
- batoolset/command_line/tools.py +18 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/dicts/__init__.py +0 -0
- batoolset/dicts/tools.py +299 -0
- batoolset/dims/__init__.py +0 -0
- batoolset/dims/tools.py +83 -0
- batoolset/draw/__init__.py +0 -0
- batoolset/draw/shapes/Position.py +183 -0
- batoolset/draw/shapes/__init__.py +0 -0
- batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/draw/shapes/circle2d.py +99 -0
- batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
- batoolset/draw/shapes/ellipse2d.py +336 -0
- batoolset/draw/shapes/freehand2d.py +235 -0
- batoolset/draw/shapes/group.py +1830 -0
- batoolset/draw/shapes/image2d.py +2469 -0
- batoolset/draw/shapes/line2d.py +575 -0
- batoolset/draw/shapes/point2d.py +257 -0
- batoolset/draw/shapes/polygon2d.py +357 -0
- batoolset/draw/shapes/polyline2d.py +235 -0
- batoolset/draw/shapes/rect2d.py +388 -0
- batoolset/draw/shapes/rectangle2d.py +601 -0
- batoolset/draw/shapes/scalebar.py +304 -0
- batoolset/draw/shapes/serializablefont.py +126 -0
- batoolset/draw/shapes/serializableguiparams.py +10 -0
- batoolset/draw/shapes/square2d.py +103 -0
- batoolset/draw/shapes/textorientation.py +45 -0
- batoolset/draw/shapes/tools.py +467 -0
- batoolset/draw/shapes/transform2D.py +350 -0
- batoolset/draw/shapes/txt2d.py +550 -0
- batoolset/draw/widgets/__init__.py +0 -0
- batoolset/draw/widgets/col.py +343 -0
- batoolset/draw/widgets/image_group.py +248 -0
- batoolset/draw/widgets/image_organizer.py +96 -0
- batoolset/draw/widgets/paint.py +184 -0
- batoolset/draw/widgets/vectorial.py +257 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +814 -0
- batoolset/figure/column.py +1117 -0
- batoolset/figure/fig_tools.py +285 -0
- batoolset/figure/minimal_debugger_scale_etc.py +139 -0
- batoolset/figure/panel.py +697 -0
- batoolset/figure/row.py +852 -0
- batoolset/figure/user_selection.py +287 -0
- batoolset/files/__init__.py +0 -0
- batoolset/files/tools.py +1321 -0
- batoolset/images/__init__.py +0 -0
- batoolset/images/tools.py +81 -0
- batoolset/img.py +5216 -0
- batoolset/linux/__init__.py +0 -0
- batoolset/linux/tools.py +72 -0
- batoolset/lists/__init__.py +0 -0
- batoolset/lists/tools.py +436 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1207 -0
- batoolset/matplolib/__init__.py +0 -0
- batoolset/matplolib/tools.py +44 -0
- batoolset/np_tools/__init__.py +0 -0
- batoolset/np_tools/tools.py +252 -0
- batoolset/np_tools/trash.py +15 -0
- batoolset/pandas_tools/__init__.py +0 -0
- batoolset/pandas_tools/tools.py +880 -0
- batoolset/partials/__init__.py +0 -0
- batoolset/partials/tools.py +83 -0
- batoolset/plot_tools/__init__.py +0 -0
- batoolset/plot_tools/tools.py +70 -0
- batoolset/pyqt/__init__.py +0 -0
- batoolset/pyqt/tools.py +691 -0
- batoolset/re_tools/__init__.py +0 -0
- batoolset/re_tools/tools.py +35 -0
- batoolset/serialization/__init__.py +0 -0
- batoolset/serialization/tools.py +1192 -0
- batoolset/sets/__init__.py +0 -0
- batoolset/sets/tools.py +109 -0
- batoolset/settings/__init__.py +0 -0
- batoolset/settings/global_settings.py +134 -0
- batoolset/strings/__init__.py +0 -0
- batoolset/strings/tools.py +225 -0
- batoolset/ta/__init__.py +0 -0
- batoolset/ta/database/__init__.py +0 -0
- batoolset/ta/database/advanced_sql_plotter.py +1170 -0
- batoolset/ta/database/my_qt_table.py +79 -0
- batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
- batoolset/ta/database/sql.py +2141 -0
- batoolset/ta/database/sql_column_name_dialog.py +122 -0
- batoolset/ta/measurements/TAmeasures.py +2226 -0
- batoolset/ta/measurements/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
- batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
- batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
- batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
- batoolset/ta/measurements/nematic.py +562 -0
- batoolset/ta/measurements/nematic_measurements.py +107 -0
- batoolset/ta/segmentation/__init__.py +0 -0
- batoolset/ta/segmentation/neo_wshed.py +314 -0
- batoolset/ta/selections/__init__.py +0 -0
- batoolset/ta/selections/selection.py +329 -0
- batoolset/ta/tracking/__init__.py +0 -0
- batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
- batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
- batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
- batoolset/ta/tracking/registration.py +108 -0
- batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
- batoolset/ta/tracking/track_correction.py +238 -0
- batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
- batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
- batoolset/ta/utils/TA_tools.py +43 -0
- batoolset/ta/utils/__init__.py +0 -0
- batoolset/ta/utils/rps_tools.py +1783 -0
- batoolset/tests/__init__.py +0 -0
- batoolset/tests/rps_tools.py +51 -0
- batoolset/tests/tools.py +10 -0
- batoolset/tools/__init__.py +0 -0
- batoolset/tools/early_stopper_class.py +9 -0
- batoolset/tools/guided_data_recoverer.py +110 -0
- batoolset/tools/logger.py +100 -0
- batoolset/tools/mytimer.py +31 -0
- batoolset/tools/prompt_color.py +160 -0
- batoolset/tools/qthandler.py +118 -0
- batoolset/uitools/__init__.py +0 -0
- batoolset/uitools/blinker.py +56 -0
- batoolset/unsafe/__init__.py +0 -0
- batoolset/unsafe/tools.py +115 -0
- batoolset/utils/__init__.py +0 -0
- batoolset/utils/commontools.py +158 -0
- batoolset/utils/loadlist.py +728 -0
- batoolset/version.py +10 -0
- batoolset/xml/__init__.py +0 -0
- batoolset/xml/tools.py +65 -0
- batoolset/zip_tools/__init__.py +0 -0
- batoolset/zip_tools/tools.py +76 -0
- batoolset-0.1.0.dist-info/LICENSE +24 -0
- batoolset-0.1.0.dist-info/METADATA +45 -0
- batoolset-0.1.0.dist-info/RECORD +162 -0
- batoolset-0.1.0.dist-info/WHEEL +5 -0
- batoolset-0.1.0.dist-info/top_level.txt +1 -0
batoolset/files/tools.py
ADDED
|
@@ -0,0 +1,1321 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A collection of file related methods
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
from batoolset.lists.tools import find_first_index, flatten_list
|
|
7
|
+
from batoolset.strings.tools import is_string_a_list_string, reload_string_list
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
import subprocess
|
|
10
|
+
import tempfile
|
|
11
|
+
import glob
|
|
12
|
+
import hashlib
|
|
13
|
+
import platform
|
|
14
|
+
from batoolset.utils.loadlist import loadlist
|
|
15
|
+
import os
|
|
16
|
+
import shutil
|
|
17
|
+
import uuid
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
import numpy as np
|
|
22
|
+
from skimage.draw import polygon, polygon_perimeter
|
|
23
|
+
from skimage.measure import regionprops
|
|
24
|
+
from skimage import measure
|
|
25
|
+
from collections import Counter
|
|
26
|
+
from natsort import natsorted
|
|
27
|
+
from batoolset.utils.loadlist import loadlist
|
|
28
|
+
from batoolset.colors.colorgen import get_unique_random_color_int24
|
|
29
|
+
import os
|
|
30
|
+
|
|
31
|
+
from batoolset.tools.logger import TA_logger # logging
|
|
32
|
+
|
|
33
|
+
logger = TA_logger()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_TA_file(file_name_without_ext, TA_file):
|
|
37
|
+
"""
|
|
38
|
+
Returns the path to the TA file by joining the file name without extension and the TA file.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
file_name_without_ext (str): File name without extension.
|
|
42
|
+
TA_file (str): TA file.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
str: Path to the TA file.
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
return os.path.join(file_name_without_ext, TA_file)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_n_consecutive_input_files_and_output_folders(images_to_analyze, start_idx, nb_of_images_to_get, incr=1):
|
|
52
|
+
"""
|
|
53
|
+
Returns a list of consecutive input files and output folders.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
images_to_analyze (list): List of images to analyze.
|
|
57
|
+
start_idx (int): Starting index.
|
|
58
|
+
nb_of_images_to_get (int): Number of consecutive images to get.
|
|
59
|
+
incr (int, optional): Increment value. Defaults to 1.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
list: List of input files and output folders.
|
|
63
|
+
|
|
64
|
+
"""
|
|
65
|
+
return get_n_input_files_and_output_folders(images_to_analyze, start_idx, 0, nb_of_images_to_get, incr=incr)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_n_input_files_and_output_folders(images_to_analyze, start_idx, start_range, end_range_inclusive, incr=1):
|
|
69
|
+
"""
|
|
70
|
+
Returns a list of input files and output folders within a specified range.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
images_to_analyze (list): List of images to analyze.
|
|
74
|
+
start_idx (int): Starting index.
|
|
75
|
+
start_range (int): Starting range.
|
|
76
|
+
end_range_inclusive (int): Ending range (inclusive).
|
|
77
|
+
incr (int, optional): Increment value. Defaults to 1.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
list: List of input files and output folders.
|
|
81
|
+
|
|
82
|
+
"""
|
|
83
|
+
try:
|
|
84
|
+
return images_to_analyze[start_idx + start_range: start_idx + end_range_inclusive: incr]
|
|
85
|
+
except:
|
|
86
|
+
output_data = []
|
|
87
|
+
for i in range(start_range, end_range_inclusive + 1, incr):
|
|
88
|
+
output_data.append(get_input_file_and_output_folder(images_to_analyze, start_idx + i))
|
|
89
|
+
return output_data
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_n_files_from_list(images_to_analyze, start_idx, start_range, end_range_inclusive, incr=1):
|
|
93
|
+
"""
|
|
94
|
+
Returns a list of files from a given list within a specified range.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
images_to_analyze (list): List of images to analyze.
|
|
98
|
+
start_idx (int): Starting index.
|
|
99
|
+
start_range (int): Starting range.
|
|
100
|
+
end_range_inclusive (int): Ending range (inclusive).
|
|
101
|
+
incr (int, optional): Increment value. Defaults to 1.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
list: List of files.
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
Exception: Raises an exception if the list is empty.
|
|
108
|
+
|
|
109
|
+
"""
|
|
110
|
+
if images_to_analyze is None or not images_to_analyze:
|
|
111
|
+
raise Exception('Empty list, nothing to do...')
|
|
112
|
+
try:
|
|
113
|
+
if start_idx + start_range < 0 or start_idx + end_range_inclusive >= len(images_to_analyze):
|
|
114
|
+
raise IndexError("List index out of range")
|
|
115
|
+
return images_to_analyze[start_idx + start_range: start_idx + end_range_inclusive + 1: incr]
|
|
116
|
+
except:
|
|
117
|
+
output_data = []
|
|
118
|
+
for i in range(start_range, end_range_inclusive + 1, incr):
|
|
119
|
+
if start_idx + i < 0 or start_idx + i >= len(images_to_analyze):
|
|
120
|
+
output_data.append(None)
|
|
121
|
+
continue
|
|
122
|
+
output_data.append(images_to_analyze[start_idx + i])
|
|
123
|
+
return output_data
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
known_parsers = ['parent',
|
|
127
|
+
'ext',
|
|
128
|
+
'short',
|
|
129
|
+
'full_no_ext',
|
|
130
|
+
'TA', # same as full no ext
|
|
131
|
+
'short_no_ext',
|
|
132
|
+
'full',
|
|
133
|
+
'full_no_end_slash',
|
|
134
|
+
'short_pop_all_exts', # extreme version of short no ext where series of exts are removed, e.g. hiC_250522.pairs.txt.gz -−> hiC_250522
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def replace_empty_string_by_none(input_string):
|
|
139
|
+
"""
|
|
140
|
+
Replaces an empty string with None.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
input_string (str): Input string.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
str: Input string with empty string replaced by None.
|
|
147
|
+
|
|
148
|
+
"""
|
|
149
|
+
if not input_string:
|
|
150
|
+
return None
|
|
151
|
+
return input_string
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def smart_name_appender(name, condition_boolean, text_to_append_if_condition_is_true=None,
|
|
155
|
+
text_to_append_if_condition_is_false=None):
|
|
156
|
+
"""
|
|
157
|
+
Appends a string to a name depending on a condition.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
name (str): Name to append the string.
|
|
161
|
+
condition_boolean (bool): Condition.
|
|
162
|
+
text_to_append_if_condition_is_true (str, optional): Text to append if the condition is True. Defaults to None.
|
|
163
|
+
text_to_append_if_condition_is_false (str, optional): Text to append if the condition is False. Defaults to None.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
str: Modified name.
|
|
167
|
+
|
|
168
|
+
"""
|
|
169
|
+
if condition_boolean:
|
|
170
|
+
if text_to_append_if_condition_is_true is not None:
|
|
171
|
+
name += text_to_append_if_condition_is_true
|
|
172
|
+
else:
|
|
173
|
+
if text_to_append_if_condition_is_false is not None:
|
|
174
|
+
name += text_to_append_if_condition_is_false
|
|
175
|
+
return name
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def smart_name_parser(full_file_path, ordered_output=known_parsers, appenders=None, replace_empty_by_none=False):
|
|
179
|
+
"""
|
|
180
|
+
Parses the full file path and returns the specified output.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
full_file_path (str): Full file path.
|
|
184
|
+
ordered_output (str or list, optional): Ordered list of output formats. Defaults to known_parsers.
|
|
185
|
+
appenders (str or list, optional): String or list of strings to append to the output. Defaults to None.
|
|
186
|
+
replace_empty_by_none (bool, optional): Replace empty strings by None. Defaults to False.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
str or list: Parsed output.
|
|
190
|
+
|
|
191
|
+
"""
|
|
192
|
+
if full_file_path is None:
|
|
193
|
+
logger.error('Please specify an input file name')
|
|
194
|
+
return
|
|
195
|
+
if ordered_output is None:
|
|
196
|
+
logger.error('Parsing unspecified, nothing to do')
|
|
197
|
+
return
|
|
198
|
+
|
|
199
|
+
fixed_path = full_file_path.replace('\\\\', '/').replace('\\', '/')
|
|
200
|
+
filename0_without_path = os.path.basename(fixed_path)
|
|
201
|
+
filename0_without_ext, ext = os.path.splitext(filename0_without_path)
|
|
202
|
+
parent_dir_of_filename0 = os.path.dirname(fixed_path)
|
|
203
|
+
|
|
204
|
+
single_output = False
|
|
205
|
+
if isinstance(ordered_output, str):
|
|
206
|
+
single_output = True
|
|
207
|
+
ordered_output = [ordered_output]
|
|
208
|
+
|
|
209
|
+
sorted_output = []
|
|
210
|
+
for parser in ordered_output:
|
|
211
|
+
if parser not in known_parsers:
|
|
212
|
+
sorted_output.append(os.path.join(parent_dir_of_filename0, os.path.join(filename0_without_ext, parser)))
|
|
213
|
+
continue
|
|
214
|
+
if parser == 'parent':
|
|
215
|
+
sorted_output.append(parent_dir_of_filename0)
|
|
216
|
+
continue
|
|
217
|
+
if parser == 'short_no_ext':
|
|
218
|
+
sorted_output.append(filename0_without_ext)
|
|
219
|
+
continue
|
|
220
|
+
if parser == 'short_pop_all_exts':
|
|
221
|
+
extracted = filename0_without_ext
|
|
222
|
+
while '.' in extracted:
|
|
223
|
+
extracted, _ = os.path.splitext(extracted)
|
|
224
|
+
sorted_output.append(extracted)
|
|
225
|
+
if parser == 'full_no_ext' or parser == 'TA':
|
|
226
|
+
sorted_output.append(os.path.join(parent_dir_of_filename0, filename0_without_ext))
|
|
227
|
+
continue
|
|
228
|
+
if parser == 'short':
|
|
229
|
+
sorted_output.append(filename0_without_path)
|
|
230
|
+
continue
|
|
231
|
+
if parser == 'full':
|
|
232
|
+
sorted_output.append(full_file_path)
|
|
233
|
+
continue
|
|
234
|
+
if parser == 'ext':
|
|
235
|
+
sorted_output.append(ext)
|
|
236
|
+
continue
|
|
237
|
+
if parser == 'full_no_end_slash':
|
|
238
|
+
out = fixed_path
|
|
239
|
+
if out.endswith('/'):
|
|
240
|
+
out = out[:-1]
|
|
241
|
+
sorted_output.append(out)
|
|
242
|
+
|
|
243
|
+
if appenders is not None:
|
|
244
|
+
if not isinstance(appenders, list):
|
|
245
|
+
appenders = [appenders]
|
|
246
|
+
sorted_output = [os.path.join(txt, *appenders) for txt in sorted_output]
|
|
247
|
+
|
|
248
|
+
if replace_empty_by_none:
|
|
249
|
+
sorted_output = [replace_empty_string_by_none(input_string) for input_string in sorted_output]
|
|
250
|
+
|
|
251
|
+
if single_output:
|
|
252
|
+
return sorted_output[0]
|
|
253
|
+
return sorted_output
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def get_input_file_and_output_folder(images_to_analyze, idx):
|
|
257
|
+
"""
|
|
258
|
+
Returns the input file and output folder for a given index.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
images_to_analyze (list): List of images to analyze.
|
|
262
|
+
idx (int): Index of the image to retrieve.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
tuple: Input file path and output folder path.
|
|
266
|
+
|
|
267
|
+
"""
|
|
268
|
+
file_path_0 = images_to_analyze[idx]
|
|
269
|
+
filename0_without_ext = os.path.splitext(file_path_0)[0]
|
|
270
|
+
return file_path_0, filename0_without_ext
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def get_input_files_and_output_folders(images_to_analyze, start_idx, incr=1):
|
|
274
|
+
"""
|
|
275
|
+
Returns the input files and output folders for consecutive indices.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
images_to_analyze (list): List of images to analyze.
|
|
279
|
+
start_idx (int): Starting index.
|
|
280
|
+
incr (int, optional): Increment value. Defaults to 1.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
tuple: Input file paths and output folder paths.
|
|
284
|
+
|
|
285
|
+
"""
|
|
286
|
+
file_path_0 = images_to_analyze[start_idx]
|
|
287
|
+
file_path_1 = images_to_analyze[start_idx + incr]
|
|
288
|
+
|
|
289
|
+
filename0_without_ext = os.path.splitext(file_path_0)[0]
|
|
290
|
+
filename1_without_ext = os.path.splitext(file_path_1)[0]
|
|
291
|
+
|
|
292
|
+
return file_path_0, file_path_1, filename0_without_ext, filename1_without_ext
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def get_list_of_files(path):
|
|
296
|
+
"""
|
|
297
|
+
Returns a list of files in the given path.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
path (str or list): Path to the directory or a list of file paths.
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
list: List of file paths.
|
|
304
|
+
|
|
305
|
+
# Examples:
|
|
306
|
+
# >>> get_list_of_files('/path/to/files')
|
|
307
|
+
# ['/path/to/files/file1.txt', '/path/to/files/file2.txt', '/path/to/files/file3.txt']
|
|
308
|
+
#
|
|
309
|
+
# >>> get_list_of_files(['/path/to/files/file1.txt', '/path/to/files/file2.txt'])
|
|
310
|
+
# ['/path/to/files/file1.txt', '/path/to/files/file2.txt']
|
|
311
|
+
|
|
312
|
+
"""
|
|
313
|
+
if isinstance(path, list):
|
|
314
|
+
return path
|
|
315
|
+
|
|
316
|
+
if not path.lower().endswith('.txt') and not path.lower().endswith('.lst'):
|
|
317
|
+
images_to_analyze = os.listdir(path)
|
|
318
|
+
images_to_analyze = [os.path.join(path, f) for f in images_to_analyze if os.path.isfile(os.path.join(path, f))]
|
|
319
|
+
images_to_analyze = natsorted(images_to_analyze)
|
|
320
|
+
else:
|
|
321
|
+
images_to_analyze = loadlist(path)
|
|
322
|
+
|
|
323
|
+
return images_to_analyze
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def first_image_tracking(mask_t0, labels_t0, regprps=None, assigned_ids=None, seed=None):
|
|
327
|
+
"""
|
|
328
|
+
Performs tracking on the first image.
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
mask_t0 (ndarray): Binary mask of the first image.
|
|
332
|
+
labels_t0 (ndarray): Labels of the first image.
|
|
333
|
+
regprps (list, optional): List of region properties. Defaults to None.
|
|
334
|
+
assigned_ids (list, optional): List of assigned IDs. Defaults to None.
|
|
335
|
+
seed (int, optional): Random seed. Defaults to None.
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
ndarray: Tracked image.
|
|
339
|
+
|
|
340
|
+
"""
|
|
341
|
+
tracks_t0 = np.zeros_like(mask_t0, dtype=np.uint32)
|
|
342
|
+
|
|
343
|
+
if regprps is None:
|
|
344
|
+
regprps = regionprops(labels_t0)
|
|
345
|
+
|
|
346
|
+
for iii, region in enumerate(regprps):
|
|
347
|
+
# create a random color and store it
|
|
348
|
+
if iii == 0:
|
|
349
|
+
new_col = get_unique_random_color_int24(forbidden_colors=assigned_ids, seed_random=seed,
|
|
350
|
+
assign_new_col_to_forbidden=True)
|
|
351
|
+
else:
|
|
352
|
+
new_col = get_unique_random_color_int24(forbidden_colors=assigned_ids, assign_new_col_to_forbidden=True)
|
|
353
|
+
|
|
354
|
+
tracks_t0[labels_t0 == iii + 1] = new_col
|
|
355
|
+
|
|
356
|
+
tracks_t0[labels_t0 == 0] = 0xFFFFFF
|
|
357
|
+
# save the image or return it
|
|
358
|
+
return tracks_t0 # this is the image # need copy it
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def deduplicate_duplicated_cells_using_random_ids(RGB24, labels=None, background=0xFFFFFF, assigned_ids=None):
|
|
362
|
+
"""
|
|
363
|
+
Deduplicates duplicated cells using random IDs.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
RGB24 (ndarray): RGB image.
|
|
367
|
+
labels (ndarray, optional): Label image. Defaults to None.
|
|
368
|
+
background (int, optional): Background color. Defaults to 0xFFFFFF.
|
|
369
|
+
assigned_ids (list, optional): List of assigned IDs. Defaults to None.
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
ndarray: Deduplicated RGB image.
|
|
373
|
+
|
|
374
|
+
"""
|
|
375
|
+
if labels is None:
|
|
376
|
+
labels = measure.label(RGB24, connectivity=1, background=background)
|
|
377
|
+
|
|
378
|
+
cell_ids = []
|
|
379
|
+
for region in regionprops(labels):
|
|
380
|
+
cell_ids.append(RGB24[region.coords[0][0], region.coords[0][1]])
|
|
381
|
+
|
|
382
|
+
cell_ids_n_count = Counter(cell_ids)
|
|
383
|
+
duplicated_cells = {k: v for k, v in cell_ids_n_count.items() if v >= 2}
|
|
384
|
+
|
|
385
|
+
duplicated_cells_keys = list(duplicated_cells.keys())
|
|
386
|
+
for region in regionprops(labels):
|
|
387
|
+
id = RGB24[region.coords[0][0], region.coords[0][1]]
|
|
388
|
+
if id in duplicated_cells_keys:
|
|
389
|
+
duplication_count = duplicated_cells[id]
|
|
390
|
+
if duplication_count >= 2:
|
|
391
|
+
duplicated_cells[id] = duplication_count - 1
|
|
392
|
+
RGB24[labels == region.label] = get_unique_random_color_int24(forbidden_colors=assigned_ids,
|
|
393
|
+
assign_new_col_to_forbidden=True)
|
|
394
|
+
else:
|
|
395
|
+
duplicated_cells_keys.remove(id)
|
|
396
|
+
|
|
397
|
+
return RGB24
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def assign_random_ID_to_missing_cells(RGB24img, labels, regprps=None, assigned_ids=None):
|
|
401
|
+
"""
|
|
402
|
+
Assigns random IDs to missing cells in the image.
|
|
403
|
+
|
|
404
|
+
Args:
|
|
405
|
+
RGB24img (ndarray): RGB image.
|
|
406
|
+
labels (ndarray): Label image.
|
|
407
|
+
regprps (list, optional): List of region properties. Defaults to None.
|
|
408
|
+
assigned_ids (list, optional): List of assigned IDs. Defaults to None.
|
|
409
|
+
|
|
410
|
+
Returns:
|
|
411
|
+
ndarray: RGB image with assigned random IDs.
|
|
412
|
+
|
|
413
|
+
"""
|
|
414
|
+
if regprps is None:
|
|
415
|
+
regprps = regionprops(labels)
|
|
416
|
+
|
|
417
|
+
for iii, region in enumerate(regprps):
|
|
418
|
+
color_of_first_pixel_of_potential_match = RGB24img[region.coords[0][0], region.coords[0][1]]
|
|
419
|
+
|
|
420
|
+
if color_of_first_pixel_of_potential_match == 0:
|
|
421
|
+
new_col = get_unique_random_color_int24(forbidden_colors=assigned_ids, assign_new_col_to_forbidden=True)
|
|
422
|
+
RGB24img[labels == labels[region.coords[0][0], region.coords[0][1]]] = new_col
|
|
423
|
+
|
|
424
|
+
return RGB24img
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def get_lost_cells_between_first_and_second_set(first_set, second_set):
|
|
428
|
+
"""
|
|
429
|
+
Returns the lost cells between the first and second set.
|
|
430
|
+
|
|
431
|
+
Args:
|
|
432
|
+
first_set (list or set): First set of cells.
|
|
433
|
+
second_set (list or set): Second set of cells.
|
|
434
|
+
|
|
435
|
+
Returns:
|
|
436
|
+
set: Set of lost cells.
|
|
437
|
+
|
|
438
|
+
Examples:
|
|
439
|
+
>>> get_lost_cells_between_first_and_second_set([1, 2, 3, 4, 5], [2, 4, 6, 8])
|
|
440
|
+
{1, 3, 5}
|
|
441
|
+
|
|
442
|
+
>>> get_lost_cells_between_first_and_second_set({1, 2, 3, 4, 5}, {2, 4, 6, 8})
|
|
443
|
+
{1, 3, 5}
|
|
444
|
+
|
|
445
|
+
"""
|
|
446
|
+
set_t0 = first_set
|
|
447
|
+
if not isinstance(set_t0, set):
|
|
448
|
+
set_t0 = set(set_t0)
|
|
449
|
+
set_t1 = second_set
|
|
450
|
+
if not isinstance(set_t1, set):
|
|
451
|
+
set_t1 = set(set_t1)
|
|
452
|
+
return set_t0.difference(set_t1)
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def get_common_cells(first_set, second_set):
|
|
456
|
+
"""
|
|
457
|
+
Returns the common cells between the first and second set.
|
|
458
|
+
|
|
459
|
+
Args:
|
|
460
|
+
first_set (list or set): First set of cells.
|
|
461
|
+
second_set (list or set): Second set of cells.
|
|
462
|
+
|
|
463
|
+
Returns:
|
|
464
|
+
set: Set of common cells.
|
|
465
|
+
|
|
466
|
+
Examples:
|
|
467
|
+
>>> get_common_cells([1, 2, 3, 4, 5], [2, 4, 6, 8])
|
|
468
|
+
{2, 4}
|
|
469
|
+
|
|
470
|
+
>>> get_common_cells({1, 2, 3, 4, 5}, {2, 4, 6, 8})
|
|
471
|
+
{2, 4}
|
|
472
|
+
|
|
473
|
+
"""
|
|
474
|
+
set_t0 = first_set
|
|
475
|
+
if not isinstance(set_t0, set):
|
|
476
|
+
set_t0 = set(set_t0)
|
|
477
|
+
set_t1 = second_set
|
|
478
|
+
if not isinstance(set_t1, set):
|
|
479
|
+
set_t1 = set(set_t1)
|
|
480
|
+
return set_t0.intersection(set_t1)
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def get_cells_in_image(RGB24_img):
|
|
484
|
+
"""
|
|
485
|
+
Returns the unique IDs of cells in the image.
|
|
486
|
+
|
|
487
|
+
Args:
|
|
488
|
+
RGB24_img (ndarray): RGB image.
|
|
489
|
+
|
|
490
|
+
Returns:
|
|
491
|
+
ndarray: Array of unique cell IDs.
|
|
492
|
+
|
|
493
|
+
"""
|
|
494
|
+
unique_ids = np.unique(RGB24_img)
|
|
495
|
+
return unique_ids
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
def get_cells_in_image_n_fisrt_pixel(RGB24_img):
|
|
499
|
+
"""
|
|
500
|
+
Returns the unique IDs of cells in the image and their corresponding first pixel indices.
|
|
501
|
+
|
|
502
|
+
Args:
|
|
503
|
+
RGB24_img (ndarray): RGB image.
|
|
504
|
+
|
|
505
|
+
Returns:
|
|
506
|
+
ndarray: Array of unique cell IDs.
|
|
507
|
+
ndarray: Array of indices of the first pixels of the cells.
|
|
508
|
+
|
|
509
|
+
"""
|
|
510
|
+
u, indices = np.unique(RGB24_img, return_index=True)
|
|
511
|
+
return u, indices
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
def get_cells_in_image_n_count(RGB24_img):
|
|
515
|
+
"""
|
|
516
|
+
Returns the unique IDs of cells in the image and their corresponding counts.
|
|
517
|
+
|
|
518
|
+
Args:
|
|
519
|
+
RGB24_img (ndarray): RGB image.
|
|
520
|
+
|
|
521
|
+
Returns:
|
|
522
|
+
ndarray: Array of unique cell IDs.
|
|
523
|
+
ndarray: Array of counts for each cell ID.
|
|
524
|
+
|
|
525
|
+
"""
|
|
526
|
+
u, counts = np.unique(RGB24_img, return_counts=True)
|
|
527
|
+
return u, counts
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def plot_triangles(img, coords, tri, inner_color, perimeter_color=None):
|
|
531
|
+
"""
|
|
532
|
+
Plot the triangles of a cell on an image.
|
|
533
|
+
|
|
534
|
+
Args:
|
|
535
|
+
img (ndarray): Image to plot on.
|
|
536
|
+
coords (ndarray): Coordinates of the cell vertices.
|
|
537
|
+
tri (Delaunay): Delaunay triangulation of the cell.
|
|
538
|
+
inner_color (int): Inner color of the triangles.
|
|
539
|
+
perimeter_color (int, optional): Perimeter color of the triangles. Defaults to None.
|
|
540
|
+
|
|
541
|
+
"""
|
|
542
|
+
for simplex in tri.simplices:
|
|
543
|
+
r = coords[simplex][:, 0] # get the y coords of the simplex
|
|
544
|
+
c = coords[simplex][:, 1] # get the x coords of the simplex
|
|
545
|
+
rr, cc = polygon(r, c)
|
|
546
|
+
img[rr, cc] = inner_color
|
|
547
|
+
if perimeter_color is not None:
|
|
548
|
+
rr, cc = polygon_perimeter(r, c)
|
|
549
|
+
img[rr, cc] = perimeter_color
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def backup_file_with_date(source_file, verbose=False, append_time=True):
|
|
553
|
+
"""
|
|
554
|
+
Bcakup a file and append the current date in 'yyyymmdd' format to it.
|
|
555
|
+
|
|
556
|
+
Args:
|
|
557
|
+
source_file (str): The path to the source file to be backed up.
|
|
558
|
+
|
|
559
|
+
Returns:
|
|
560
|
+
str: The path to the copied file with the date appended.
|
|
561
|
+
"""
|
|
562
|
+
# Check if the source file exists
|
|
563
|
+
if os.path.exists(source_file):
|
|
564
|
+
# Get the current date in 'yyyymmdd' format
|
|
565
|
+
|
|
566
|
+
if append_time:
|
|
567
|
+
current_date = datetime.now().strftime('%Y%m%d_%H%M%S')
|
|
568
|
+
else:
|
|
569
|
+
current_date = datetime.now().strftime('%Y%m%d')
|
|
570
|
+
|
|
571
|
+
# Construct the new file name with the date appended
|
|
572
|
+
new_file_name = f"{source_file}.{current_date}"
|
|
573
|
+
|
|
574
|
+
if verbose:
|
|
575
|
+
print('creating a backup', source_file, new_file_name)
|
|
576
|
+
|
|
577
|
+
# Copy the source file to the destination with the new name
|
|
578
|
+
shutil.copy(source_file, new_file_name)
|
|
579
|
+
|
|
580
|
+
return new_file_name
|
|
581
|
+
else:
|
|
582
|
+
raise FileNotFoundError("Source file does not exist.")
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
def make_dirs_for_file_saving(save_name):
|
|
586
|
+
"""
|
|
587
|
+
Create directories for file saving based on the given save_name.
|
|
588
|
+
|
|
589
|
+
Parameters:
|
|
590
|
+
- save_name: The name of the file to be saved.
|
|
591
|
+
|
|
592
|
+
Returns:
|
|
593
|
+
None
|
|
594
|
+
"""
|
|
595
|
+
|
|
596
|
+
# Parse the parent folder name from the save_name using smart_name_parser
|
|
597
|
+
parent_folder = smart_name_parser(save_name, 'parent')
|
|
598
|
+
|
|
599
|
+
# Create the parent folder and any necessary intermediate directories
|
|
600
|
+
os.makedirs(parent_folder, exist_ok=True)
|
|
601
|
+
|
|
602
|
+
def open_file_with_default_handler(file_path):
|
|
603
|
+
"""
|
|
604
|
+
Opens a file with the default system handler.
|
|
605
|
+
|
|
606
|
+
Args:
|
|
607
|
+
file_path (str): The path to the file to be opened.
|
|
608
|
+
|
|
609
|
+
Returns:
|
|
610
|
+
bool: True if the file was opened successfully, False otherwise.
|
|
611
|
+
"""
|
|
612
|
+
if os.path.isfile(file_path):
|
|
613
|
+
try:
|
|
614
|
+
subprocess.run(['open', file_path], check=True)
|
|
615
|
+
return True
|
|
616
|
+
except subprocess.CalledProcessError as e:
|
|
617
|
+
print(f"Error: {e}")
|
|
618
|
+
return False
|
|
619
|
+
else:
|
|
620
|
+
print(f"The file '{file_path}' does not exist.")
|
|
621
|
+
return False
|
|
622
|
+
|
|
623
|
+
def open_file_with_default_app(file_path):
|
|
624
|
+
"""
|
|
625
|
+
Opens a file using the default system application.
|
|
626
|
+
|
|
627
|
+
Parameters:
|
|
628
|
+
- file_path (str): The path to the file to be opened.
|
|
629
|
+
"""
|
|
630
|
+
|
|
631
|
+
# Determine the platform
|
|
632
|
+
current_platform = platform.system()
|
|
633
|
+
|
|
634
|
+
# Open the file using the default system application
|
|
635
|
+
if current_platform == 'Windows':
|
|
636
|
+
os.startfile(file_path)
|
|
637
|
+
elif current_platform == 'Darwin': # macOS
|
|
638
|
+
os.system('open "{}"'.format(file_path))
|
|
639
|
+
elif current_platform == 'Linux':
|
|
640
|
+
os.system('xdg-open "{}"'.format(file_path))
|
|
641
|
+
else:
|
|
642
|
+
print("Unsupported operating system")
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
def create_temporary_file(extension=None, delete=True, return_file=True):
|
|
646
|
+
"""
|
|
647
|
+
Create a temporary file with a specified file extension and automatic deletion on close.
|
|
648
|
+
|
|
649
|
+
Args:
|
|
650
|
+
extension (str): The desired file extension, including the dot (e.g., '.txt', '.csv').
|
|
651
|
+
|
|
652
|
+
Returns:
|
|
653
|
+
tempfile.NamedTemporaryFile: A NamedTemporaryFile object with the specified extension.
|
|
654
|
+
|
|
655
|
+
Example:
|
|
656
|
+
>>> with create_temporary_file() as temp_file:
|
|
657
|
+
... temp_file.write(b"Hello, World!")
|
|
658
|
+
... temp_file.seek(0)
|
|
659
|
+
... data = temp_file.read()
|
|
660
|
+
... print(data) # Output: b'Hello, World!'
|
|
661
|
+
13
|
|
662
|
+
0
|
|
663
|
+
b'Hello, World!'
|
|
664
|
+
"""
|
|
665
|
+
if extension is not None and extension:
|
|
666
|
+
if not extension.startswith('.'):
|
|
667
|
+
extension = '.'+extension
|
|
668
|
+
temp_file = tempfile.NamedTemporaryFile(delete=delete, suffix=extension)
|
|
669
|
+
if return_file:
|
|
670
|
+
return temp_file
|
|
671
|
+
else:
|
|
672
|
+
return temp_file.name
|
|
673
|
+
|
|
674
|
+
# # maybe allow glob with exceptions
|
|
675
|
+
# def rm(file_path, exceptions=None):
|
|
676
|
+
# """
|
|
677
|
+
# Delete a file if it exists.
|
|
678
|
+
#
|
|
679
|
+
# Args:
|
|
680
|
+
# file_path (str): The path to the file you want to delete.
|
|
681
|
+
#
|
|
682
|
+
# Returns:
|
|
683
|
+
# str: A message indicating the result of the deletion.
|
|
684
|
+
#
|
|
685
|
+
# # Example:
|
|
686
|
+
# # >>> rm("example.txt")
|
|
687
|
+
# # >>> rm("nonexistent_file.txt")
|
|
688
|
+
# """
|
|
689
|
+
#
|
|
690
|
+
# if '*' in file_path:
|
|
691
|
+
# # run glob
|
|
692
|
+
#
|
|
693
|
+
#
|
|
694
|
+
# if os.path.exists(file_path):
|
|
695
|
+
# try:
|
|
696
|
+
# os.remove(file_path)
|
|
697
|
+
# except Exception as e:
|
|
698
|
+
# pass
|
|
699
|
+
def rm(file_path, exceptions=None):
|
|
700
|
+
"""
|
|
701
|
+
Delete a file if it exists.
|
|
702
|
+
|
|
703
|
+
Args:
|
|
704
|
+
file_path (str): The path to the file you want to delete.
|
|
705
|
+
exceptions (list, optional): A list of file names to exclude from deletion. Default is None.
|
|
706
|
+
|
|
707
|
+
Returns:
|
|
708
|
+
str: A message indicating the result of the deletion.
|
|
709
|
+
|
|
710
|
+
# Example:
|
|
711
|
+
# >>> rm("example.txt")
|
|
712
|
+
# 'File 'example.txt' has been deleted.'
|
|
713
|
+
# >>> rm("nonexistent_file.txt")
|
|
714
|
+
# 'The file 'nonexistent_file.txt' does not exist.'
|
|
715
|
+
# >>> rm("*.txt", exceptions=["example.txt"])
|
|
716
|
+
# 'All matching files except ['example.txt'] have been deleted.'
|
|
717
|
+
"""
|
|
718
|
+
if exceptions is not None:
|
|
719
|
+
if isinstance(exceptions,str):
|
|
720
|
+
exceptions = [exceptions]
|
|
721
|
+
|
|
722
|
+
if '*' in file_path:
|
|
723
|
+
# Use glob to create a list of files that match the pattern
|
|
724
|
+
files_to_delete = glob.glob(file_path)
|
|
725
|
+
if exceptions:
|
|
726
|
+
files_to_delete = [f for f in files_to_delete if os.path.basename(f) not in exceptions]
|
|
727
|
+
# if exceptions:
|
|
728
|
+
# files_to_delete = [f for f in files_to_delete if os.path.basename(f) not in exceptions]
|
|
729
|
+
|
|
730
|
+
if not files_to_delete:
|
|
731
|
+
# print('No files matching the pattern found or all were exceptions.')
|
|
732
|
+
return
|
|
733
|
+
|
|
734
|
+
deleted_files = []
|
|
735
|
+
for file_to_delete in files_to_delete:
|
|
736
|
+
try:
|
|
737
|
+
os.remove(file_to_delete)
|
|
738
|
+
deleted_files.append(file_to_delete)
|
|
739
|
+
except Exception as e:
|
|
740
|
+
pass
|
|
741
|
+
|
|
742
|
+
if deleted_files:
|
|
743
|
+
# return f'All matching files except {exceptions if exceptions else "none"} have been deleted.'
|
|
744
|
+
return
|
|
745
|
+
else:
|
|
746
|
+
# return f'No matching files were deleted due to exceptions or errors.'
|
|
747
|
+
return
|
|
748
|
+
|
|
749
|
+
elif os.path.exists(file_path):
|
|
750
|
+
try:
|
|
751
|
+
os.remove(file_path)
|
|
752
|
+
# return f"File '{file_path}' has been deleted."
|
|
753
|
+
return
|
|
754
|
+
except Exception as e:
|
|
755
|
+
pass
|
|
756
|
+
else:
|
|
757
|
+
# return f"The file '{file_path}' does not exist."
|
|
758
|
+
return
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
def is_file_more_recent(file1, file2):
|
|
762
|
+
"""
|
|
763
|
+
Check if file1 was modified more recently than file2.
|
|
764
|
+
|
|
765
|
+
Parameters:
|
|
766
|
+
- file1: Path to the first file
|
|
767
|
+
- file2: Path to the second file
|
|
768
|
+
|
|
769
|
+
Returns:
|
|
770
|
+
- True if file1 is more recent than file2, False otherwise
|
|
771
|
+
"""
|
|
772
|
+
try:
|
|
773
|
+
# Get the modification time of each file
|
|
774
|
+
time1 = os.path.getmtime(file1)
|
|
775
|
+
time2 = os.path.getmtime(file2)
|
|
776
|
+
|
|
777
|
+
# Compare the modification times
|
|
778
|
+
return time1 > time2
|
|
779
|
+
except FileNotFoundError:
|
|
780
|
+
print("One or both of the files do not exist.")
|
|
781
|
+
return False
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
def get_md5_hash(filename):
|
|
785
|
+
if not os.path.isfile(filename):
|
|
786
|
+
return None
|
|
787
|
+
hash_md5 = hashlib.md5()
|
|
788
|
+
with open(filename, 'rb') as f:
|
|
789
|
+
for chunk in iter(lambda: f.read(4096), b''):
|
|
790
|
+
hash_md5.update(chunk)
|
|
791
|
+
return hash_md5.hexdigest()
|
|
792
|
+
|
|
793
|
+
def get_sha256(filename):
|
|
794
|
+
return get_md5_hash(filename)
|
|
795
|
+
|
|
796
|
+
def get_file_size(path, return_size_in_mb=True):
|
|
797
|
+
size = os.path.getsize(path)
|
|
798
|
+
if return_size_in_mb:
|
|
799
|
+
size/= (1024*1024)
|
|
800
|
+
return size
|
|
801
|
+
|
|
802
|
+
def find_files_by_extension(folder_path, extension):
|
|
803
|
+
file_paths = []
|
|
804
|
+
for root, dirs, files in os.walk(folder_path):
|
|
805
|
+
for file in files:
|
|
806
|
+
if file.endswith(extension):
|
|
807
|
+
file_paths.append(os.path.join(root, file))
|
|
808
|
+
return file_paths
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
def merge_files(input_lst, extra_TA_name, output_file):
|
|
812
|
+
|
|
813
|
+
with open(output_file, 'w') as outfile:
|
|
814
|
+
for filename in input_lst:
|
|
815
|
+
if extra_TA_name is not None:
|
|
816
|
+
filename = smart_name_parser(filename,extra_TA_name)
|
|
817
|
+
# if filename.endswith(".txt"): # only process text files
|
|
818
|
+
# basename = os.path.splitext(filename)[0] # get the basename without extension
|
|
819
|
+
sep = None
|
|
820
|
+
with open(filename, 'r') as infile:
|
|
821
|
+
for line in infile:
|
|
822
|
+
if sep is None:
|
|
823
|
+
if ',' in line:
|
|
824
|
+
sep = ','
|
|
825
|
+
else:
|
|
826
|
+
sep='\t'
|
|
827
|
+
new_line = ''
|
|
828
|
+
if not '\n' in line:
|
|
829
|
+
new_line='\n'
|
|
830
|
+
outfile.write(f'{filename}{sep}{line}{new_line}')
|
|
831
|
+
|
|
832
|
+
def write_string_to_file(file_path, string):
|
|
833
|
+
make_dirs_for_file_saving(file_path)
|
|
834
|
+
# Open the file for writing
|
|
835
|
+
with open(file_path, 'w') as f:
|
|
836
|
+
# Write the string to the file
|
|
837
|
+
f.write(string)
|
|
838
|
+
|
|
839
|
+
def read_string_from_file(file_path):
|
|
840
|
+
# Open the file for reading
|
|
841
|
+
with open(file_path, 'r') as f:
|
|
842
|
+
# Read the string from the file
|
|
843
|
+
string = f.read()
|
|
844
|
+
return string
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
def get_consolidated_filename_from_parent(filename, parent_file):
|
|
849
|
+
# check if this is a consolidated file and if so try to find the consolidation name
|
|
850
|
+
if not filename:
|
|
851
|
+
return filename
|
|
852
|
+
if '.files' in filename:
|
|
853
|
+
# try to get it from the other file
|
|
854
|
+
# cut last files and add the parent stuff
|
|
855
|
+
|
|
856
|
+
if not is_string_a_list_string(filename):
|
|
857
|
+
# Split the file path at the last occurrence of '.files'
|
|
858
|
+
file_end = filename.rsplit('.files', 1)[-1]
|
|
859
|
+
corrected_filename = smart_name_parser(parent_file, 'full_no_ext')+'.files'+file_end
|
|
860
|
+
filename = corrected_filename
|
|
861
|
+
# print(corrected_filename)
|
|
862
|
+
else:
|
|
863
|
+
files = reload_string_list(filename)
|
|
864
|
+
|
|
865
|
+
corrected_files = []
|
|
866
|
+
for file in files:
|
|
867
|
+
file_end = file.rsplit('.files', 1)[-1]
|
|
868
|
+
corrected_filename = smart_name_parser(parent_file, 'full_no_ext') + '.files' + file_end
|
|
869
|
+
corrected_files.append(corrected_filename)
|
|
870
|
+
|
|
871
|
+
filename = str(corrected_files)
|
|
872
|
+
|
|
873
|
+
return filename
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
def _consolidate_single_file(file_path, save_folder, mock):
|
|
879
|
+
new_paths=[]
|
|
880
|
+
# Get the base name of the file
|
|
881
|
+
base_name = os.path.basename(file_path)
|
|
882
|
+
|
|
883
|
+
# here there can be an error for multi files --> just try to save them once and that's it
|
|
884
|
+
|
|
885
|
+
# Create a unique folder for each file
|
|
886
|
+
unique_id = str(uuid.uuid4())
|
|
887
|
+
unique_folder = os.path.join(save_folder, f"{unique_id}")
|
|
888
|
+
if not mock:
|
|
889
|
+
os.makedirs(unique_folder, exist_ok=True)
|
|
890
|
+
|
|
891
|
+
# Define the new path for the file
|
|
892
|
+
new_path = os.path.join(unique_folder, base_name)
|
|
893
|
+
|
|
894
|
+
# Copy the file to the new path
|
|
895
|
+
try:
|
|
896
|
+
if not mock:
|
|
897
|
+
shutil.copy2(file_path, new_path)
|
|
898
|
+
new_paths.append(new_path)
|
|
899
|
+
except:
|
|
900
|
+
print(f'file {file_path} does not exist -−> copy not possible')
|
|
901
|
+
new_paths.append(file_path) # keep the original path then (useful for reapplying the name to the files)
|
|
902
|
+
|
|
903
|
+
return new_paths
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
# this is a real file consolidation
|
|
908
|
+
def consolidate_files2(save_folder, files_to_consolidate, consolidated_files):
|
|
909
|
+
folders_to_delete = []
|
|
910
|
+
if os.path.exists(save_folder):
|
|
911
|
+
for folder in os.listdir(save_folder):
|
|
912
|
+
if os.path.isdir(os.path.join(save_folder, folder)):
|
|
913
|
+
folders_to_delete.append(folder)
|
|
914
|
+
|
|
915
|
+
# print('folders_to_delete before', folders_to_delete)
|
|
916
|
+
|
|
917
|
+
os.makedirs(save_folder, exist_ok=True)
|
|
918
|
+
|
|
919
|
+
for file_path, new_path in zip(files_to_consolidate, consolidated_files):
|
|
920
|
+
print(file_path, '->', new_path)
|
|
921
|
+
|
|
922
|
+
try:
|
|
923
|
+
folder_save = smart_name_parser(new_path, 'parent')
|
|
924
|
+
os.makedirs(folder_save, exist_ok=True)
|
|
925
|
+
# print('success',success)
|
|
926
|
+
# print(folder_save)
|
|
927
|
+
shutil.copy2(file_path, new_path)
|
|
928
|
+
|
|
929
|
+
# print(os.path.exists(new_path)) # this is supposed to exist but I
|
|
930
|
+
# print(new_path)
|
|
931
|
+
except IOError as e:
|
|
932
|
+
print("Unable to copy file. IOError({0}): {1}".format(e.errno, e.strerror))
|
|
933
|
+
print(f'file {file_path} does not exist -−> copy not possible')
|
|
934
|
+
except:
|
|
935
|
+
print("Unexpected error:", sys.exc_info()[0])
|
|
936
|
+
print(f'file {file_path} does not exist -−> copy not possible')
|
|
937
|
+
|
|
938
|
+
# print('folders_to_delete',folders_to_delete)
|
|
939
|
+
|
|
940
|
+
# somehow I delete all I build
|
|
941
|
+
|
|
942
|
+
if folders_to_delete:
|
|
943
|
+
# print('folders_to_delete inside', folders_to_delete)
|
|
944
|
+
for folder in folders_to_delete:
|
|
945
|
+
# print('deleting',os.path.join(save_folder, folder))
|
|
946
|
+
shutil.rmtree(os.path.join(save_folder, folder))
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
def consolidate_files(file_paths, save_folder, empty_folder=True, mock =True):
|
|
950
|
+
if mock:
|
|
951
|
+
empty_folder = False
|
|
952
|
+
# If empty_folder is True, collect the names of the folders to be deleted
|
|
953
|
+
folders_to_delete = []
|
|
954
|
+
if empty_folder and os.path.exists(save_folder):
|
|
955
|
+
for folder in os.listdir(save_folder):
|
|
956
|
+
if os.path.isdir(os.path.join(save_folder, folder)):
|
|
957
|
+
folders_to_delete.append(folder)
|
|
958
|
+
if not mock:
|
|
959
|
+
# Create the save folder if it doesn't exist
|
|
960
|
+
os.makedirs(save_folder, exist_ok=True)
|
|
961
|
+
|
|
962
|
+
new_paths = []
|
|
963
|
+
for file_path in file_paths:
|
|
964
|
+
# # Get the base name of the file
|
|
965
|
+
# base_name = os.path.basename(file_path)
|
|
966
|
+
#
|
|
967
|
+
# # here there can be an error for multi files --> just try to save them once and that's it
|
|
968
|
+
#
|
|
969
|
+
#
|
|
970
|
+
# # Create a unique folder for each file
|
|
971
|
+
# unique_id = str(uuid.uuid4())
|
|
972
|
+
# unique_folder = os.path.join(save_folder, f"{unique_id}")
|
|
973
|
+
# os.makedirs(unique_folder, exist_ok=True)
|
|
974
|
+
#
|
|
975
|
+
# # Define the new path for the file
|
|
976
|
+
# new_path = os.path.join(unique_folder, base_name)
|
|
977
|
+
#
|
|
978
|
+
# # Copy the file to the new path
|
|
979
|
+
# try:
|
|
980
|
+
# if not mock:
|
|
981
|
+
# shutil.copy2(file_path, new_path)
|
|
982
|
+
# new_paths.append(new_path)
|
|
983
|
+
# except:
|
|
984
|
+
# print(f'file {file_path} does not exist -−> copy not possible')
|
|
985
|
+
# new_paths.append(file_path) # keep the original path then (useful for reapplying the name to the files)
|
|
986
|
+
|
|
987
|
+
if not is_string_a_list_string(file_path):
|
|
988
|
+
consolidated_files = _consolidate_single_file(file_path, save_folder, mock)
|
|
989
|
+
new_paths.extend(consolidated_files)
|
|
990
|
+
else:
|
|
991
|
+
consolidated_files = []
|
|
992
|
+
lst_of_files = reload_string_list(file_path)
|
|
993
|
+
for f in lst_of_files:
|
|
994
|
+
consolidated_files.extend(_consolidate_single_file(f, save_folder, mock))
|
|
995
|
+
new_paths.append(str(consolidated_files))
|
|
996
|
+
|
|
997
|
+
# If empty_folder is True, delete the folders to be deleted
|
|
998
|
+
if empty_folder:
|
|
999
|
+
for folder in folders_to_delete:
|
|
1000
|
+
shutil.rmtree(os.path.join(save_folder, folder))
|
|
1001
|
+
|
|
1002
|
+
return file_paths, new_paths
|
|
1003
|
+
|
|
1004
|
+
def consolidate_files_from_paired_lists(file_paths, dest_list,save_folder, empty_folder=True):
|
|
1005
|
+
# If empty_folder is True, collect the names of the folders to be deleted
|
|
1006
|
+
folders_to_delete = []
|
|
1007
|
+
if empty_folder and os.path.exists(save_folder):
|
|
1008
|
+
for folder in os.listdir(save_folder):
|
|
1009
|
+
if os.path.isdir(os.path.join(save_folder, folder)):
|
|
1010
|
+
folders_to_delete.append(folder)
|
|
1011
|
+
# Create the save folder if it doesn't exist
|
|
1012
|
+
os.makedirs(save_folder, exist_ok=True)
|
|
1013
|
+
|
|
1014
|
+
new_paths=[]
|
|
1015
|
+
for iii, file_path in enumerate(file_paths):
|
|
1016
|
+
# Get the base name of the file
|
|
1017
|
+
# base_name = os.path.basename(file_path)
|
|
1018
|
+
|
|
1019
|
+
# Create a unique folder for each file
|
|
1020
|
+
unique_folder= smart_name_parser(file_path, 'parent')
|
|
1021
|
+
os.makedirs(unique_folder, exist_ok=True)
|
|
1022
|
+
|
|
1023
|
+
# Define the new path for the file
|
|
1024
|
+
new_path = dest_list[iii]
|
|
1025
|
+
|
|
1026
|
+
# Copy the file to the new path
|
|
1027
|
+
try:
|
|
1028
|
+
shutil.copy2(file_path, new_path)
|
|
1029
|
+
new_paths.append(new_path)
|
|
1030
|
+
except:
|
|
1031
|
+
print(f'file {file_path} does not exist -−> copy not possible')
|
|
1032
|
+
new_paths.append(file_path) # keep the original path then (useful for reapplying the name to the files)
|
|
1033
|
+
|
|
1034
|
+
# If empty_folder is True, delete the folders to be deleted
|
|
1035
|
+
if empty_folder:
|
|
1036
|
+
for folder in folders_to_delete:
|
|
1037
|
+
shutil.rmtree(os.path.join(save_folder, folder))
|
|
1038
|
+
|
|
1039
|
+
return file_paths, new_paths
|
|
1040
|
+
|
|
1041
|
+
def smartly_consolidate_files_to_reduce_dupes(full_list_of_filenames_to_consolidate, dest_folder):
|
|
1042
|
+
full_list_of_filenames_to_consolidate, consolidated_files = consolidate_files(full_list_of_filenames_to_consolidate, dest_folder)
|
|
1043
|
+
# now reduce the pairs so that we do not duplicate the same files and therfore minimize resources this si very importnat for crops and the same logic can be applied to minimize resources and loading
|
|
1044
|
+
|
|
1045
|
+
print('dabu',len(full_list_of_filenames_to_consolidate)==len(consolidated_files)) # ok here too
|
|
1046
|
+
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
# flatten the lists if not flat to make things better
|
|
1050
|
+
|
|
1051
|
+
# if there are multiple files I need to flatten them --> TODO
|
|
1052
|
+
|
|
1053
|
+
full_list_of_filenames_to_consolidate = [elm if not is_string_a_list_string(elm) else reload_string_list(elm) for elm in full_list_of_filenames_to_consolidate]
|
|
1054
|
+
consolidated_files = [elm if not is_string_a_list_string(elm) else reload_string_list(elm) for elm in consolidated_files]
|
|
1055
|
+
|
|
1056
|
+
full_list_of_filenames_to_consolidate = flatten_list(full_list_of_filenames_to_consolidate)
|
|
1057
|
+
consolidated_files = flatten_list(consolidated_files)
|
|
1058
|
+
|
|
1059
|
+
print('dabu flattened',len(full_list_of_filenames_to_consolidate)==len(consolidated_files), len(full_list_of_filenames_to_consolidate),len(consolidated_files)) # ok here too
|
|
1060
|
+
print('full_list_of_filenames_to_consolidate',full_list_of_filenames_to_consolidate)
|
|
1061
|
+
print('consolidated_files',consolidated_files)
|
|
1062
|
+
|
|
1063
|
+
# TODO --> handle here the multi files too !!! -−> this will not be so easy because I need to loop over other loops -−> not so easy --> think of it
|
|
1064
|
+
final_version_of_consolidated_files = []
|
|
1065
|
+
# for elm in full_list_of_images:
|
|
1066
|
+
# idx = find_first_index(elm.filename,full_list_of_filenames_to_consolidate)
|
|
1067
|
+
#
|
|
1068
|
+
# if idx is not None and idx >=0:
|
|
1069
|
+
# final_version_of_consolidated_files.append(consolidated_files[idx])
|
|
1070
|
+
# else:
|
|
1071
|
+
# print(idx, elm.filename,'not found')
|
|
1072
|
+
for elm in full_list_of_filenames_to_consolidate:
|
|
1073
|
+
idx = find_first_index(elm,full_list_of_filenames_to_consolidate)
|
|
1074
|
+
|
|
1075
|
+
if idx is not None and idx >=0:
|
|
1076
|
+
final_version_of_consolidated_files.append(consolidated_files[idx])
|
|
1077
|
+
else:
|
|
1078
|
+
print(idx, elm.filename,'not found')
|
|
1079
|
+
return full_list_of_filenames_to_consolidate,final_version_of_consolidated_files
|
|
1080
|
+
|
|
1081
|
+
if __name__ == '__main__':
|
|
1082
|
+
import sys
|
|
1083
|
+
|
|
1084
|
+
if True:
|
|
1085
|
+
# Usage
|
|
1086
|
+
file_paths = ["/home/aigouy/Bureau/test.pdf", "/home/aigouy/Bureau/test_export.pdf",
|
|
1087
|
+
"/home/aigouy/Bureau/test.svg",
|
|
1088
|
+
'/home/aigouy/Bureau/test_consolidation.files/34a95ae3-ca74-47ff-b95b-3875593231ce/test.pdf']
|
|
1089
|
+
save_folder = "/home/aigouy/Bureau/test_consolidation.files"
|
|
1090
|
+
file_paths, new_paths = consolidate_files(file_paths, save_folder)
|
|
1091
|
+
|
|
1092
|
+
print(len(file_paths))
|
|
1093
|
+
print(len(new_paths))
|
|
1094
|
+
print(new_paths)
|
|
1095
|
+
|
|
1096
|
+
for f1, f2 in zip(file_paths, new_paths):
|
|
1097
|
+
print(f'{f1}-->{f2}')
|
|
1098
|
+
|
|
1099
|
+
sys.exit(0)
|
|
1100
|
+
|
|
1101
|
+
if True:
|
|
1102
|
+
files = '/media/teamPrudhomme/EqpPrudhomme2/Bernard/Apotome/Pour quantif Benoit/*.tif'
|
|
1103
|
+
list_of_files = loadlist(files, recursive=1)
|
|
1104
|
+
print(list_of_files)
|
|
1105
|
+
file = 'spots_count.txt'
|
|
1106
|
+
merge_files(list_of_files, file, os.path.join(smart_name_parser(files, 'parent'),file))
|
|
1107
|
+
file = 'spots.csv'
|
|
1108
|
+
merge_files(list_of_files, file, os.path.join(smart_name_parser(files, 'parent'),file))
|
|
1109
|
+
|
|
1110
|
+
sys.exit(0)
|
|
1111
|
+
|
|
1112
|
+
if True:
|
|
1113
|
+
# Example usage:
|
|
1114
|
+
file_path1 = "/F/genomic_resources/db_100_genomes/drosophila_only_with_gunu_human_readbale_names/100genomes_with_annots/0_suz_genome_us/D_suzukii.fasta.ndb"
|
|
1115
|
+
file_path2 = "/F/genomic_resources/db_100_genomes/drosophila_only_with_gunu_human_readbale_names/100genomes_with_annots/0_suz_genome_us/D_suzukii.fasta"
|
|
1116
|
+
file_path2 = "/F/genomic_resources/db_100_genomes/drosophila_only_with_gunu_human_readbale_names/100genomes_with_annots/0_suz_genome_us/D_suzukii.fasta.nin"
|
|
1117
|
+
|
|
1118
|
+
# file_path1, file_path2 = file_path2, file_path1
|
|
1119
|
+
|
|
1120
|
+
if is_file_more_recent(file_path1, file_path2):
|
|
1121
|
+
print(f"{file_path1} is more recent than {file_path2}")
|
|
1122
|
+
else:
|
|
1123
|
+
print(f"{file_path1} is not more recent than {file_path2}")
|
|
1124
|
+
sys.exit(0)
|
|
1125
|
+
|
|
1126
|
+
if True:
|
|
1127
|
+
tst_name = '/F/hiC_microC/haplotype_resolved_embryo/GSE121255_RAW/GSM3428927_2_4hrs-R2.dedup.pairs.txt.gz'
|
|
1128
|
+
|
|
1129
|
+
print(smart_name_parser(tst_name, 'short_pop_all_exts'))
|
|
1130
|
+
|
|
1131
|
+
tst_name = '/F/hiC_microC/haplotype_resolved_embryo/GSE121255_RAW/GSM3428927_2_4hrs-R2'
|
|
1132
|
+
print(smart_name_parser(tst_name, 'short_pop_all_exts'))
|
|
1133
|
+
|
|
1134
|
+
tst_name = '/F/hiC_microC/haplotype_resolved_embryo/GSE121255_RAW/GSM3428927_2_4hrs-R2.txt'
|
|
1135
|
+
print(smart_name_parser(tst_name, 'short_pop_all_exts'))
|
|
1136
|
+
|
|
1137
|
+
import sys
|
|
1138
|
+
|
|
1139
|
+
sys.exit(0)
|
|
1140
|
+
|
|
1141
|
+
if True:
|
|
1142
|
+
print(smart_name_parser('Série 10kb X1 Spot196 mut2 TgX malex.tif.tif', 'tutu'))
|
|
1143
|
+
|
|
1144
|
+
import sys
|
|
1145
|
+
|
|
1146
|
+
sys.exit(0)
|
|
1147
|
+
|
|
1148
|
+
if True:
|
|
1149
|
+
# these are the tests for the smart_name_parser
|
|
1150
|
+
|
|
1151
|
+
print(smart_name_parser('/this/is/a/test/of/your/system.tif', 'parent', appenders=['toto', 'tutu',
|
|
1152
|
+
'tata.tif']))
|
|
1153
|
+
print(smart_name_parser('/this/is/a/test/of/your/system.tif', 'parent',
|
|
1154
|
+
appenders='tata.tif'))
|
|
1155
|
+
print(smart_name_parser('/this/is/a/test/of/your/system.tif', 'full_no_ext',
|
|
1156
|
+
appenders='tata.tif'))
|
|
1157
|
+
print(smart_name_parser('/this/is/a/test/of/your/system.tif', ['TA', 'parent'],
|
|
1158
|
+
appenders='tata.tif'))
|
|
1159
|
+
|
|
1160
|
+
print('smart_name_parser', smart_name_parser(
|
|
1161
|
+
'/E/Sample_images/sample_images_PA/mini/focused_Series012.png')) # ['/E/Sample_images/sample_images_PA/mini', '', 'focused_Series012', '/E/Sample_images/sample_images_PA/mini/focused_Series012', 'focused_Series012', '/E/Sample_images/sample_images_PA/mini/focused_Series012']
|
|
1162
|
+
print('smart_name_parser', smart_name_parser(
|
|
1163
|
+
'/E/Sample_images/sample_images_PA/mini/focused_Series012')) # ['/E/Sample_images/sample_images_PA/mini', '', 'focused_Series012', '/E/Sample_images/sample_images_PA/mini/focused_Series012', 'focused_Series012', '/E/Sample_images/sample_images_PA/mini/focused_Series012']
|
|
1164
|
+
print('smart_name_parser', smart_name_parser(
|
|
1165
|
+
'focused_Series012.png')) # smart_name_parser ['', '.png', 'focused_Series012.png', 'focused_Series012', 'focused_Series012', 'focused_Series012.png']
|
|
1166
|
+
print('smart_name_parser',
|
|
1167
|
+
smart_name_parser('D:\\Sample_images\\sample_images_PA\\trash_test_mem\\mini\\focused_Series012.png'))
|
|
1168
|
+
print('smart_name_parser', smart_name_parser(
|
|
1169
|
+
'D:\\Sample_images\\\\sample_images_PA/trash_test_mem\\mini\\focused_Series012.png')) # hybrid widows linux names
|
|
1170
|
+
print('smart_name_parser',
|
|
1171
|
+
smart_name_parser('D:\\Sample_images\\\\sample_images_PA/trash_test_mem\\mini\\focused_Series012'))
|
|
1172
|
+
print('smart_name_parser', smart_name_parser(''))
|
|
1173
|
+
print('smart_name_parser', smart_name_parser('', replace_empty_by_none=True))
|
|
1174
|
+
print('smart_name_parser', smart_name_parser(None))
|
|
1175
|
+
print('smart_name_parser',
|
|
1176
|
+
smart_name_parser('/E/Sample_images/sample_images_PA/mini/focused_Series012.png',
|
|
1177
|
+
ordered_output=[
|
|
1178
|
+
'tracked_cells_resized.png'])) # retruns a TA name --> it is really cool!!!
|
|
1179
|
+
tracked_cells_resized, TA_path = smart_name_parser(
|
|
1180
|
+
'/E/Sample_images/sample_images_PA/mini/focused_Series012.png',
|
|
1181
|
+
ordered_output=['full_no_ext', 'tracked_cells_resized.png'])
|
|
1182
|
+
print('TADA', tracked_cells_resized, TA_path)
|
|
1183
|
+
tracked_cells_resized, TA_path = smart_name_parser(
|
|
1184
|
+
'/E/Sample_images/sample_images_PA/mini/focused_Series012.png',
|
|
1185
|
+
ordered_output=['TA', 'tracked_cells_resized.png'])
|
|
1186
|
+
print('TADA2', tracked_cells_resized, TA_path)
|
|
1187
|
+
import sys
|
|
1188
|
+
|
|
1189
|
+
sys.exit(0)
|
|
1190
|
+
|
|
1191
|
+
if True:
|
|
1192
|
+
# test of getting n consecutive images
|
|
1193
|
+
# also see how to handle None --> TODO
|
|
1194
|
+
img_list = loadlist('/E/Sample_images/sample_images_PA/mini/list.lst')
|
|
1195
|
+
print(img_list)
|
|
1196
|
+
|
|
1197
|
+
desired_images = get_n_input_files_and_output_folders(img_list, 1, -1, 1) # get one image before and after
|
|
1198
|
+
|
|
1199
|
+
print(desired_images)
|
|
1200
|
+
import sys
|
|
1201
|
+
|
|
1202
|
+
sys.exit(0)
|
|
1203
|
+
|
|
1204
|
+
# if True:
|
|
1205
|
+
# random_vx_images = (np.random.randint(2, size=(1024, 1024)) * 255).astype('uint8')
|
|
1206
|
+
# cell_labels = (np.random.randint(255, size=(1024, 1024))).astype('uint8')
|
|
1207
|
+
# vertices = np.where(random_vx_images == 255) # c'est
|
|
1208
|
+
# count_same = 0
|
|
1209
|
+
# count_different = 0
|
|
1210
|
+
#
|
|
1211
|
+
# start_all = timer()
|
|
1212
|
+
# for i in range(len(vertices[0])):
|
|
1213
|
+
# y = vertices[0][i]
|
|
1214
|
+
# x = vertices[1][i]
|
|
1215
|
+
# # ids = neighbors8((y, x), cell_labels).tolist() # celui ci est faux
|
|
1216
|
+
# ids2 = neighbors8_2((y, x), cell_labels)
|
|
1217
|
+
#
|
|
1218
|
+
# # if ids!=ids2:
|
|
1219
|
+
# # print(ids, ids2, ids==ids2)
|
|
1220
|
+
#
|
|
1221
|
+
# print('time', timer() - start_all)
|
|
1222
|
+
# # start_all = timer()
|
|
1223
|
+
# # for i in range(len(vertices[0])):
|
|
1224
|
+
# # y = vertices[0][i]
|
|
1225
|
+
# # x = vertices[1][i]
|
|
1226
|
+
# # ids = neighbors8((y, x), cell_labels).tolist() # celui ci est faux # --> keep my old way but fix its errors
|
|
1227
|
+
# # ids2 = neighbors8_2((y, x), cell_labels)
|
|
1228
|
+
# #
|
|
1229
|
+
# # if ids != ids2:
|
|
1230
|
+
# # print(ids, ids2, ids == ids2, y, x)
|
|
1231
|
+
# # count_different+=1
|
|
1232
|
+
# # else:
|
|
1233
|
+
# # count_same+=1
|
|
1234
|
+
# #
|
|
1235
|
+
# # print(count_same, count_different)
|
|
1236
|
+
# # print('time', timer() - start_all)
|
|
1237
|
+
#
|
|
1238
|
+
# # this one is much faster but why ???
|
|
1239
|
+
# start_all = timer()
|
|
1240
|
+
# for i in range(len(vertices[0])):
|
|
1241
|
+
# y = vertices[0][i]
|
|
1242
|
+
# x = vertices[1][i]
|
|
1243
|
+
# ids = neighbors8((y, x), cell_labels).tolist() # celui ci est faux # --> keep my old way but fix its errors
|
|
1244
|
+
# # ids2 = neighbors8_2((y, x), cell_labels)
|
|
1245
|
+
#
|
|
1246
|
+
# # if ids!=ids2:
|
|
1247
|
+
# # print(ids, ids2, ids==ids2)
|
|
1248
|
+
#
|
|
1249
|
+
# print('time', timer() - start_all)
|
|
1250
|
+
|
|
1251
|
+
cells_at_t0 = [0, 1, 2, 3, 4, 5, 6, 7, 128]
|
|
1252
|
+
cells_at_t1 = [1, 3, 4, 5, 128, 33, 24, 52]
|
|
1253
|
+
|
|
1254
|
+
print(get_lost_cells_between_first_and_second_set(cells_at_t0, cells_at_t1))
|
|
1255
|
+
print(get_lost_cells_between_first_and_second_set(cells_at_t1, cells_at_t0))
|
|
1256
|
+
|
|
1257
|
+
img = Img(
|
|
1258
|
+
'/E/Sample_images/segmentation_assistant/ovipo_uncropped/200709_armGFP_suz_46hAPF_ON.lif - Series011/tracked_cells_resized.tif')
|
|
1259
|
+
img = RGB_to_int24(img)
|
|
1260
|
+
start_all = timer()
|
|
1261
|
+
print(len(get_cells_in_image(img))) # ça marche et c'est super rapide en fait --> really good and fast
|
|
1262
|
+
print('time', timer() - start_all)
|
|
1263
|
+
# can get the first pixel of each using indices
|
|
1264
|
+
|
|
1265
|
+
start_all = timer()
|
|
1266
|
+
cells, first_px = get_cells_in_image_n_fisrt_pixel(
|
|
1267
|
+
img) # ça marche et c'est super rapide en fait --> really good and fast
|
|
1268
|
+
print(cells)
|
|
1269
|
+
print(first_px) # this is the ravel index
|
|
1270
|
+
print('time', timer() - start_all)
|
|
1271
|
+
|
|
1272
|
+
# --> 0.20 secs
|
|
1273
|
+
start_all = timer()
|
|
1274
|
+
cells, area = get_cells_in_image_n_count(img)
|
|
1275
|
+
print(cells)
|
|
1276
|
+
print(area)
|
|
1277
|
+
print('time', timer() - start_all)
|
|
1278
|
+
|
|
1279
|
+
# full self replacement of one image using == --> 14 secs
|
|
1280
|
+
start_all = timer()
|
|
1281
|
+
for cell in cells:
|
|
1282
|
+
img[img == cell] = cell
|
|
1283
|
+
print('time', timer() - start_all)
|
|
1284
|
+
|
|
1285
|
+
# start_all = timer()
|
|
1286
|
+
# for cell in cells:
|
|
1287
|
+
#
|
|
1288
|
+
# img[img == cell] = cell
|
|
1289
|
+
# print('time', timer() - start_all)
|
|
1290
|
+
|
|
1291
|
+
# encore plus lent et null --> 45 secs
|
|
1292
|
+
# start_all = timer()
|
|
1293
|
+
# for cell in cells:
|
|
1294
|
+
# np.where(img == cell, cell, img)
|
|
1295
|
+
# # img[img == cell] = cell
|
|
1296
|
+
# print('time', timer() - start_all)
|
|
1297
|
+
|
|
1298
|
+
# super slow --> do not use np.where in fact cause super slow
|
|
1299
|
+
start_all = timer()
|
|
1300
|
+
for cell in cells:
|
|
1301
|
+
cond = np.where(img == cell)
|
|
1302
|
+
img[cond] = cell
|
|
1303
|
+
print('time', timer() - start_all)
|
|
1304
|
+
|
|
1305
|
+
# print('neighbs length', len(ids))
|
|
1306
|
+
|
|
1307
|
+
# print(vertices)
|
|
1308
|
+
# if vertices[0].size != 0:
|
|
1309
|
+
# print('y', vertices[0][0])
|
|
1310
|
+
# if vertices[1].size != 0:
|
|
1311
|
+
# print('x', vertices[1][0])
|
|
1312
|
+
# if vertices[0].size + vertices[1].size != 0:
|
|
1313
|
+
# print('first vx', result[vertices[0][0], vertices[1][0]])
|
|
1314
|
+
|
|
1315
|
+
import importlib
|
|
1316
|
+
print(importlib.import_module("batoolset.files.tools")) #<module 'batoolset.files.tools' from '/home/aigouy/mon_prog/Python/epyseg_pkg/epyseg/files/tools.py'>
|
|
1317
|
+
|
|
1318
|
+
# rm('/E/Sample_images/cells_escaping_silencing_test_count/14,5kb T2A DsRed X2 B4 Tg/14,5kb T2A DsRed X2 B4 Tg 0001/wing_mask.tif')
|
|
1319
|
+
rm('/E/Sample_images/cells_escaping_silencing_test_count/14,5kb T2A DsRed X2 B4 Tg/14,5kb T2A DsRed X2 B4 Tg 0001/*.tif', exceptions=['veins_deep.tif','wing_cells.tif'])
|
|
1320
|
+
rm('/E/Sample_images/cells_escaping_silencing_test_count/14,5kb T2A DsRed X2 B4 Tg/14,5kb T2A DsRed X2 B4 Tg 0001/*.db', exceptions='spots.db')
|
|
1321
|
+
|