Skip to content

Commit

Permalink
added image exporter for pyTFM
Browse files Browse the repository at this point in the history
  • Loading branch information
rgerum committed Dec 29, 2023
1 parent baeb777 commit 3debe9c
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 38 deletions.
10 changes: 6 additions & 4 deletions saenopy/gui/common/PipelineModule.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,12 @@ def setResult(self, result: Result):
mapping.setResult(result)

if result is not None and getattr(self, "t_slider", None) is not None:
if isinstance(result, ResultSpheroid):
self.t_slider.setRange(0, len(result.images) - 1)
else:
self.t_slider.setRange(0, len(result.stacks) - 2)
data = result.get_data_structure()
#if isinstance(result, ResultSpheroid):
# self.t_slider.setRange(0, len(result.images) - 1)
#else:
# self.t_slider.setRange(0, len(result.stacks) - 2)
self.t_slider.setRange(0, data["time_point_count"])

self.state_changed(result)
if self.tab is not None:
Expand Down
2 changes: 1 addition & 1 deletion saenopy/gui/solver/modules/exporter/ExportRenderCommon.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def get_mesh_arrows(params, result):
if data["fields"][params["arrows"]]["measure"] == "deformation":
if mesh is not None and field is not None:
return mesh, field, params["deformation_arrows"], data["fields"][params["arrows"]]["name"]
if data["fields"][params["arrows"]]["measure"] == "deformation":
if data["fields"][params["arrows"]]["measure"] == "force":
if mesh is not None and field is not None:
return mesh, field, params["force_arrows"], data["fields"][params["arrows"]]["name"]
return None, None, {}, ""
Expand Down
16 changes: 9 additions & 7 deletions saenopy/gui/solver/modules/exporter/Exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,13 @@ def hide2D(self):
self.rotate_steps.setEnabled(is3D)

def hide_timestamp(self):
isTimeAvailable = self.result is not None and self.result.time_delta is not None
data = self.result.get_data_structure() if self.result is not None else None
isTimeAvailable = data and data["time_delta"] is not None
self.time_check.setEnabled(isTimeAvailable)
self.button_export_time.setEnabled(isTimeAvailable)
self.time_fps.setEnabled(isTimeAvailable)
self.time_steps.setEnabled(isTimeAvailable)
isTime = self.time_check.value() and self.result is not None and self.result.time_delta is not None
isTime = self.time_check.value() and self.result is not None and data["time_delta"] is not None
self.time_format.setEnabled(isTime)
self.time_start.setEnabled(isTime)
self.time_size.setEnabled(isTime)
Expand All @@ -552,8 +553,10 @@ def hide_fiber(self):
self.input_thresh.setEnabled(isActiveBoth)

def hide_arrow(self):
isDeformation = self.input_arrows.value() in ["piv", "target deformations", "fitted deformations"]
isForce = self.input_arrows.value() in ["fitted forces"]
data = self.result.get_data_structure() if self.result is not None else {}
measure = data.get("fields", {}).get(self.input_arrows.value(), {}).get("measure", "")
isDeformation = measure == "deformation"
isForce = measure == "force"

self.box_deformation_arrows.setEnabled(isDeformation)
self.box_force_arrows.setEnabled(isForce)
Expand Down Expand Up @@ -658,9 +661,7 @@ def do_export_zscan(self):
def check_evaluated(self, result: Result) -> bool:
if result is None:
return False
if isinstance(result, ResultSpheroid):
return result.displacements is not None and len(result.displacements) > 0
return result.stacks is not None and len(result.stacks) > 0
return True

def setResult(self, result: Result, no_update_display=False):
self.result = result
Expand Down Expand Up @@ -734,6 +735,7 @@ def setResult(self, result: Result, no_update_display=False):

super().setResult(result)
self.hide_timestamp()
self.hide_arrow()
if not no_update_display:
self.update_display()

Expand Down
7 changes: 4 additions & 3 deletions saenopy/gui/solver/modules/exporter/ExporterRender2D.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ def project_data(R, field, skip=1):
R = R[:, :2][:, ::-1] * scale + offset
field = field[:, :2][:, ::-1] * scale * params_arrows["arrow_scale"]

if name == "forces":
field *= 1e4
if name == "forces":
field *= 1e4

if scale_max is None:
max_length = np.nanmax(np.linalg.norm(field, axis=1))# * params_arrows["arrow_scale"]
Expand Down Expand Up @@ -161,7 +161,8 @@ def getBarParameters(pixtomu, scale=1):


