diff --git a/saenopy/gui/common/PipelineModule.py b/saenopy/gui/common/PipelineModule.py index 87ac8c2..405265c 100644 --- a/saenopy/gui/common/PipelineModule.py +++ b/saenopy/gui/common/PipelineModule.py @@ -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: diff --git a/saenopy/gui/solver/modules/exporter/ExportRenderCommon.py b/saenopy/gui/solver/modules/exporter/ExportRenderCommon.py index b3cd315..1be0625 100644 --- a/saenopy/gui/solver/modules/exporter/ExportRenderCommon.py +++ b/saenopy/gui/solver/modules/exporter/ExportRenderCommon.py @@ -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, {}, "" diff --git a/saenopy/gui/solver/modules/exporter/Exporter.py b/saenopy/gui/solver/modules/exporter/Exporter.py index 2b8fc5f..e3d8708 100644 --- a/saenopy/gui/solver/modules/exporter/Exporter.py +++ b/saenopy/gui/solver/modules/exporter/Exporter.py @@ -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) @@ -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) @@ -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 @@ -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() diff --git a/saenopy/gui/solver/modules/exporter/ExporterRender2D.py b/saenopy/gui/solver/modules/exporter/ExporterRender2D.py index 195f309..cda14fd 100644 --- a/saenopy/gui/solver/modules/exporter/ExporterRender2D.py +++ b/saenopy/gui/solver/modules/exporter/ExporterRender2D.py @@ -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"] @@ -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 diff --git a/saenopy/gui/tfm2d/modules/BatchEvaluate.py b/saenopy/gui/tfm2d/modules/BatchEvaluate.py index 8e2d5c8..fc0c542 100644 --- a/saenopy/gui/tfm2d/modules/BatchEvaluate.py +++ b/saenopy/gui/tfm2d/modules/BatchEvaluate.py @@ -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): @@ -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() diff --git a/saenopy/gui/tfm2d/modules/result.py b/saenopy/gui/tfm2d/modules/result.py index d5bd84b..3d106eb 100644 --- a/saenopy/gui/tfm2d/modules/result.py +++ b/saenopy/gui/tfm2d/modules/result.py @@ -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): @@ -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]) @@ -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):