11# %% import
22
3+ import sympy
4+
5+ from skimage import draw
6+ import random
7+ from random import randint
8+ import matplotlib .pyplot as plt
9+ from sympy import geometry
10+
311import os
412import pathlib
513import shutil
@@ -157,6 +165,66 @@ def validation_curv(output_location, repeats, window_size_px, resolution=1):
157165 return main_output_path
158166
159167
168+ def sim_ellipse (output_directory , im_width_px , im_height_px , min_diam_um , max_diam_um , px_per_um , angle_deg ):
169+ # conversions
170+ um_per_inch = 25400
171+ dpi = int (px_per_um * um_per_inch )
172+ min_rad_um = min_diam_um / 2
173+ max_rad_um = max_diam_um / 2
174+
175+ # image size in inches
176+ im_width_inch = (im_width_px / px_per_um ) / um_per_inch
177+ im_height_inch = (im_height_px / px_per_um ) / um_per_inch
178+
179+ imsize_inch = im_height_inch , im_width_inch
180+ imsize_px = im_height_px , im_width_px
181+
182+ min_rad_px = min_rad_um * px_per_um
183+ max_rad_px = max_rad_um * px_per_um
184+
185+ # generate array of ones (will show up as white background)
186+ img = np .ones (imsize_px , dtype = np .uint8 )
187+
188+ # generate ellipse in center of image
189+ rr , cc = draw .ellipse (im_height_px / 2 , im_width_px / 2 , min_rad_px , max_rad_px , shape = img .shape ,
190+ rotation = np .deg2rad (angle_deg ))
191+ img [rr , cc ] = 0
192+
193+ fig = plt .figure (frameon = False )
194+ fig .set_size_inches (im_width_inch , im_height_inch )
195+ ax = plt .Axes (fig , [0 , 0 , 1 , 1 ])
196+ ax .set_axis_off ()
197+ fig .add_axes (ax )
198+
199+ p1 = geometry .Point ((im_height_px / px_per_um ) / 2 , (im_width_px / px_per_um ) / 2 )
200+ e1 = geometry .Ellipse (p1 , hradius = max_rad_um , vradius = min_rad_um )
201+ area = sympy .N (e1 .area )
202+ eccentricity = e1 .eccentricity
203+ ax .imshow (img , cmap = "gray" , aspect = 'auto' )
204+
205+ jetzt = datetime .now ()
206+ timestamp = jetzt .strftime ("%b%d_%H%M_%S_%f" )
207+
208+ name = "sim_ellipse_" + str (timestamp )
209+
210+ im_path = pathlib .Path (output_directory ).joinpath ("im_" + name + ".tiff" )
211+ df_path = pathlib .Path (output_directory ).joinpath ("df_" + name + ".csv" )
212+
213+ data = {'name' : [name ], 'area' : [area ], 'eccentricity' : [eccentricity ], 'ref_min_diam' : [min_diam_um ],
214+ 'ref_max_diam' : [max_diam_um ]}
215+
216+ df = pd .DataFrame (data )
217+
218+ df .to_csv (df_path )
219+
220+ plt .ioff ()
221+ fig .savefig (fname = im_path , dpi = dpi )
222+ plt .cla ()
223+ plt .close ()
224+
225+ return df
226+
227+
160228def validation_section (output_location , repeats ):
161229
162230 jetzt = datetime .now ()
@@ -166,52 +234,28 @@ def validation_section(output_location, repeats):
166234 main_output_path = fibermorph .make_subdirectory (output_location , append_name = testname )
167235
168236 dummy_dir = fibermorph .make_subdirectory (main_output_path , append_name = "ValidationData" )
169- shape_list = ["circle" , "ellipse" ]
170-
171- replist = [el for el in shape_list for i in range (repeats )]
172-
173- output_path = fibermorph .make_subdirectory (main_output_path , append_name = "ValidationAnalysis" )
174-
175- for shape in tqdm (replist , desc = "Generating & analyzing dummy data" , position = 0 , unit = "datasets" , leave = True ):
176- # print(shape)
177- df , img , im_path , df_path = dummy_data .dummy_data_gen (
178- output_directory = dummy_dir ,
179- shape = shape ,
180- min_elem = 1 ,
181- max_elem = 1 ,
182- im_width = 5200 ,
183- im_height = 3900 ,
184- width = 1 )
185-
186- valid_df = pd .DataFrame (df ).sort_values (by = [0 ], axis = 1 )
187- min_ax = np .asarray (valid_df )[0 ][0 ]
188- max_ax = np .asarray (valid_df )[0 ][1 ]
189- valid_df ['ref_min' ] = min_ax
190- valid_df ['ref_max' ] = max_ax
191- valid_df ['ref_eccentricity' ] = np .sqrt (1 - (min_ax ** 2 ) / (max_ax ** 2 ))
192- valid_df .drop (columns = ['ref_height' , 'ref_width' ])
193-
194- test_df = fibermorph .analyze_section (im_path , output_path , minsize = 0 , maxsize = 3900 , resolution = 1.0 )
195-
196- test_df ['error_min' ] = abs (valid_df ['ref_min' ] - test_df ['min' ]) / valid_df ['ref_min' ]
197- test_df ['error_max' ] = abs (valid_df ['ref_max' ] - test_df ['max' ]) / valid_df ['ref_max' ]
198-
199- test_df ['error_area' ] = abs (valid_df ['ref_area' ] - test_df ['area' ]) / valid_df ['ref_area' ]
200- test_df ['error_eccentricity' ] = np .nan_to_num (
201- abs (valid_df ['ref_eccentricity' ] - test_df ['eccentricity' ]) / valid_df ['ref_eccentricity' ], posinf = 0 )
202-
203- valid_df2 = valid_df .join (test_df )
204-
205- col_list = ['error_min' , 'error_max' , 'error_area' , 'error_eccentricity' ]
206-
207- error_df = valid_df2
208- # error_df = valid_df2[col_list]
209-
210- im_name = im_path .stem
211- df_path = pathlib .Path (output_path ).joinpath (str (im_name ) + "_errordata.csv" )
212- error_df .to_csv (df_path )
237+
238+ # create list of random variables from range
239+ def gen_ellipse_data ():
240+ max_diam_um = random .uniform (50 , 120 )
241+ min_diam_um = random .uniform (30 , max_diam_um )
242+ angle_deg = random .randint (0 , 360 )
243+ list = [max_diam_um , min_diam_um , angle_deg ]
244+ return list
245+
246+ tempdf = [gen_ellipse_data () for i in range (repeats )]
247+
248+ gen_ellipse_df = pd .DataFrame (tempdf , columns = ['max_diam_um' , 'min_diam_um' , 'angle_deg' ])
249+
250+ df_list = []
251+ for index , row in tqdm (gen_ellipse_df .iterrows (), desc = "Generating ellipses" , position = 0 , unit = "datasets" , leave = True ):
252+ df = sim_ellipse (dummy_dir , 5200 , 3900 , row ['min_diam_um' ], row ['max_diam_um' ], 4.25 , row ['angle_deg' ])
253+ df_list .append (df )
254+
255+ sim_ellipse_sum_df = pd .concat (df_list )
213256
214- # tqdm.write("\nResults saved as:\n{}\n\n".format(df_path))
257+ with pathlib .Path (main_output_path ).joinpath ("summary_" + testname + ".csv" ) as savename :
258+ sim_ellipse_sum_df .to_csv (savename )
215259
216260 return main_output_path
217261
0 commit comments