11"""Pythonic wrapper for :class:`pyopenms.ExperimentalDesign`."""
2+
23from __future__ import annotations
34
45from pathlib import Path
5- from typing import Union , Optional , Set
6- import pandas as pd
6+ from typing import Union , Optional , Set , TYPE_CHECKING
77
88import pyopenms as oms
99
1010from ._io_utils import ensure_allowed_suffix
1111
12+ if TYPE_CHECKING :
13+ from .py_consensusmap import Py_ConsensusMap
14+ from .py_featuremap import Py_FeatureMap
15+
1216# Supported file extensions for experimental design
1317EXPERIMENTAL_DESIGN_EXTENSIONS = {".tsv" }
1418
1519
1620class Py_ExperimentalDesign :
1721 """A Pythonic wrapper around :class:`pyopenms.ExperimentalDesign`.
18-
22+
1923 This class provides convenient methods for loading, storing, and working with
2024 experimental design files in OpenMS format.
21-
25+
2226 Example:
2327 >>> from openms_python import Py_ExperimentalDesign
2428 >>> design = Py_ExperimentalDesign.from_file("design.tsv")
@@ -27,7 +31,7 @@ class Py_ExperimentalDesign:
2731
2832 def __init__ (self , native_design : Optional [oms .ExperimentalDesign ] = None ):
2933 """Initialize with an optional native ExperimentalDesign object.
30-
34+
3135 Parameters
3236 ----------
3337 native_design:
@@ -36,34 +40,34 @@ def __init__(self, native_design: Optional[oms.ExperimentalDesign] = None):
3640 self ._design = native_design if native_design is not None else oms .ExperimentalDesign ()
3741
3842 @classmethod
39- def from_file (cls , filepath : Union [str , Path ]) -> ' Py_ExperimentalDesign' :
43+ def from_file (cls , filepath : Union [str , Path ]) -> " Py_ExperimentalDesign" :
4044 """Load an experimental design from a TSV file.
41-
45+
4246 Parameters
4347 ----------
4448 filepath:
4549 Path to the experimental design TSV file.
46-
50+
4751 Returns
4852 -------
4953 Py_ExperimentalDesign
5054 A new instance with the loaded design.
51-
55+
5256 Example:
5357 >>> design = Py_ExperimentalDesign.from_file("design.tsv")
5458 """
5559 instance = cls ()
5660 instance .load (filepath )
5761 return instance
5862
59- def load (self , filepath : Union [str , Path ]) -> ' Py_ExperimentalDesign' :
63+ def load (self , filepath : Union [str , Path ]) -> " Py_ExperimentalDesign" :
6064 """Load an experimental design from disk.
61-
65+
6266 Parameters
6367 ----------
6468 filepath:
6569 Path to the experimental design TSV file.
66-
70+
6771 Returns
6872 -------
6973 Py_ExperimentalDesign
@@ -74,22 +78,22 @@ def load(self, filepath: Union[str, Path]) -> 'Py_ExperimentalDesign':
7478 self ._design = edf .load (str (filepath ), False )
7579 return self
7680
77- def store (self , filepath : Union [str , Path ]) -> ' Py_ExperimentalDesign' :
81+ def store (self , filepath : Union [str , Path ]) -> " Py_ExperimentalDesign" :
7882 """Store the experimental design to disk.
79-
83+
8084 Note: Storage functionality is not available in the current pyOpenMS API.
8185 This method is provided for API consistency but will raise NotImplementedError.
82-
86+
8387 Parameters
8488 ----------
8589 filepath:
8690 Path where the experimental design should be saved.
87-
91+
8892 Returns
8993 -------
9094 Py_ExperimentalDesign
9195 Self for method chaining.
92-
96+
9397 Raises
9498 ------
9599 NotImplementedError
@@ -146,7 +150,7 @@ def same_n_ms_files_per_fraction(self) -> bool:
146150 @property
147151 def samples (self ) -> Set [str ]:
148152 """Set of sample identifiers in the design.
149-
153+
150154 Returns
151155 -------
152156 Set[str]
@@ -161,20 +165,20 @@ def samples(self) -> Set[str]:
161165
162166 def summary (self ) -> dict :
163167 """Get a summary of the experimental design.
164-
168+
165169 Returns
166170 -------
167171 dict
168172 Dictionary with summary statistics.
169173 """
170174 return {
171- ' n_samples' : self .n_samples ,
172- ' n_ms_files' : self .n_ms_files ,
173- ' n_fractions' : self .n_fractions ,
174- ' n_fraction_groups' : self .n_fraction_groups ,
175- ' n_labels' : self .n_labels ,
176- ' is_fractionated' : self .is_fractionated ,
177- ' samples' : sorted (self .samples ),
175+ " n_samples" : self .n_samples ,
176+ " n_ms_files" : self .n_ms_files ,
177+ " n_fractions" : self .n_fractions ,
178+ " n_fraction_groups" : self .n_fraction_groups ,
179+ " n_labels" : self .n_labels ,
180+ " is_fractionated" : self .is_fractionated ,
181+ " samples" : sorted (self .samples ),
178182 }
179183
180184 def print_summary (self ) -> None :
@@ -188,61 +192,62 @@ def print_summary(self) -> None:
188192 print (f"Fraction Groups: { summary ['n_fraction_groups' ]} " )
189193 print (f"Labels: { summary ['n_labels' ]} " )
190194 print (f"Fractionated: { summary ['is_fractionated' ]} " )
191- if summary [' samples' ]:
195+ if summary [" samples" ]:
192196 print (f"Sample IDs: { ', ' .join (summary ['samples' ])} " )
193197
194198 # ==================== Factory methods ====================
195199
196200 @classmethod
197- def from_consensus_map (cls , consensus_map : Union ['Py_ConsensusMap' , oms .ConsensusMap ]) -> 'Py_ExperimentalDesign' :
201+ def from_consensus_map (
202+ cls , consensus_map : Union ["Py_ConsensusMap" , oms .ConsensusMap ]
203+ ) -> "Py_ExperimentalDesign" :
198204 """Create an ExperimentalDesign from a ConsensusMap.
199-
205+
200206 Parameters
201207 ----------
202208 consensus_map:
203209 A :class:`Py_ConsensusMap` or :class:`pyopenms.ConsensusMap`.
204-
210+
205211 Returns
206212 -------
207213 Py_ExperimentalDesign
208214 A new instance derived from the consensus map.
209215 """
210216 # Handle both Py_ConsensusMap and native ConsensusMap
211- native_map = consensus_map .native if hasattr (consensus_map , ' native' ) else consensus_map
217+ native_map = consensus_map .native if hasattr (consensus_map , " native" ) else consensus_map
212218 design = oms .ExperimentalDesign .fromConsensusMap (native_map )
213219 return cls (design )
214220
215221 @classmethod
216- def from_feature_map (cls , feature_map : Union ['Py_FeatureMap' , oms .FeatureMap ]) -> 'Py_ExperimentalDesign' :
222+ def from_feature_map (
223+ cls , feature_map : Union ["Py_FeatureMap" , oms .FeatureMap ]
224+ ) -> "Py_ExperimentalDesign" :
217225 """Create an ExperimentalDesign from a FeatureMap.
218-
226+
219227 Parameters
220228 ----------
221229 feature_map:
222230 A :class:`Py_FeatureMap` or :class:`pyopenms.FeatureMap`.
223-
231+
224232 Returns
225233 -------
226234 Py_ExperimentalDesign
227235 A new instance derived from the feature map.
228236 """
229237 # Handle both Py_FeatureMap and native FeatureMap
230- native_map = feature_map .native if hasattr (feature_map , ' native' ) else feature_map
238+ native_map = feature_map .native if hasattr (feature_map , " native" ) else feature_map
231239 design = oms .ExperimentalDesign .fromFeatureMap (native_map )
232240 return cls (design )
233241
234242 @classmethod
235- def from_identifications (
236- cls ,
237- protein_ids : list
238- ) -> 'Py_ExperimentalDesign' :
243+ def from_identifications (cls , protein_ids : list ) -> "Py_ExperimentalDesign" :
239244 """Create an ExperimentalDesign from protein identification data.
240-
245+
241246 Parameters
242247 ----------
243248 protein_ids:
244249 List of :class:`pyopenms.ProteinIdentification` objects.
245-
250+
246251 Returns
247252 -------
248253 Py_ExperimentalDesign
0 commit comments