msreport 0.0.31__tar.gz → 0.0.32__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.
- {msreport-0.0.31 → msreport-0.0.32}/PKG-INFO +1 -1
- {msreport-0.0.31 → msreport-0.0.32}/msreport/__init__.py +1 -1
- {msreport-0.0.31 → msreport-0.0.32}/msreport/export.py +1 -1
- {msreport-0.0.31 → msreport-0.0.32}/msreport/helper/maxlfq.py +3 -3
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/comparison.py +7 -2
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/multivariate.py +34 -15
- {msreport-0.0.31 → msreport-0.0.32}/msreport/reader.py +146 -14
- {msreport-0.0.31 → msreport-0.0.32}/msreport.egg-info/PKG-INFO +1 -1
- {msreport-0.0.31 → msreport-0.0.32}/pyproject.toml +8 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_plot.py +4 -0
- {msreport-0.0.31 → msreport-0.0.32}/LICENSE.txt +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/README.md +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/aggregate/__init__.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/aggregate/condense.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/aggregate/pivot.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/aggregate/summarize.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/analyze.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/errors.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/fasta.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/helper/__init__.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/helper/calc.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/helper/table.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/helper/temp.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/impute.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/isobar.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/normalize.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/peptidoform.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/__init__.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/_partial_plots.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/distribution.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/quality.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/style.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/style_sheets/msreport-notebook.mplstyle +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/plot/style_sheets/seaborn-whitegrid.mplstyle +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/qtable.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/rinterface/__init__.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/rinterface/limma.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/rinterface/rinstaller.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport/rinterface/rscripts/limma.R +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport.egg-info/SOURCES.txt +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport.egg-info/dependency_links.txt +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport.egg-info/requires.txt +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/msreport.egg-info/top_level.txt +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/setup.cfg +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/setup.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_analyze.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_export.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_helper.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_impute.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_isobar.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_maxlfq.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_peptidoform.py +0 -0
- {msreport-0.0.31 → msreport-0.0.32}/tests/test_qtable.py +0 -0
|
@@ -113,9 +113,9 @@ def calculate_pairwise_mode_log_ratio_matrix(
|
|
|
113
113
|
... ]
|
|
114
114
|
... )
|
|
115
115
|
>>> calculate_pairwise_mode_log_ratio_matrix(array)
|
|
116
|
-
array([[ 0.
|
|
117
|
-
[ 0.
|
|
118
|
-
[ 1.
|
|
116
|
+
array([[ 0. , -0.08496251, -1. ],
|
|
117
|
+
[ 0.08496251, 0. , -1. ],
|
|
118
|
+
[ 1. , 1. , 0. ]])
|
|
119
119
|
"""
|
|
120
120
|
ratio_marix = _calculate_pairwise_centered_log_ratio_matrix(
|
|
121
121
|
array, msreport.helper.mode, log_transformed=log_transformed
|
|
@@ -77,10 +77,15 @@ def volcano_ma(
|
|
|
77
77
|
)
|
|
78
78
|
special_entries = list(special_entries) + list(special_proteins)
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
if annotation_column not in data.columns:
|
|
80
|
+
if annotation_column not in qtable.data.columns:
|
|
82
81
|
annotation_column = qtable.id_column
|
|
83
82
|
|
|
83
|
+
data = qtable.get_data(exclude_invalid=exclude_invalid)
|
|
84
|
+
mask = np.ones(data.shape[0], dtype=bool)
|
|
85
|
+
for tag in [ratio_tag, expression_tag, pvalue_tag]:
|
|
86
|
+
mask = mask & np.isfinite(data[f"{tag} {comparison_group}"])
|
|
87
|
+
data = data[mask]
|
|
88
|
+
|
|
84
89
|
scatter_size = 2 / (max(min(data.shape[0], 10000), 1000) / 1000)
|
|
85
90
|
|
|
86
91
|
masks = {
|
|
@@ -21,6 +21,7 @@ def sample_pca(
|
|
|
21
21
|
pc_x: str = "PC1",
|
|
22
22
|
pc_y: str = "PC2",
|
|
23
23
|
exclude_invalid: bool = True,
|
|
24
|
+
exclude_missing: bool = False,
|
|
24
25
|
) -> tuple[plt.Figure, list[plt.Axes]]:
|
|
25
26
|
"""Figure to compare sample similarities with a principle component analysis.
|
|
26
27
|
|
|
@@ -44,11 +45,14 @@ def sample_pca(
|
|
|
44
45
|
samples.
|
|
45
46
|
exclude_invalid: If True, rows are filtered according to the Boolean entries of
|
|
46
47
|
the "Valid" column.
|
|
48
|
+
exclude_missing: If True, only rows without any missing values are used.
|
|
47
49
|
|
|
48
50
|
Returns:
|
|
49
51
|
A matplotlib Figure and a list of Axes objects, containing the PCA plots.
|
|
50
52
|
"""
|
|
51
53
|
design = qtable.get_design()
|
|
54
|
+
samples = qtable.get_samples()
|
|
55
|
+
|
|
52
56
|
if design.shape[0] < 3:
|
|
53
57
|
fig, ax = plt.subplots(1, 1, figsize=(2, 1.3))
|
|
54
58
|
fig.suptitle(f'PCA of "{tag}" values', y=1.1)
|
|
@@ -65,13 +69,22 @@ def sample_pca(
|
|
|
65
69
|
return fig, np.array([ax])
|
|
66
70
|
|
|
67
71
|
table = qtable.make_sample_table(
|
|
68
|
-
tag, samples_as_columns=True, exclude_invalid=
|
|
72
|
+
tag, samples_as_columns=True, exclude_invalid=False
|
|
69
73
|
)
|
|
74
|
+
|
|
75
|
+
inclusion_mask = np.ones(qtable.data.shape[0], dtype=bool)
|
|
76
|
+
if exclude_invalid:
|
|
77
|
+
inclusion_mask = inclusion_mask & qtable["Valid"]
|
|
78
|
+
if exclude_missing:
|
|
79
|
+
_non_missing_masks = [(qtable[f"Missing {s}"] == 0) for s in samples]
|
|
80
|
+
inclusion_mask = inclusion_mask & (np.all(_non_missing_masks, axis=0))
|
|
81
|
+
table = table[inclusion_mask]
|
|
82
|
+
|
|
70
83
|
table = table.replace({0: np.nan})
|
|
71
84
|
table = table[np.isfinite(table).sum(axis=1) > 0]
|
|
72
85
|
if not msreport.helper.intensities_in_logspace(table):
|
|
73
86
|
table = np.log2(table)
|
|
74
|
-
table
|
|
87
|
+
table = table.fillna(0)
|
|
75
88
|
|
|
76
89
|
table = table.transpose()
|
|
77
90
|
sample_index = table.index.tolist()
|
|
@@ -203,6 +216,7 @@ def sample_pca(
|
|
|
203
216
|
def expression_clustermap(
|
|
204
217
|
qtable: Qtable,
|
|
205
218
|
exclude_invalid: bool = True,
|
|
219
|
+
exclude_missing: bool = False,
|
|
206
220
|
remove_imputation: bool = True,
|
|
207
221
|
mean_center: bool = False,
|
|
208
222
|
cluster_samples: bool = True,
|
|
@@ -218,6 +232,7 @@ def expression_clustermap(
|
|
|
218
232
|
qtable: A `Qtable` instance, which data is used for plotting.
|
|
219
233
|
exclude_invalid: If True, rows are filtered according to the Boolean entries of
|
|
220
234
|
the "Valid" column.
|
|
235
|
+
exclude_missing: If True, only rows without any missing values are used.
|
|
221
236
|
remove_imputation: If True, imputed values are set to 0 before clustering.
|
|
222
237
|
Defaults to True.
|
|
223
238
|
mean_center: If True, the data is mean-centered before clustering. Defaults to
|
|
@@ -242,25 +257,29 @@ def expression_clustermap(
|
|
|
242
257
|
if len(samples) < 2:
|
|
243
258
|
raise ValueError("At least two samples are required to generate a clustermap.")
|
|
244
259
|
|
|
245
|
-
data = qtable.make_expression_table(samples_as_columns=True)
|
|
260
|
+
data = qtable.make_expression_table(samples_as_columns=True, exclude_invalid=False)
|
|
246
261
|
data = data[samples]
|
|
262
|
+
data = data.fillna(0)
|
|
247
263
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
data.loc[qtable.data[f"Missing {sample}"], sample] = 0
|
|
251
|
-
data[sample] = data[sample].fillna(0)
|
|
252
|
-
|
|
253
|
-
if not mean_center:
|
|
254
|
-
# Hide missing values in the heatmap, making them appear white
|
|
255
|
-
mask_values = qtable.data[
|
|
264
|
+
if not mean_center: # Hide missing values in the heatmap, making them appear white
|
|
265
|
+
hide_values_mask = qtable.data[
|
|
256
266
|
[f"Missing {sample}" for sample in samples]
|
|
257
267
|
].to_numpy()
|
|
258
268
|
else:
|
|
259
|
-
|
|
269
|
+
hide_values_mask = np.zeros(data.shape, dtype=bool)
|
|
270
|
+
|
|
271
|
+
if remove_imputation:
|
|
272
|
+
for sample in samples:
|
|
273
|
+
data.loc[qtable.data[f"Missing {sample}"], sample] = 0
|
|
260
274
|
|
|
275
|
+
inclusion_mask = np.ones(data.shape[0], dtype=bool)
|
|
261
276
|
if exclude_invalid:
|
|
262
|
-
|
|
263
|
-
|
|
277
|
+
inclusion_mask = inclusion_mask & qtable["Valid"]
|
|
278
|
+
if exclude_missing:
|
|
279
|
+
_non_missing_masks = [(qtable[f"Missing {s}"] == 0) for s in samples]
|
|
280
|
+
inclusion_mask = inclusion_mask & (np.all(_non_missing_masks, axis=0))
|
|
281
|
+
hide_values_mask = hide_values_mask[inclusion_mask]
|
|
282
|
+
data = data[inclusion_mask]
|
|
264
283
|
|
|
265
284
|
color_wheel = ColorWheelDict()
|
|
266
285
|
for exp in experiments:
|
|
@@ -314,7 +333,7 @@ def expression_clustermap(
|
|
|
314
333
|
col_cluster=cluster_samples,
|
|
315
334
|
col_colors=sample_colors,
|
|
316
335
|
row_colors=["#000000" for _ in range(len(data))],
|
|
317
|
-
mask=
|
|
336
|
+
mask=hide_values_mask,
|
|
318
337
|
method=cluster_method,
|
|
319
338
|
metric="euclidean",
|
|
320
339
|
**heatmap_args,
|
|
@@ -545,7 +545,12 @@ class FragPipeReader(ResultReader):
|
|
|
545
545
|
"""FragPipe result reader.
|
|
546
546
|
|
|
547
547
|
Methods:
|
|
548
|
-
import_design:
|
|
548
|
+
import_design: Depending on the quantification strategy, imports either the
|
|
549
|
+
manifest file or the experiment annotation file and returns a processed
|
|
550
|
+
design dataframe.
|
|
551
|
+
import_manifest: Reads a "fragpipe-files.fp-manifest" file and returns a
|
|
552
|
+
processed design dataframe.
|
|
553
|
+
import_experiment_annotation: Reads a "experiment_annotation" file and returns a
|
|
549
554
|
processed design dataframe.
|
|
550
555
|
import_proteins: Reads a "combined_protein.tsv" or "protein.tsv" file and
|
|
551
556
|
returns a processed dataframe, conforming to the MsReport naming
|
|
@@ -589,12 +594,8 @@ class FragPipeReader(ResultReader):
|
|
|
589
594
|
"ions": "combined_ion.tsv",
|
|
590
595
|
"ion_evidence": "ion.tsv",
|
|
591
596
|
"psm_evidence": "psm.tsv",
|
|
592
|
-
"
|
|
593
|
-
|
|
594
|
-
isobar_filenames: dict[str, str] = {
|
|
595
|
-
"proteins": "protein.tsv",
|
|
596
|
-
"peptides": "peptide.tsv",
|
|
597
|
-
"ions": "ion.tsv",
|
|
597
|
+
"manifest": "fragpipe-files.fp-manifest",
|
|
598
|
+
"experiment_annotation": "experiment_annotation.tsv",
|
|
598
599
|
}
|
|
599
600
|
sil_filenames: dict[str, str] = {
|
|
600
601
|
"proteins": "combined_protein_label_quant.tsv",
|
|
@@ -675,14 +676,27 @@ class FragPipeReader(ResultReader):
|
|
|
675
676
|
self._isobar: bool = isobar
|
|
676
677
|
self._sil: bool = sil
|
|
677
678
|
self._contaminant_tag: str = contaminant_tag
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
self.filenames
|
|
679
|
+
|
|
680
|
+
self.filenames = self.default_filenames.copy()
|
|
681
|
+
if sil:
|
|
682
|
+
self.filenames.update(self.sil_filenames)
|
|
683
|
+
|
|
684
|
+
def import_design(self, sort: bool = False) -> pd.DataFrame:
|
|
685
|
+
"""Reads the experimental design file and returns a processed design dataframe.
|
|
686
|
+
|
|
687
|
+
Depending on the quantification strategy (isobaric or label-free/sil), either
|
|
688
|
+
the experiment annotation file or the manifest file is imported.
|
|
689
|
+
|
|
690
|
+
Args:
|
|
691
|
+
sort: If True, the design dataframe is sorted by "Experiment" and
|
|
692
|
+
"Replicate"; default False.
|
|
693
|
+
"""
|
|
694
|
+
if self._isobar:
|
|
695
|
+
return self.import_experiment_annotation(sort=sort)
|
|
682
696
|
else:
|
|
683
|
-
self.
|
|
697
|
+
return self.import_manifest(sort=sort)
|
|
684
698
|
|
|
685
|
-
def
|
|
699
|
+
def import_manifest(
|
|
686
700
|
self, filename: Optional[str] = None, sort: bool = False
|
|
687
701
|
) -> pd.DataFrame:
|
|
688
702
|
"""Read a 'fp-manifest' file and returns a processed design dataframe.
|
|
@@ -709,7 +723,7 @@ class FragPipeReader(ResultReader):
|
|
|
709
723
|
FileNotFoundError: If the specified manifest file does not exist.
|
|
710
724
|
"""
|
|
711
725
|
if filename is None:
|
|
712
|
-
filepath = os.path.join(self.data_directory, self.filenames["
|
|
726
|
+
filepath = os.path.join(self.data_directory, self.filenames["manifest"])
|
|
713
727
|
else:
|
|
714
728
|
filepath = os.path.join(self.data_directory, filename)
|
|
715
729
|
if not os.path.exists(filepath):
|
|
@@ -748,6 +762,63 @@ class FragPipeReader(ResultReader):
|
|
|
748
762
|
design.reset_index(drop=True, inplace=True)
|
|
749
763
|
return design
|
|
750
764
|
|
|
765
|
+
def import_experiment_annotation(
|
|
766
|
+
self, filename: Optional[str] = None, sort: bool = False
|
|
767
|
+
) -> pd.DataFrame:
|
|
768
|
+
"""Read a 'experiment_annotation' file and returns a processed design dataframe.
|
|
769
|
+
|
|
770
|
+
The annotation columns "sample", "channel", and "plex" are mapped to the design
|
|
771
|
+
table columns "Sample", "Channel", and "Plex". The "Experiment" and "Replicate"
|
|
772
|
+
columns are extracted from the "Sample" column by splitting at the last
|
|
773
|
+
underscore, if there is no underscore, "Replicate" is set to an empty string.
|
|
774
|
+
|
|
775
|
+
Note that this convention of splitting the "Sample" column does confirm to the
|
|
776
|
+
FragPipe convention, but FragPipe does not enforce it for the experiment
|
|
777
|
+
annotation file.
|
|
778
|
+
|
|
779
|
+
Args:
|
|
780
|
+
filename: Allows specifying an alternative filename, otherwise the default
|
|
781
|
+
filename is used.
|
|
782
|
+
sort: If True, the design dataframe is sorted by "Experiment" and
|
|
783
|
+
"Replicate"; default False.
|
|
784
|
+
|
|
785
|
+
Returns:
|
|
786
|
+
A dataframe containing the processed design table with columns:
|
|
787
|
+
"Sample", "Experiment", "Replicate", "Channel", and "Plex".
|
|
788
|
+
|
|
789
|
+
Raises:
|
|
790
|
+
FileNotFoundError: If the specified manifest file does not exist.
|
|
791
|
+
"""
|
|
792
|
+
if filename is None:
|
|
793
|
+
filepath = os.path.join(
|
|
794
|
+
self.data_directory, self.filenames["experiment_annotation"]
|
|
795
|
+
)
|
|
796
|
+
else:
|
|
797
|
+
filepath = os.path.join(self.data_directory, filename)
|
|
798
|
+
if not os.path.exists(filepath):
|
|
799
|
+
raise FileNotFoundError(
|
|
800
|
+
f"File '{filepath}' does not exist. Please check the file path."
|
|
801
|
+
)
|
|
802
|
+
|
|
803
|
+
annotation = pd.read_csv(filepath, sep="\t")
|
|
804
|
+
|
|
805
|
+
design = pd.DataFrame(
|
|
806
|
+
{
|
|
807
|
+
"Sample": annotation["sample"],
|
|
808
|
+
"Experiment": annotation["sample"].str.rsplit("_", n=1).str[0],
|
|
809
|
+
"Replicate": annotation["sample"].str.rsplit("_", n=1).str[1],
|
|
810
|
+
"Channel": annotation["channel"],
|
|
811
|
+
"Plex": annotation["plex"],
|
|
812
|
+
}
|
|
813
|
+
)
|
|
814
|
+
design["Replicate"] = design["Replicate"].fillna("")
|
|
815
|
+
|
|
816
|
+
if sort:
|
|
817
|
+
design.sort_values(by=["Experiment", "Replicate"], inplace=True)
|
|
818
|
+
design.reset_index(drop=True, inplace=True)
|
|
819
|
+
|
|
820
|
+
return design
|
|
821
|
+
|
|
751
822
|
def import_proteins(
|
|
752
823
|
self,
|
|
753
824
|
filename: Optional[str] = None,
|
|
@@ -1034,6 +1105,7 @@ class FragPipeReader(ResultReader):
|
|
|
1034
1105
|
)
|
|
1035
1106
|
df["Modified sequence"] = mod_entries["Modified sequence"]
|
|
1036
1107
|
df["Modifications"] = mod_entries["Modifications"]
|
|
1108
|
+
df = self._add_modification_localization_string_to_psm_evidence(df)
|
|
1037
1109
|
return df
|
|
1038
1110
|
|
|
1039
1111
|
def _add_protein_entries(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
@@ -1207,6 +1279,66 @@ class FragPipeReader(ResultReader):
|
|
|
1207
1279
|
new_df[new_column] = localization_strings
|
|
1208
1280
|
return new_df
|
|
1209
1281
|
|
|
1282
|
+
def _add_modification_localization_string_to_psm_evidence(
|
|
1283
|
+
self, df: pd.DataFrame
|
|
1284
|
+
) -> pd.DataFrame:
|
|
1285
|
+
"""Adds a modification localization string column to a PSM evidence table.
|
|
1286
|
+
|
|
1287
|
+
Extracts localization probabilities from all columns in the form
|
|
1288
|
+
f"{aa:modification}", converts them into the standardized modification
|
|
1289
|
+
localization string format used by msreport, and adds a new column
|
|
1290
|
+
"Modification localization string".
|
|
1291
|
+
|
|
1292
|
+
Probabilities are written in the format
|
|
1293
|
+
"Mod1@Site1:Probability1,Site2:Probability2;Mod2@Site3:Probability3",
|
|
1294
|
+
e.g. "15.9949@11:1.000;79.9663@3:0.200,4:0.800". Refer to
|
|
1295
|
+
`msreport.peptidoform.make_localization_string` for details.
|
|
1296
|
+
|
|
1297
|
+
Args:
|
|
1298
|
+
df: A dataframe containing PSM tables from FragPipe.
|
|
1299
|
+
|
|
1300
|
+
Returns:
|
|
1301
|
+
A copy of the input dataframe with the added
|
|
1302
|
+
"Modification localization string" column.
|
|
1303
|
+
"""
|
|
1304
|
+
new_df = df.copy()
|
|
1305
|
+
_search_tag = " Best Localization"
|
|
1306
|
+
mod_localization_columns = [
|
|
1307
|
+
c.strip(_search_tag) for c in new_df.columns if c.endswith(_search_tag)
|
|
1308
|
+
]
|
|
1309
|
+
if not mod_localization_columns:
|
|
1310
|
+
new_df["Modification localization string"] = ""
|
|
1311
|
+
return new_df
|
|
1312
|
+
|
|
1313
|
+
df[mod_localization_columns] = (
|
|
1314
|
+
df[mod_localization_columns].astype(str).replace("nan", "")
|
|
1315
|
+
)
|
|
1316
|
+
row_mod_probabilities: list[dict[str, dict[int, float]]] = [
|
|
1317
|
+
{} for i in range(df.shape[0])
|
|
1318
|
+
]
|
|
1319
|
+
for mod_localization_column in mod_localization_columns:
|
|
1320
|
+
modification = mod_localization_column.split(":")[1]
|
|
1321
|
+
for modification_probabilities, probability_sequence in zip(
|
|
1322
|
+
row_mod_probabilities, df[mod_localization_column]
|
|
1323
|
+
):
|
|
1324
|
+
if not probability_sequence:
|
|
1325
|
+
continue
|
|
1326
|
+
_, probabilities = msreport.peptidoform.parse_modified_sequence(
|
|
1327
|
+
probability_sequence, "(", ")"
|
|
1328
|
+
)
|
|
1329
|
+
modification_probabilities[modification] = {
|
|
1330
|
+
site: float(probability) for site, probability in probabilities
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
localization_strings = []
|
|
1334
|
+
for localization_probabilities in row_mod_probabilities:
|
|
1335
|
+
localization_string = msreport.peptidoform.make_localization_string(
|
|
1336
|
+
localization_probabilities
|
|
1337
|
+
)
|
|
1338
|
+
localization_strings.append(localization_string)
|
|
1339
|
+
new_df["Modification localization string"] = localization_strings
|
|
1340
|
+
return new_df
|
|
1341
|
+
|
|
1210
1342
|
|
|
1211
1343
|
class SpectronautReader(ResultReader):
|
|
1212
1344
|
"""Spectronaut result reader.
|
|
@@ -112,3 +112,11 @@ module = [
|
|
|
112
112
|
"yaml.*",
|
|
113
113
|
]
|
|
114
114
|
follow_untyped_imports = true
|
|
115
|
+
|
|
116
|
+
[tool.pytest.ini_options]
|
|
117
|
+
addopts = "--doctest-modules"
|
|
118
|
+
doctest_optionflags = "NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL"
|
|
119
|
+
testpaths = [
|
|
120
|
+
"tests",
|
|
121
|
+
"msreport",
|
|
122
|
+
]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import matplotlib
|
|
1
2
|
import numpy as np
|
|
2
3
|
import pandas as pd
|
|
3
4
|
import pytest
|
|
@@ -5,6 +6,9 @@ import pytest
|
|
|
5
6
|
import msreport.plot
|
|
6
7
|
import msreport.qtable
|
|
7
8
|
|
|
9
|
+
# Use the 'Agg' backend for plotting tests to prevent TclError in headless environments.
|
|
10
|
+
matplotlib.use("Agg")
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
@pytest.fixture
|
|
10
14
|
def example_data():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|