Skip to content
This repository was archived by the owner on Nov 17, 2025. It is now read-only.

Commit 023ff91

Browse files
authored
Merge pull request #31 from AllenCellModeling/nma_fig_update
plot frequencies and put all timestep vtk files in a dir
2 parents aedaf2d + f837047 commit 023ff91

File tree

3 files changed

+72
-28
lines changed

3 files changed

+72
-28
lines changed

mti_nma/steps/nma/nma.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from typing import Optional, List
44

55
import matplotlib
6-
import matplotlib.pyplot as plt
76
import numpy as np
87
import pandas as pd
98
import vtk
@@ -53,7 +52,7 @@ def __init__(
5352
@log_run_params
5453
def run(
5554
self,
56-
mode_list=list(range(6)),
55+
mode_list=list(range(10)),
5756
avg_df=None,
5857
struct="Nuc",
5958
norm_vecs=True,
@@ -119,13 +118,17 @@ def run(
119118

120119
verts, faces = get_vtk_verts_faces(polydata)
121120
w, v = run_nma(verts, faces)
122-
draw_whist(w)
121+
fpaths = draw_whist(w, int(verts.shape[0]), nma_data_dir, struct)
123122
vmags = get_eigvec_mags(v)
124123

125124
# Working the visualization of eigenvectors on VTK
126125
n = polydata.GetNumberOfPoints()
127126
writer = vtk.vtkPolyDataWriter()
128127

128+
# Create directory to hold vtk files
129+
vtk_dir = nma_data_dir / "vtk_timestep_files"
130+
vtk_dir.mkdir(parents=True, exist_ok=True)
131+
129132
for id_mode in range(9):
130133

131134
# 1st Get eigenvector of interest as a Nx3 array
@@ -145,7 +148,7 @@ def run(
145148
num_array=arr_eigenvec,
146149
deep=True,
147150
array_type=vtk.VTK_DOUBLE)
148-
eigenvec.SetName('Eigenvector')
151+
eigenvec.SetName("Eigenvector")
149152

150153
# Assign eigenvectors as mesh points
151154
polydata.GetPointData().AddArray(eigenvec)
@@ -165,11 +168,9 @@ def run(
165168
# Write mesh with new coordinates
166169
writer.SetInputData(polydata)
167170
writer.SetFileName(str(
168-
nma_data_dir / f"avgshape_{struct}_M{id_mode}_T{id_theta:03d}.vtk"))
171+
vtk_dir / f"avgshape_{struct}_M{id_mode}_T{id_theta:03d}.vtk"))
169172
writer.Write()
170173

171-
fig_path = nma_data_dir / f"w_fig_{struct}.pdf"
172-
plt.savefig(fig_path, format="pdf")
173174
w_path = nma_data_dir / f"eigvals_{struct}.npy"
174175
np.save(w_path, w)
175176
v_path = nma_data_dir / f"eigvecs_{struct}.npy"
@@ -183,7 +184,9 @@ def run(
183184
"w_FilePath": w_path,
184185
"v_FilePath": v_path,
185186
"vmag_FilePath": vmags_path,
186-
"fig_FilePath": fig_path,
187+
"eigval_hist_FilePath": fpaths[0],
188+
"freq_hist_FilePath": fpaths[1],
189+
"time_hist_FilePath": fpaths[2],
187190
"Structure": struct
188191
}, index=[0])
189192

mti_nma/steps/nma/nma_utils.py

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -223,37 +223,78 @@ def get_faces(i, polydata):
223223
return mesh_verts, mesh_faces
224224

225225

226-
def draw_whist(w):
226+
def draw_whist(w, npts, nma_data_dir, struct, logscale=False):
227227
"""
228228
Draws a histogram figure of the eigenvalues
229229
230230
Parameters
231231
----------
232232
w: Numpy 1D array
233233
An array of eigenvalue values
234+
npts: int
235+
Number of points in mesh
234236
Returns
235237
-------
236238
fig: Matplotlib Figure object
237239
Figure containg a histogram of eigenvalues
238240
"""
239-
240-
plt.clf()
241-
fig = plt.figure()
242-
243-
# set binning
244-
minval = min(w) - 0.5
245-
maxval = max(w) + 0.5
246-
if len(w) < 20:
247-
N = int(max(w) + 2)
248-
else:
249-
N = 30
250-
bins = np.linspace(minval, maxval, N)
251-
252-
sb.distplot(w, kde=False, bins=bins)
253-
plt.xlabel("Eigenvalues (w2*m/k)")
254-
plt.ylabel("Counts")
255-
256-
return fig
241+
xlabels = ["Eigenvalues (w2*m/k)", "Frequencies (Hz)", "Timescales (s)"]
242+
fpaths = [nma_data_dir / f"eigval_hist_{struct}.pdf",
243+
nma_data_dir / f"freq_hist_{struct}.pdf",
244+
nma_data_dir / f"time_hist_{struct}.pdf"]
245+
246+
# Fix rounding errors to 0
247+
idx = [i for i, n in enumerate(w) if n < 10**-10]
248+
w[idx] = 0
249+
print(w[0:7])
250+
251+
# set values to eigenvalues, frequencies, or timescales (1/f)
252+
for i in range(3):
253+
if i == 0:
254+
vals = w
255+
else:
256+
m_total = 10**-13 # kg
257+
m_vert = m_total / npts
258+
k = 0.0001 # N/m
259+
vals = np.sqrt(w * k / m_vert) / (2 * np.pi)
260+
if i == 1:
261+
tmp = [i for i in vals if i != 0]
262+
if i == 2:
263+
tmp = [1 / i for i in vals if i != 0]
264+
vals = tmp
265+
266+
plt.clf()
267+
fig = plt.figure()
268+
269+
# set binning
270+
minval = min(vals)
271+
maxval = max(vals)
272+
if len(vals) < 20:
273+
N = int(max(vals) + 2)
274+
else:
275+
N = 40
276+
bins = np.linspace(minval, maxval, N)
277+
278+
if i == 0:
279+
sb.distplot(vals, kde=False, bins=bins)
280+
if i == 1:
281+
if logscale:
282+
logbins = np.logspace(np.log10(bins[0]), np.log10(bins[-1]), len(bins))
283+
sb.distplot(vals, kde=False, bins=logbins)
284+
plt.xscale("log")
285+
else:
286+
sb.distplot([i / 1000 for i in vals], kde=False, bins=bins / 1000)
287+
xlabels[i] = "Frequencies (kHz)"
288+
if i == 2:
289+
plt.yscale("log")
290+
sb.distplot(vals, kde=False, bins=bins)
291+
plt.xlabel(xlabels[i])
292+
plt.ylabel("Counts")
293+
294+
fig.savefig(fpaths[i], format="pdf")
295+
plt.close(fig)
296+
297+
return fpaths
257298

258299

259300
def color_vertices_by_magnitude(

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"python-dateutil<=2.8.0", # need <=2.8.0 for quilt3 in step
6464
"scikit-image",
6565
"seaborn",
66-
"vtk",
66+
"vtk>=9.0",
6767
"prefect[viz]"
6868
]
6969

0 commit comments

Comments
 (0)