def render_2d_time(params, result, pil_image):
if result is not None and result.time_delta is not None and params["time"]["display"]:
data = result.get_data_structure()
if result is not None and data["time_delta"] is not None and params["time"]["display"]:
pil_image = add_text(pil_image, get_time_text(params, result), position=(10, 10))
return pil_image

Expand Down
3 changes: 2 additions & 1 deletion saenopy/gui/tfm2d/modules/BatchEvaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from saenopy.examples import get_examples_2D

from saenopy.gui.common.BatchEvaluate import BatchEvaluate
from ...solver.modules.exporter.Exporter import ExportViewer


class BatchEvaluate(BatchEvaluate):
Expand All @@ -39,7 +40,7 @@ def add_modules(self):
self.sub_force = Force(self, layout0)
self.sub_force_gen = ForceGeneration(self, layout0)
self.sub_stress = CalculateStress(self, layout0)
# self.sub_module_export = ExportViewer(self, layout0)
self.sub_module_export = ExportViewer(self, layout0)
layout0.addStretch()

box = QtWidgets.QGroupBox("painting").addToLayout()
Expand Down
76 changes: 54 additions & 22 deletions saenopy/gui/tfm2d/modules/result.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import io
import matplotlib.pyplot as plt
from saenopy.saveable import Saveable
import glob
from pathlib import Path
import os
import numpy as np
from tifffile import imread
from pyTFM.plotting import show_quiver
import matplotlib.pyplot as plt

from saenopy.saveable import Saveable
from saenopy.result_file import make_path_absolute
from .draw import get_mask_using_gui

from pyTFM.plotting import plot_continuous_boundary_stresses
from pyTFM.plotting import show_quiver


class Result2D(Saveable):
Expand Down Expand Up @@ -147,45 +152,74 @@ def get_data_structure(self):
return {
"dimensions": 2,
"z_slices_count": 1,
"im_shape": self.shape,
"im_shape": [self.shape[0], self.shape[1], 1],
"time_point_count": 1,
"has_reference": True,
"voxel_size": [self.pixel_size, self.pixel_size, 1],
"time_delta": None,
"channels": ["default"],
"channels": ["cells", "beads"],
"fields": {
"deformation": {
"type": "vector",
"measure": "deformation",
"unit": "pixel",
"name": "displacements_measured",
},
"forces": {
"type": "vector",
"measure": "force",
"unit": "pixel",
"name": "force",
}
}
}

def get_image_data(self, time_point, channel="default", use_reference=False):
im = imread(self.images[time_point])
if channel == "cells":
im = self.get_image(-1)
else:
if use_reference:
im = self.get_image(0)
else:
im = self.get_image(1)
if len(im.shape) == 2:
return im[:, :, None, None]
return im[:, :, :, None]

def get_field_data(self, name, time_point):
if self.displacements is not None and time_point > 0:
try:
disp = self.displacements[time_point - 1]
mesh = Mesh2D()
mesh.units = "pixels"
mesh.nodes = np.array([disp["x"].ravel(), disp["y"].ravel()]).T
mesh.displacements_measured = np.array([disp["u"].ravel(), disp["v"].ravel()]).T * 1

if mesh is not None:
return mesh, mesh.displacements_measured
except IndexError:
pass
class Mesh2D:
pass

vx = None
vy = None
vf = 1

if name == "deformation":
vx = self.u
vy = self.v
vf = 10
if name == "forces":
print("do force")
vx = self.tx
vy = self.ty
vf = 0.1
print("vx", vx)
print("vx shape", vx is not None)
if vx is not None:
mesh = Mesh2D()
mesh.units = "pixels"
f = self.shape[0] / vx.shape[0]
x, y = np.meshgrid(np.arange(vx.shape[1]), np.arange(vx.shape[0]))
x = x * f
y = y * f
y = self.shape[0] - y
mesh.nodes = np.array([x.ravel(), y.ravel()]).T
mesh.displacements_measured = np.array([vx.ravel(), -vy.ravel()]).T * vf
return mesh, mesh.displacements_measured
#print("tx", self.tx.shape)
return None, None



def fig_to_numpy(fig1, shape):
fig1.axes[0].set_position([0, 0, 1, 1])
fig1.axes[1].set_position([1, 1, 0.1, 0.1])
Expand All @@ -196,9 +230,7 @@ def fig_to_numpy(fig1, shape):
buff.seek(0)
return plt.imread(buff)

import glob
from pathlib import Path
import os

def get_stacks2D(output_path, bf_stack, active_stack, reference_stack, pixel_size,
exist_overwrite_callback=None,
load_existing=False):
Expand Down

0 comments on commit 3debe9c

Please sign in to comment.