#import "template.typ": *
#import "@preview/fletcher:0.5.8" as fletcher: diagram, node, edge
#import fletcher.shapes: diamond, brace, cylinder
#import "@preview/clean-cnam-template:1.2.0": *
#import "@preview/proteograph:0.2.2": *


#show: clean-cnam-template.with(
  title: "PeptidOMS documentation",
  subtitle: "PeptidOMS-ANR-24-CE45-3296",
  author: "Olivier Langella",
  class: "technical documentation",
  affiliation: "PAPPSO",
  //logo: image("./assets/cnam_logo.svg"),
  start-date: datetime(day: 11, month: 7, year: 2025),
  main-color: navy,
  default-font: "New Computer Modern Math",
  code-font: "Andale Mono",
  outline-code: outline(
    title: "Table of content",
    depth: 2,
    indent: auto,
  ),
)

#set text(lang: "en")
#set heading(numbering: "1.1")



#let peptidoms = "PeptidOMS"
#let protein-matcher = "ProteinMatcher"
#let specglobtool = "SpecGlobTool"
#let specoms = "SpecOMS"
#let spoms = "Spoms"

= Introduction

#peptidoms aligns MS2 fragmentation spectra directly to protein sequences.
Algorithm is described in @benoist_specpeptidoms_2025.

= Source code

Current source code is available at #link("https://forge.inrae.fr/peptidoms/specpeptidoms","https://forge.inrae.fr/peptidoms/specpeptidoms").


= PSM CBOR file workflow

#set text(10pt)
#diagram(
	node-stroke: .1em,
	node-fill: gradient.radial(blue.lighten(80%), blue, center: (30%, 20%), radius: 80%),
	spacing: 4em,
	node((-1,0.5), `fasta file`, shape: diamond, fill: none, name: <fastafile>),
	node((-1,-0.5), `mzML file`, shape: diamond, fill: none, name: <mzmlfile>),
	node((0,0), `peptidoms`, radius: 3em, name: <peptidoms>),
	edge(``, "-|>"),
	node((1,0), `PSM cbor file`, shape: diamond, fill: none, name: <peptidomscbor>),
	edge(``, "-|>"),
	node((2,0), `psmfeatures`, radius: 3em),
	edge(``, "-|>"),
	node((3,0), `ODS export`, radius: 2em),
	node((2,1), `deeplc mumble`, radius: 2em, name: <deeplc>),
	edge(<peptidomscbor>, <deeplc>, ``, "-|>"),
	edge(<fastafile>,<peptidoms.west>, "-|>", bend: 20deg),
	edge(<mzmlfile>,<peptidoms.west>, "-|>", bend: -20deg),
)


= Command line interface

#peptidoms works on a collection of MS/MS spectra (mzML file typically) and a protein sequence database (FASTA file) and produces a PSM CBOR file as output.

#code-block("peptidoms -p params.json -m mzdata.mzml -f protein_sequences.fasta -o results.cbor", "bash")

To get a readable file results, use "peptidoms-export" to produce JSON or ODS files:

#code-block("peptidoms-export --ods results.ods -i results.cbor", "bash")

#code-block("peptidoms-export --json results.json -i results.cbor", "bash")




= JSON parameter file

#peptidoms parameters are specified in a JSON file

#let code_psm = read("json/peptidoms_parameters.json")
#code-block(code_psm, "json", title: "JSON parameter file")


= CBOR peptidoms eval PSM structure

#peptidoms writes results in a PSM CBOR file.
For each PSM, #peptidoms uses the "eval" section to store its scores :

#let code_psm = read("json/peptidoms_psm_eval.json")
#code-block(code_psm, "json", title: "peptidosm PSM eval structure")



= Tests for #spoms


#code-block("./src/spoms -p ../doc/typst/json/spoms_parameters_test.json -f /gorgone/pappso/moulon/database/Genome_Z_mays_5a.fasta -m /gorgone/pappso/data_extraction_pappso/mzML/20120906_balliau_extract_1_A01_urnb-1.mzML -o /tmp/test.cbor", "bash")
#code-block("./src/spoms -p ../doc/typst/json/spoms_parameters_test.json -f /gorgone/pappso/moulon/database/Genome_Z_mays_5a.fasta -m /gorgone/pappso/data_extraction_pappso/mzcbor/20120906_balliau_extract_1_A01_urnb-1.mzcbor -o /tmp/test.cbor", "bash")

