pymzcbor 0.0.2__py3-none-any.whl
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.
- pymzcbor/__init__.py +6 -0
- pymzcbor/cli/__init__.py +3 -0
- pymzcbor/cli/mz2scan.py +101 -0
- pymzcbor/cli/mzcbor2scan.py +101 -0
- pymzcbor/cli/mzcbortic.py +65 -0
- pymzcbor/cli/mzmltic.py +91 -0
- pymzcbor/data/typst/scan_report.typ +119 -0
- pymzcbor/data/typst/tic.typ +19 -0
- pymzcbor/enums.py +52 -0
- pymzcbor/harvestmzcbor.py +110 -0
- pymzcbor/model/__init__.py +5 -0
- pymzcbor/model/mzcvparam.py +43 -0
- pymzcbor/model/mzcvparamlist.py +37 -0
- pymzcbor/model/mzprecursor.py +46 -0
- pymzcbor/model/mzscan.py +26 -0
- pymzcbor/model/mzscanlist.py +33 -0
- pymzcbor/model/mzselectedion.py +58 -0
- pymzcbor/model/mzspectrum.py +245 -0
- pymzcbor/mzcborindex.py +124 -0
- pymzcbor/mzcborreader.py +83 -0
- pymzcbor/mzml/__init__.py +0 -0
- pymzcbor/mzml/mz_reader.py +104 -0
- pymzcbor/mzml/mzmlparser.py +147 -0
- pymzcbor/mzreaderbase.py +48 -0
- pymzcbor-0.0.2.dist-info/METADATA +18 -0
- pymzcbor-0.0.2.dist-info/RECORD +29 -0
- pymzcbor-0.0.2.dist-info/WHEEL +5 -0
- pymzcbor-0.0.2.dist-info/licenses/LICENSE +232 -0
- pymzcbor-0.0.2.dist-info/top_level.txt +1 -0
pymzcbor/__init__.py
ADDED
pymzcbor/cli/__init__.py
ADDED
pymzcbor/cli/mz2scan.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import json as json_ns
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
import importlib_resources as resources
|
|
7
|
+
import typst
|
|
8
|
+
|
|
9
|
+
from pymzcbor import MzReader
|
|
10
|
+
from pymzcbor.model.mzspectrum import MzSpectrum
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_typst_cmd():
|
|
14
|
+
ref = resources.files("pymzcbor") / "data/typst/scan_report.typ"
|
|
15
|
+
return ref.read_text(encoding="utf-8")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.command()
|
|
19
|
+
@click.argument("input", nargs=1)
|
|
20
|
+
@click.option(
|
|
21
|
+
"--index",
|
|
22
|
+
prompt="list of scan index to extract",
|
|
23
|
+
help="list of scan index to extract.",
|
|
24
|
+
)
|
|
25
|
+
@click.option("--json", help="The JSON file containing scans.")
|
|
26
|
+
@click.option("--mgf", help="The MGF file containing scans.")
|
|
27
|
+
@click.option(
|
|
28
|
+
"--pdf",
|
|
29
|
+
help="The PDF output to display scans.",
|
|
30
|
+
default="scans.pdf",
|
|
31
|
+
)
|
|
32
|
+
def mzcbor2scan(input, index, json, pdf, mgf):
|
|
33
|
+
"""MassChroQ CBOR data file extractor to JSON."""
|
|
34
|
+
|
|
35
|
+
scan_json = []
|
|
36
|
+
index_num_list = []
|
|
37
|
+
precursor_scan_json = {}
|
|
38
|
+
|
|
39
|
+
for str_num in index.split():
|
|
40
|
+
index_num_list.append(int(str_num))
|
|
41
|
+
mz_reader = MzReader(input)
|
|
42
|
+
|
|
43
|
+
mgf_data_file = None
|
|
44
|
+
|
|
45
|
+
if mgf is not None:
|
|
46
|
+
# print(json_string)
|
|
47
|
+
print("write MGF output file : ", mgf)
|
|
48
|
+
mgf_data_file = open(mgf, "w")
|
|
49
|
+
|
|
50
|
+
for spectrum_index in index_num_list:
|
|
51
|
+
mz_spectrum = mz_reader.get_mz_spectrum_by_index(0, spectrum_index)
|
|
52
|
+
if mz_spectrum is not None:
|
|
53
|
+
if mgf_data_file is not None:
|
|
54
|
+
mgf_data_file.write(mz_spectrum.to_mgf())
|
|
55
|
+
scan_json.append(mz_spectrum.to_dict())
|
|
56
|
+
precursor_list = mz_spectrum.get_precursor_list()
|
|
57
|
+
if precursor_list is not None:
|
|
58
|
+
for precursor_mz in precursor_list:
|
|
59
|
+
precursor_id = precursor_mz.spectrum_ref
|
|
60
|
+
precursor_spectrum = mz_reader.get_mz_spectrum_by_native_id(
|
|
61
|
+
0, precursor_id
|
|
62
|
+
)
|
|
63
|
+
if precursor_spectrum is not None:
|
|
64
|
+
precursor_scan_json[precursor_id] = precursor_spectrum.to_dict()
|
|
65
|
+
|
|
66
|
+
if mgf_data_file is not None:
|
|
67
|
+
mgf_data_file.close()
|
|
68
|
+
|
|
69
|
+
json_string = json_ns.dumps(
|
|
70
|
+
{"precursor_spectrum_map": precursor_scan_json, "scan_list": scan_json},
|
|
71
|
+
indent=4,
|
|
72
|
+
)
|
|
73
|
+
if json is not None:
|
|
74
|
+
# print(json_string)
|
|
75
|
+
|
|
76
|
+
print("write json output file : ", json)
|
|
77
|
+
with open(json, "w") as json_data_file:
|
|
78
|
+
json_data_file.write(json_string)
|
|
79
|
+
json_data_file.close()
|
|
80
|
+
else:
|
|
81
|
+
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
82
|
+
print("created temporary directory", tmpdirname)
|
|
83
|
+
with open(
|
|
84
|
+
os.path.join(tmpdirname, "scan_data.json"), "w"
|
|
85
|
+
) as json_data_file:
|
|
86
|
+
json_data_file.write(json_string)
|
|
87
|
+
json_data_file.close()
|
|
88
|
+
with open(
|
|
89
|
+
os.path.join(tmpdirname, "scan_report.typ"), "w"
|
|
90
|
+
) as align_typ_file:
|
|
91
|
+
print("write pdf output file : ", pdf)
|
|
92
|
+
align_typ_file.write(get_typst_cmd())
|
|
93
|
+
align_typ_file.close()
|
|
94
|
+
typst.compile(
|
|
95
|
+
os.path.join(tmpdirname, "scan_report.typ"),
|
|
96
|
+
output=pdf,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
mzcbor2scan()
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import json as json_ns
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
import importlib_resources as resources
|
|
7
|
+
import typst
|
|
8
|
+
|
|
9
|
+
from pymzcbor import MzReader
|
|
10
|
+
from pymzcbor.model.mzspectrum import MzSpectrum
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_typst_cmd():
|
|
14
|
+
ref = resources.files("pymzcbor") / "data/typst/scan_report.typ"
|
|
15
|
+
return ref.read_text(encoding="utf-8")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.command()
|
|
19
|
+
@click.argument("input", nargs=1)
|
|
20
|
+
@click.option(
|
|
21
|
+
"--index",
|
|
22
|
+
prompt="list of scan index to extract",
|
|
23
|
+
help="list of scan index to extract.",
|
|
24
|
+
)
|
|
25
|
+
@click.option("--json", help="The JSON file containing scans.")
|
|
26
|
+
@click.option("--mgf", help="The MGF file containing scans.")
|
|
27
|
+
@click.option(
|
|
28
|
+
"--pdf",
|
|
29
|
+
help="The PDF output to display scans.",
|
|
30
|
+
default="scans.pdf",
|
|
31
|
+
)
|
|
32
|
+
def mzcbor2scan(input, index, json, pdf, mgf):
|
|
33
|
+
"""MassChroQ CBOR data file extractor to JSON."""
|
|
34
|
+
|
|
35
|
+
scan_json = []
|
|
36
|
+
index_num_list = []
|
|
37
|
+
precursor_scan_json = {}
|
|
38
|
+
|
|
39
|
+
for str_num in index.split():
|
|
40
|
+
index_num_list.append(int(str_num))
|
|
41
|
+
mz_reader = MzReader(input)
|
|
42
|
+
|
|
43
|
+
mgf_data_file = None
|
|
44
|
+
|
|
45
|
+
if mgf is not None:
|
|
46
|
+
# print(json_string)
|
|
47
|
+
print("write MGF output file : ", mgf)
|
|
48
|
+
mgf_data_file = open(mgf, "w")
|
|
49
|
+
|
|
50
|
+
for spectrum_index in index_num_list:
|
|
51
|
+
mz_spectrum = mz_reader.get_mz_spectrum_by_index(0, spectrum_index)
|
|
52
|
+
if mz_spectrum is not None:
|
|
53
|
+
if mgf_data_file is not None:
|
|
54
|
+
mgf_data_file.write(mz_spectrum.to_mgf())
|
|
55
|
+
scan_json.append(mz_spectrum.to_dict())
|
|
56
|
+
precursor_list = mz_spectrum.get_precursor_list()
|
|
57
|
+
if precursor_list is not None:
|
|
58
|
+
for precursor_mz in precursor_list:
|
|
59
|
+
precursor_id = precursor_mz.spectrum_ref
|
|
60
|
+
precursor_spectrum = mz_reader.get_mz_spectrum_by_native_id(
|
|
61
|
+
0, precursor_id
|
|
62
|
+
)
|
|
63
|
+
if precursor_spectrum is not None:
|
|
64
|
+
precursor_scan_json[precursor_id] = precursor_spectrum.to_dict()
|
|
65
|
+
|
|
66
|
+
if mgf_data_file is not None:
|
|
67
|
+
mgf_data_file.close()
|
|
68
|
+
|
|
69
|
+
json_string = json_ns.dumps(
|
|
70
|
+
{"precursor_spectrum_map": precursor_scan_json, "scan_list": scan_json},
|
|
71
|
+
indent=4,
|
|
72
|
+
)
|
|
73
|
+
if json is not None:
|
|
74
|
+
# print(json_string)
|
|
75
|
+
|
|
76
|
+
print("write json output file : ", json)
|
|
77
|
+
with open(json, "w") as json_data_file:
|
|
78
|
+
json_data_file.write(json_string)
|
|
79
|
+
json_data_file.close()
|
|
80
|
+
else:
|
|
81
|
+
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
82
|
+
print("created temporary directory", tmpdirname)
|
|
83
|
+
with open(
|
|
84
|
+
os.path.join(tmpdirname, "scan_data.json"), "w"
|
|
85
|
+
) as json_data_file:
|
|
86
|
+
json_data_file.write(json_string)
|
|
87
|
+
json_data_file.close()
|
|
88
|
+
with open(
|
|
89
|
+
os.path.join(tmpdirname, "scan_report.typ"), "w"
|
|
90
|
+
) as align_typ_file:
|
|
91
|
+
print("write pdf output file : ", pdf)
|
|
92
|
+
align_typ_file.write(get_typst_cmd())
|
|
93
|
+
align_typ_file.close()
|
|
94
|
+
typst.compile(
|
|
95
|
+
os.path.join(tmpdirname, "scan_report.typ"),
|
|
96
|
+
output=pdf,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
mzcbor2scan()
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import json as json_ns
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
import importlib_resources as resources
|
|
7
|
+
import typst
|
|
8
|
+
|
|
9
|
+
from pymzcbor import MzCborReader
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_typst_cmd():
|
|
13
|
+
ref = resources.files("pymzcbor") / "data/typst/tic.typ"
|
|
14
|
+
return ref.read_text(encoding="utf-8")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@click.command()
|
|
18
|
+
@click.argument("input", nargs=1)
|
|
19
|
+
@click.option(
|
|
20
|
+
"--pdf",
|
|
21
|
+
help="The PDF output to display total ion count chromatogram.",
|
|
22
|
+
default="tic.pdf",
|
|
23
|
+
)
|
|
24
|
+
def mzcbortic(input, pdf):
|
|
25
|
+
"""MassChroQ CBOR data file extractor to JSON."""
|
|
26
|
+
|
|
27
|
+
mz_reader = MzCborReader(input)
|
|
28
|
+
|
|
29
|
+
tic_dict = mz_reader.mzcbor_index.get_tic_chromatogram(0)
|
|
30
|
+
|
|
31
|
+
source_file_list = mz_reader.get_source_file_list()
|
|
32
|
+
title = "Total Ion Count"
|
|
33
|
+
if len(source_file_list) > 0:
|
|
34
|
+
title = source_file_list[0].get("name")
|
|
35
|
+
|
|
36
|
+
json_string = json_ns.dumps(
|
|
37
|
+
{
|
|
38
|
+
"title": title,
|
|
39
|
+
"tic": tic_dict,
|
|
40
|
+
"rt_units": "minutes",
|
|
41
|
+
"scan_count": {
|
|
42
|
+
"MS1": mz_reader.mzcbor_index.count_msn_in_run(0, 1),
|
|
43
|
+
"MS2": mz_reader.mzcbor_index.count_msn_in_run(0, 2),
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
indent=4,
|
|
47
|
+
)
|
|
48
|
+
if tic_dict is not None:
|
|
49
|
+
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
50
|
+
print("created temporary directory", tmpdirname)
|
|
51
|
+
with open(os.path.join(tmpdirname, "tic.json"), "w") as json_data_file:
|
|
52
|
+
json_data_file.write(json_string)
|
|
53
|
+
json_data_file.close()
|
|
54
|
+
with open(os.path.join(tmpdirname, "tic.typ"), "w") as tic_file:
|
|
55
|
+
print("write pdf output file : ", pdf)
|
|
56
|
+
tic_file.write(get_typst_cmd())
|
|
57
|
+
tic_file.close()
|
|
58
|
+
typst.compile(
|
|
59
|
+
os.path.join(tmpdirname, "tic.typ"),
|
|
60
|
+
output=pdf,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
mzcbortic()
|
pymzcbor/cli/mzmltic.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import json as json_ns
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
import xml.etree.ElementTree as ET
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
import importlib_resources as resources
|
|
8
|
+
import typst
|
|
9
|
+
from pyteomics import mzml
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_typst_cmd():
|
|
13
|
+
ref = resources.files("pymzcbor") / "data/typst/tic.typ"
|
|
14
|
+
return ref.read_text(encoding="utf-8")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_retention_time_in_second(spectrum: dict) -> float:
|
|
18
|
+
# <cvParam cvRef="MS" accession="MS:1000016" value="0.0048758833" name="scan start time" unitAccession="UO:0000031" unitName="minute" unitCvRef="UO" />
|
|
19
|
+
start_time = spectrum["scanList"]["scan"][0]["scan start time"]
|
|
20
|
+
if start_time.unit_info == "second":
|
|
21
|
+
return start_time
|
|
22
|
+
if start_time.unit_info == "minute":
|
|
23
|
+
return start_time * 60
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_mzml_sample_name(input: str) -> str:
|
|
27
|
+
try:
|
|
28
|
+
context = ET.iterparse(input, events=("start", "end"))
|
|
29
|
+
for event, elem in context:
|
|
30
|
+
# print(elem.tag)
|
|
31
|
+
if event == "start" and elem.tag.endswith("}sourceFile"):
|
|
32
|
+
return elem.attrib["name"]
|
|
33
|
+
return ""
|
|
34
|
+
except:
|
|
35
|
+
return ""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@click.command()
|
|
39
|
+
@click.argument("input", nargs=1)
|
|
40
|
+
@click.option(
|
|
41
|
+
"--pdf",
|
|
42
|
+
help="The PDF output to display total ion count chromatogram.",
|
|
43
|
+
default="tic.pdf",
|
|
44
|
+
)
|
|
45
|
+
def mzmltic(input, pdf):
|
|
46
|
+
"""MassChroQ CBOR data file extractor to JSON.
|
|
47
|
+
reading mzML using pyteomics"""
|
|
48
|
+
|
|
49
|
+
title = get_mzml_sample_name(input)
|
|
50
|
+
# print(title)
|
|
51
|
+
tic_dict = {"x": [], "y": []}
|
|
52
|
+
ms1_count = 0
|
|
53
|
+
ms2_count = 0
|
|
54
|
+
with mzml.read(input) as reader:
|
|
55
|
+
for chromatogram in reader:
|
|
56
|
+
if chromatogram["ms level"] == 1:
|
|
57
|
+
ms1_count += 1
|
|
58
|
+
tic_dict["y"].append(chromatogram["total ion current"])
|
|
59
|
+
tic_dict["x"].append(get_retention_time_in_second(chromatogram))
|
|
60
|
+
elif chromatogram["ms level"] == 2:
|
|
61
|
+
ms2_count += 1
|
|
62
|
+
|
|
63
|
+
json_string = json_ns.dumps(
|
|
64
|
+
{
|
|
65
|
+
"title": title,
|
|
66
|
+
"tic": tic_dict,
|
|
67
|
+
"scan_count": {
|
|
68
|
+
"MS1": ms1_count,
|
|
69
|
+
"MS2": ms2_count,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
indent=4,
|
|
73
|
+
)
|
|
74
|
+
if tic_dict is not None:
|
|
75
|
+
with tempfile.TemporaryDirectory() as tmpdirname:
|
|
76
|
+
print("created temporary directory", tmpdirname)
|
|
77
|
+
with open(os.path.join(tmpdirname, "tic.json"), "w") as json_data_file:
|
|
78
|
+
json_data_file.write(json_string)
|
|
79
|
+
json_data_file.close()
|
|
80
|
+
with open(os.path.join(tmpdirname, "tic.typ"), "w") as tic_file:
|
|
81
|
+
print("write pdf output file : ", pdf)
|
|
82
|
+
tic_file.write(get_typst_cmd())
|
|
83
|
+
tic_file.close()
|
|
84
|
+
typst.compile(
|
|
85
|
+
os.path.join(tmpdirname, "tic.typ"),
|
|
86
|
+
output=pdf,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if __name__ == "__main__":
|
|
91
|
+
mzmltic()
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#import "@preview/proteograph:0.2.2": *
|
|
2
|
+
|
|
3
|
+
= Display spectra
|
|
4
|
+
|
|
5
|
+
#let mcq3_json = json("scan_data.json")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/// Filter to keep only m/z higher than threshold
|
|
9
|
+
/// -> object
|
|
10
|
+
#let spectra-filter-high-pass(spectra, mz-cutoff) = {
|
|
11
|
+
let spectra-zip = spectra.intensity.zip(spectra.mz)
|
|
12
|
+
let new-spectra = (mz: (), intensity: ())
|
|
13
|
+
|
|
14
|
+
for (intensity, mz) in spectra-zip {
|
|
15
|
+
if (mz > mz-cutoff) {
|
|
16
|
+
new-spectra.intensity.push(intensity)
|
|
17
|
+
new-spectra.mz.push(mz)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
(new-spectra)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/// Filter to keep only m/z lower than threshold
|
|
24
|
+
/// -> object
|
|
25
|
+
#let spectra-filter-low-pass(spectra, mz-cutoff) = {
|
|
26
|
+
let spectra-zip = spectra.intensity.zip(spectra.mz)
|
|
27
|
+
let new-spectra = (mz: (), intensity: ())
|
|
28
|
+
|
|
29
|
+
for (intensity, mz) in spectra-zip {
|
|
30
|
+
if (mz < mz-cutoff) {
|
|
31
|
+
new-spectra.intensity.push(intensity)
|
|
32
|
+
new-spectra.mz.push(mz)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
(new-spectra)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
#let find-cv-param(cv-param-list, accession) = {
|
|
40
|
+
cv-param-list.find(cv-param => {
|
|
41
|
+
if (cv-param.accession == accession) {
|
|
42
|
+
true
|
|
43
|
+
} else { false }
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#let mzcborjson-get-precursor-isolation-window(one-precursor) = {
|
|
48
|
+
(
|
|
49
|
+
"cv-target": find-cv-param(one-precursor.isolationWindow.cvParam, "MS:1000827"),
|
|
50
|
+
"cv-target-lower": find-cv-param(one-precursor.isolationWindow.cvParam, "MS:1000828"),
|
|
51
|
+
"cv-target-upper": find-cv-param(one-precursor.isolationWindow.cvParam, "MS:1000829"),
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
#let mz_spectrum2spectrum_array(mz_spectrum) = {
|
|
55
|
+
let spectra = ("mz": (), "intensity": ())
|
|
56
|
+
if (mz_spectrum.binaryDataArray.at(0).unit == "MS:1000514") {
|
|
57
|
+
spectra.mz = mz_spectrum.binaryDataArray.at(0).data
|
|
58
|
+
} else {
|
|
59
|
+
spectra.intensity = mz_spectrum.binaryDataArray.at(0).data
|
|
60
|
+
}
|
|
61
|
+
if (mz_spectrum.binaryDataArray.at(1).unit == "MS:1000515") {
|
|
62
|
+
spectra.intensity = mz_spectrum.binaryDataArray.at(1).data
|
|
63
|
+
} else {
|
|
64
|
+
spectra.mz = mz_spectrum.binaryDataArray.at(1).data
|
|
65
|
+
}
|
|
66
|
+
spectra
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#for scan in mcq3_json.scan_list {
|
|
73
|
+
//[== index=#{ scan.index } #{ scan.id }]
|
|
74
|
+
|
|
75
|
+
let precursor-list = scan.at("precursorList", default: none)
|
|
76
|
+
if (precursor-list != none) {
|
|
77
|
+
for precursor in precursor-list.precursor {
|
|
78
|
+
//print precursor isolation window
|
|
79
|
+
let window = mzcborjson-get-precursor-isolation-window(precursor)
|
|
80
|
+
let mz-low = window.cv-target.value - window.cv-target-lower.value
|
|
81
|
+
let mz-up = window.cv-target.value + window.cv-target-upper.value
|
|
82
|
+
|
|
83
|
+
let delta_arr = (
|
|
84
|
+
(
|
|
85
|
+
"ion": "y",
|
|
86
|
+
"mz": (mz-low, mz-up),
|
|
87
|
+
"level": 1,
|
|
88
|
+
"label": "selection",
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
let precursor-id = precursor.spectrumRef
|
|
93
|
+
let mz_prec_spectrum = mcq3_json.precursor_spectrum_map.at(precursor-id, default: none)
|
|
94
|
+
if (mz_prec_spectrum != none) {
|
|
95
|
+
box({
|
|
96
|
+
mzcborjson-report-spectrum-metadata(mz_prec_spectrum)
|
|
97
|
+
ms2spectra-plot(
|
|
98
|
+
width: 15cm,
|
|
99
|
+
height: 7cm,
|
|
100
|
+
spectra: spectra-filter-low-pass(
|
|
101
|
+
spectra-filter-high-pass(mz_spectrum2spectrum_array(mz_prec_spectrum), mz-low - 4),
|
|
102
|
+
mz-up + 4,
|
|
103
|
+
),
|
|
104
|
+
delta: delta_arr,
|
|
105
|
+
mz-range: (mz-low - 4, mz-up + 4),
|
|
106
|
+
)
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
box({
|
|
112
|
+
mzcborjson-report-spectrum-metadata(scan)
|
|
113
|
+
// "binaryDataArray": [
|
|
114
|
+
// {
|
|
115
|
+
// "unit": "MS:1000514",
|
|
116
|
+
// "data": [
|
|
117
|
+
ms2spectra-plot(width: 15cm, height: 7cm, spectra: mz_spectrum2spectrum_array(scan))
|
|
118
|
+
})
|
|
119
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#import "@preview/proteograph:0.2.2": *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#let tic_json = json("tic.json")
|
|
5
|
+
|
|
6
|
+
= #tic_json.title
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
#let xic0 = tic_json.tic
|
|
10
|
+
#xic0.insert("TIC", "TIC")
|
|
11
|
+
|
|
12
|
+
#xic-plot(
|
|
13
|
+
height: 10cm,
|
|
14
|
+
title: "Total Ion Count",
|
|
15
|
+
xic0,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
/ MS1 count: #tic_json.scan_count.MS1
|
|
19
|
+
/ MS2 count: #tic_json.scan_count.MS2
|
pymzcbor/enums.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# This file is part of pymzcbor.
|
|
2
|
+
#
|
|
3
|
+
# pymzcbor is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# pymzcbor is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with pymzcbor. If not, see <http://www.gnu.org/licenses/>.
|
|
15
|
+
#
|
|
16
|
+
from enum import Enum
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class MzDataArrayType(Enum):
|
|
20
|
+
mz = "MS:1000514" # "MS:1000514"
|
|
21
|
+
intensity = "MS:1000515" # "MS:1000514"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MzDataArrayBits(Enum):
|
|
25
|
+
f64 = "MS:1000523" # accession="MS:1000523" value="" name="64-bit float"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class MzCompressionLib(Enum):
|
|
29
|
+
zlib = "MS:1000574"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class MzSpectrumParam(Enum):
|
|
33
|
+
ms_level = "MS:1000511"
|
|
34
|
+
MSn_spectrum = "MS:1000580"
|
|
35
|
+
positive_scan = "MS:1000130"
|
|
36
|
+
total_ion_current = "MS:1000285"
|
|
37
|
+
centroid_spectrum = "MS:1000127"
|
|
38
|
+
base_peak_mz = "MS:1000504"
|
|
39
|
+
base_peak_intensity = "MS:1000505"
|
|
40
|
+
lowest_observed_mz = "MS:1000528"
|
|
41
|
+
highest_observed_mz = "MS:1000527"
|
|
42
|
+
scan_start_time = "MS:1000016"
|
|
43
|
+
uo_minute = "UO:0000031"
|
|
44
|
+
uo_millisecond = "UO:0000028"
|
|
45
|
+
ion_injection_time = "MS:1000927"
|
|
46
|
+
isolation_window_lower_offset = "MS:1000828"
|
|
47
|
+
isolation_window_upper_offset = "MS:1000829"
|
|
48
|
+
selected_ion_mz = "MS:1000744"
|
|
49
|
+
selected_ion_charge_state = "MS:1000041"
|
|
50
|
+
selected_ion_peak_intensity = "MS:1000042"
|
|
51
|
+
activation_collision_energy = "MS:1000045"
|
|
52
|
+
activation_beam_type_collision_induced_dissociation = "MS:1000422"
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# This file is part of pymzcbor.
|
|
2
|
+
#
|
|
3
|
+
# pymzcbor is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# pymzcbor is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with pymzcbor. If not, see <http://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
from collections.abc import Generator
|
|
17
|
+
from typing import IO
|
|
18
|
+
|
|
19
|
+
from pycborstream import CborStreamDec
|
|
20
|
+
|
|
21
|
+
from .model.mzspectrum import MzSpectrum
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class HarvestMzCbor:
|
|
25
|
+
def __init__(self, fp: IO[bytes]):
|
|
26
|
+
self._cbor_stream_decoder = CborStreamDec(fp)
|
|
27
|
+
self._cbor_stream_decoder.enter_container()
|
|
28
|
+
|
|
29
|
+
def _goto_root_tag(self, tag_name: str):
|
|
30
|
+
# mzCBOR
|
|
31
|
+
# mzML
|
|
32
|
+
# cvList
|
|
33
|
+
# fileDescription
|
|
34
|
+
# referenceableParamGroupList
|
|
35
|
+
# softwareList
|
|
36
|
+
# instrumentConfigurationList
|
|
37
|
+
# dataProcessingList
|
|
38
|
+
# run
|
|
39
|
+
while self._cbor_stream_decoder.has_next():
|
|
40
|
+
cbor_value = self._cbor_stream_decoder.value()
|
|
41
|
+
if cbor_value == tag_name:
|
|
42
|
+
return
|
|
43
|
+
print(cbor_value)
|
|
44
|
+
self._cbor_stream_decoder.next()
|
|
45
|
+
raise ValueError(f"CBOR stream does not contain {tag_name}")
|
|
46
|
+
|
|
47
|
+
def yield_spectrums(self):
|
|
48
|
+
yield from self.yield_spectrums_if(lambda scan: True)
|
|
49
|
+
|
|
50
|
+
def yield_spectrums_if(self, condition_met) -> Generator[MzSpectrum, None, None]:
|
|
51
|
+
"""mzCBOR spectrum harvester"""
|
|
52
|
+
self._goto_root_tag("run")
|
|
53
|
+
self._cbor_stream_decoder.enter_container() # enter run
|
|
54
|
+
# id
|
|
55
|
+
# defaultInstrumentConfigurationRef
|
|
56
|
+
# startTimeStamp
|
|
57
|
+
# defaultSourceFileRef
|
|
58
|
+
# spectrumList
|
|
59
|
+
self._goto_root_tag("spectrumList")
|
|
60
|
+
self._cbor_stream_decoder.enter_container() # enter spectrumList
|
|
61
|
+
# count
|
|
62
|
+
# defaultDataProcessingRef
|
|
63
|
+
self._goto_root_tag("spectrum")
|
|
64
|
+
self._cbor_stream_decoder.enter_container() # enter spectrum array
|
|
65
|
+
while self._cbor_stream_decoder.has_next():
|
|
66
|
+
spectrum = MzSpectrum(self._cbor_stream_decoder.to_dict())
|
|
67
|
+
if condition_met(spectrum):
|
|
68
|
+
yield spectrum
|
|
69
|
+
self._cbor_stream_decoder.leave_container()
|
|
70
|
+
self._cbor_stream_decoder.leave_container()
|
|
71
|
+
self._cbor_stream_decoder.leave_container()
|
|
72
|
+
|
|
73
|
+
def yield_source_file(self):
|
|
74
|
+
# <sourceFileList count="1">
|
|
75
|
+
# <sourceFile id="RAW1" name="20120906_balliau_extract_1_A01_urnb-1" location="file:///./20120906_balliau_extract_1_A01_urnb-1.raw">
|
|
76
|
+
# <cvParam cvRef="MS" accession="MS:1000768" value="" name="Thermo nativeID format" />
|
|
77
|
+
# <cvParam cvRef="MS" accession="MS:1000563" value="" name="Thermo RAW format" />
|
|
78
|
+
# <cvParam cvRef="MS" accession="MS:1000569" value="69604cb2afac8225c016af24219e66a6845b4f81" name="SHA-1" />
|
|
79
|
+
# </sourceFile>
|
|
80
|
+
#
|
|
81
|
+
self._cbor_stream_decoder.fp_seek(0)
|
|
82
|
+
self._cbor_stream_decoder.enter_container()
|
|
83
|
+
self._goto_root_tag("fileDescription")
|
|
84
|
+
self._cbor_stream_decoder.enter_container()
|
|
85
|
+
self._goto_root_tag("sourceFileList")
|
|
86
|
+
self._cbor_stream_decoder.enter_container()
|
|
87
|
+
self._goto_root_tag("sourceFile")
|
|
88
|
+
self._cbor_stream_decoder.enter_container()
|
|
89
|
+
while self._cbor_stream_decoder.has_next():
|
|
90
|
+
source_file = self._cbor_stream_decoder.to_dict()
|
|
91
|
+
yield source_file
|
|
92
|
+
self._cbor_stream_decoder.leave_container()
|
|
93
|
+
self._cbor_stream_decoder.leave_container()
|
|
94
|
+
self._cbor_stream_decoder.leave_container()
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def mz_informations(self) -> dict:
|
|
98
|
+
self._cbor_stream_decoder.fp_seek(0)
|
|
99
|
+
self._cbor_stream_decoder.enter_container()
|
|
100
|
+
self._goto_root_tag("mzCBOR")
|
|
101
|
+
self._cbor_stream_decoder.enter_container()
|
|
102
|
+
self._goto_root_tag("informations")
|
|
103
|
+
informations = self._cbor_stream_decoder.to_dict()
|
|
104
|
+
if informations is not None:
|
|
105
|
+
return informations
|
|
106
|
+
raise ValueError("mzCBOR informations not found")
|
|
107
|
+
|
|
108
|
+
def mz_spectrum(self, offset: int) -> MzSpectrum:
|
|
109
|
+
self._cbor_stream_decoder.fp_seek(offset)
|
|
110
|
+
return MzSpectrum(self._cbor_stream_decoder.to_dict())
|