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.
Files changed (162) hide show
  1. batoolset/GUI/__init__.py +0 -0
  2. batoolset/GUI/list_gui.py +513 -0
  3. batoolset/GUI/multi_image_display.py +989 -0
  4. batoolset/GUI/open.py +325 -0
  5. batoolset/GUI/overlay_hints.py +45 -0
  6. batoolset/GUI/paint2.py +1345 -0
  7. batoolset/GUI/scrollablepaint.py +1152 -0
  8. batoolset/IJ_ROIs/__init__.py +0 -0
  9. batoolset/IJ_ROIs/tools.py +40 -0
  10. batoolset/PATH/__init__.py +0 -0
  11. batoolset/PATH/tools.py +79 -0
  12. batoolset/SQLite_tools/__init__.py +0 -0
  13. batoolset/SQLite_tools/tools.py +840 -0
  14. batoolset/__init__.py +0 -0
  15. batoolset/binary/__init__.py +0 -0
  16. batoolset/binary/tools.py +123 -0
  17. batoolset/binarytools/__init__.py +0 -0
  18. batoolset/binarytools/cell_center_detector.py +290 -0
  19. batoolset/clipboard_tools/__init__.py +0 -0
  20. batoolset/clipboard_tools/tools.py +7 -0
  21. batoolset/colors/__init__.py +0 -0
  22. batoolset/colors/colorgen.py +193 -0
  23. batoolset/colors/tools.py +22 -0
  24. batoolset/command_line/__init__.py +0 -0
  25. batoolset/command_line/tools.py +18 -0
  26. batoolset/dialogs/__init__.py +0 -0
  27. batoolset/dialogs/opensave.py +228 -0
  28. batoolset/dicts/__init__.py +0 -0
  29. batoolset/dicts/tools.py +299 -0
  30. batoolset/dims/__init__.py +0 -0
  31. batoolset/dims/tools.py +83 -0
  32. batoolset/draw/__init__.py +0 -0
  33. batoolset/draw/shapes/Position.py +183 -0
  34. batoolset/draw/shapes/__init__.py +0 -0
  35. batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
  36. batoolset/draw/shapes/circle2d.py +99 -0
  37. batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
  38. batoolset/draw/shapes/ellipse2d.py +336 -0
  39. batoolset/draw/shapes/freehand2d.py +235 -0
  40. batoolset/draw/shapes/group.py +1830 -0
  41. batoolset/draw/shapes/image2d.py +2469 -0
  42. batoolset/draw/shapes/line2d.py +575 -0
  43. batoolset/draw/shapes/point2d.py +257 -0
  44. batoolset/draw/shapes/polygon2d.py +357 -0
  45. batoolset/draw/shapes/polyline2d.py +235 -0
  46. batoolset/draw/shapes/rect2d.py +388 -0
  47. batoolset/draw/shapes/rectangle2d.py +601 -0
  48. batoolset/draw/shapes/scalebar.py +304 -0
  49. batoolset/draw/shapes/serializablefont.py +126 -0
  50. batoolset/draw/shapes/serializableguiparams.py +10 -0
  51. batoolset/draw/shapes/square2d.py +103 -0
  52. batoolset/draw/shapes/textorientation.py +45 -0
  53. batoolset/draw/shapes/tools.py +467 -0
  54. batoolset/draw/shapes/transform2D.py +350 -0
  55. batoolset/draw/shapes/txt2d.py +550 -0
  56. batoolset/draw/widgets/__init__.py +0 -0
  57. batoolset/draw/widgets/col.py +343 -0
  58. batoolset/draw/widgets/image_group.py +248 -0
  59. batoolset/draw/widgets/image_organizer.py +96 -0
  60. batoolset/draw/widgets/paint.py +184 -0
  61. batoolset/draw/widgets/vectorial.py +257 -0
  62. batoolset/figure/__init__.py +0 -0
  63. batoolset/figure/alignment.py +814 -0
  64. batoolset/figure/column.py +1117 -0
  65. batoolset/figure/fig_tools.py +285 -0
  66. batoolset/figure/minimal_debugger_scale_etc.py +139 -0
  67. batoolset/figure/panel.py +697 -0
  68. batoolset/figure/row.py +852 -0
  69. batoolset/figure/user_selection.py +287 -0
  70. batoolset/files/__init__.py +0 -0
  71. batoolset/files/tools.py +1321 -0
  72. batoolset/images/__init__.py +0 -0
  73. batoolset/images/tools.py +81 -0
  74. batoolset/img.py +5216 -0
  75. batoolset/linux/__init__.py +0 -0
  76. batoolset/linux/tools.py +72 -0
  77. batoolset/lists/__init__.py +0 -0
  78. batoolset/lists/tools.py +436 -0
  79. batoolset/luts/__init__.py +0 -0
  80. batoolset/luts/lut_minimal_test.py +1207 -0
  81. batoolset/matplolib/__init__.py +0 -0
  82. batoolset/matplolib/tools.py +44 -0
  83. batoolset/np_tools/__init__.py +0 -0
  84. batoolset/np_tools/tools.py +252 -0
  85. batoolset/np_tools/trash.py +15 -0
  86. batoolset/pandas_tools/__init__.py +0 -0
  87. batoolset/pandas_tools/tools.py +880 -0
  88. batoolset/partials/__init__.py +0 -0
  89. batoolset/partials/tools.py +83 -0
  90. batoolset/plot_tools/__init__.py +0 -0
  91. batoolset/plot_tools/tools.py +70 -0
  92. batoolset/pyqt/__init__.py +0 -0
  93. batoolset/pyqt/tools.py +691 -0
  94. batoolset/re_tools/__init__.py +0 -0
  95. batoolset/re_tools/tools.py +35 -0
  96. batoolset/serialization/__init__.py +0 -0
  97. batoolset/serialization/tools.py +1192 -0
  98. batoolset/sets/__init__.py +0 -0
  99. batoolset/sets/tools.py +109 -0
  100. batoolset/settings/__init__.py +0 -0
  101. batoolset/settings/global_settings.py +134 -0
  102. batoolset/strings/__init__.py +0 -0
  103. batoolset/strings/tools.py +225 -0
  104. batoolset/ta/__init__.py +0 -0
  105. batoolset/ta/database/__init__.py +0 -0
  106. batoolset/ta/database/advanced_sql_plotter.py +1170 -0
  107. batoolset/ta/database/my_qt_table.py +79 -0
  108. batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
  109. batoolset/ta/database/sql.py +2141 -0
  110. batoolset/ta/database/sql_column_name_dialog.py +122 -0
  111. batoolset/ta/measurements/TAmeasures.py +2226 -0
  112. batoolset/ta/measurements/__init__.py +0 -0
  113. batoolset/ta/measurements/measurements3D/__init__.py +0 -0
  114. batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
  115. batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
  116. batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
  117. batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
  118. batoolset/ta/measurements/nematic.py +562 -0
  119. batoolset/ta/measurements/nematic_measurements.py +107 -0
  120. batoolset/ta/segmentation/__init__.py +0 -0
  121. batoolset/ta/segmentation/neo_wshed.py +314 -0
  122. batoolset/ta/selections/__init__.py +0 -0
  123. batoolset/ta/selections/selection.py +329 -0
  124. batoolset/ta/tracking/__init__.py +0 -0
  125. batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
  126. batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
  127. batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
  128. batoolset/ta/tracking/registration.py +108 -0
  129. batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
  130. batoolset/ta/tracking/track_correction.py +238 -0
  131. batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
  132. batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
  133. batoolset/ta/utils/TA_tools.py +43 -0
  134. batoolset/ta/utils/__init__.py +0 -0
  135. batoolset/ta/utils/rps_tools.py +1783 -0
  136. batoolset/tests/__init__.py +0 -0
  137. batoolset/tests/rps_tools.py +51 -0
  138. batoolset/tests/tools.py +10 -0
  139. batoolset/tools/__init__.py +0 -0
  140. batoolset/tools/early_stopper_class.py +9 -0
  141. batoolset/tools/guided_data_recoverer.py +110 -0
  142. batoolset/tools/logger.py +100 -0
  143. batoolset/tools/mytimer.py +31 -0
  144. batoolset/tools/prompt_color.py +160 -0
  145. batoolset/tools/qthandler.py +118 -0
  146. batoolset/uitools/__init__.py +0 -0
  147. batoolset/uitools/blinker.py +56 -0
  148. batoolset/unsafe/__init__.py +0 -0
  149. batoolset/unsafe/tools.py +115 -0
  150. batoolset/utils/__init__.py +0 -0
  151. batoolset/utils/commontools.py +158 -0
  152. batoolset/utils/loadlist.py +728 -0
  153. batoolset/version.py +10 -0
  154. batoolset/xml/__init__.py +0 -0
  155. batoolset/xml/tools.py +65 -0
  156. batoolset/zip_tools/__init__.py +0 -0
  157. batoolset/zip_tools/tools.py +76 -0
  158. batoolset-0.1.0.dist-info/LICENSE +24 -0
  159. batoolset-0.1.0.dist-info/METADATA +45 -0
  160. batoolset-0.1.0.dist-info/RECORD +162 -0
  161. batoolset-0.1.0.dist-info/WHEEL +5 -0
  162. batoolset-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,728 @@