```bash
Process for spectrum index 2406 finished. Slowest one is 2287 2290
total 236
```

== Smaller dataset


#code-block("./src/spoms -p ../doc/typst/json/spoms_parameters_test.json -f ../tests/data/fasta/small_zea_mays.fasta -m ../tests/data/peaklists/peaklist_15046.mgf -o /tmp/test.cbor", "bash")



#code-block("./src/spoms -p ../tests/data/parameters/DATNVGDEGGFAPNIIENK_parameters.json -f ../tests/data/fasta/databankThreeProteinsHuman.fasta -m ../tests/data/peaklists/DATNVGDEGGFAPNIIENK.mgf -o DATNVGDEGGFAPNIIENK.cbor -c 10", "bash")



= Tests for #peptidoms


#code-block("./src/peptidoms -p ../doc/typst/json/peptidoms_parameters.json -f /gorgone/pappso/moulon/database/Genome_Z_mays_5a.fasta -m /gorgone/pappso/data_extraction_pappso/mzML/20120906_balliau_extract_1_A01_urnb-1.mzML -o /tmp/test.cbor", "bash")


== Smaller dataset


#code-block("./src/peptidoms -p ../doc/typst/json/peptidoms_parameters.json -f ../tests/data/fasta/small_zea_mays.fasta -m ../tests/data/peaklists/peaklist_15046.mgf -o /tmp/test.cbor", "bash")



#code-block("./src/peptidoms -p ../tests/data/parameters/DATNVGDEGGFAPNIIENK_parameters.json -f ../tests/data/fasta/databankThreeProteinsHuman.fasta -m ../tests/data/peaklists/DATNVGDEGGFAPNIIENK.mgf -o DATNVGDEGGFAPNIIENK.cbor -c 10", "bash")



= Tests for #protein-matcher


#code-block("./src/proteinmatcher -p ../doc/typst/json/proteinmatcher_parameters.json -f /gorgone/pappso/moulon/database/Genome_Z_mays_5a.fasta -m /gorgone/pappso/data_extraction_pappso/mzML/20120906_balliau_extract_1_A01_urnb-1.mzML -o /tmp/test.cbor", "bash")


good match "index": 2605,    "native_id": "controllerType=0 controllerNumber=1 scan=2606"
"proforma":"MESGTGNGDSEVQR",

TPVDNALR on index 4503 should be a good match

