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.
Files changed (18) hide show
  1. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/CompactionFunctions.py +169 -117
  2. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/plotting.py +9 -6
  3. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/utilities.py +7 -5
  4. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/PKG-INFO +2 -2
  5. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/PKG-INFO +2 -2
  6. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/README.md +18 -5
  7. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/setup.py +2 -2
  8. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/GUI_old_use_saenopy_instead.py +0 -0
  9. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/QExtendedGraphicsView.py +0 -0
  10. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/QtShortCuts.py +0 -0
  11. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/StructureTensor.py +0 -0
  12. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer/__init__.py +0 -0
  13. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/SOURCES.txt +0 -0
  14. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/dependency_links.txt +0 -0
  15. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/requires.txt +0 -0
  16. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/CompactionAnalyzer.egg-info/top_level.txt +0 -0
  17. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/LICENSE +0 -0
  18. {compactionanalyzer-1.0.3 → compactionanalyzer-1.0.5}/setup.cfg +0 -0
@@ -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 = False , # saves numpy arrays for later analysis - can create large data files
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): # if True the cell area is not set to nan and orientation are calculted everywhere - still the cell center is calculated from segmention
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
- # plt.ion()
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
- im_cell = imageio.v2.imread(cell_list[n]) #color.rgb2gray(..)
307
- im_fiber = imageio.v2.imread(fiber_list[n]) #color.rgb2gray()
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
- excel_total.to_excel(os.path.join(out_list[n],"results_total.xlsx"))
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
- excel_angles.to_excel(os.path.join(out_list[n],"results_angles.xlsx"))
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
- # initialize result dictionary
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
- # mean intensity
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
- excel_distance.to_excel(os.path.join(out_list[n],"results_distance.xlsx"))
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
- np.save(os.path.join(numpy_out, "segmention.npy" ),segmention)
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
- # plot orientation and angle deviation maps together with orientation structure
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
- ### more fancy overlay plot of cell & fiber & orientation (notweighted)
666
- plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
667
- im_cell_n[edge:-edge,edge:-edge],
668
- orientation_dev, cmap_angle="coolwarm",
669
- path_png= os.path.join(figures,"Orientation_overlay.png"),
670
- label="Orientation",dpi=dpi,
671
- # ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
672
- # cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
673
- omin=-1, omax=1,scale=scale)
674
-
675
- plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
676
- im_cell_n[edge:-edge,edge:-edge],
677
- ori, cmap_angle="turbo",
678
- path_png= os.path.join(figures,"Coherency_overlay.png"),
679
- label="Coherency",dpi=dpi,
680
- # ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
681
- # cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
682
- omin=0, omax=1,scale=scale)
683
-
684
- plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
685
- im_cell_n[edge:-edge,edge:-edge],
686
- angle_dev, cmap_angle="viridis_r",
687
- path_png= os.path.join(figures,"Angle_Deviation_overlay.png"),
688
- label="Angle Deviation",dpi=dpi,
689
- # ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
690
- # cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
691
- omin=0, omax=90,scale=scale)
692
-
693
- plot_fancy_overlay(im_fiber_n[edge:-edge,edge:-edge],
694
- im_cell_n[edge:-edge,edge:-edge],
695
- angle_no_reference, cmap_angle="gist_rainbow",
696
- path_png= os.path.join(figures,"Angle_NoReference_overlay.png"),
697
- label="Angle (no reference)",dpi=dpi,
698
- # ,cmap_cell="Greys_r",cmap_fiber="Greys_r", ### use default values here
699
- # cmap_angle="viridis", alpha_ori =0.8, alpha_cell = 0.4, alpha_fiber = 0.4,
700
- omin=-180, omax=180,
701
- scale=scale)
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
- # image fiber + segmention
735
- plot_fiber_seg(fiber_image=normalize(im_fiber_n[edge:-edge,edge:-edge]) ,
736
- c0=center_small[0],c1=center_small[1],
737
- segmention=segmention["mask"][edge:-edge,edge:-edge],
738
- path_png=os.path.join(figures,"fiber_segemention.png"),dpi=dpi,scale=scale )
739
-
740
- # plot overlaywith fiber image
741
- plot_overlay(fiber_image=normalize(im_fiber_n[edge:-edge,edge:-edge]) ,
742
- c0=center_small[0],c1=center_small[1], vec0=min_evec[:,:,0],
743
- vec1=min_evec[:,:,1], coherency_map=ori, show_n=15,
744
- segmention=segmention["mask"][edge:-edge,edge:-edge],
745
- path_png=os.path.join(figures,"overlay.png"),dpi=dpi ,scale=scale)
746
-
747
- # plot_overlay(fiber_image=normalize(im_fiber_n[edge:-edge,edge:-edge]) ,
748
- # c0=center_small[0],c1=center_small[1], vec0=min_evec[:,:,0],
749
- # vec1=min_evec[:,:,1], coherency_map=ori,show_n=10,
750
- # segmention=segmention["mask"][edge:-edge,edge:-edge],
751
- # path_png=os.path.join(figures,"overlay2.png"),dpi=dpi ,scale=scale)
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
- plt.imshow(cell, cmap=cmap_cell,alpha=alpha_cell)
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
- plt.imshow(segmention, cmap=cmap, norm = my_norm, origin="upper")
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
- plt.imshow(segmention, cmap=cmap, norm = my_norm, origin="upper", zorder=100)
270
- plt.scatter(c0,c1, c= "w", zorder=200)
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
- cell_list = natsorted(glob.glob(cell_list_string)) #check that order is same to fiber
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(cell_list_string[:cell_list_string.find("*")])[0]
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 (cell_list)]
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 cell_list]
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.3
4
- Summary: A Python package to analyze tissue compaction around cells in fiber materials
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.3
4
- Summary: A Python package to analyze tissue compaction around cells in fiber materials
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 Nummpy Files" below.
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
- ## Preprint
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
- ## Saving Numpy Files
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 these fibers.
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 below. The raw angles with respect to the x-axis but with no respect to the cell center are included in `AngleMap_NoReference.npy`. They are calculated from the structure vectory in x- and y- direction stored in `Vector_min_ax0.npy` and `Vector_min_ax1.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. Technically, however, you still need to specify image pairs to start the analysis.
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.3',
8
- description='A Python package to analyze tissue compaction around cells in fiber materials',
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',