0
# Map Alignment and Consensus Features
1
2
Retention time alignment algorithms and consensus feature generation for comparative analysis across multiple LC-MS experiments. Essential for label-free quantification and multi-sample proteomics studies.
3
4
## Capabilities
5
6
### Map Alignment
7
8
#### Pose Clustering Alignment
9
10
Advanced alignment algorithm using pose clustering for robust retention time correction.
11
12
```python { .api }
13
class MapAlignmentAlgorithmPoseClustering:
14
def __init__(self) -> None: ...
15
16
def align(self, maps: list[FeatureMap], transformations: list[TransformationDescription]) -> None:
17
"""
18
Align multiple feature maps using pose clustering.
19
20
Args:
21
maps (list[FeatureMap]): Feature maps to align
22
transformations (list[TransformationDescription]): Output transformations
23
"""
24
25
def getParameters(self) -> Param:
26
"""
27
Get alignment parameters.
28
29
Returns:
30
Param: Parameter configuration
31
"""
32
33
def setParameters(self, param: Param) -> None:
34
"""
35
Set alignment parameters.
36
37
Args:
38
param (Param): Parameter configuration
39
"""
40
41
def setReference(self, reference: FeatureMap) -> None:
42
"""
43
Set reference map for alignment.
44
45
Args:
46
reference (FeatureMap): Reference feature map
47
"""
48
49
class MapAlignmentAlgorithmIdentification:
50
def __init__(self) -> None: ...
51
52
def align(self, maps: list[FeatureMap], transformations: list[TransformationDescription]) -> None:
53
"""
54
Align maps using peptide identifications.
55
56
Args:
57
maps (list[FeatureMap]): Feature maps with identifications
58
transformations (list[TransformationDescription]): Output transformations
59
"""
60
61
def getParameters(self) -> Param:
62
"""Get alignment parameters."""
63
64
def setParameters(self, param: Param) -> None:
65
"""Set alignment parameters."""
66
```
67
68
#### Map Alignment Transformer
69
70
Apply retention time transformations to align data.
71
72
```python { .api }
73
class MapAlignmentTransformer:
74
def __init__(self) -> None: ...
75
76
@staticmethod
77
def transformRetentionTimes(map: FeatureMap, trafo: TransformationDescription,
78
store_original_rt: bool = False) -> None:
79
"""
80
Transform retention times in feature map.
81
82
Args:
83
map (FeatureMap): Feature map to transform
84
trafo (TransformationDescription): Transformation to apply
85
store_original_rt (bool): Store original RT as meta value
86
"""
87
88
@staticmethod
89
def transformRetentionTimes(exp: MSExperiment, trafo: TransformationDescription,
90
store_original_rt: bool = False) -> None:
91
"""
92
Transform retention times in MS experiment.
93
94
Args:
95
exp (MSExperiment): Experiment to transform
96
trafo (TransformationDescription): Transformation to apply
97
store_original_rt (bool): Store original RT as meta value
98
"""
99
100
@staticmethod
101
def transformRetentionTimes(peptide_ids: list[PeptideIdentification],
102
trafo: TransformationDescription,
103
store_original_rt: bool = False) -> None:
104
"""
105
Transform retention times in peptide identifications.
106
107
Args:
108
peptide_ids (list[PeptideIdentification]): IDs to transform
109
trafo (TransformationDescription): Transformation to apply
110
store_original_rt (bool): Store original RT as meta value
111
"""
112
```
113
114
### Transformation Models
115
116
#### TransformationDescription
117
118
Container for retention time transformation metadata and models.
119
120
```python { .api }
121
class TransformationDescription:
122
def __init__(self) -> None: ...
123
124
def getDataPoints(self) -> list[tuple[float, float]]:
125
"""
126
Get transformation data points.
127
128
Returns:
129
list[tuple[float, float]]: List of (input_rt, output_rt) pairs
130
"""
131
132
def setDataPoints(self, data: list[tuple[float, float]]) -> None:
133
"""
134
Set transformation data points.
135
136
Args:
137
data (list[tuple[float, float]]): (input_rt, output_rt) pairs
138
"""
139
140
def apply(self, value: float) -> float:
141
"""
142
Apply transformation to retention time value.
143
144
Args:
145
value (float): Input retention time
146
147
Returns:
148
float: Transformed retention time
149
"""
150
151
def getModelType(self) -> str:
152
"""
153
Get transformation model type.
154
155
Returns:
156
str: Model type ("linear", "b_spline", etc.)
157
"""
158
159
def setModelType(self, type: str) -> None:
160
"""
161
Set transformation model type.
162
163
Args:
164
type (str): Model type
165
"""
166
167
def fitModel(self, type: str, params: Param = None) -> None:
168
"""
169
Fit transformation model to data points.
170
171
Args:
172
type (str): Model type to fit
173
params (Param): Model parameters (optional)
174
"""
175
176
def invert(self) -> TransformationDescription:
177
"""
178
Get inverted transformation.
179
180
Returns:
181
TransformationDescription: Inverted transformation
182
"""
183
184
class TransformationModel:
185
def __init__(self, data: list[tuple[float, float]], params: Param) -> None:
186
"""
187
Base transformation model.
188
189
Args:
190
data (list[tuple[float, float]]): Training data points
191
params (Param): Model parameters
192
"""
193
194
def evaluate(self, value: float) -> float:
195
"""
196
Evaluate transformation at given point.
197
198
Args:
199
value (float): Input value
200
201
Returns:
202
float: Transformed value
203
"""
204
205
class TransformationModelLinear(TransformationModel):
206
def __init__(self, data: list[tuple[float, float]], params: Param) -> None:
207
"""
208
Linear transformation model.
209
210
Args:
211
data (list[tuple[float, float]]): Training data points
212
params (Param): Model parameters
213
"""
214
215
class TransformationModelBSpline(TransformationModel):
216
def __init__(self, data: list[tuple[float, float]], params: Param) -> None:
217
"""
218
B-spline transformation model.
219
220
Args:
221
data (list[tuple[float, float]]): Training data points
222
params (Param): Model parameters including wavelength and boundary
223
"""
224
```
225
226
### Consensus Features
227
228
#### ConsensusMap
229
230
Container for consensus features across multiple experiments.
231
232
```python { .api }
233
class ConsensusMap:
234
def __init__(self) -> None: ...
235
236
def size(self) -> int:
237
"""
238
Get number of consensus features.
239
240
Returns:
241
int: Number of consensus features
242
"""
243
244
def empty(self) -> bool:
245
"""
246
Check if consensus map is empty.
247
248
Returns:
249
bool: True if empty
250
"""
251
252
def push_back(self, feature: ConsensusFeature) -> None:
253
"""
254
Add consensus feature.
255
256
Args:
257
feature (ConsensusFeature): Consensus feature to add
258
"""
259
260
def __getitem__(self, index: int) -> ConsensusFeature:
261
"""
262
Get consensus feature by index.
263
264
Args:
265
index (int): Feature index
266
267
Returns:
268
ConsensusFeature: Consensus feature
269
"""
270
271
def clear(self) -> None:
272
"""Remove all consensus features."""
273
274
def getColumnHeaders(self) -> dict[int, ColumnHeader]:
275
"""
276
Get column headers describing input maps.
277
278
Returns:
279
dict[int, ColumnHeader]: Map index to column header mapping
280
"""
281
282
def setColumnHeaders(self, headers: dict[int, ColumnHeader]) -> None:
283
"""
284
Set column headers.
285
286
Args:
287
headers (dict[int, ColumnHeader]): Column headers
288
"""
289
290
def getExperimentType(self) -> str:
291
"""
292
Get experiment type.
293
294
Returns:
295
str: Experiment type ("label-free", "itraq", etc.)
296
"""
297
298
def setExperimentType(self, type: str) -> None:
299
"""
300
Set experiment type.
301
302
Args:
303
type (str): Experiment type
304
"""
305
306
def sortByRT(self) -> None:
307
"""Sort consensus features by retention time."""
308
309
def sortByMZ(self) -> None:
310
"""Sort consensus features by m/z."""
311
312
def sortByIntensity(self, reverse: bool = True) -> None:
313
"""
314
Sort by intensity.
315
316
Args:
317
reverse (bool): Sort in descending order
318
"""
319
320
def updateRanges(self) -> None:
321
"""Update RT/m/z ranges from features."""
322
323
def get_intensity_df(self) -> DataFrame:
324
"""
325
Export intensity data to pandas DataFrame.
326
327
Returns:
328
DataFrame: Intensity data in long or wide format
329
"""
330
331
def get_metadata_df(self) -> DataFrame:
332
"""
333
Export feature metadata to pandas DataFrame.
334
335
Returns:
336
DataFrame: Feature metadata (RT, m/z, quality, etc.)
337
"""
338
339
def get_df(self) -> DataFrame:
340
"""
341
Export complete consensus data to pandas DataFrame.
342
343
Returns:
344
DataFrame: Combined metadata and intensity data
345
"""
346
347
class ColumnHeader:
348
def __init__(self) -> None: ...
349
350
def filename(self) -> str:
351
"""
352
Get filename.
353
354
Returns:
355
str: Input file name
356
"""
357
358
def setFilename(self, filename: str) -> None:
359
"""
360
Set filename.
361
362
Args:
363
filename (str): Input file name
364
"""
365
366
def label(self) -> str:
367
"""
368
Get label.
369
370
Returns:
371
str: Sample label
372
"""
373
374
def setLabel(self, label: str) -> None:
375
"""
376
Set label.
377
378
Args:
379
label (str): Sample label
380
"""
381
382
def size(self) -> int:
383
"""
384
Get number of features in original map.
385
386
Returns:
387
int: Feature count
388
"""
389
390
def setSize(self, size: int) -> None:
391
"""
392
Set feature count.
393
394
Args:
395
size (int): Feature count
396
"""
397
```
398
399
#### ConsensusFeature
400
401
Individual consensus feature linking features across experiments.
402
403
```python { .api }
404
class ConsensusFeature:
405
def __init__(self) -> None: ...
406
407
def getRT(self) -> float:
408
"""
409
Get consensus retention time.
410
411
Returns:
412
float: Consensus retention time
413
"""
414
415
def setRT(self, rt: float) -> None:
416
"""
417
Set retention time.
418
419
Args:
420
rt (float): Retention time
421
"""
422
423
def getMZ(self) -> float:
424
"""
425
Get consensus m/z.
426
427
Returns:
428
float: Consensus m/z
429
"""
430
431
def setMZ(self, mz: float) -> None:
432
"""
433
Set m/z.
434
435
Args:
436
mz (float): m/z value
437
"""
438
439
def getIntensity(self) -> float:
440
"""
441
Get consensus intensity.
442
443
Returns:
444
float: Consensus intensity
445
"""
446
447
def setIntensity(self, intensity: float) -> None:
448
"""
449
Set intensity.
450
451
Args:
452
intensity (float): Intensity value
453
"""
454
455
def getCharge(self) -> int:
456
"""
457
Get consensus charge.
458
459
Returns:
460
int: Charge state
461
"""
462
463
def setCharge(self, charge: int) -> None:
464
"""
465
Set charge.
466
467
Args:
468
charge (int): Charge state
469
"""
470
471
def getQuality(self) -> float:
472
"""
473
Get consensus quality.
474
475
Returns:
476
float: Quality score
477
"""
478
479
def setQuality(self, quality: float) -> None:
480
"""
481
Set quality.
482
483
Args:
484
quality (float): Quality score
485
"""
486
487
def getFeatureList(self) -> list[FeatureHandle]:
488
"""
489
Get constituent features.
490
491
Returns:
492
list[FeatureHandle]: Features from individual maps
493
"""
494
495
def setFeatureList(self, features: list[FeatureHandle]) -> None:
496
"""
497
Set constituent features.
498
499
Args:
500
features (list[FeatureHandle]): Features from individual maps
501
"""
502
503
def insert(self, handle: FeatureHandle) -> None:
504
"""
505
Add feature handle.
506
507
Args:
508
handle (FeatureHandle): Feature handle to add
509
"""
510
511
def getUniqueId(self) -> int:
512
"""
513
Get unique consensus feature ID.
514
515
Returns:
516
int: Unique identifier
517
"""
518
519
def getPeptideIdentifications(self) -> list[PeptideIdentification]:
520
"""
521
Get assigned peptide identifications.
522
523
Returns:
524
list[PeptideIdentification]: Peptide IDs
525
"""
526
527
class FeatureHandle:
528
def __init__(self) -> None: ...
529
530
def getRT(self) -> float:
531
"""Get retention time."""
532
533
def getMZ(self) -> float:
534
"""Get m/z."""
535
536
def getIntensity(self) -> float:
537
"""Get intensity."""
538
539
def getCharge(self) -> int:
540
"""Get charge."""
541
542
def getMapIndex(self) -> int:
543
"""
544
Get source map index.
545
546
Returns:
547
int: Index of source map
548
"""
549
550
def setMapIndex(self, index: int) -> None:
551
"""
552
Set source map index.
553
554
Args:
555
index (int): Source map index
556
"""
557
558
def getUniqueId(self) -> int:
559
"""
560
Get unique feature ID.
561
562
Returns:
563
int: Unique ID in source map
564
"""
565
566
def setUniqueId(self, id: int) -> None:
567
"""
568
Set unique feature ID.
569
570
Args:
571
id (int): Unique ID
572
"""
573
```
574
575
### Feature Linking
576
577
#### FeatureGroupingAlgorithm
578
579
Base class for feature grouping across maps.
580
581
```python { .api }
582
class FeatureGroupingAlgorithm:
583
def __init__(self) -> None: ...
584
585
def group(self, maps: list[FeatureMap], consensus_map: ConsensusMap) -> None:
586
"""
587
Group features across maps.
588
589
Args:
590
maps (list[FeatureMap]): Input feature maps
591
consensus_map (ConsensusMap): Output consensus map
592
"""
593
594
def getParameters(self) -> Param:
595
"""Get grouping parameters."""
596
597
def setParameters(self, param: Param) -> None:
598
"""Set grouping parameters."""
599
600
class FeatureGroupingAlgorithmQT:
601
def __init__(self) -> None: ...
602
603
def group(self, maps: list[FeatureMap], consensus_map: ConsensusMap) -> None:
604
"""
605
Group features using QT clustering.
606
607
Args:
608
maps (list[FeatureMap]): Input feature maps
609
consensus_map (ConsensusMap): Output consensus map
610
"""
611
612
def getParameters(self) -> Param:
613
"""
614
Get QT clustering parameters.
615
616
Returns:
617
Param: Parameters including distance thresholds
618
"""
619
620
class FeatureGroupingAlgorithmUnlabeled:
621
def __init__(self) -> None: ...
622
623
def group(self, maps: list[FeatureMap], consensus_map: ConsensusMap) -> None:
624
"""
625
Group features for unlabeled data.
626
627
Args:
628
maps (list[FeatureMap]): Input feature maps
629
consensus_map (ConsensusMap): Output consensus map
630
"""
631
```
632
633
## Usage Examples
634
635
### Map Alignment Workflow
636
637
```python
638
import pyopenms
639
640
# Load feature maps from multiple runs
641
feature_maps = []
642
filenames = ["run1_features.featureXML", "run2_features.featureXML", "run3_features.featureXML"]
643
644
for filename in filenames:
645
features = pyopenms.FeatureMap()
646
pyopenms.FeatureXMLFile().load(filename, features)
647
feature_maps.append(features)
648
649
print(f"Loaded {len(feature_maps)} feature maps")
650
651
# Set up alignment algorithm
652
alignment = pyopenms.MapAlignmentAlgorithmPoseClustering()
653
654
# Configure alignment parameters
655
params = alignment.getParameters()
656
params.setValue("max_num_peaks_considered", 1000)
657
params.setValue("superimposer:mz_pair_max_distance", 0.05)
658
params.setValue("superimposer:rt_pair_distance_fraction", 0.1)
659
alignment.setParameters(params)
660
661
# Use first map as reference
662
alignment.setReference(feature_maps[0])
663
664
# Perform alignment
665
transformations = []
666
alignment.align(feature_maps, transformations)
667
668
print(f"Generated {len(transformations)} transformations")
669
670
# Apply transformations to feature maps
671
transformer = pyopenms.MapAlignmentTransformer()
672
for i, (fmap, trafo) in enumerate(zip(feature_maps[1:], transformations[1:]), 1):
673
print(f"Applying transformation to map {i+1}")
674
transformer.transformRetentionTimes(fmap, trafo, store_original_rt=True)
675
676
# Save aligned feature maps
677
for i, fmap in enumerate(feature_maps):
678
output_file = f"aligned_run{i+1}_features.featureXML"
679
pyopenms.FeatureXMLFile().store(output_file, fmap)
680
```
681
682
### Consensus Feature Generation
683
684
```python
685
import pyopenms
686
687
# Load aligned feature maps
688
feature_maps = []
689
for i in range(3):
690
features = pyopenms.FeatureMap()
691
pyopenms.FeatureXMLFile().load(f"aligned_run{i+1}_features.featureXML", features)
692
feature_maps.append(features)
693
694
# Set up feature grouping
695
grouper = pyopenms.FeatureGroupingAlgorithmQT()
696
697
# Configure grouping parameters
698
params = grouper.getParameters()
699
params.setValue("distance_RT:max_difference", 30.0) # 30 seconds RT tolerance
700
params.setValue("distance_MZ:max_difference", 0.01) # 0.01 Da m/z tolerance
701
params.setValue("distance_MZ:unit", "Da")
702
grouper.setParameters(params)
703
704
# Create consensus map
705
consensus_map = pyopenms.ConsensusMap()
706
707
# Set column headers for input maps
708
headers = {}
709
for i, fmap in enumerate(feature_maps):
710
header = pyopenms.ColumnHeader()
711
header.setFilename(f"run{i+1}.mzML")
712
header.setLabel(f"run{i+1}")
713
header.setSize(fmap.size())
714
headers[i] = header
715
716
consensus_map.setColumnHeaders(headers)
717
consensus_map.setExperimentType("label-free")
718
719
# Group features
720
grouper.group(feature_maps, consensus_map)
721
722
print(f"Generated {consensus_map.size()} consensus features")
723
724
# Save consensus map
725
pyopenms.ConsensusXMLFile().store("consensus_features.consensusXML", consensus_map)
726
727
# Export to DataFrame for analysis
728
df = consensus_map.get_df()
729
print(f"Exported consensus data: {df.shape}")
730
print(df.head())
731
```
732
733
### Analyzing Consensus Results
734
735
```python
736
import pyopenms
737
import pandas as pd
738
739
# Load consensus map
740
consensus_map = pyopenms.ConsensusMap()
741
pyopenms.ConsensusXMLFile().load("consensus_features.consensusXML", consensus_map)
742
743
# Export intensity data
744
intensity_df = consensus_map.get_intensity_df()
745
metadata_df = consensus_map.get_metadata_df()
746
747
print("Intensity data shape:", intensity_df.shape)
748
print("Metadata shape:", metadata_df.shape)
749
750
# Analyze feature presence across runs
751
feature_presence = (intensity_df > 0).sum(axis=1)
752
print("Features detected in all runs:", (feature_presence == intensity_df.shape[1]).sum())
753
print("Features detected in at least 2 runs:", (feature_presence >= 2).sum())
754
755
# Quality assessment
756
print("Quality score distribution:")
757
print(metadata_df['quality'].describe())
758
759
# Find high-quality features present in all runs
760
high_quality_complete = metadata_df[
761
(metadata_df['quality'] > 0.7) &
762
(feature_presence == intensity_df.shape[1])
763
]
764
765
print(f"High-quality features in all runs: {len(high_quality_complete)}")
766
```
767
768
### Custom Transformation Models
769
770
```python
771
import pyopenms
772
773
# Create transformation description with data points
774
trafo = pyopenms.TransformationDescription()
775
776
# Add alignment points (input_rt, reference_rt)
777
data_points = [
778
(100.0, 105.0),
779
(200.0, 210.0),
780
(300.0, 315.0),
781
(400.0, 420.0),
782
(500.0, 525.0)
783
]
784
785
trafo.setDataPoints(data_points)
786
787
# Fit different models
788
print("Linear model:")
789
trafo.fitModel("linear")
790
print(f"Transform 250.0 -> {trafo.apply(250.0):.2f}")
791
792
print("B-spline model:")
793
params = pyopenms.Param()
794
params.setValue("num_breakpoints", 5)
795
params.setValue("break_positions", "uniform")
796
trafo.fitModel("b_spline", params)
797
print(f"Transform 250.0 -> {trafo.apply(250.0):.2f}")
798
799
# Apply transformation to feature map
800
features = pyopenms.FeatureMap()
801
pyopenms.FeatureXMLFile().load("features.featureXML", features)
802
803
transformer = pyopenms.MapAlignmentTransformer()
804
transformer.transformRetentionTimes(features, trafo, store_original_rt=True)
805
806
# Check transformation results
807
for i in range(min(5, features.size())):
808
feature = features[i]
809
original_rt = feature.getMetaValue("original_RT") if feature.metaValueExists("original_RT") else "N/A"
810
print(f"Feature {i}: RT {feature.getRT():.2f} (original: {original_rt})")
811
```