QQVM[MOD:00425]VGYSDSGK on index 4291

    "accession": "GRMZM2G326111_P01",
    "positions": [
"eval":{
    "matcher": {
        "score": 107855
    },
    "peptidoms": {
        "bracket": "[G][N]GTGGESIYGEK",
        "nam": 0,
        "score": 69,
        "spc": 11
    }
}

== Smaller dataset


#code-block("./src/proteinmatcher -p ../doc/typst/json/proteinmatcher_parameters.json -f ../tests/data/fasta/small_zea_mays.fasta -m ../tests/data/peaklists/peaklist_15046.mgf -o /tmp/test.cbor", "bash")



== C++ vs Java issue

Some important issue remains in the C++ version.

For example on a small Zea mays database (tests/data/fasta/small_ze_mays.fasta) and a single spectra (test/data/peaklists/peaklist_15046.mgf), the java version can successfully identify AIADGSLLDLLR from GRMZM2G083841_P01


#let complete_psm = json("json_data/pepa1a3_20120906_balliau_extract_1_A01_urnb-1_15045.json")
#ms2spectra-plot(width: 15cm, height: 7cm, title: "AIADGSLLDLLR", spectra: complete_psm.spectra, ion-series: complete_psm.ion-series)

JAVA results :
```tsv
spectrum title;spectrum scan;spectrum id;peptide;protein positions;alignment;score;number of shared peaks;post-processed non-aligned mass;post-processed peptide;post-processed protein positions;post-processed alignment;post-processed score;post-processed number of common peaks
Elution from: 0.03 to 0.03   period: 0   experiment: 1 cycles:  1 AIADGSLLDLLR GRMZM2G083841_P01;-1;0;AIADGSLLDLLR;[429,440];[A][I]ADGSLLDLLR;76;14;;;;;;;
Elution from: 0.03 to 0.03   period: 0   experiment: 1 cycles:  1 AIADGSLLDLLR GRMZM2G083841_P01;-1;0;GSSEALIR;[188,195];[182,11]GSSEAL[242,13]IR;44;11;;;;;;;
```

#let json_cpp = read("json_data/json_cpp_results_15046.json")
#code-block(json_cpp, "json", title: "C++ results")


= Close look on AIADGSLLDLLR


#let complete_psm = json("json_data/pepa1a3_20120906_balliau_extract_1_A01_urnb-1_15045.json")
#let delta_psm = json("json_data/pepa1a3_20120906_balliau_extract_1_A01_urnb-1_15045-aapos.json")
#ms2spectra-plot(width: 15cm, height: 7cm, title: "AIADGSLLDLLR", spectra: complete_psm.spectra, delta: delta_psm.delta)



= Benchmark specpetidoms vs spoms fast alignment

2026-02-20

/tests/data/fasta/very_small_zea_mays.fasta

```bash
langella@milano:~/developpement/git/peptidoms/specpeptidoms/build$ ./tests/benchmark/catch2-benchmark-tests [specpeptidoms] -s --benchmark-samples 1
Filters: [specpeptidoms]
Randomness seeded to: 226359403
/home/langella/developpement/git/peptidoms/specpeptidoms/tests/common.cpp readMgf 58 1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
catch2-benchmark-tests is a Catch2 v3.7.1 host application.
Run with -? for options

-------------------------------------------------------------------------------
cbor psm map test suite.
  ..:: PSM cbor features::..
-------------------------------------------------------------------------------
/home/langella/developpement/git/peptidoms/specpeptidoms/tests/benchmark/benchmark_alignment.cpp:80
...............................................................................

benchmark name                       samples       iterations    est run time
                                     mean          low mean      high mean
                                     std dev       low std dev   high std dev
-------------------------------------------------------------------------------
fastAlign on all protein                         1             1     6.03099 s
                                         15.7746 s     15.7746 s     15.7746 s
                                              0 ns          0 ns          0 ns


/home/langella/developpement/git/peptidoms/specpeptidoms/tests/benchmark/benchmark_alignment.cpp:153: PASSED:
  REQUIRE( locations.size() == 5 )
with expansion:
  5 == 5

benchmark name                       samples       iterations    est run time
                                     mean          low mean      high mean
                                     std dev       low std dev   high std dev
-------------------------------------------------------------------------------
locations                                        1             1     3.46423 s
                                         3.46705 s     3.46705 s     3.46705 s
                                              0 ns          0 ns          0 ns


===============================================================================
All tests passed (1 assertion in 1 test case)
```

```bash
langella@milano:~/developpement/git/peptidoms/specpeptidoms/build$ ./tests/benchmark/catch2-benchmark-tests [spoms] -s --benchmark-samples 1
Filters: [spoms]
Randomness seeded to: 3013200688
/home/langella/developpement/git/peptidoms/specpeptidoms/tests/common.cpp readMgf 58 1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
catch2-benchmark-tests is a Catch2 v3.7.1 host application.
Run with -? for options

-------------------------------------------------------------------------------
cbor psm map test suite.
  ..:: PSM cbor features::..
-------------------------------------------------------------------------------
/home/langella/developpement/git/peptidoms/specpeptidoms/tests/benchmark/benchmark_alignment_ng.cpp:84
...............................................................................

benchmark name                       samples       iterations    est run time
                                     mean          low mean      high mean
                                     std dev       low std dev   high std dev
-------------------------------------------------------------------------------
fastAlign on all protein                         1             1    18.1479 ms
                                        17.2535 ms    17.2535 ms    17.2535 ms
                                              0 ns          0 ns          0 ns


===============================================================================
test cases: 1 | 1 passed
assertions: - none -
```

= debug #spoms

```bash
langella@piccolo:~/developpement/git/peptidoms/specpeptidoms/build$ ./src/spoms -p ../doc/typst/json/spoms_parameters_test.json -f /gorgone/pappso/moulon/database/Genome_Z_mays_5a.fasta -m /gorgone/pappso/data_extraction_pappso/mzML/20120906_balliau_extract_1_A01_urnb-1.mzML -o /tmp/test.cbor
...
unknown@0, unknown(): start spectrum index: 504    accession: "GRMZM2G466358_P01"
Erreur de segmentation
```

#bibliography(style:"frontiers", "bibliography.bib")