1
+ # TODO add glob to loadlist to load generic lists --> good idea I think and offer various sorting algos including natsort
2
+ # a tool to load lists that is smarter than the TA list loader
3
+
4
+ import os
5
+ import traceback
6
+ from functools import partial
7
+ from batoolset.tools.early_stopper_class import early_stop
8
+ from batoolset.tools.logger import TA_logger # logging
9
+ import glob
10
+ import shutil
11
+ from natsort import natsorted
12
+
13
+ from batoolset.utils.commontools import execute_chained_functions_and_save_as_tiff
14
+
15
+ logger = TA_logger()
16
+
17
+
18
+ def list_files_in_child_dirs(parent_directory, depth=1):
19
+ """
20
+ Recursively list files in child directories up to a specified depth.
21
+
22
+ Args:
23
+ parent_directory (str): The path to the parent directory to start the search.
24
+ depth (int): The maximum depth to search for child directories. Defaults to 1.
25
+
26
+ Returns:
27
+ list: A list of file paths found within the specified depth.
28
+
29
+ Example:
30
+ Given the directory structure:
31
+ parent_dir/
32
+ ├── child_dir1/
33
+ │ ├── file1.txt
34
+ │ └── file2.txt
35
+ ├── child_dir2/
36
+ │ ├── file3.txt
37
+ └── child_dir3/
38
+ └── file4.txt
39
+
40
+ To list files in child directories up to a depth of 1:
41
+ # >>> list_files_in_child_dirs("parent_dir", depth=1)
42
+ # Output: ['parent_dir/child_dir1/file1.txt', 'parent_dir/child_dir1/file2.txt', 'parent_dir/child_dir2/file3.txt']
43
+ """
44
+ tif_files = []
45
+ parent_directory, ext = parent_directory.split('*')
46
+
47
+ def recursive_list(directory, current_depth):
48
+ if current_depth >= depth:
49
+ return
50
+ for child_dir in os.listdir(directory):
51
+ child_dir_path = os.path.join(directory, child_dir)
52
+ if os.path.isdir(child_dir_path):
53
+ tif_files.extend(glob.glob(os.path.join(child_dir_path, f'*{ext}')))
54
+ recursive_list(child_dir_path, current_depth + 1)
55
+
56
+ recursive_list(parent_directory, current_depth=0)
57
+ return tif_files
58
+
59
+ def create_list(input_folder, save=False, output_name=None, extensions=['*.tif', '*.tiff', '*.jpg', '*.jpeg', '*.png', '*.bmp', '*.tga', '*.lif'], sort_type='natsort', recursive=False):
60
+ """
61
+ Creates a list of file paths in the specified input folder based on the given extensions.
62
+
63
+ Parameters:
64
+ - input_folder: The path to the input folder where the files are located.
65
+ - save: A flag indicating whether to save the list to a file (default is False).
66
+ - output_name: The name of the output file (default is None, which generates a file named 'list.lst' in the input folder).
67
+ - extensions: A list of file extensions to consider when creating the list (default is a list of common image extensions).
68
+ - sort_type: The type of sorting to apply to the list of file paths (default is 'natsort').
69
+
70
+ Returns:
71
+ A list of file paths.
72
+
73
+ Examples:
74
+ Suppose we have an input folder named 'images' with the following files:
75
+ - image1.jpg
76
+ - image2.png
77
+ - image3.tif
78
+
79
+ >>> create_list('.',extensions=['.py'])
80
+ ['./__init__.py', './commontools.py', './loadlist.py']
81
+ """
82
+
83
+ lst = [] # Initialize an empty list to store file paths
84
+
85
+ if not extensions:
86
+ logger.error('Extensions are not defined --> list cannot be created')
87
+ return lst
88
+
89
+ path = input_folder # Assign the input_folder path to the 'path' variable
90
+
91
+ if not path.endswith('/') and not path.endswith('\\') and not '*' in path and not os.path.isfile(path):
92
+ path += '/' # Append a trailing slash to the path if it doesn't have one
93
+
94
+ if not '*' in path:
95
+ # Iterate over the extensions and append matching file paths to the list
96
+ for ext in extensions:
97
+ if not ext.startswith('*'):
98
+ ext = '*' + ext # Prepend '*' to the extension if it doesn't have one
99
+ lst += glob.glob(path + ext)
100
+ else:
101
+ if not recursive:
102
+ lst += glob.glob(path) # Append all file paths in the path to the list
103
+ else:
104
+ if isinstance(recursive, int):
105
+ lst = list_files_in_child_dirs(path, depth=recursive)
106
+ else:
107
+ # Recursively search for .tif files in the folder and its subdirectories
108
+ path, ext = path.split('*')
109
+ for root, _,_ in os.walk(path):
110
+ lst.extend(glob.glob(os.path.join(root, '*'+ext)))
111
+
112
+ if sort_type == 'natsort':
113
+ lst = natsorted(lst) # Apply natural sorting to the list of file paths
114
+
115
+ if save:
116
+ if output_name is None:
117
+ output_name = os.path.join(input_folder, 'list.lst') # Generate the default output file name
118
+ save_list_to_file(lst, output_name) # Save the list to the specified output file
119
+
120
+ return lst # Return the list of file paths
121
+
122
+
123
+ def get_resume_list(input_list, resume_value):
124
+ """
125
+ Retrieves a resumed list starting from the specified resume_value.
126
+
127
+ Parameters:
128
+ - input_list: The input list to retrieve the resume list from.
129
+ - resume_value: The value in the list to resume from.
130
+
131
+ Returns:
132
+ A new list starting from the resume_value.
133
+
134
+ Examples:
135
+ >>> files = ['file1.jpg', 'file2.png', 'file3.tif', 'file4.jpg']
136
+ >>> get_resume_list(files, 'file2.png')
137
+ ['file2.png', 'file3.tif', 'file4.jpg']
138
+ """
139
+
140
+ try:
141
+ resume_index = input_list.index(resume_value)
142
+ resume_list = input_list[resume_index:]
143
+ return resume_list
144
+ except ValueError:
145
+ return []
146
+
147
+
148
+
149
+ def loadlist(txtfile, always_prefer_local_directory_if_file_exists=True, filter_existing_files_only=False,
150
+ smart_local_folder_detection=True, skip_hashtag_commented_lines=True, skip_empty_lines=True, recursive=False):
151
+ """
152
+ Loads a list from a text file with optional filtering and processing options.
153
+
154
+ Parameters:
155
+ - txtfile: The path to the text file to load the list from.
156
+ - always_prefer_local_directory_if_file_exists: If True, files located in the .lst/.txt file containing folder will be preferred if they exist.
157
+ - filter_existing_files_only: If True, filters the list to include only existing files.
158
+ - smart_local_folder_detection: If True, applies local paths to the common root path in the list for smarter list opening.
159
+ - skip_hashtag_commented_lines: If True, skips lines starting with '#' (commented lines) in the list.
160
+ - skip_empty_lines: If True, skips empty lines and lines containing spaces only.
161
+
162
+ Returns:
163
+ The loaded list with the specified filtering and processing options.
164
+
165
+ Examples:
166
+ >>> list_file = 'loadlist.py'
167
+ >>> loadlist(list_file, always_prefer_local_directory_if_file_exists=True, filter_existing_files_only=False)[:2]
168
+ ['import os', 'import traceback']
169
+ """
170
+
171
+ if not os.path.exists(txtfile) or not os.path.isfile(txtfile):
172
+ if not '*' in txtfile and not os.path.isdir(txtfile):
173
+ return None
174
+ else:
175
+ lst = create_list(txtfile, save=False, recursive=recursive) # Create a list using create_list() if txtfile is a directory or contains wildcard characters ('*')
176
+ else:
177
+ with open(txtfile) as f:
178
+ if not skip_hashtag_commented_lines:
179
+ lst = [line.rstrip() for line in f] # Read all lines from the text file and remove trailing whitespaces
180
+ else:
181
+ lst = [line.rstrip() for line in f if not line.rstrip().startswith('#')] # Exclude lines starting with '#' (commented lines)
182
+ if skip_empty_lines:
183
+ lst = [line.rstrip() for line in lst if not line.strip() == ''] # Exclude lines containing only spaces or empty lines
184
+
185
+ if always_prefer_local_directory_if_file_exists:
186
+ logger.debug('Files located in the .lst/.txt file containing folder will be preferred if they exist.')
187
+
188
+ list_file_directory = os.path.dirname(txtfile) # Get the directory of the txtfile
189
+
190
+ if not smart_local_folder_detection:
191
+ lst = [os.path.join(list_file_directory, os.path.basename(line)) if os.path.isfile(
192
+ os.path.join(list_file_directory, os.path.basename(line))) else line for line in lst]
193
+ # Prepend the list items with the list_file_directory if the file exists in the directory, otherwise keep the item as it is
194
+ else:
195
+ common_path = os.path.commonprefix(lst) # Find the common root path of all items in the list
196
+ if not os.path.isdir(common_path):
197
+ common_path = os.path.dirname(common_path)
198
+
199
+ if common_path != '':
200
+ relative_paths = [os.path.relpath(path, common_path) for path in lst] # Get the relative paths to the common_path
201
+ lst = [os.path.join(list_file_directory, rel) if os.path.isfile(
202
+ os.path.join(list_file_directory, rel)) else line for rel, line in zip(relative_paths, lst)]
203
+ # Prepend the list_file_directory to the relative paths if the file exists in the directory, otherwise keep the item as it is
204
+
205
+ if filter_existing_files_only:
206
+ logger.debug('Checking list for existing files')
207
+ lst = [line for line in lst if os.path.isfile(line)] # Filter the list to include only existing files
208
+
209
+ return lst
210
+
211
+ def TA_smart_pairing_list(TA_list, corresponding_list_of_files_to_inject_or_folder, stop_on_error=False):
212
+ """
213
+ Performs smart pairing of two lists, TA_list and corresponding_list_of_files_to_inject_or_folder, based on certain conditions.
214
+
215
+ Parameters:
216
+ - TA_list: The list to be paired.
217
+ - corresponding_list_of_files_to_inject_or_folder: The list of files or folder to be paired with TA_list.
218
+ - stop_on_error: If True, stops the execution if the input lists/folders don't match.
219
+
220
+ Returns:
221
+ The paired list as a result of smart pairing.
222
+
223
+ # Examples:
224
+ # >>> ta_list = 'ta_list.txt'
225
+ # >>> files_folder = 'files_folder'
226
+ # >>> TA_smart_pairing_list(ta_list, files_folder, stop_on_error=True)
227
+ # [('files_folder/file1.jpg', 'file1.jpg'), ('files_folder/file2.png', 'file2.png'), ('files_folder/file3.tif', 'file3.tif')]
228
+ """
229
+
230
+ if TA_list.lower().endswith('.txt') or TA_list.lower().endswith('.lst'):
231
+ TA_list = loadlist(TA_list) # Load the list from a text file if TA_list ends with '.txt' or '.lst'
232
+
233
+ if os.path.isdir(corresponding_list_of_files_to_inject_or_folder):
234
+ # If corresponding_list_of_files_to_inject_or_folder is a directory, assume same name as for input
235
+ # corresponding_list_of_files_to_inject_or_folder
236
+ matching_list = []
237
+ for file in TA_list:
238
+ filename0_without_path = os.path.basename(file) # Get the filename without the path
239
+ matching_list.append(os.path.join(corresponding_list_of_files_to_inject_or_folder, filename0_without_path))
240
+ # Create the matching list by joining the corresponding_list_of_files_to_inject_or_folder with the filename without the path
241
+ elif corresponding_list_of_files_to_inject_or_folder.lower().endswith('.txt') or \
242
+ corresponding_list_of_files_to_inject_or_folder.lower().endswith('.lst'):
243
+ matching_list = loadlist(corresponding_list_of_files_to_inject_or_folder)
244
+ # Load the matching list from a text file if corresponding_list_of_files_to_inject_or_folder ends with '.txt' or '.lst'
245
+
246
+ # Try zipping and print correspondence and if it fails, try smart matching
247
+ if len(matching_list) != len(TA_list):
248
+ if stop_on_error:
249
+ print('Input lists/folders don\'t match', len(TA_list), len(matching_list))
250
+ return
251
+ else:
252
+ # TODO: Implement rescue strategy for matching when lengths don't match
253
+ pass
254
+
255
+ zipped = list(zip(matching_list, TA_list)) # Zip the matching_list and TA_list together
256
+ return zipped
257
+
258
+
259
+ def TA_injector(TA_list, corresponding_list_of_files_to_inject_or_folder, generic_TA_name_for_injected=None, stop_on_error=True, move_file=False, simulate_only=False):
260
+ """
261
+ Performs injection of files from the corresponding_list_of_files_to_inject_or_folder into the destination folders specified by the TA_list.
262
+
263
+ Parameters:
264
+ - TA_list: The list specifying the destination folders for injection.
265
+ - corresponding_list_of_files_to_inject_or_folder: The list of files or folder to be injected.
266
+ - generic_TA_name_for_injected: The generic name to be used for the injected files. If None, the original filename will be used.
267
+ - stop_on_error: If True, stops the execution if the input lists/folders don't match.
268
+ - move_file: If True, moves the files instead of copying them.
269
+ - simulate_only: If True, simulates the injection without actually performing any file operations.
270
+
271
+ Returns:
272
+ None
273
+
274
+ # Examples:
275
+ # >>> ta_list = ['folder1', 'folder2']
276
+ # >>> files_folder = 'files_folder'
277
+ # >>> TA_injector(ta_list, files_folder, generic_TA_name_for_injected='injected.jpg', stop_on_error=False, move_file=True, simulate_only=False)
278
+ # move files_folder/file1.jpg --> folder1/injected.jpg
279
+ # move files_folder/file2.png --> folder2/injected.jpg
280
+ """
281
+
282
+ zipped = TA_smart_pairing_list(TA_list, corresponding_list_of_files_to_inject_or_folder)
283
+ if zipped is None:
284
+ # Nothing to do, maybe return an error
285
+ return
286
+
287
+ for matching_things in zipped:
288
+ file_to_copy = matching_things[0]
289
+ file_to_copy_without_path = os.path.basename(file_to_copy)
290
+ file = matching_things[-1]
291
+ filename0_without_path = os.path.basename(file)
292
+ filename0_without_ext = os.path.splitext(filename0_without_path)[0]
293
+ path = os.path.dirname(file)
294
+ destination_folder = os.path.join(path, filename0_without_ext)
295
+ destination_name = os.path.join(destination_folder, file_to_copy_without_path if generic_TA_name_for_injected is None else generic_TA_name_for_injected)
296
+
297
+ # Make sure the folder exists for the copy
298
+ if not simulate_only:
299
+ os.makedirs(os.path.dirname(destination_folder), exist_ok=True)
300
+
301
+ if not move_file:
302
+ print('copy', file_to_copy, '-->', destination_name)
303
+ if not simulate_only:
304
+ shutil.copy2(file_to_copy, destination_name)
305
+ else:
306
+ print('move', file_to_copy, '-->', destination_name)
307
+ if not simulate_only:
308
+ shutil.move(file_to_copy, destination_name)
309
+
310
+
311
+
312
+ # creates based on the main TA list a list of files with alternative names and returns it
313
+ # NB will only change name if the file with the alternate name exists --> I think this is the behaviour I want but ok
314
+ def smart_TA_list(main_list, name_to_search_first, alternative_name_if_name_to_search_first_does_not_exist=None):
315
+ """
316
+ Creates a smart list by combining the main_list with the specified name_to_search_first and an alternative name if the name_to_search_first doesn't exist.
317
+
318
+ Parameters:
319
+ - main_list: The main list of paths.
320
+ - name_to_search_first: The name to search first in each path.
321
+ - alternative_name_if_name_to_search_first_does_not_exist: The alternative name to use if the name_to_search_first doesn't exist.
322
+
323
+ Returns:
324
+ The smart list generated by combining the main_list with the specified names.
325
+
326
+ # Examples:
327
+ # >>> main_list = ['path1/file.txt', 'path2/image.png', 'path3/document.doc']
328
+ # >>> name_to_search_first = 'data.txt'
329
+ # >>> alternative_name_if_name_to_search_first_does_not_exist = 'backup.txt'
330
+ # >>> smart_TA_list(main_list, name_to_search_first, alternative_name_if_name_to_search_first_does_not_exist)
331
+ # ['path1/data.txt', 'path2/data.txt', 'path3/data.txt']
332
+ """
333
+
334
+ lst = [os.path.join(os.path.splitext(line)[0], name_to_search_first) for line in main_list]
335
+ # Generate a list by joining the path without the extension with the name_to_search_first
336
+
337
+ if alternative_name_if_name_to_search_first_does_not_exist is not None:
338
+ lst = [line if os.path.isfile(line) or not os.path.isfile(os.path.join(os.path.dirname(line), alternative_name_if_name_to_search_first_does_not_exist)) else os.path.join(os.path.dirname(line), alternative_name_if_name_to_search_first_does_not_exist) for line in lst]
339
+ # Check if the line is a file or if the alternative name doesn't exist in the same directory.
340
+ # If it's a file or the alternative name exists, keep the line as it is.
341
+ # Otherwise, replace the line with the alternative name.
342
+
343
+ return lst
344
+
345
+ def save_list_to_file(lst, filename, col_separator='\t'):
346
+ """
347
+ Saves the given list to a file.
348
+
349
+ Parameters:
350
+ - lst: The list to be saved.
351
+ - filename: The name of the file to save the list.
352
+ - col_separator: The separator character to use for items in the list.
353
+
354
+ Returns:
355
+ The input list if successfully saved.
356
+
357
+ Raises:
358
+ ValueError: If the list is empty.
359
+
360
+ # Examples:
361
+ # >>> lst = ['item1', 'item2', 'item3']
362
+ # >>> filename = 'output.txt'
363
+ # >>> save_list_to_file(lst, filename, col_separator='\t')
364
+ # ['item1', 'item2', 'item3']
365
+ """
366
+
367
+ if lst is not None:
368
+ with open(filename, 'w') as f:
369
+ for item in lst:
370
+ if not isinstance(item, list) and not isinstance(item, tuple):
371
+ f.write("%s\n" % item)
372
+ # Write each item in the list to a new line in the file.
373
+ else:
374
+ f.write("%s\n" % col_separator.join([str(i) for i in item]))
375
+ # If the item is a list, join its elements with the col_separator and write to the file.
376
+
377
+ return lst
378
+ else:
379
+ raise ValueError('Empty list --> cannot save it to a file')
380
+ # Raise an error if the list is empty.
381
+
382
+
383
+ # this gives the optimal folder name for saving images without requiring other stuff, from various models --> use that for ensemble tools
384
+ def smart_output_folder_name(lst):
385
+ """
386
+ Generates the smartest name for the output folder based on the given list of paths.
387
+
388
+ Parameters:
389
+ - lst: The list of paths.
390
+
391
+ Returns:
392
+ The list of smart folder names.
393
+
394
+ """
395
+
396
+ # TODO no clue what i wanted to do here, maybe just return the commaon path ?
397
+
398
+ # Get the common path among all the paths in the list
399
+ common_path = os.path.commonprefix(lst)
400
+
401
+ if not os.path.isdir(common_path):
402
+ common_path = os.path.dirname(common_path)
403
+
404
+ if common_path == '':
405
+ return None
406
+
407
+ # Replace slashes and backslashes in the common path with underscores to create a meaningful name
408
+ smart_name = [os.path.splitext(name.replace(common_path, '').replace('/', '_').replace('\\', '_'))[0] for name in lst]
409
+
410
+ # Remove leading underscores from the folder names
411
+ smart_name = [name if not name.startswith('_') else name[1:] for name in smart_name]
412
+
413
+ return smart_name
414
+
415
+ # can create a list of files with the same name across several folders generated by different models for example --> can then be used for ensemble or averaging...
416
+ def get_transversal_list(root_path):
417
+ """
418
+ Generates a transversal list of files by traversing through folders.
419
+
420
+ Parameters:
421
+ - root_path: The root path to start the traversal.
422
+
423
+ Returns:
424
+ The transversal list of files.
425
+
426
+ # Examples:
427
+ # >>> root_path = '/E/Sample_images/Consensus_learning/gray/CARE/'
428
+ # >>> get_transversal_list(root_path)
429
+ # [['/E/Sample_images/Consensus_learning/gray/CARE/folder1/file1.txt',
430
+ # '/E/Sample_images/Consensus_learning/gray/CARE/folder2/file1.txt'],
431
+ # ['/E/Sample_images/Consensus_learning/gray/CARE/folder1/file2.txt',
432
+ # '/E/Sample_images/Consensus_learning/gray/CARE/folder2/file2.txt']]
433
+ """
434
+
435
+ transverse_list = []
436
+
437
+ # Get the list of folders within the root path
438
+ folders = os.listdir(root_path)
439
+ folders = [os.path.join(root_path, folder) for folder in folders]
440
+ folders = natsorted(folders)
441
+
442
+ # Get the list of files in the first folder
443
+ files_in_first_folder = os.listdir(folders[0])
444
+
445
+ # Traverse through the files in the first folder
446
+ for file in files_in_first_folder:
447
+ multifolder_list = []
448
+
449
+ # Check if the file exists in other folders and add them to the list
450
+ for folder in folders:
451
+ final_file = os.path.join(folder, file)
452
+ if os.path.isfile(final_file):
453
+ try:
454
+ multifolder_list.append(final_file)
455
+ except:
456
+ print('invalid file', final_file)
457
+
458
+ transverse_list.append(multifolder_list)
459
+
460
+ return transverse_list
461
+
462
+
463
+ def list_processor(lst, processing_fn, multithreading=True, progress_callback=None, use_save_execution_if_chained=False, name_processor_function_for_saving=None):
464
+ """
465
+ Processes a list using a specified processing function.
466
+
467
+ Parameters:
468
+ - lst: The list to process.
469
+ - processing_fn: The processing function to apply to each element of the list.
470
+ - multithreading: Boolean value indicating whether to use multithreading.
471
+ - progress_callback: Callback function to track the progress of the processing.
472
+ - use_save_execution_if_chained: Boolean value indicating whether to use save execution if the processing function is chained.
473
+ - name_processor_function_for_saving: Name of the processor function for saving.
474
+
475
+ Returns:
476
+ None
477
+
478
+ # Examples:
479
+ # >>>lst = loadlist('/E/Sample_images/sample_images_PA/mini_empty/list.lst')
480
+ # >>>def output_file_name(input_file_name):
481
+ # ... return smart_name_parser(input_file_name, 'full_no_ext') + 'inverted2.tif'
482
+ # >>>chained_functions = [Img, invert, elastic_deform]
483
+ # >>>list_processor(lst=lst, processing_fn=chained_functions, multithreading=True, use_save_execution_if_chained=True,progress_callback=None, name_processor_function_for_saving=output_file_name)
484
+
485
+ """
486
+
487
+ from tqdm import tqdm
488
+ import multiprocessing
489
+ from multiprocessing import Pool
490
+ from timeit import default_timer as timer
491
+
492
+ start = timer()
493
+
494
+ nb_procs = multiprocessing.cpu_count() - 1
495
+ if nb_procs <= 0:
496
+ nb_procs = 1
497
+
498
+ if multithreading:
499
+ print('using', nb_procs, 'processors')
500
+
501
+ if isinstance(processing_fn, list):
502
+ processing_fn = partial(execute_chained_functions_and_save_as_tiff, function_to_chain_iterable=processing_fn,
503
+ output_file_name=name_processor_function_for_saving, reverse=False)
504
+
505
+ if multithreading:
506
+ import gc
507
+ gc.collect()
508
+ with Pool(processes=nb_procs) as pool:
509
+ for i, _ in enumerate(tqdm(pool.imap_unordered(processing_fn, lst), total=len(lst))):
510
+ if early_stop.stop:
511
+ pool.close()
512
+ pool.join()
513
+ return
514
+ if progress_callback is not None:
515
+ try:
516
+ from qtpy.QtWidgets import QProgressBar
517
+ if isinstance(progress_callback, QProgressBar):
518
+ progress_callback.setValue(int((i / len(lst)) * 100))
519
+ else:
520
+ progress_callback.emit(int((i / len(lst)) * 100))
521
+ except:
522
+ traceback.print_exc()
523
+ pool.close()
524
+ pool.join()
525
+ else:
526
+ for i, lst_elm in enumerate(lst):
527
+ result = processing_fn(lst_elm)
528
+ if early_stop.stop:
529
+ return
530
+ if progress_callback is not None:
531
+ try:
532
+ from qtpy.QtWidgets import QProgressBar
533
+ if isinstance(progress_callback, QProgressBar):
534
+ progress_callback.setValue(int((i / len(lst)) * 100))
535
+ else:
536
+ progress_callback.emit(int((i / len(lst)) * 100))
537
+ except:
538
+ traceback.print_exc()
539
+
540
+ print('total time', timer() - start)
541
+
542
+
543
+ if __name__ == '__main__':
544
+
545
+ if True:
546
+ transversal_list =get_transversal_list('/E/Sample_images/Consensus_learning/gray/CARE/')
547
+ print(transversal_list)
548
+ # for each can do an avg for example
549
+
550
+ import sys
551
+ sys.exit(0)
552
+
553
+
554
+ if True:
555
+ import sys
556
+ models = [
557
+ 'CARE_model_trained_MAE_in_epyseg_29-1_50steps_per_epoch_not_outstanding_though/CARE_model-0.h5', # 0 #####
558
+ 'CARE_model_trained_MSE_error_instead_MAE_in_epyseg_29-1/CARE_model-0.h5', #1
559
+ 'CARESEG3D_models_trained_on_colab_201214/CARESEG3D_model-0.h5', #2
560
+ 'CARESEG_another_normal_training_201216_colab_but_gave_crap/CARESEG_model-0.h5', # 3 # not bad in fact especially when there is an amazing amount of noise because it is an amazing denoiser...
561
+ 'CARESEG/CARESEG_model-0.h5', #4
562
+ 'CARESEG_first_correct_test/CARESEG_model-0-0-0.h5', #5
563
+ ## 'CARESEG_first_correct_test/CARESEG_model-0-0-4.h5', #6
564
+ 'CARESEG_first_successful_retrain_on_CARE_data_very_very_good_surface_proj_but_not_for_all/CARESEG_model-0-0.h5', #7
565
+ # 'CARESEG_first_successful_retrain_on_CARE_data_very_very_good_surface_proj_but_not_for_all/CARESEG_model-0-1.h5', #8
566
+ # 'CARESEG_first_successful_retrain_on_CARE_data_very_very_good_surface_proj_but_not_for_all/CARESEG_model-0-2.h5', #9
567
+ # 'CARESEG_first_successful_retrain_on_CARE_data_very_very_good_surface_proj_but_not_for_all/CARESEG_model-0-3.h5',#10
568
+ # 'CARESEG_first_successful_retrain_on_CARE_data_very_very_good_surface_proj_but_not_for_all/CARESEG_model-0-4.h5',#11
569
+ 'CARESEG_masked_data_and_masked_loss_to_prevent_identity_v1_210107_good/CARESEG_model-0.h5',#12
570
+ 'CARESEG_masked_data_and_partial_masked_loss_to_limit_identity_but_not_remove_it_v1_210107_outstanding_on_some_just_good_on_others/CARESEG_model-0.h5',
571
+ #####
572
+ # 13
573
+ 'CARESEG_masked_data_and_partial_masked_loss_to_limit_identity_but_not_remove_it_v2_zRoll_stack_210108_quite_good_but_a_bit_low_signal/CARESEG_model-0.h5',
574
+ ##### doesn't seem to require extra black frames and denoiser sucks because it has a lot of noise --> see the best of all
575
+ ##########DO NOT USE NEO######## 'CARESEG_masked_data_and_partial_masked_loss_to_limit_identity_but_not_remove_it_v2_zRoll_stack_210108_quite_good_but_a_bit_low_signal/complete_model_with_3_outputs.h5', # NEO
576
+ # 14
577
+ 'CARESEG_my_loss_mae_first_chan_dice_other_chans/CARESEG_model-0.h5',#15
578
+ 'CARESEG_RETRAINED_NEW_LOSS_DICE_201215/CARESEG_model-0.h5',#16
579
+ 'CARESEG_retrained_normally_201216/CARESEG_model-0.h5', # 17 #####
580
+ 'CARESEG_second_correct_tested_210219_outstanding_denoise/CARESEG_model-0.h5', # 18 #####
581
+ 'CARESEG_second_successful_retrain_on_CARE_data_better_than_previous_need_longer_training_and_more_diverse_one_too/CARESEG_model-0.h5',#19
582
+ 'CARESEG_shuffle_n_roll_models_trained_on_colab_201215/CARESEG_model-0.h5',#20
583
+ 'CARESEG_test_combined_loss_properly_made_with_reduce_mean_220105/CARESEG_model-0.h5',#21
584
+ 'CARESEG_test_combined_mae_jaccard_loss_properly_made_with_reduce_mean_220105_terrible_no_clue_why/CARESEG_model-0.h5',# 22
585
+ 'CARESEG_trained_different_losses_for_channels_mae_bce/CARESEG_model-0.h5', # 23
586
+ 'CARESEG_trained_on_CARE_data_with_dilation_good/CARESEG_model-0.h5',# 24
587
+ 'CARESEG_Zroll_models_trained_on_colab_201215/CARESEG_model-0.h5',# 25
588
+ 'CARE_trained_on_its_data_and_mine_not_working_on_its/CARE_model-0.h5',# 26
589
+ 'CARE_training_on_its_own_data_with_CARESEG/CARESEG_model-0-0.h5',# 27
590
+ # 'CARE_training_on_its_own_data_with_CARESEG/CARESEG_model-0-4.h5',# 28
591
+ 'retrained_CARE_my_soft_fixed_normalization_not_outstanding_but_improving/CARE_model-0.h5',# 29
592
+ 'CARE_finally_working_retrain_with_CARE_normalization/CARE_model-0.h5', # 30
593
+ 'CARE_models_trained_on_colab_201214/CARE_model-0.h5', # 31 #####
594
+ 'CARE_masked_data_and_partial_masked_loss_to_limit_identity_but_not_remove_it_v1_210120_not_outstanding_CARESEG_is_better/CARE_model-0.h5',# 32
595
+ ]
596
+
597
+ for idx, model in enumerate(models):
598
+ models[idx] = os.path.join('/E/models/my_model/bckup/', model)
599
+
600
+ print(models)
601
+
602
+ smart_output_folder_name(models)
603
+
604
+ # get smart_output_folder_name
605
+
606
+ sys.exit(0)
607
+
608
+
609
+ if False:
610
+ import sys
611
+
612
+ # THIS CODE COPIES METADATA FROM ONE FILE TO ANOTHER
613
+ # CAN I USE LEICA DATA TODO STUFF
614
+ # I may still need a time file at least for a while until I change my other tools but that could be useful still
615
+ # TODO --> make this its own function or class !!!!
616
+ # do a generic executer within this class and say whether it can be Mted or not ... --> Could be useful
617
+ list_file = [
618
+ '/E/Sample_images/sample_images_denoise_manue/210402_EcadKI_mel_female_26hAPF_pupae_from_old_tube/predict/predict_model_nb_0_not_best_but_very_good_still/list.lst'] # done 3D
619
+ list_file.append(
620
+ '/E/Sample_images/sample_images_denoise_manue/210324_ON_suz_22h45_armGFP_line2/predict/predict_model_nb_0/mini_list.lst')
621
+ list_file.append(
622
+ '/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/21-03/GT/predict/predict_model_nb_3/list.lst')
623
+ list_file.append(
624
+ '/E/Sample_images/sample_images_denoise_manue/210312_armGFP_line2_suz_39h30APF/predict/predict_model_nb_0/list.lst')
625
+
626
+ list_file.append(
627
+ '/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/25-1/GT/predict/predict_model_nb_3/list.lst')
628
+ list_file.append(
629
+ '/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/070219/predict/predict_model_nb_0/list.lst')
630
+ list_file.append(
631
+ '/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/20-2/predict/predict_model_nb_0/list.lst')
632
+ list_file.append(
633
+ '/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/210219/predict/predict_model_nb_0/list.lst')
634
+ list_file.append(
635
+ '/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/27-02/predict/predict_model_nb_0/list.lst')
636
+ list_file.append(
637
+ '/E/Sample_images/sample_images_denoise_manue/210409_EcadKI_ovipo_female_around_40hAPF/predict/predict_model_nb_4/list.lst')
638
+ # list_file = []
639
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/210121_armGFP_suz_line2_47h30_APF/predict/before_crash/predict_model_nb_0/mini_list.lst')
640
+
641
+ # list_file = []
642
+ list_file.append(
643
+ '/E/Sample_images/sample_images_denoise_manue/201104_armGFP_different_lines_tila/predict/predict_model_nb_0/mini_list.lst') # TODO
644
+
645
+ # HACK FOR THE LAST BECAUSE IT IS INCORRECT!!!
646
+ # zipped = TA_smart_pairing_list('/E/Sample_images/sample_images_denoise_manue/201104_armGFP_different_lines_tila/predict/predict_model_nb_0/registered/splitted/list2_matching.lst', '/E/Sample_images/sample_images_denoise_manue/201104_armGFP_different_lines_tila/list1.lst')
647
+
648
+ # map 2 lists
649
+ for lst in list_file:
650
+
651
+ parent_folder = heightmap_folder = lst.split('/predict/')[0]
652
+ # print(os.path.exists(heightmap_folder))
653
+ if not os.path.exists(parent_folder):
654
+ print('error', parent_folder)
655
+
656
+ # print(parent_folder)
657
+
658
+ # zipped = TA_smart_pairing_list(lst, parent_folder)
659
+
660
+ # HACK FOR THE LAST BECAUSE IT IS INCORRECT!!!
661
+ # zipped = TA_smart_pairing_list('/E/Sample_images/sample_images_denoise_manue/201104_armGFP_different_lines_tila/predict/predict_model_nb_0/registered/splitted/list2_matching.lst', '/E/Sample_images/sample_images_denoise_manue/201104_armGFP_different_lines_tila/list1.lst')
662
+ zipped = TA_smart_pairing_list(lst, parent_folder)
663
+ # print(zipped)
664
+ for files in zipped:
665
+ print('transferring metadata from', files[0], 'to', files[1])
666
+ _transfer_voxel_size_metadata(files[0], files[1])#.replace('.tif','.lsm')
667
+ # pass
668
+ sys.exit(0)
669
+
670
+ if True:
671
+ # TODO add glob
672
+
673
+
674
+ import sys
675
+ # copy and inject height maps to the file
676
+ # TA_injector
677
+ simulate_only = False
678
+ generic_TA_name = 'height_map.tif'
679
+
680
+ list_file = ['/E/Sample_images/sample_images_denoise_manue/210402_EcadKI_mel_female_26hAPF_pupae_from_old_tube/predict/predict_model_nb_0_not_best_but_very_good_still/list.lst'] # done 3D
681
+
682
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/210324_ON_suz_22h45_armGFP_line2/predict/predict_model_nb_0/mini_list.lst')
683
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/21-03/GT/predict/predict_model_nb_3/list.lst')
684
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/210312_armGFP_line2_suz_39h30APF/predict/predict_model_nb_0/list.lst')
685
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/25-1/GT/predict/predict_model_nb_3/list.lst')
686
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/070219/predict/predict_model_nb_0/list.lst')
687
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/20-2/predict/predict_model_nb_0/list.lst')
688
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/210219/predict/predict_model_nb_0/list.lst')
689
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/fullset_Manue/Ovipositors/27-02/predict/predict_model_nb_0/list.lst')
690
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/210409_EcadKI_ovipo_female_around_40hAPF/predict/predict_model_nb_4/list.lst')
691
+ list_file.append(
692
+ '/E/Sample_images/sample_images_denoise_manue/210121_armGFP_suz_line2_47h30_APF/predict/before_crash/predict_model_nb_0/mini_list.lst')
693
+ # TODO hack the last one
694
+ # list_file = []
695
+ # list_file.append('/E/Sample_images/sample_images_denoise_manue/201104_armGFP_different_lines_tila/predict/predict_model_nb_0/registered/splitted/mini_list.lst')
696
+ list_file.append('/E/Sample_images/sample_images_denoise_manue/201104_armGFP_different_lines_tila/predict/predict_model_nb_0/mini_list.lst')
697
+
698
+ for lst in list_file:
699
+ # TA_injector('/E/Sample_images/sample_images_denoise_manue/210402_EcadKI_mel_female_26hAPF_pupae_from_old_tube/predict/predict_model_nb_0_not_best_but_very_good_still/list.lst', '/E/Sample_images/sample_images_denoise_manue/210402_EcadKI_mel_female_26hAPF_pupae_from_old_tube/predict/height_map_test1', simulate_only=simulate_only, generic_TA_name_for_injected=generic_TA_name)
700
+ heightmap_folder = lst.split('/predict/')[0]+'/predict/height_maps/'
701
+ # print(os.path.exists(heightmap_folder))
702
+ if not os.path.exists(heightmap_folder):
703
+ print(heightmap_folder)
704
+ # TA_injector(list, '/E/Sample_images/sample_images_denoise_manue/210402_EcadKI_mel_female_26hAPF_pupae_from_old_tube/predict/height_map_test1', simulate_only=simulate_only, generic_TA_name_for_injected=generic_TA_name)
705
+ TA_injector(lst, heightmap_folder, simulate_only=simulate_only, generic_TA_name_for_injected=generic_TA_name)
706
+ sys.exit(0)
707
+
708
+ # TODO transform this into tests (just create some tmp files)
709
+ print(loadlist('/E/Sample_images/sample_images_denoise_manue/200722_armGFP_suz_ON_47hAPF/predict/predict_model_nb_4/list.lst'))
710
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list.lst'))
711
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list.lst', always_prefer_local_directory_if_file_exists=False))
712
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list.lst', always_prefer_local_directory_if_file_exists=False, filter_existing_files_only=True))
713
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list.lst', always_prefer_local_directory_if_file_exists=True, filter_existing_files_only=True))
714
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list_smart.lst', always_prefer_local_directory_if_file_exists=True, smart_local_folder_detection=False))
715
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list_smart.lst', always_prefer_local_directory_if_file_exists=True))
716
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list_smart.lst')) # this is the default behavior and I do really love it
717
+ print(loadlist('/E/Sample_images/sample_images_PA/mini/list_smart.lst', always_prefer_local_directory_if_file_exists=True, smart_local_folder_detection=False, filter_existing_files_only=True))
718
+
719
+ tmp_lst = loadlist('/E/Sample_images/sample_images_PA/mini/list.lst', always_prefer_local_directory_if_file_exists=True, filter_existing_files_only=True)
720
+ print(smart_TA_list(tmp_lst, 'tutu.tif'))
721
+ print(smart_TA_list(tmp_lst, 'handCorrection.tif', alternative_name_if_name_to_search_first_does_not_exist=None))
722
+ print(smart_TA_list(tmp_lst, 'handCorrection.tif', alternative_name_if_name_to_search_first_does_not_exist='handCorrection.png'))
723
+ # I think that works as I want
724
+ print(smart_TA_list(tmp_lst, 'handCorrection2.png', alternative_name_if_name_to_search_first_does_not_exist='handCorrection.png'))
725
+
726
+ save_list_to_file(smart_TA_list(tmp_lst, 'handCorrection.tif', alternative_name_if_name_to_search_first_does_not_exist='handCorrection.png'), '/E/Sample_images/sample_images_PA/mini/list_masks.lst')
727
+
728
+ print('final list',create_list('/E/Sample_images/sample_images_denoiseg/train/raw/', save=True))