metafold 0.13.dev1__tar.gz → 0.13.dev3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {metafold-0.13.dev1 → metafold-0.13.dev3}/PKG-INFO +1 -1
  2. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/compression_experiment.py +5 -3
  3. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/compression_simulation.py +4 -0
  4. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/run_experiment.py +9 -11
  5. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/PKG-INFO +1 -1
  6. {metafold-0.13.dev1 → metafold-0.13.dev3}/pyproject.toml +1 -1
  7. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_compession_experiment.py +6 -0
  8. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_run_experiment.py +12 -0
  9. {metafold-0.13.dev1 → metafold-0.13.dev3}/LICENSE +0 -0
  10. {metafold-0.13.dev1 → metafold-0.13.dev3}/README.md +0 -0
  11. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/__init__.py +0 -0
  12. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/api.py +0 -0
  13. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/assets.py +0 -0
  14. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/auth.py +0 -0
  15. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/client.py +0 -0
  16. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/exceptions.py +0 -0
  17. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/jobs.py +0 -0
  18. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/materials.py +0 -0
  19. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/projects.py +0 -0
  20. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/__init__.py +0 -0
  21. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/utils.py +0 -0
  22. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/workflows.py +0 -0
  23. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/SOURCES.txt +0 -0
  24. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/dependency_links.txt +0 -0
  25. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/requires.txt +0 -0
  26. {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/top_level.txt +0 -0
  27. {metafold-0.13.dev1 → metafold-0.13.dev3}/setup.cfg +0 -0
  28. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_assets.py +0 -0
  29. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_compression_simulation.py +0 -0
  30. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_jobs.py +0 -0
  31. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_materials.py +0 -0
  32. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_projects.py +0 -0
  33. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_shear_simulation.py +0 -0
  34. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_utils.py +0 -0
  35. {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_workflows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metafold
3
- Version: 0.13.dev1
3
+ Version: 0.13.dev3
4
4
  Summary: Metafold SDK for Python
5
5
  Author-email: Metafold 3D <info@metafold3d.com>
6
6
  License: Copyright 2024 Metafold 3D
@@ -206,15 +206,17 @@ class CompressionExperiment:
206
206
  return custom or f"{self.base_simulation.simulation_name}_sim{sim_index}"
207
207
 
208
208
  def _validate_simulation_names(self):
209
- """Names must be a list of path-safe strings and resolve to a unique
210
- name per sim (they become filenames and zip member paths)."""
209
+ """Names must be a list of path-safe strings (None or "" = use the
210
+ auto name) and resolve to a unique name per sim (they become filenames
211
+ and zip member paths)."""
211
212
  if not isinstance(self.simulation_names, list) or not all(
212
- isinstance(n, str) for n in self.simulation_names
213
+ n is None or isinstance(n, str) for n in self.simulation_names
213
214
  ):
214
215
  raise ValueError(
215
216
  f"simulation_names must be a list of strings, got: "
216
217
  f"{self.simulation_names!r}"
217
218
  )
219
+ self.simulation_names = [n or "" for n in self.simulation_names]
218
220
  for name in self.simulation_names:
219
221
  if any(c in name for c in "/\\:"):
220
222
  raise ValueError(
@@ -2544,6 +2544,10 @@ class CompressionSimulation:
2544
2544
  server_result["data"] = {}
2545
2545
  server_results.append(server_result)
2546
2546
 
2547
+ # ensure material index is set on all parts for a multi-simulation experiment
2548
+ for i, part_info in enumerate(self.part_infos):
2549
+ part_info.material_index = i
2550
+
2547
2551
  self.make_manifest_v2(results=server_results)
2548
2552
  manifest = copy.deepcopy(self.manifest)
2549
2553
  manifest["results"] = server_results
@@ -92,9 +92,9 @@ JSON manifest format
92
92
  ],
93
93
 
94
94
  # Optional display name per simulation variant, index-aligned with the variants
95
- # the varying entries produce. A blank/missing entry falls back to "<name>_sim<i>".
96
- # Names must be unique and must not contain path separators.
97
- "simulation_names": ["slow piston", "fast piston", "fastest piston"]
95
+ # the varying entries produce. A null/blank/missing entry falls back to
96
+ # "<name>_sim<i>". Names must be unique and must not contain path separators.
97
+ "simulation_names": ["slow piston", null, "fastest piston"]
98
98
  }
99
99
 
100
100
  Available material presets
@@ -193,6 +193,8 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
193
193
 
194
194
  if part_type == "piston_cylinder":
195
195
  kwargs = {}
196
+ if "name" in entry:
197
+ kwargs["name"] = entry["name"]
196
198
  if "velocity" in entry:
197
199
  kwargs["velocity"] = entry["velocity"]
198
200
  if "shape_parameters" in entry:
@@ -203,6 +205,8 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
203
205
 
204
206
  elif part_type == "piston_box":
205
207
  kwargs = {}
208
+ if "name" in entry:
209
+ kwargs["name"] = entry["name"]
206
210
  if "velocity" in entry:
207
211
  kwargs["velocity"] = entry["velocity"]
208
212
  if "shape_parameters" in entry:
@@ -213,6 +217,8 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
213
217
 
214
218
  elif part_type == "piston_mesh":
215
219
  kwargs = {"filename": entry["file"]}
220
+ if "name" in entry:
221
+ kwargs["name"] = entry["name"]
216
222
  if "velocity" in entry:
217
223
  kwargs["velocity"] = entry["velocity"]
218
224
  if "material" in entry:
@@ -240,14 +246,6 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
240
246
  def _build_varying(varying_config: list[dict]) -> list[ExperimentVarying]:
241
247
  varying: list[ExperimentVarying] = []
242
248
  for entry in varying_config:
243
- # Each entry varies exactly one thing; to vary several, use several entries.
244
- kinds = [k for k in ("files", "material", "velocity", "values") if k in entry]
245
- if len(kinds) > 1:
246
- raise ValueError(
247
- f"varying entry may only vary one of files/material/velocity/values, "
248
- f"got {kinds}: {entry}"
249
- )
250
-
251
249
  if "part" in entry and "files" in entry:
252
250
  files = entry["files"]
253
251
  if not isinstance(files, list):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metafold
3
- Version: 0.13.dev1
3
+ Version: 0.13.dev3
4
4
  Summary: Metafold SDK for Python
5
5
  Author-email: Metafold 3D <info@metafold3d.com>
6
6
  License: Copyright 2024 Metafold 3D
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "metafold"
7
- version = "0.13.dev1"
7
+ version = "0.13.dev3"
8
8
  authors = [
9
9
  {name = "Metafold 3D", email = "info@metafold3d.com"},
10
10
  ]
@@ -331,6 +331,12 @@ class TestSimulationNames:
331
331
  with pytest.raises(ValueError, match="path separator"):
332
332
  self._experiment(mock_sim, ["run/1"])
333
333
 
334
+ def test_none_entry_falls_back_to_auto(self, mock_sim):
335
+ exp = self._experiment(mock_sim, [None, "custom2", None])
336
+ exp.prepare()
337
+ assert [s.simulation_name for s in exp.sims] == [
338
+ "base_sim_sim0", "custom2", "base_sim_sim2"]
339
+
334
340
  def test_non_list_rejected(self, mock_sim):
335
341
  with pytest.raises(ValueError, match="list of strings"):
336
342
  self._experiment(mock_sim, "baseline")
@@ -110,6 +110,18 @@ class TestBuildParts:
110
110
  assert isinstance(parts[0], ExperimentPistonMesh)
111
111
  assert parts[0].filename == "piston.ply"
112
112
 
113
+ def test_piston_parts_custom_name(self):
114
+ parts = _build_parts([
115
+ {"type": "piston_mesh", "name": "last", "file": "last.ply"},
116
+ {"type": "piston_cylinder", "name": "press"},
117
+ {"type": "piston_box", "name": "anvil"},
118
+ ])
119
+ assert [p.name for p in parts] == ["last", "press", "anvil"]
120
+
121
+ def test_piston_parts_default_name_when_omitted(self):
122
+ parts = _build_parts([{"type": "piston_mesh", "file": "piston.ply"}])
123
+ assert parts[0].name == "piston"
124
+
113
125
  def test_piston_mesh_with_velocity(self):
114
126
  velocity = [[0.0, 0, 0, 0.0], [0.02, 0, 0, -1.25], [0.04, 0, 0, 0.0]]
115
127
  parts = _build_parts([{"type": "piston_mesh", "file": "piston.ply", "velocity": velocity}])
File without changes
File without changes
File without changes