From 08ff842c880182649de04c6abec7fcf260e9a828 Mon Sep 17 00:00:00 2001 From: Chengxin Dai <37200167+daichengxin@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:49:49 +0800 Subject: [PATCH 1/4] fixed bugs for proteomicslfq --- onsite/ascore/cli.py | 16 ++++++++++++++++ onsite/idparquet.py | 2 +- onsite/lucxor/cli.py | 31 ++++++++++++++++++++----------- onsite/onsitec.py | 16 ++++++++++++++++ onsite/phosphors/cli.py | 16 ++++++++++++++++ pyproject.toml | 2 +- tests/test_output_validation.py | 1 + 7 files changed, 71 insertions(+), 13 deletions(-) diff --git a/onsite/ascore/cli.py b/onsite/ascore/cli.py index 6a354a6..e369c29 100644 --- a/onsite/ascore/cli.py +++ b/onsite/ascore/cli.py @@ -204,10 +204,26 @@ def ascore( else: stats["errors"] += 1 + # Count how many PSMs had their modification sites reassigned + relocated_count = 0 + orig_pf_map = {} + for _, group_df in grouped: + pep_idx = group_df.iloc[0].get("peptide_identification_index") + orig_pf = str(group_df.iloc[0].get("peptidoform", "")) + if orig_pf: + orig_pf_map[pep_idx] = orig_pf + for row in result_rows: + pep_idx = row.get("peptide_identification_index") + orig_pf = orig_pf_map.get(pep_idx, "") + out_pf = str(row.get("peptidoform", "")) + if orig_pf and orig_pf != out_pf: + relocated_count += 1 + elapsed = time.time() - start_time click.echo(f"\nProcessing Complete:") click.echo(f" Total identifications: {stats['total']}") click.echo(f" Successfully processed: {stats['processed']}") + click.echo(f" Modification sites reassigned: {relocated_count}") click.echo(f" Phosphorylated peptides: {stats['phospho']}") click.echo(f" Processing errors: {stats['errors']}") click.echo(f" Time elapsed: {elapsed:.2f} seconds") diff --git a/onsite/idparquet.py b/onsite/idparquet.py index 1a92dcc..7a67b4b 100644 --- a/onsite/idparquet.py +++ b/onsite/idparquet.py @@ -265,7 +265,7 @@ def _pa_col(name, values): return pa.array(values, type=tbl.schema.field(name).type) updates = {} - for col in ("peptidoform", "sequence", "score", "score_type", "higher_score_better"): + for col in ("peptidoform",): updates[col] = _pa_col(col, psms_df[col].tolist()) updates["psm_metavalues"] = _pa_col("psm_metavalues", psms_df["psm_metavalues"].tolist()) diff --git a/onsite/lucxor/cli.py b/onsite/lucxor/cli.py index a26fa5d..a5f6055 100644 --- a/onsite/lucxor/cli.py +++ b/onsite/lucxor/cli.py @@ -748,6 +748,7 @@ def run( result_rows = [] phospho_count = 0 + relocated_count = 0 for pep_idx, psm in enumerate(all_psms): # Use metadata stashed during load_input_files mz = getattr(psm, "_mz", 0.0) @@ -775,17 +776,6 @@ def run( peptidoform = pyopenms_to_unimod_notation(seq_str).upper() - # Use pyOpenMS to get unmodified string if possible - try: - seq_obj = AASequence.fromString(seq_str) if seq_str else None - if seq_obj: - base_seq = seq_obj.toUnmodifiedString() - else: - base_seq = re.sub(r"\([^)]*\)", "", seq_str).upper() - except Exception: - # Fallback: strip all (...) modification annotations and uppercase - base_seq = re.sub(r"\([^)]*\)", "", seq_str).upper() - # Build psm_metavalues: preserve original + add Luciphor scores _lucxor_df = getattr(self, "_psms_df_template", None) if _lucxor_df is not None: @@ -797,6 +787,24 @@ def run( _orig_list = [] else: _orig_list = [] + + # Track how many peptides had their modification positions changed + if _lucxor_df is not None and pep_idx < len(_best): + orig_peptidoform = str(_best.iloc[pep_idx].get("peptidoform", "")) + if orig_peptidoform and orig_peptidoform != peptidoform: + relocated_count += 1 + + # Use pyOpenMS to get unmodified string if possible + try: + seq_obj = AASequence.fromString(seq_str) if seq_str else None + if seq_obj: + base_seq = seq_obj.toUnmodifiedString() + else: + base_seq = re.sub(r"\([^)]*\)", "", seq_str).upper() + except Exception: + # Fallback: strip all (...) modification annotations and uppercase + base_seq = re.sub(r"\([^)]*\)", "", seq_str).upper() + _lucxor_managed = {"search_engine_sequence", "Luciphor_pep_score", "Luciphor_global_flr", "Luciphor_local_flr", "Luciphor_site_scores"} _filtered_orig = [m for m in _orig_list if isinstance(m, dict) and m.get("name") not in _lucxor_managed] @@ -864,6 +872,7 @@ def run( print("\nProcessing Complete:") print(f" Total identifications: {total}") print(f" Successfully processed: {processed}") + print(f" Modification sites reassigned: {relocated_count}") print(f" Phosphorylated peptides: {phospho_count}") print(f" Processing errors: {errors}") print(f" Time elapsed: {elapsed:.2f} seconds") diff --git a/onsite/onsitec.py b/onsite/onsitec.py index f467771..e77f320 100644 --- a/onsite/onsitec.py +++ b/onsite/onsitec.py @@ -408,8 +408,24 @@ def merge_algorithm_results(ascore_file, phosphors_file, lucxor_file, output_fil out_df = full_df.reset_index() + # Count how many peptides had their modification sites reassigned by LucXor + relocated_count = 0 + input_psms_df, _, _, _ = load_dataframes(input_idparquet) + input_pf_map = {} + for _, row in input_psms_df.iterrows(): + pep_idx = row.get("peptide_identification_index") + if pep_idx is not None: + input_pf_map[pep_idx] = str(row.get("peptidoform", "")) + for _, row in out_df.iterrows(): + pep_idx = row.get("peptide_identification_index") + out_pf = str(row.get("peptidoform", "")) + orig_pf = input_pf_map.get(pep_idx, "") + if orig_pf and orig_pf != out_pf: + relocated_count += 1 + save_dataframes(output_file, out_df, proteins_df, template_df=lucxor_df, source_idparquet=input_idparquet) click.echo(f"Successfully merged {stats['merged']} peptide identifications") + click.echo(f" Modification sites reassigned: {relocated_count}") click.echo("Each peptide contains scores from all three algorithms") diff --git a/onsite/phosphors/cli.py b/onsite/phosphors/cli.py index c493355..4cd5f32 100644 --- a/onsite/phosphors/cli.py +++ b/onsite/phosphors/cli.py @@ -253,11 +253,27 @@ def phosphors( f"Error processing identification: {res.get('reason', 'unknown')}" ) + # Count how many PSMs had their modification sites reassigned + relocated_count = 0 + orig_pf_map = {} + for _, group_df in grouped: + pep_idx = group_df.iloc[0].get("peptide_identification_index") + orig_pf = str(group_df.iloc[0].get("peptidoform", "")) + if orig_pf: + orig_pf_map[pep_idx] = orig_pf + for row in result_rows: + pep_idx = row.get("peptide_identification_index") + orig_pf = orig_pf_map.get(pep_idx, "") + out_pf = str(row.get("peptidoform", "")) + if orig_pf and orig_pf != out_pf: + relocated_count += 1 + # Report elapsed = time.time() - start_time click.echo(f"\nProcessing Complete:") click.echo(f" Total identifications: {stats['total']}") click.echo(f" Successfully processed: {stats['processed']}") + click.echo(f" Modification sites reassigned: {relocated_count}") click.echo(f" Phosphorylated peptides: {stats['phospho']}") click.echo(f" Processing errors: {stats['errors']}") click.echo(f" Time elapsed: {elapsed:.2f} seconds") diff --git a/pyproject.toml b/pyproject.toml index 6df903a..835ffd8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "pyonsite" -version = "0.0.3" +version = "0.0.4" description = "onsite: mass spectrometry post-translational localization tool" authors = [ {name = "BigBio Stack"} diff --git a/tests/test_output_validation.py b/tests/test_output_validation.py index faacc09..19ee221 100644 --- a/tests/test_output_validation.py +++ b/tests/test_output_validation.py @@ -57,6 +57,7 @@ def test_output_content_validation(self, idparquet_dir, mzml_file): "--input-id", idparquet_dir, "--output", out, "--target-modifications", "Phospho(S),Phospho(T),Phospho(Y)", + "--modeling-score-threshold", "0.3", ]) if r.exit_code != 0: pytest.skip(f"LucXor required but failed: {r.output[:200]}") From 39fdedbf9a97ab185bd6f644f28d220fcd7d6328 Mon Sep 17 00:00:00 2001 From: Chengxin Dai <37200167+daichengxin@users.noreply.github.com> Date: Wed, 17 Jun 2026 12:24:14 +0800 Subject: [PATCH 2/4] update --- .../protein_groups.parquet | Bin 0 -> 3643 bytes .../proteins.parquet | Bin 0 -> 7151 bytes .../psms.parquet | Bin 0 -> 91075 bytes .../search_params.parquet | Bin 0 -> 15133 bytes onsite/onsitec.py | 30 ++++++++++++------ 5 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 data/test_compute_all_rep1.idparquet/protein_groups.parquet create mode 100644 data/test_compute_all_rep1.idparquet/proteins.parquet create mode 100644 data/test_compute_all_rep1.idparquet/psms.parquet create mode 100644 data/test_compute_all_rep1.idparquet/search_params.parquet diff --git a/data/test_compute_all_rep1.idparquet/protein_groups.parquet b/data/test_compute_all_rep1.idparquet/protein_groups.parquet new file mode 100644 index 0000000000000000000000000000000000000000..5853d33e370b9671ec0d0399937279f546c69672 GIT binary patch literal 3643 zcmd^COK%!i6uu$IX&onRqk;y>mAq)8RuMJ~U_;c+1F> zL)TsR7qq)9y6(EaqwA__rJi#xk1-;NvdF3}SOdkm)D=hBMgbB_0-sk9di#pKv>J|griwK&w%fPs zvJc4~j-8R&?|vkc@K<2+zVYSJAk{ zf7=unrsZ5Ub;mTS92fr2O}q$1?``-+sol}(QumW*!}^6e?y9?k-L&WT?FxEtRq!5z z{@SiDcc&!ZY0=O3H(c^kLV9o4@E()?a4Yox;_*W@`v1Pq0^dttj0YWOri_eB=t5KI z9wTYzY-sdLubA{m8ySiNeF$%nA$=)_ne$I%+T)k9LAe{3IOggtg;DLOBVkkq(nS?UFPXFg=1WE#NhzzH0d*OGegrcPEnBaD%W2iR zkkh^?d0n=`1PVvIP^K^bzx@tM4G<<9Ii&8Cr zTuN8rTTt+rb2Me?pEXsj#C5BAZsAFaa|l2cfAhE|eIk`vT-PE=OT7-)V0w;gO-|T) zPVYgiI$EwU)ots#-6SXtQB+r`ra^STAwCIITdab5$S0T`MwU;)r=87&S|py#BR)}q++xnFAqp57A?ycE&UGAwep0G{->Sez z5nrf87Wf&}M-Jr$o=g$(pn8#8jd{4;1pi*v;=o)z>InOJk3hsP?5FhxUwW{R=bV^Q ze2Gs|WcgOSYG)j(DV~m_y{|Xyb@@xwlr)Z4C3&mo3PaV_moXb7pS;3vkC%$3Z;zLT z_*CWO!{e2|O2B;z9Zf~N-sSH)KdBk=HCKEWlr`ZWO)1F2=~z!~P*6Gf7p*-9J~%%u zQU0hBM1P^wQj@_x#d+JFPvI^sW5mh7lNG*9d~SRfK%z+2{UmEaU!d#G&(PlIE4<)O zVu8B(*RJSxW~?{rw-EGejL#|LSk!ZAEhOp@b%^`n;tNd|`RH<}$@j;1T~Dbf@+Fq> z<$2;O5X(Bg)K9ab-!)}x($3bQ8Fo3`ODH`J`^Mrq#mMl|(ta-T<*HATOH=#`Vdz0a z&;|F}vXw^t1`e;${?-aF?xPD&sivesYk^4gT5{RaBIThf$1r{uh=)rDdFkSN1hPbN zuP&MjU`{i1DMkKiN=AvI7($P6Xr0IR#ZevyTF+^8^(R^val{_jvNNXAm=EvbQli2fxkNM{xJCwV-@(@_#ep;f}8*V literal 0 HcmV?d00001 diff --git a/data/test_compute_all_rep1.idparquet/proteins.parquet b/data/test_compute_all_rep1.idparquet/proteins.parquet new file mode 100644 index 0000000000000000000000000000000000000000..628dec84ff66097567c8b74792365a0e3aaddc71 GIT binary patch literal 7151 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 oI4;gy6dx~>QwOdzD$CM>VZo$yfjsyK{YaHPU!r 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