Skip to content
This repository was archived by the owner on Feb 9, 2024. It is now read-only.

Commit 8a292da

Browse files
committed
Ellipse simulation complete
Finished the ellipse simulation code and folded it into the demo.py script.
1 parent d3d22ef commit 8a292da

3 files changed

Lines changed: 103 additions & 139 deletions

File tree

fibermorph/demo.py

Lines changed: 89 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
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+
311
import os
412
import pathlib
513
import 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+
160228
def 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

fibermorph/sim_ellipse.py

Lines changed: 0 additions & 93 deletions
This file was deleted.

fibermorph/test/test_fibermorph.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
# %%
4141
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
4242
from fibermorph import fibermorph
43-
from fibermorph import dummy_data
43+
from fibermorph import demo
4444

4545
# Get current directory
4646
dir = os.path.dirname(os.path.abspath(__file__))
@@ -159,6 +159,19 @@ def test_length_measurement():
159159
print("Uncorrected length is: {}".format(element.area))
160160
print("Corrected length is: {}".format(corr_px_length))
161161

162+
def test_sim_ellipse():
163+
im_width_px = 5200
164+
im_height_px = 3900
165+
min_diam_um = 40
166+
max_diam_um = 80
167+
168+
px_per_um = 4.25
169+
angle_deg = 30
170+
171+
output_directory = '/Users/tinalasisi/Desktop'
172+
173+
df = demo.sim_ellipse(output_directory, im_width_px, im_height_px, min_diam_um, max_diam_um, px_per_um, angle_deg)
174+
pass
162175

163176
def test_copy_if_exist():
164177
# fibermorph.copy_if_exist()

0 commit comments

Comments
 (0)