CompactionAnalyzer 1.0.3__tar.gz → 1.0.5__tar.gz
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.
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/CompactionFunctions.py +169 -117
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/plotting.py +9 -6
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/utilities.py +7 -5
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/PKG-INFO +2 -2
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/PKG-INFO +2 -2
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/README.md +18 -5
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/setup.py +2 -2
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/GUI_old_use_saenopy_instead.py +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/QExtendedGraphicsView.py +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/QtShortCuts.py +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/StructureTensor.py +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/__init__.py +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/SOURCES.txt +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/dependency_links.txt +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/requires.txt +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/top_level.txt +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/LICENSE +0 -0
- {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/setup.cfg +0 -0
{compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/CompactionFunctions.py
RENAMED
|
@@ -146,7 +146,10 @@ def segment_cell(img, thres=1, seg_gaus1 = 0.5, seg_gaus2=100, seg_iter=1,show_s
|
|
|
146
146
|
height = img.shape[0]
|
|
147
147
|
width = img.shape[1]
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
## if 3 channels convert to grey
|
|
150
|
+
if len(img.shape) == 3 :
|
|
151
|
+
img = color.rgb2gray(img)
|
|
152
|
+
|
|
150
153
|
# local gaussian (or single gaussian if gaus2 == None)
|
|
151
154
|
if seg_gaus2 is not None:
|
|
152
155
|
img = np.abs(gaussian(img, sigma=seg_gaus1) - gaussian(img, sigma=seg_gaus2))
|
|
@@ -217,6 +220,24 @@ def segment_cell(img, thres=1, seg_gaus1 = 0.5, seg_gaus2=100, seg_iter=1,show_s
|
|
|
217
220
|
return {'mask': mask, 'radius': radius, 'centroid': (cx, cy)}
|
|
218
221
|
|
|
219
222
|
|
|
223
|
+
def create_centered_circle(image_shape):
|
|
224
|
+
# Extract the height and width of the image
|
|
225
|
+
height, width = image_shape[:2]
|
|
226
|
+
# Calculate the center of the image
|
|
227
|
+
center_y, center_x = height // 2, width // 2
|
|
228
|
+
# Calculate the radius of the circle (1/4 of the image height or width)
|
|
229
|
+
radius = min(height, width) // 10
|
|
230
|
+
# Create a 2D array of zeros (background)
|
|
231
|
+
circle_array = np.zeros((height, width), dtype=int)
|
|
232
|
+
# Iterate over each point in the 2D array
|
|
233
|
+
for y in range(height):
|
|
234
|
+
for x in range(width):
|
|
235
|
+
# Calculate the distance from the center
|
|
236
|
+
distance = np.sqrt((y - center_y) ** 2 + (x - center_x) ** 2)
|
|
237
|
+
# If the distance is less than or equal to the radius, set it to 1 (circle)
|
|
238
|
+
if distance <= radius:
|
|
239
|
+
circle_array[y, x] = 1
|
|
240
|
+
return circle_array
|
|
220
241
|
|
|
221
242
|
|
|
222
243
|
def StuctureAnalysisMain(fiber_list,
|
|
@@ -239,7 +260,8 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
239
260
|
manual_segmention = False , # segmentation of mask by manual clicking the cell outline
|
|
240
261
|
plotting = True , # creates and saves individual figures additionally to the excel files
|
|
241
262
|
dpi = 200 , # resolution of figures
|
|
242
|
-
SaveNumpy =
|
|
263
|
+
SaveNumpy = True , # saves numpy arrays for later analysis
|
|
264
|
+
SaveExcel = True , # saves Excel files for later analysis
|
|
243
265
|
norm1=1,norm2 = 99 , # contrast spreading for input images between norm1- and norm2-percentile; values below norm1-percentile are set to zero and
|
|
244
266
|
# values above norm2-percentile are set to 1
|
|
245
267
|
### use norm1= 0,norm2 = 100 if no contras enhancement desired
|
|
@@ -249,7 +271,13 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
249
271
|
segmention_min_area = 1000, # small bjects below this px-area are removed during cell segmentation
|
|
250
272
|
load_segmentation = False, # if True enter the path of the segementation.npy - file in path_seg
|
|
251
273
|
path_seg = None, # to load a mask
|
|
252
|
-
ignore_cell_outline=False
|
|
274
|
+
ignore_cell_outline=False, # if True the cell area is not set to nan and orientation are calculted everywhere - still the cell center is calculated from segmention
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
mode_saenopy=False): # only used for the Saenopy Version to return data files directly after single run
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
253
281
|
"""
|
|
254
282
|
Main analysis
|
|
255
283
|
|
|
@@ -264,8 +292,16 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
264
292
|
None.
|
|
265
293
|
|
|
266
294
|
"""
|
|
267
|
-
plt.ioff()
|
|
268
|
-
|
|
295
|
+
# plt.ioff()
|
|
296
|
+
# plt.ion()
|
|
297
|
+
|
|
298
|
+
# if no cell images are specified we conduct the analyis on the full image
|
|
299
|
+
# for this, we create dummy images of an artificial cell and set ignore_cell_outline to True
|
|
300
|
+
# Might be usefull to look at quantities such as fiber coherency or angle towards x-axis
|
|
301
|
+
if cell_list == None:
|
|
302
|
+
ignore_cell_outline= True
|
|
303
|
+
dummy_cell = create_centered_circle(imageio.v2.imread(fiber_list[0]).shape)
|
|
304
|
+
|
|
269
305
|
|
|
270
306
|
# if not specified use 7um for tensor analysis and 5um shells
|
|
271
307
|
if not sigma_tensor:
|
|
@@ -300,17 +336,21 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
300
336
|
}
|
|
301
337
|
with open(os.path.join(out_list[n],"parameters.yml"), 'w') as yaml_file:
|
|
302
338
|
yaml.dump(dict_file, yaml_file, default_flow_style=False)
|
|
303
|
-
|
|
304
339
|
|
|
305
|
-
# load images
|
|
306
|
-
|
|
307
|
-
|
|
340
|
+
# load images
|
|
341
|
+
im_fiber = imageio.v2.imread(fiber_list[n]) #color.rgb2gray()
|
|
342
|
+
if cell_list == None:
|
|
343
|
+
im_cell = dummy_cell
|
|
344
|
+
else:
|
|
345
|
+
im_cell = imageio.v2.imread(cell_list[n])
|
|
346
|
+
|
|
308
347
|
|
|
309
348
|
## if 3 channels convert to grey
|
|
310
|
-
if len(im_cell.shape) == 3 :
|
|
349
|
+
if len(im_cell.shape) == 3 :
|
|
311
350
|
im_cell = color.rgb2gray(im_cell)
|
|
312
351
|
if len(im_fiber.shape) == 3 :
|
|
313
|
-
im_fiber = color.rgb2gray(im_fiber)
|
|
352
|
+
im_fiber = color.rgb2gray(im_fiber)
|
|
353
|
+
|
|
314
354
|
|
|
315
355
|
# # applying normalizing/ contrast spreading
|
|
316
356
|
im_cell_n = normalize(im_cell, norm1, norm2)
|
|
@@ -370,8 +410,8 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
370
410
|
dy_norm = (dy/distance)
|
|
371
411
|
dist_surface = distance_transform_edt(~segmention["mask"])[edge:-edge,edge:-edge] # dist to surface
|
|
372
412
|
# calculate an angle without the deviation/reference to the cell position
|
|
373
|
-
angle_no_reference = np.arctan2(min_evec[:,:,0],min_evec[:,:,1])*360/(2*np.pi)
|
|
374
|
-
|
|
413
|
+
angle_no_reference = np.abs(np.arctan2(min_evec[:,:,0],min_evec[:,:,1])*360/(2*np.pi))-90 # -90 to +90° towards x-axis
|
|
414
|
+
|
|
375
415
|
|
|
376
416
|
"""
|
|
377
417
|
total image analysis
|
|
@@ -458,7 +498,8 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
458
498
|
results_total['Orientation (weighted by intensity and coherency)'].append(cos_dev_total3)
|
|
459
499
|
|
|
460
500
|
excel_total = pd.DataFrame.from_dict(results_total)
|
|
461
|
-
|
|
501
|
+
if SaveExcel:
|
|
502
|
+
excel_total.to_excel(os.path.join(out_list[n],"results_total.xlsx"))
|
|
462
503
|
|
|
463
504
|
|
|
464
505
|
"""
|
|
@@ -513,14 +554,18 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
513
554
|
|
|
514
555
|
# create excel sheet with results for angle analysis
|
|
515
556
|
excel_angles= pd.DataFrame.from_dict(results_angle)
|
|
516
|
-
|
|
517
|
-
|
|
557
|
+
if SaveExcel:
|
|
558
|
+
excel_angles.to_excel(os.path.join(out_list[n],"results_angles.xlsx"))
|
|
518
559
|
|
|
560
|
+
|
|
519
561
|
"""
|
|
520
562
|
Distance Evaluation
|
|
521
563
|
"""
|
|
522
564
|
|
|
523
|
-
|
|
565
|
+
|
|
566
|
+
# def distance_analysis(shells,shell_width,dist_surface,scale,angle_dev, ori, orientation_dev, weight_image,im_fiber_g):
|
|
567
|
+
|
|
568
|
+
# initialize result dictionary
|
|
524
569
|
results_distance = {'Shell_mid (px)': [], 'Shell_mid (µm)': [], 'Intensity (accumulated)': [],
|
|
525
570
|
'Intensity (individual)': [], 'Intensity Norm (individual)': [],
|
|
526
571
|
'Intensity Norm (accumulated)': [], 'Angle (accumulated)': [], 'Angle (individual)': [], 'Angle (individual-weightInt)': [],
|
|
@@ -532,7 +577,7 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
532
577
|
'Angle disttocenter (accumulated)': [], 'Angle disttocenter (individual)': [],
|
|
533
578
|
'Orientation disttocenter (accumulated)': [], 'Orientation disttocenter (individual)': [],
|
|
534
579
|
'Angle disttocenter (individual)': []
|
|
535
|
-
|
|
580
|
+
}
|
|
536
581
|
|
|
537
582
|
mask_shells = {'Mask_shell': [], 'Mask_shell_center': [] }
|
|
538
583
|
# shell distances
|
|
@@ -565,7 +610,7 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
565
610
|
results_distance['Orientation (individual-weightInt)'].append(np.nanmean(orientation_dev[mask_shell]*ori[mask_shell]*weight_image[mask_shell]/np.nanmean(ori[mask_shell]*weight_image[mask_shell]) ))
|
|
566
611
|
|
|
567
612
|
|
|
568
|
-
|
|
613
|
+
# mean intensity
|
|
569
614
|
results_distance['Intensity (accumulated)'].append(np.nanmean(im_fiber_g[mask_shell_lower])) # accumulation of lower shells
|
|
570
615
|
results_distance['Intensity (individual)'].append(np.nanmean(im_fiber_g[mask_shell]) ) # exclusively in certain shell
|
|
571
616
|
|
|
@@ -599,7 +644,8 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
599
644
|
results_distance['Intensity Norm disttocenter (accumulated)'].extend(list(norm_accum_int_c) )
|
|
600
645
|
# create excel sheet with results for angle analysis
|
|
601
646
|
excel_distance = pd.DataFrame.from_dict(results_distance)
|
|
602
|
-
|
|
647
|
+
if SaveExcel:
|
|
648
|
+
excel_distance.to_excel(os.path.join(out_list[n],"results_distance.xlsx"))
|
|
603
649
|
|
|
604
650
|
|
|
605
651
|
|
|
@@ -609,8 +655,9 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
609
655
|
print (numpy_out)
|
|
610
656
|
if not os.path.exists(numpy_out):
|
|
611
657
|
os.makedirs(numpy_out)
|
|
612
|
-
|
|
613
|
-
|
|
658
|
+
# save data array all with the size of the evaluated arrays
|
|
659
|
+
# that are "edge" - pixels smaller to get rid of boundary artefacts
|
|
660
|
+
np.save(os.path.join(numpy_out, "segmention.npy" ),segmention["mask"][edge:-edge,edge:-edge])
|
|
614
661
|
np.save(os.path.join(numpy_out, "AngleDeviationMap.npy" ),angle_dev )
|
|
615
662
|
#np.save(os.path.join(numpy_out, "AngleMap(weight_int).npy" ),angle_dev_weighted)
|
|
616
663
|
np.save(os.path.join(numpy_out, "AngleDeviationMap(weight_int_coh).npy"),angle_dev_weighted2 )
|
|
@@ -623,8 +670,15 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
623
670
|
#np.save(os.path.join(numpy_out, "CoherencyMap(weighted_int).npy" ),ori_weight2)
|
|
624
671
|
np.save(os.path.join(numpy_out, "Vector_min_ax0.npy"),min_evec[:,:,0])
|
|
625
672
|
np.save(os.path.join(numpy_out, "Vector_min_ax1.npy"),min_evec[:,:,1])
|
|
673
|
+
np.save(os.path.join(numpy_out, "center.npy"),center_small)
|
|
626
674
|
#np.save(os.path.join(numpy_out, "mask_surface_shells.npy"),mask_shells['Mask_shell'])
|
|
627
675
|
#np.save(os.path.join(numpy_out, "mask_spherical_shells.npy"),mask_shells['Mask_shell_center'])
|
|
676
|
+
|
|
677
|
+
# check the shapes --> everything is the same format
|
|
678
|
+
# print(segmention["mask"][edge:-edge,edge:-edge].shape)
|
|
679
|
+
# print(orientation_dev.shape)
|
|
680
|
+
# print(normalize(im_fiber_n[edge:-edge,edge:-edge]).shape)
|
|
681
|
+
# print(angle_no_reference.shape)
|
|
628
682
|
|
|
629
683
|
|
|
630
684
|
"""
|
|
@@ -641,68 +695,75 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
641
695
|
plot_angle_dev(angle_map = orientation_dev, vmin=-1,vmax=1,
|
|
642
696
|
vec0=min_evec[:,:,0] ,vec1=min_evec[:,:,1] ,coherency_map=ori,
|
|
643
697
|
path_png= os.path.join(figures,"Orientation.png"),label="Orientation",dpi=dpi,cmap="coolwarm")
|
|
644
|
-
|
|
645
|
-
# plot_angle_dev(angle_map = angle_dev, vmin=0,vmax=90,
|
|
646
|
-
# vec0=min_evec[:,:,0] ,vec1=min_evec[:,:,1] ,coherency_map=ori,
|
|
647
|
-
# path_png= os.path.join(figures,"Angle_deviation.png"),label="Angle Deviation",dpi=dpi,cmap="viridis_r")
|
|
648
|
-
|
|
649
|
-
# # do not show the weighted ones here, as only the mean has the same range again and here angles can be smaller/large
|
|
650
|
-
# plot_angle_dev(angle_map = angle_dev_weighted2,
|
|
651
|
-
# vec0=min_evec[:,:,0] ,vec1=min_evec[:,:,1] ,coherency_map=ori,
|
|
652
|
-
# path_png= os.path.join(figures,"Angle_deviation_weighted.png"),label="Angle Deviation",dpi=dpi,cmap="viridis_r")
|
|
653
|
-
# plot_angle_dev(angle_map = orientation_dev_weighted2 ,
|
|
654
|
-
# vec0=min_evec[:,:,0] ,vec1=min_evec[:,:,1] ,coherency_map=ori,
|
|
655
|
-
# path_png= os.path.join(figures,"Orientation_weighted.png"),label="Orientation",dpi=dpi,cmap="viridis")
|
|
656
|
-
|
|
657
|
-
# # pure coherency and pure orientation
|
|
658
|
-
# plot_coherency(ori,path_png= os.path.join(figures,"coherency_noquiver.png"),
|
|
659
|
-
# label="Coherency",vmin=0,vmax=1,cmap="turbo",dpi=dpi)
|
|
660
|
-
# plot_coherency(orientation_dev,
|
|
661
|
-
# path_png= os.path.join(figures,"Orientation_noquiver.png"),
|
|
662
|
-
# label="Orientation",vmin=-1,vmax=1,cmap="coolwarm",dpi=dpi)
|
|
698
|
+
|
|
663
699
|
|
|
700
|
+
|
|
701
|
+
if cell_list == None:
|
|
702
|
+
plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
|
|
703
|
+
None,
|
|
704
|
+
angle_no_reference, cmap_angle="gist_rainbow",
|
|
705
|
+
path_png= os.path.join(figures,"Angle_NoReference_overlay_nocell.png"),
|
|
706
|
+
label="Angle (x-axis)",dpi=dpi,
|
|
707
|
+
# ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
|
|
708
|
+
# cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
|
|
709
|
+
omin=-90, omax=90,
|
|
710
|
+
scale=scale)
|
|
711
|
+
plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
|
|
712
|
+
None,
|
|
713
|
+
ori, cmap_angle="turbo",
|
|
714
|
+
path_png= os.path.join(figures,"Coherency_overlay_nocell.png"),
|
|
715
|
+
label="Coherency",dpi=dpi,
|
|
716
|
+
# ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
|
|
717
|
+
# cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
|
|
718
|
+
omin=0, omax=1,scale=scale)
|
|
719
|
+
plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
|
|
720
|
+
im_cell_n[edge:-edge,edge:-edge],
|
|
721
|
+
orientation_dev, cmap_angle="coolwarm",
|
|
722
|
+
path_png= os.path.join(figures,"Orientation_overlay.png"),
|
|
723
|
+
label="Orientation",dpi=dpi,
|
|
724
|
+
omin=-1, omax=1,scale=scale)
|
|
664
725
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
726
|
+
else:
|
|
727
|
+
### more fancy overlay plot of cell & fiber & orientation (notweighted)
|
|
728
|
+
plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
|
|
729
|
+
im_cell_n[edge:-edge,edge:-edge],
|
|
730
|
+
orientation_dev, cmap_angle="coolwarm",
|
|
731
|
+
path_png= os.path.join(figures,"Orientation_overlay.png"),
|
|
732
|
+
label="Orientation",dpi=dpi,
|
|
733
|
+
# ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
|
|
734
|
+
# cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
|
|
735
|
+
omin=-1, omax=1,scale=scale)
|
|
736
|
+
|
|
737
|
+
plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
|
|
738
|
+
im_cell_n[edge:-edge,edge:-edge],
|
|
739
|
+
ori, cmap_angle="turbo",
|
|
740
|
+
path_png= os.path.join(figures,"Coherency_overlay.png"),
|
|
741
|
+
label="Coherency",dpi=dpi,
|
|
742
|
+
# ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
|
|
743
|
+
# cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
|
|
744
|
+
omin=0, omax=1,scale=scale)
|
|
745
|
+
|
|
746
|
+
plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
|
|
747
|
+
im_cell_n[edge:-edge,edge:-edge],
|
|
748
|
+
angle_dev, cmap_angle="viridis_r",
|
|
749
|
+
path_png= os.path.join(figures,"Angle_Deviation_overlay.png"),
|
|
750
|
+
label="Angle Deviation",dpi=dpi,
|
|
751
|
+
# ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
|
|
752
|
+
# cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
|
|
753
|
+
omin=0, omax=90,scale=scale)
|
|
754
|
+
|
|
755
|
+
plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
|
|
756
|
+
im_cell_n[edge:-edge,edge:-edge],
|
|
757
|
+
angle_no_reference, cmap_angle="gist_rainbow",
|
|
758
|
+
path_png= os.path.join(figures,"Angle_NoReference_overlay.png"),
|
|
759
|
+
label="Angle (x-axis)",dpi=dpi,
|
|
760
|
+
# ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
|
|
761
|
+
# cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
|
|
762
|
+
omin=-90, omax=90,
|
|
763
|
+
scale=scale)
|
|
764
|
+
|
|
702
765
|
|
|
703
|
-
|
|
704
766
|
plt.close("all")
|
|
705
|
-
|
|
706
767
|
|
|
707
768
|
# Polar plots
|
|
708
769
|
plot_polar(results_angle['Angles Plotting'], results_angle['Coherency (weighted by intensity)'],
|
|
@@ -713,43 +774,31 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
713
774
|
path_png= os.path.join(figures,"polar_orientation_double.png"), label = "Orientation (weighted)",
|
|
714
775
|
something2 = results_angle['Orientation'], label2 = "Orientation",dpi=dpi, vmin=-1,vmax=1)
|
|
715
776
|
|
|
716
|
-
# plot_polar(results_angle['Angles Plotting'], results_angle['Coherency (weighted by intensity)'],
|
|
717
|
-
# path_png= os.path.join(figures,"polar_coherency_weighted.png"), label = "Coherency (weighted)",dpi=dpi)
|
|
718
|
-
|
|
719
|
-
# plot_polar(results_angle['Angles Plotting'], results_angle['Mean Intensity'],
|
|
720
|
-
# path_png= os.path.join(figures,"polar_intensity.png"), label = "Mean Intensity",dpi=dpi)
|
|
721
|
-
|
|
722
|
-
# plot_polar(results_angle['Angles Plotting'], results_angle['Orientation (weighted by intensity and coherency)'],
|
|
723
|
-
# path_png= os.path.join(figures,"Orientation_weighted_polar.png"), label = "Orientation",dpi=dpi)
|
|
724
|
-
|
|
725
|
-
# plot_polar(results_angle['Angles Plotting'], results_angle['Orientation'],
|
|
726
|
-
# path_png= os.path.join(figures,"Orientation_polar.png"), label = "Orientation",dpi=dpi)
|
|
727
|
-
# quiver plots with center overlay
|
|
728
|
-
# quiv_coherency_center(vec0=min_evec[:,:,0] ,vec1=min_evec[:,:,1] ,coherency_map=ori,
|
|
729
|
-
# center0=center_small[0],center1 = center_small[1],
|
|
730
|
-
# path_png= os.path.join(figures,"quiv_coherency_center.png"),dpi=dpi )
|
|
731
|
-
|
|
732
777
|
# summarizing triple plot
|
|
733
778
|
plot_triple(results_angle,results_total , path_png= os.path.join(figures,"Triple_plot.png") ,dpi=dpi)
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
779
|
+
|
|
780
|
+
if cell_list is not None:
|
|
781
|
+
|
|
782
|
+
# image fiber + segmention
|
|
783
|
+
plot_fiber_seg(fiber_image=normalize(im_fiber_n[edge:-edge,edge:-edge]) ,
|
|
784
|
+
c0=center_small[0],c1=center_small[1],
|
|
785
|
+
segmention=segmention["mask"][edge:-edge,edge:-edge],
|
|
786
|
+
path_png=os.path.join(figures,"fiber_celloutline.png"),dpi=dpi,scale=scale )
|
|
787
|
+
# plot overlaywith fiber image
|
|
788
|
+
plot_overlay(fiber_image=normalize(im_fiber_n[edge:-edge,edge:-edge]) ,
|
|
789
|
+
c0=center_small[0],c1=center_small[1], vec0=min_evec[:,:,0],
|
|
790
|
+
vec1=min_evec[:,:,1], coherency_map=ori, show_n=15,
|
|
791
|
+
segmention=segmention["mask"][edge:-edge,edge:-edge],
|
|
792
|
+
path_png=os.path.join(figures,"fiber_cell_structure.png"),dpi=dpi ,scale=scale)
|
|
793
|
+
else:
|
|
794
|
+
# plot overlaywith fiber image
|
|
795
|
+
plot_overlay(fiber_image=normalize(im_fiber_n[edge:-edge,edge:-edge]) ,
|
|
796
|
+
c0=center_small[0],c1=center_small[1], vec0=min_evec[:,:,0],
|
|
797
|
+
vec1=min_evec[:,:,1], coherency_map=ori, show_n=15,
|
|
798
|
+
segmention=None,
|
|
799
|
+
path_png=os.path.join(figures,"fiber_structure.png"),dpi=dpi ,scale=scale)
|
|
800
|
+
|
|
801
|
+
|
|
753
802
|
plt.close("all")
|
|
754
803
|
### DISTANCE PLOTS
|
|
755
804
|
# plot shells - deactived as it consumes a lot of time
|
|
@@ -765,9 +814,12 @@ def StuctureAnalysisMain(fiber_list,
|
|
|
765
814
|
|
|
766
815
|
# save raw cell image
|
|
767
816
|
plot_cell(im_cell_n, path_png=os.path.join(figures,"cell-raw.png"), scale=scale, dpi=dpi)
|
|
817
|
+
plot_cell(normalize(im_fiber_n[edge:-edge,edge:-edge]), path_png=os.path.join(figures,"fiber-raw.png"), scale=scale, dpi=dpi)
|
|
768
818
|
|
|
769
|
-
plt.close("all")
|
|
770
|
-
|
|
819
|
+
plt.close("all")
|
|
820
|
+
|
|
821
|
+
if mode_saenopy == True: # only evaluates a single item at each call and returns the arrays
|
|
822
|
+
return angle_no_reference, orientation_dev, ori, min_evec, excel_total, excel_angles, excel_distance
|
|
771
823
|
return
|
|
772
824
|
|
|
773
825
|
|
|
@@ -4,7 +4,7 @@ import matplotlib.pyplot as plt
|
|
|
4
4
|
import matplotlib
|
|
5
5
|
from matplotlib_scalebar.scalebar import ScaleBar
|
|
6
6
|
import warnings
|
|
7
|
-
matplotlib.pyplot.switch_backend("agg")
|
|
7
|
+
#matplotlib.pyplot.switch_backend("agg")
|
|
8
8
|
|
|
9
9
|
def scale_for_quiver(ar1, ar2, dims, scale_ratio=0.2, return_scale=False):
|
|
10
10
|
scale = scale_ratio * np.max(dims) / np.nanmax(np.sqrt((ar1) ** 2 + (ar2) ** 2))
|
|
@@ -161,7 +161,8 @@ def plot_fancy_overlay(fiber, cell, field,path_png,label="field",dpi=300,cmap_ce
|
|
|
161
161
|
fig =plt.figure()
|
|
162
162
|
plt.imshow(field,cmap=cmap_angle,vmin=omin,vmax=omax,alpha=alpha_ori);cbar =plt.colorbar()
|
|
163
163
|
plt.imshow(fiber, cmap=cmap_fiber,alpha=alpha_fiber)
|
|
164
|
-
|
|
164
|
+
if cell is not None:
|
|
165
|
+
plt.imshow(cell, cmap=cmap_cell,alpha=alpha_cell)
|
|
165
166
|
plt.axis('off');
|
|
166
167
|
cbar.set_label(label,fontsize=12)
|
|
167
168
|
if scale is not None:
|
|
@@ -242,7 +243,8 @@ def plot_fiber_seg(fiber_image,c0,c1,segmention, path_png,dpi=200, scale=None ):
|
|
|
242
243
|
cmap.set_over('k', alpha=1)
|
|
243
244
|
# plot mask and center
|
|
244
245
|
plt.imshow(fiber_image, origin="upper")
|
|
245
|
-
|
|
246
|
+
if segmention is not None:
|
|
247
|
+
plt.imshow(segmention, cmap=cmap, norm = my_norm, origin="upper")
|
|
246
248
|
plt.scatter(c0,c1, c= "w");plt.axis('off');
|
|
247
249
|
if scale is not None:
|
|
248
250
|
scalebar = ScaleBar(scale, "um", length_fraction=0.1, location="lower right", box_alpha=0 ,
|
|
@@ -266,8 +268,9 @@ def plot_overlay(fiber_image , c0,c1, vec0,vec1, coherency_map,
|
|
|
266
268
|
# plot mask and center
|
|
267
269
|
show_quiver (vec0 * coherency_map, vec1 * coherency_map, filter=[f, show_n],alpha=0 , scale_ratio=0.08,width=0.002, plot_cbar=False, cbar_str="coherency", cmap="viridis")
|
|
268
270
|
plt.imshow(fiber_image, origin="upper")
|
|
269
|
-
|
|
270
|
-
|
|
271
|
+
if segmention is not None:
|
|
272
|
+
plt.imshow(segmention, cmap=cmap, norm = my_norm, origin="upper", zorder=100)
|
|
273
|
+
plt.scatter(c0,c1, c= "w", zorder=200)
|
|
271
274
|
if scale is not None:
|
|
272
275
|
scalebar = ScaleBar(scale, "um", length_fraction=0.1, location="lower right", box_alpha=0 ,
|
|
273
276
|
color="k")
|
|
@@ -304,7 +307,7 @@ def plot_distance(results_distance,path_png,string_plot = "Orientation (individu
|
|
|
304
307
|
return fig
|
|
305
308
|
|
|
306
309
|
def plot_cell(im_cell_n, path_png,scale=None,dpi=200):
|
|
307
|
-
fig = plt.figure(); plt.imshow(im_cell_n);plt.axis("off"),plt.tight_layout()
|
|
310
|
+
fig = plt.figure(); plt.imshow(im_cell_n, cmap="viridis");plt.axis("off"),plt.tight_layout()
|
|
308
311
|
if scale is not None:
|
|
309
312
|
scalebar = ScaleBar(scale, "um", length_fraction=0.1, location="lower right", box_alpha=0 ,
|
|
310
313
|
color="k")
|
|
@@ -29,16 +29,18 @@ def generate_lists(fiber_list_string, cell_list_string, output_main = "Output"):
|
|
|
29
29
|
|
|
30
30
|
# read in images (must be in same order)
|
|
31
31
|
fiber_list = natsorted(glob.glob(fiber_list_string))
|
|
32
|
-
|
|
32
|
+
if cell_list_string is not None:
|
|
33
|
+
cell_list = natsorted(glob.glob(cell_list_string)) #check that order is same to fiber
|
|
34
|
+
else:
|
|
35
|
+
cell_list = None
|
|
33
36
|
# get base path (before * in glob - even works without any *)
|
|
34
|
-
base = os.path.split(
|
|
37
|
+
base = os.path.split(fiber_list_string[:fiber_list_string.find("*")])[0]
|
|
35
38
|
# get the rest of the path
|
|
36
|
-
rest_paths =[os.path.split(os.path.relpath(p, base))[0] for p in (
|
|
39
|
+
rest_paths =[os.path.split(os.path.relpath(p, base))[0] for p in (fiber_list)]
|
|
37
40
|
# get the file name
|
|
38
|
-
names = [os.path.splitext(os.path.split(p)[1])[0] for p in
|
|
41
|
+
names = [os.path.splitext(os.path.split(p)[1])[0] for p in fiber_list]
|
|
39
42
|
# put together accordingly in the output_main folder
|
|
40
43
|
out_list = [os.path.join(output_main,rest_path, name) for name, rest_path in zip(names, rest_paths)]
|
|
41
|
-
|
|
42
44
|
return fiber_list,cell_list, out_list
|
|
43
45
|
|
|
44
46
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CompactionAnalyzer
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: A
|
|
3
|
+
Version: 1.0.5
|
|
4
|
+
Summary: A python package to analyze matrix fiber alignment around cells (proxy for cellular forces)
|
|
5
5
|
Home-page:
|
|
6
6
|
Download-URL:
|
|
7
7
|
Author: David Böhringer, Andreas Bauer
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: CompactionAnalyzer
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: A
|
|
3
|
+
Version: 1.0.5
|
|
4
|
+
Summary: A python package to analyze matrix fiber alignment around cells (proxy for cellular forces)
|
|
5
5
|
Home-page:
|
|
6
6
|
Download-URL:
|
|
7
7
|
Author: David Böhringer, Andreas Bauer
|
|
@@ -16,7 +16,7 @@ Python package to quantify the tissue compaction (as a measure of the contractil
|
|
|
16
16
|
* Evaluating the directionality of fibers towards the cell center.
|
|
17
17
|
* Evaluating the increased fiber intensity around the cell.
|
|
18
18
|
|
|
19
|
-
Further, the package can be used to evaluate the strength of allignment (coherency) regardless of the allignment direction, or the allignment orientation towards the x-axis (instead of the cell center). For this, see the point "Save
|
|
19
|
+
Further, the package can be used to evaluate the strength of allignment (coherency) regardless of the allignment direction, or the allignment orientation towards the x-axis (instead of the cell center). For this, see the point "Save Numpy Files" below.
|
|
20
20
|
|
|
21
21
|
<img src="../master//docs/images/Fig1-rawtostructure.png" width="1000" />
|
|
22
22
|
|
|
@@ -47,7 +47,7 @@ CompactionAnalyzer is included within the [saenopy package](https://github.com/r
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
##
|
|
50
|
+
## Read More
|
|
51
51
|
If you'd like to learn more about the mehtod, have a look at our paper:
|
|
52
52
|
|
|
53
53
|
*Böhringer D, Bauer A, Moravec I, Bischof L, Kah D, Mark C, Grundy TJ, Görlach E, O'Neill GM, Budday S, Strissel PL, Strick R, Malandrino A, Gerum R, Mak M, Rausch M, Fabry B*. **Fiber alignment in 3D collagen networks as a biophysical marker for cell contractility**. Matrix Biology (2023). [doi: 10.1016/j.matbio.2023.11.004](https://www.sciencedirect.com/science/article/pii/S0945053X23001166?via%3Dihub)
|
|
@@ -109,6 +109,7 @@ segmention_method="otsu" # use "otsu", "entropy" or "yen" as segmentatio
|
|
|
109
109
|
segmention_min_area = 1000 # small bjects below this px-area are removed during cell segmentation
|
|
110
110
|
load_segmentation = False # if True enter the path of the segementation.npy - file in path_seg
|
|
111
111
|
path_seg = None # to load a mask
|
|
112
|
+
ignore_cell_outline= False # if True also values at the cell-occupied areas are included in the analysis
|
|
112
113
|
```
|
|
113
114
|
|
|
114
115
|
|
|
@@ -152,18 +153,30 @@ We receive a compromised excel sheet that returns the global analysis for all ce
|
|
|
152
153
|
|
|
153
154
|
<img src="../master/docs/images/Fig3-combineexcel.png" width="800" />
|
|
154
155
|
|
|
155
|
-
##
|
|
156
|
+
## Save Numpy Files
|
|
156
157
|
|
|
157
158
|
If you want to save the angle or coherency maps for different kind of analysis, you can specify the parameter `SaveNumpy = True`.
|
|
158
159
|
Each output folder will then contain among other properties the following npy-files:
|
|
159
160
|
|
|
160
161
|
<img src="../master//docs/images/npy-files-1.png" width="800" />
|
|
161
162
|
|
|
162
|
-
`FiberImageCrop.npy` contains the original input fiber image resized to the size of the output analysis maps. These files have (depending on the argument `edge`) less pixels because the image edges should be excluded to avoid orientation analysis artifacts (default: 15px). `OrientationMap.npy` includes the orientation to the cell center (between -1 and 1) as explained above. `CoherencyMap.npy` can be used as a measure of anisotropy or orientation strength within the image (between 0 and 1), regardless of the specific direction of the orientation. This can be advantageous when the direction varies, such as in images containing multiple cells with stained stress fibers oriented in different directions. Quantifying the average coherence of these stress fibers in the cell occupied area can still provide insight into the strength of
|
|
163
|
+
`FiberImageCrop.npy` contains the original input fiber image resized to the size of the output analysis maps. These files have (depending on the argument `edge`) less pixels because the image edges should be excluded to avoid orientation analysis artifacts (default: 15px). `OrientationMap.npy` includes the orientation to the cell center (between -1 and 1) as explained above. `CoherencyMap.npy` can be used as a measure of anisotropy or orientation strength within the image (between 0 and 1), regardless of the specific direction of the orientation. This can be advantageous when the direction varies, such as in images containing multiple cells with stained stress fibers oriented in different directions. Quantifying the average coherence of these stress fibers in the cell occupied area can still provide insight into the strength of the allignment.
|
|
163
164
|
|
|
164
165
|
<img src="../master//docs/images/npy-files-2.png" width="800" />
|
|
165
166
|
|
|
166
|
-
`AngleDeviationMap.npy` includes the deviation of the raw angles with respect to the cell center. These angles are used to calculate the orientation map
|
|
167
|
+
`AngleDeviationMap.npy` includes the deviation of the raw angles with respect to the cell center. These angles are used to calculate the orientation map. The raw angles with respect to the x-axis (but with no respect to the cell center) are included in `AngleMap_NoReference.npy` (between -90 and 90 degree). They are calculated from the structure vectory in x- and y- direction stored in `Vector_min_ax1.npy` and `Vector_min_ax0.npy`. `segmentation.npy` contains the segmented cell mask, where no analysis is performed in the normal procedure. To compute and store all these numpy fields even in places where the cell is segmented, you can use the argument `ignore_cell_outline=True` in the analysis pipeline. This will compute these maps within the entire image.
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
If you want to calculate the fiber coherency `CoherencyMap.npy` or the angle towards the x-axis `AngleMap_NoReference.npy` (between -90 and 90 degree) without an image of the cell you can start the analysis by setting `cell_list_string = None`:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
fiber_list, cell_list, out_list = generate_lists(fiber_list_string, None, output_main =output_folder)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This option will start the analysis without the second image pair of cell images and automatically compute all maps within the entire image using the `ignore_cell_outline=True` argument. The typical orientation map is calculated with respect to the image center.
|
|
177
|
+
|
|
178
|
+
<img src="../master//docs/images/npy-files-3.png" width="800" />
|
|
179
|
+
|
|
167
180
|
|
|
168
181
|
## Graphical User Interface (GUI)
|
|
169
182
|
|
|
@@ -4,8 +4,8 @@ from setuptools import setup
|
|
|
4
4
|
setup(
|
|
5
5
|
name='CompactionAnalyzer',
|
|
6
6
|
packages=['CompactionAnalyzer'],
|
|
7
|
-
version='1.0.
|
|
8
|
-
description='A
|
|
7
|
+
version='1.0.5',
|
|
8
|
+
description='A python package to analyze matrix fiber alignment around cells (proxy for cellular forces)',
|
|
9
9
|
url='',
|
|
10
10
|
download_url = '',
|
|
11
11
|
author='David Böhringer, Andreas Bauer',
|
|
File without changes
|
{compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/QExtendedGraphicsView.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/requires.txt
RENAMED
|
File without changes
|
{compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|