Skip to content

Commit f9cb0dc

Browse files
Implement store() method for Py_ExperimentalDesign
Co-authored-by: timosachsenberg <5803621+timosachsenberg@users.noreply.github.com>
1 parent e783d35 commit f9cb0dc

File tree

3 files changed

+50
-15
lines changed

3 files changed

+50
-15
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ df = pd.DataFrame({
230230
})
231231
design = Py_ExperimentalDesign.from_dataframe(df)
232232

233+
# Store to file
234+
design.store("output_design.tsv")
235+
233236
# Create from existing OpenMS objects
234237
from openms_python import Py_ConsensusMap
235238
consensus = Py_ConsensusMap.from_file("results.consensusXML")

openms_python/py_experimentaldesign.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ def load(self, filepath: Union[str, Path]) -> "Py_ExperimentalDesign":
8080
return self
8181

8282
def store(self, filepath: Union[str, Path]) -> "Py_ExperimentalDesign":
83-
"""Store the experimental design to disk.
83+
"""Store the experimental design to disk as a TSV file.
8484
85-
Note: Storage functionality is not available in the current pyOpenMS API.
86-
This method is provided for API consistency but will raise NotImplementedError.
85+
The design is converted to a DataFrame and written in the format
86+
expected by OpenMS ExperimentalDesignFile.
8787
8888
Parameters
8989
----------
@@ -95,16 +95,14 @@ def store(self, filepath: Union[str, Path]) -> "Py_ExperimentalDesign":
9595
Py_ExperimentalDesign
9696
Self for method chaining.
9797
98-
Raises
99-
------
100-
NotImplementedError
101-
Storage is not yet implemented in pyOpenMS.
98+
Example:
99+
>>> design = Py_ExperimentalDesign.from_file("input.tsv")
100+
>>> design.store("output.tsv")
102101
"""
103102
ensure_allowed_suffix(filepath, EXPERIMENTAL_DESIGN_EXTENSIONS, "ExperimentalDesign")
104-
raise NotImplementedError(
105-
"ExperimentalDesign storage is not yet available in pyOpenMS. "
106-
"Please use the native pyOpenMS API if this functionality is needed."
107-
)
103+
df = self.to_dataframe()
104+
df.to_csv(str(filepath), sep="\t", index=False)
105+
return self
108106

109107
@property
110108
def native(self) -> oms.ExperimentalDesign:

tests/test_py_experimentaldesign.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,53 @@ def test_py_experimentaldesign_invalid_extension():
128128
Path(temp_path).unlink()
129129

130130

131-
def test_py_experimentaldesign_store_not_implemented():
132-
"""Test that store method raises NotImplementedError."""
131+
def test_py_experimentaldesign_store_roundtrip():
132+
"""Test that store method works and roundtrips correctly."""
133133
example_path = get_example("experimental_design.tsv")
134134
design = Py_ExperimentalDesign.from_file(example_path)
135135

136136
with tempfile.NamedTemporaryFile(suffix=".tsv", delete=False) as f:
137137
temp_path = f.name
138138

139139
try:
140-
with pytest.raises(NotImplementedError, match="not yet available"):
140+
# Store the design
141+
result = design.store(temp_path)
142+
assert result is design # Check method chaining
143+
144+
# Verify file was created
145+
assert Path(temp_path).exists()
146+
147+
# Load it back and verify
148+
design2 = Py_ExperimentalDesign.from_file(temp_path)
149+
assert design2.n_samples == design.n_samples
150+
assert design2.n_ms_files == design.n_ms_files
151+
assert design2.n_fractions == design.n_fractions
152+
assert design2.n_fraction_groups == design.n_fraction_groups
153+
assert design2.n_labels == design.n_labels
154+
155+
# Verify DataFrame content matches
156+
df1 = design.to_dataframe()
157+
df2 = design2.to_dataframe()
158+
assert df1.equals(df2)
159+
finally:
160+
if Path(temp_path).exists():
161+
Path(temp_path).unlink()
162+
163+
164+
def test_py_experimentaldesign_store_invalid_extension():
165+
"""Test that store rejects invalid file extensions."""
166+
example_path = get_example("experimental_design.tsv")
167+
design = Py_ExperimentalDesign.from_file(example_path)
168+
169+
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
170+
temp_path = f.name
171+
172+
try:
173+
with pytest.raises(ValueError, match="ExperimentalDesign"):
141174
design.store(temp_path)
142175
finally:
143-
Path(temp_path).unlink()
176+
if Path(temp_path).exists():
177+
Path(temp_path).unlink()
144178

145179

146180
def test_py_experimentaldesign_delegation():

0 commit comments

Comments
 (0)