diff --git a/docs/source/_static/js/3d_viewer.mjs b/docs/source/_static/js/3d_viewer.mjs index 8a73f6b0..c83e39d3 100644 --- a/docs/source/_static/js/3d_viewer.mjs +++ b/docs/source/_static/js/3d_viewer.mjs @@ -58,7 +58,13 @@ const zip_entries = {} async function get_file_from_zip(url, filename, return_type="blob") { if(zip_entries[url] === undefined) { async function get_entries(url) { - const zipReader = new ZipReader(new BlobReader(await (await fetch(url)).blob())); + let zipReader; + if(typeof url === "string") { + zipReader = new ZipReader(new BlobReader(await (await fetch(url)).blob())); + } + else { + zipReader = new ZipReader(new BlobReader(url)); + } const entries = await zipReader.getEntries(); const entry_map = {} for (let entry of entries) { @@ -393,7 +399,7 @@ async function add_image(scene, params) { const textures = []; for (let i = 0; i < params.data.stacks.z_slices_count; i++) { - textures.push(get_file_from_zip(params.data.path, "0/stack/" + params.data.stacks.channels[0] + "/" + pad_zero(i, 3) + ".jpg", "texture")); + textures.push(get_file_from_zip(params.data.path, "stacks/0/" + params.data.stacks.channels[0] + "/" + pad_zero(i, 3) + ".jpg", "texture")); textures[i].then((v) => {textures[i] = v}) } @@ -461,24 +467,34 @@ async function add_test(scene, params) { needs_update = true; if (params.field !== "none") { try { - nodes = await loadNpy(await get_file_from_zip(params.data.path, "0/" + params.data.fields[params.field].nodes, "blob")); - vectors = await loadNpy(await get_file_from_zip(params.data.path, "0/" + params.data.fields[params.field].vectors, "blob")); + nodes = await loadNpy(await get_file_from_zip(params.data.path, params.data.fields[params.field].nodes, "blob")); + vectors = await loadNpy(await get_file_from_zip(params.data.path, params.data.fields[params.field].vectors, "blob")); } catch (e) {} } if (!nodes || !vectors) { } else { - for (let i = 0; i < nodes.length; i++) { - const position = convert_pos( - nodes[i * 3], - nodes[i * 3 + 1], - nodes[i * 3 + 2], - ); - const orientationVector = convert_vec( - vectors[i * 3], - vectors[i * 3 + 1], - vectors[i * 3 + 2], - ); + for (let i = 0; i < nodes.header.shape[0]; i++) { + const position = nodes.header.fortran_order ? + convert_pos( + nodes[i], + nodes[i + nodes.header.shape[0]], + nodes[i + nodes.header.shape[0]*2], + ) : convert_pos( + nodes[i * nodes.header.shape[1]], + nodes[i * nodes.header.shape[1] + 1], + nodes[i * nodes.header.shape[1] + 2], + ); + const orientationVector = vectors.header.fortran_order ? + convert_vec( + vectors[i], + vectors[i + vectors.header.shape[0]], + vectors[i + vectors.header.shape[0]*2], + ) : convert_vec( + vectors[i * vectors.header.shape[1]], + vectors[i * vectors.header.shape[1] + 1], + vectors[i * vectors.header.shape[1] + 2], + ); const target = position.clone().add(orientationVector); const scaleValue = orientationVector.length(); if (scaleValue > max_length) { @@ -606,6 +622,15 @@ export async function init(initial_params) { extent: [0, 1, 0, 1, 0, 1], ...initial_params, }; + params.data = { + "fields": { + "measured deformations": {"nodes": "mesh_piv/0/nodes.npy", "vectors": "mesh_piv/0/displacements_measured.npy", "unit": "\u00b5m", "factor": 1000000.0}, + "target deformations": {"nodes": "solvers/0/mesh/nodes.npy", "vectors": "solvers/0/mesh/displacements_target.npy", "unit": "\u00b5m", "factor": 1000000.0}, + "fitted deformations": {"nodes": "solvers/0/mesh/nodes.npy", "vectors": "solvers/0/mesh/displacements.npy", "unit": "\u00b5m", "factor": 1000000.0}, + "fitted forces": {"nodes": "solvers/0/mesh/nodes.npy", "vectors": "solvers/0/mesh/forces.npy", "unit": "nN", "factor": 1000000000.0} + }, + ...params.data + } if(initial_params.dom_node) { initial_params.dom_node.style.position = "relative"; diff --git a/docs/source/_static/js/load_numpy.js b/docs/source/_static/js/load_numpy.js index 36e98c09..5db8f5c0 100644 --- a/docs/source/_static/js/load_numpy.js +++ b/docs/source/_static/js/load_numpy.js @@ -40,5 +40,6 @@ export async function loadNpy(url) { } else { throw new Error("Unsupported dtype. Only Uint8 is supported. Got" + dtype); } + data.header = header; return data; } diff --git a/saenopy/export_html.py b/saenopy/export_html.py index 5adbd4b8..d6236e53 100644 --- a/saenopy/export_html.py +++ b/saenopy/export_html.py @@ -33,19 +33,23 @@ def export_html(result: saenopy.Result, path, zip_filename="data.zip", stack_qua path_data = "0/" def save(path, data, dtype): - new_data = np.zeros(data.shape, dtype=dtype) - new_data[:] = data - print(new_data.strides, new_data.shape) + #new_data = np.zeros(data.shape, dtype=dtype) + #new_data[:] = data + #print(new_data.strides, new_data.shape) image_file = BytesIO() - np.save(image_file, new_data) + np.save(image_file, np.asarray(data).astype(dtype)) zipFp.writestr(path, image_file.getvalue()) data = {} mesh = result.solvers[0].mesh piv = result.mesh_piv[0] - save(path_data + "nodes_piv.npy", piv.nodes, np.float32) - save(path_data + "displacements_piv.npy", piv.displacements_measured, np.float32) + + path_data = "mesh_piv/0/" + save(path_data + "nodes.npy", piv.nodes, np.float32) + save(path_data + "displacements_measured.npy", piv.displacements_measured, np.float32) + + path_data = "solvers/0/mesh/" save(path_data + "nodes.npy", mesh.nodes, np.float32) save(path_data + "displacements_target.npy", mesh.displacements_target, np.float32) save(path_data + "displacements.npy", mesh.displacements, np.float32) @@ -67,13 +71,15 @@ def save(path, data, dtype): if stack_downsample > 1: im = im.resize((im.width//stack_downsample, im.height//stack_downsample), Image.Resampling.LANCZOS) im.save(image_file, 'JPEG', quality=stack_quality) - zipFp.writestr(f"0/stack/0/{z//stack_downsample_z:03d}.jpg", image_file.getvalue()) + zipFp.writestr(f"stacks/0/0/{z//stack_downsample_z:03d}.jpg", image_file.getvalue()) z_count += 1 + voxel_size = result.get_data_structure()["voxel_size"] + voxel_size[2] = voxel_size[2] * stack_downsample_z + + save("stacks/0/voxel_size.npy", voxel_size, np.float32) im_shape = [int(x) for x in result.get_data_structure()["im_shape"]] im_shape[2] = im_shape[2]//stack_downsample_z - voxel_size = result.get_data_structure()["voxel_size"] - voxel_size[2] = voxel_size[2] * stack_downsample_z data["path"] = zip_filename @@ -83,12 +89,14 @@ def save(path, data, dtype): "im_shape": tuple(im_shape), "voxel_size": tuple(voxel_size), } + """ data["fields"] = { - "measured deformations": {"nodes": "nodes_piv.npy", "vectors": "displacements_piv.npy", "unit": "µm", "factor": 1e6}, - "target deformations": {"nodes": "nodes.npy", "vectors": "displacements_target.npy", "unit": "µm", "factor": 1e6}, - "fitted deformations": {"nodes": "nodes.npy", "vectors": "displacements.npy", "unit": "µm", "factor": 1e6}, - "fitted forces": {"nodes": "nodes.npy", "vectors": "forces.npy", "unit": "nN", "factor": 1e9}, + "measured deformations": {"nodes": "mesh_piv/0/nodes.npy", "vectors": "mesh_piv/0/displacements_measured.npy", "unit": "µm", "factor": 1e6}, + "target deformations": {"nodes": "solvers/0/mesh/nodes.npy", "vectors": "solvers/0/mesh/displacements_target.npy", "unit": "µm", "factor": 1e6}, + "fitted deformations": {"nodes": "solvers/0/mesh/nodes.npy", "vectors": "solvers/0/mesh/displacements.npy", "unit": "µm", "factor": 1e6}, + "fitted forces": {"nodes": "solvers/0/mesh/nodes.npy", "vectors": "solvers/0/mesh/forces.npy", "unit": "nN", "factor": 1e9}, } + """ data["time_point_count"] = result.get_data_structure()["time_point_count"] print(data) @@ -115,7 +123,7 @@ def save(path, data, dtype): "imports": { "three": "https://unpkg.com/three@v0.158.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@v0.158.0/examples/jsm/", - "3d_viewer": "https://saenopy.readthedocs.io/en/latest/_static/js/3d_viewer.mjs" + "3d_viewer": "./3d_viewer.mjs" } }