imspy-simulation 0.4.0__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.
Files changed (112) hide show
  1. imspy_simulation-0.4.0/PKG-INFO +111 -0
  2. imspy_simulation-0.4.0/README.md +80 -0
  3. imspy_simulation-0.4.0/pyproject.toml +49 -0
  4. imspy_simulation-0.4.0/src/imspy_simulation/__init__.py +115 -0
  5. imspy_simulation-0.4.0/src/imspy_simulation/acquisition.py +336 -0
  6. imspy_simulation-0.4.0/src/imspy_simulation/annotation.py +422 -0
  7. imspy_simulation-0.4.0/src/imspy_simulation/builders/__init__.py +13 -0
  8. imspy_simulation-0.4.0/src/imspy_simulation/builders/dda.py +342 -0
  9. imspy_simulation-0.4.0/src/imspy_simulation/builders/dia.py +512 -0
  10. imspy_simulation-0.4.0/src/imspy_simulation/builders/factory.py +153 -0
  11. imspy_simulation-0.4.0/src/imspy_simulation/core/__init__.py +10 -0
  12. imspy_simulation-0.4.0/src/imspy_simulation/core/protocols.py +136 -0
  13. imspy_simulation-0.4.0/src/imspy_simulation/core/wrapper.py +84 -0
  14. imspy_simulation-0.4.0/src/imspy_simulation/data/__init__.py +10 -0
  15. imspy_simulation-0.4.0/src/imspy_simulation/data/database.py +280 -0
  16. imspy_simulation-0.4.0/src/imspy_simulation/data/transmission.py +146 -0
  17. imspy_simulation-0.4.0/src/imspy_simulation/experiment.py +674 -0
  18. imspy_simulation-0.4.0/src/imspy_simulation/feature.py +226 -0
  19. imspy_simulation-0.4.0/src/imspy_simulation/handle.py +99 -0
  20. imspy_simulation-0.4.0/src/imspy_simulation/isotopes.py +245 -0
  21. imspy_simulation-0.4.0/src/imspy_simulation/math_utils.py +119 -0
  22. imspy_simulation-0.4.0/src/imspy_simulation/noise.py +130 -0
  23. imspy_simulation-0.4.0/src/imspy_simulation/proteome.py +82 -0
  24. imspy_simulation-0.4.0/src/imspy_simulation/resources/NATIVE.d/analysis.tdf +0 -0
  25. imspy_simulation-0.4.0/src/imspy_simulation/resources/NATIVE.d/analysis.tdf_bin +0 -0
  26. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/dia_ms_ms_windows.csv +37 -0
  27. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/diapasef.toml +5 -0
  28. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/dilution_factors.csv +4 -0
  29. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/midia_ms_ms_windows.csv +18361 -0
  30. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/midiapasef.toml +5 -0
  31. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/slice_ms_ms_windows.csv +34 -0
  32. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/slicepasef.toml +5 -0
  33. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/synchro_ms_ms_windows.csv +3709 -0
  34. imspy_simulation-0.4.0/src/imspy_simulation/resources/configs/synchropasef.toml +5 -0
  35. imspy_simulation-0.4.0/src/imspy_simulation/resources/docs/documentation.md +472 -0
  36. imspy_simulation-0.4.0/src/imspy_simulation/resources/icons/info_icon.png +0 -0
  37. imspy_simulation-0.4.0/src/imspy_simulation/resources/icons/logo_2.png +0 -0
  38. imspy_simulation-0.4.0/src/imspy_simulation/resources/icons/rustims_logo.png +0 -0
  39. imspy_simulation-0.4.0/src/imspy_simulation/tdf.py +458 -0
  40. imspy_simulation-0.4.0/src/imspy_simulation/timsim/configs/config.toml +362 -0
  41. imspy_simulation-0.4.0/src/imspy_simulation/timsim/configs/config_dda_example.toml +66 -0
  42. imspy_simulation-0.4.0/src/imspy_simulation/timsim/configs/config_dia_example.toml +60 -0
  43. imspy_simulation-0.4.0/src/imspy_simulation/timsim/configs/config_hela_25k_nogpu.toml +140 -0
  44. imspy_simulation-0.4.0/src/imspy_simulation/timsim/configs/config_minimal.toml +26 -0
  45. imspy_simulation-0.4.0/src/imspy_simulation/timsim/configs/modifications.toml +9 -0
  46. imspy_simulation-0.4.0/src/imspy_simulation/timsim/configs/modifications_hla.toml +8 -0
  47. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/__init__.py +5 -0
  48. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/app.py +401 -0
  49. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/components/__init__.py +19 -0
  50. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/components/config_sections.py +242 -0
  51. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/components/console.py +88 -0
  52. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/components/file_inputs.py +322 -0
  53. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/components/plots.py +763 -0
  54. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/components/visualization3d.py +294 -0
  55. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/pages/__init__.py +6 -0
  56. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/pages/advanced.py +1661 -0
  57. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/pages/simple.py +310 -0
  58. imspy_simulation-0.4.0/src/imspy_simulation/timsim/gui/state.py +616 -0
  59. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/VALIDATION_README.md +383 -0
  60. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/__init__.py +60 -0
  61. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DDA-HLA.toml +193 -0
  62. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DDA-PARTIAL-FRAG-BINOM.toml +203 -0
  63. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DDA-PARTIAL-FRAG.toml +209 -0
  64. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DDA-TOPN.toml +193 -0
  65. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-HELA.toml +183 -0
  66. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-HYE-A.toml +173 -0
  67. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-HYE-B.toml +183 -0
  68. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-HYE.toml +185 -0
  69. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-PARTIAL-FRAG-BINOM.toml +193 -0
  70. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-PARTIAL-FRAG.toml +199 -0
  71. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-PHOS-A.toml +162 -0
  72. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-PHOS-B.toml +163 -0
  73. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/IT-DIA-PHOS.toml +184 -0
  74. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/dilution_factors_hye.csv +4 -0
  75. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/dilution_factors_hye_A.csv +4 -0
  76. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/configs/dilution_factors_hye_B.csv +4 -0
  77. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/eval.py +1394 -0
  78. imspy_simulation-0.4.0/src/imspy_simulation/timsim/integration/sim.py +468 -0
  79. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/__init__.py +0 -0
  80. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/add_noise_from_real_data.py +125 -0
  81. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/assemble_frames.py +206 -0
  82. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/build_acquisition.py +93 -0
  83. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/dda_selection_scheme.py +318 -0
  84. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/digest_fasta.py +117 -0
  85. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_charge_states.py +66 -0
  86. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_fragment_intensities.py +562 -0
  87. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_frame_distributions_emg.py +337 -0
  88. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_ion_mobilities.py +46 -0
  89. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_ion_mobilities_and_variance.py +197 -0
  90. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_occurrences.py +44 -0
  91. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_peptides.py +210 -0
  92. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_phosphorylation.py +93 -0
  93. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_precursor_spectra.py +61 -0
  94. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_proteins.py +291 -0
  95. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_retention_time.py +73 -0
  96. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/simulate_scan_distributions_with_variance.py +91 -0
  97. imspy_simulation-0.4.0/src/imspy_simulation/timsim/jobs/utility.py +96 -0
  98. imspy_simulation-0.4.0/src/imspy_simulation/timsim/simulator.py +1277 -0
  99. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/__init__.py +55 -0
  100. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/cli.py +667 -0
  101. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/comparison.py +598 -0
  102. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/diann_executor.py +369 -0
  103. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/fragpipe_executor.py +543 -0
  104. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/html_report.py +1408 -0
  105. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/metrics.py +228 -0
  106. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/parsing.py +532 -0
  107. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/plots.py +1453 -0
  108. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/report.py +263 -0
  109. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/runner.py +737 -0
  110. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/sage_executor.py +311 -0
  111. imspy_simulation-0.4.0/src/imspy_simulation/timsim/validate/tool_comparison.py +2056 -0
  112. imspy_simulation-0.4.0/src/imspy_simulation/utility.py +611 -0
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.4
2
+ Name: imspy-simulation
3
+ Version: 0.4.0
4
+ Summary: TimsTOF data simulation tools for proteomics.
5
+ License-Expression: MIT
6
+ Author: theGreatHerrLebert
7
+ Author-email: davidteschner@googlemail.com
8
+ Requires-Python: >=3.11,<3.14
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Provides-Extra: gui
14
+ Provides-Extra: search
15
+ Requires-Dist: imspy-core (>=0.4.0)
16
+ Requires-Dist: imspy-predictors[koina] (>=0.4.0)
17
+ Requires-Dist: imspy-search (>=0.4.0) ; extra == "search"
18
+ Requires-Dist: markdown (>=3.5) ; extra == "gui"
19
+ Requires-Dist: matplotlib (>=3.5)
20
+ Requires-Dist: nicegui (>=1.4.0) ; extra == "gui"
21
+ Requires-Dist: numba (>=0.53)
22
+ Requires-Dist: numpy (>=1.24)
23
+ Requires-Dist: pandas (>=2.0)
24
+ Requires-Dist: qdarkstyle (>=3.0) ; extra == "gui"
25
+ Requires-Dist: scipy (>=1.7.1)
26
+ Requires-Dist: toml (>=0.10)
27
+ Requires-Dist: tqdm (>=4.66)
28
+ Requires-Dist: zstd (>=1.5)
29
+ Description-Content-Type: text/markdown
30
+
31
+ # imspy-simulation
32
+
33
+ TimsTOF data simulation tools for proteomics.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install imspy-simulation
39
+ ```
40
+
41
+ For search integration (validation workflows):
42
+
43
+ ```bash
44
+ pip install imspy-simulation[search]
45
+ ```
46
+
47
+ ## Features
48
+
49
+ - **Frame Builders**: DIA and DDA frame simulation with annotation support
50
+ - **TimSim**: Complete simulation pipeline for synthetic timsTOF data
51
+ - **Validation**: Tools for validating simulated data against search results
52
+ - **Isotope Simulation**: Accurate isotope distribution generation
53
+ - **TDF Writing**: Write simulated data to Bruker TDF format
54
+
55
+ ## Quick Start
56
+
57
+ ```python
58
+ from imspy_simulation import (
59
+ DIAFrameBuilder,
60
+ DDAFrameBuilder,
61
+ SimulationDatabase,
62
+ TransmissionHandle,
63
+ create_frame_builder,
64
+ AcquisitionMode,
65
+ )
66
+
67
+ # Create a DIA frame builder
68
+ frame_builder = DIAFrameBuilder(
69
+ database_path="path/to/synthetic_data.db",
70
+ num_threads=16,
71
+ )
72
+
73
+ # Build frames
74
+ frames = frame_builder.build_frames([1, 2, 3])
75
+ ```
76
+
77
+ ## CLI Tools
78
+
79
+ ### timsim
80
+ Full simulation pipeline:
81
+ ```bash
82
+ timsim --config config.toml --output /path/to/output
83
+ ```
84
+
85
+ ## Submodules
86
+
87
+ - **builders/**: Frame builder implementations (DIA, DDA)
88
+ - **core/**: Core protocols and wrappers
89
+ - **data/**: Simulation database and transmission handling
90
+ - **timsim/**: TimSim simulation pipeline
91
+ - **jobs/**: Individual simulation steps
92
+ - **integration/**: Integration workflows
93
+ - **validate/**: Validation tools
94
+
95
+ ## Dependencies
96
+
97
+ - **imspy-core**: Core data structures (required)
98
+ - **imspy-predictors**: ML predictors for CCS, RT, intensity (required)
99
+ - **imspy-search**: Database search for validation (optional)
100
+
101
+ ## Related Packages
102
+
103
+ - **imspy-core**: Core data structures and timsTOF readers
104
+ - **imspy-predictors**: ML-based predictors
105
+ - **imspy-search**: Database search functionality
106
+ - **imspy-vis**: Visualization tools
107
+
108
+ ## License
109
+
110
+ MIT License - see LICENSE file for details.
111
+
@@ -0,0 +1,80 @@
1
+ # imspy-simulation
2
+
3
+ TimsTOF data simulation tools for proteomics.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install imspy-simulation
9
+ ```
10
+
11
+ For search integration (validation workflows):
12
+
13
+ ```bash
14
+ pip install imspy-simulation[search]
15
+ ```
16
+
17
+ ## Features
18
+
19
+ - **Frame Builders**: DIA and DDA frame simulation with annotation support
20
+ - **TimSim**: Complete simulation pipeline for synthetic timsTOF data
21
+ - **Validation**: Tools for validating simulated data against search results
22
+ - **Isotope Simulation**: Accurate isotope distribution generation
23
+ - **TDF Writing**: Write simulated data to Bruker TDF format
24
+
25
+ ## Quick Start
26
+
27
+ ```python
28
+ from imspy_simulation import (
29
+ DIAFrameBuilder,
30
+ DDAFrameBuilder,
31
+ SimulationDatabase,
32
+ TransmissionHandle,
33
+ create_frame_builder,
34
+ AcquisitionMode,
35
+ )
36
+
37
+ # Create a DIA frame builder
38
+ frame_builder = DIAFrameBuilder(
39
+ database_path="path/to/synthetic_data.db",
40
+ num_threads=16,
41
+ )
42
+
43
+ # Build frames
44
+ frames = frame_builder.build_frames([1, 2, 3])
45
+ ```
46
+
47
+ ## CLI Tools
48
+
49
+ ### timsim
50
+ Full simulation pipeline:
51
+ ```bash
52
+ timsim --config config.toml --output /path/to/output
53
+ ```
54
+
55
+ ## Submodules
56
+
57
+ - **builders/**: Frame builder implementations (DIA, DDA)
58
+ - **core/**: Core protocols and wrappers
59
+ - **data/**: Simulation database and transmission handling
60
+ - **timsim/**: TimSim simulation pipeline
61
+ - **jobs/**: Individual simulation steps
62
+ - **integration/**: Integration workflows
63
+ - **validate/**: Validation tools
64
+
65
+ ## Dependencies
66
+
67
+ - **imspy-core**: Core data structures (required)
68
+ - **imspy-predictors**: ML predictors for CCS, RT, intensity (required)
69
+ - **imspy-search**: Database search for validation (optional)
70
+
71
+ ## Related Packages
72
+
73
+ - **imspy-core**: Core data structures and timsTOF readers
74
+ - **imspy-predictors**: ML-based predictors
75
+ - **imspy-search**: Database search functionality
76
+ - **imspy-vis**: Visualization tools
77
+
78
+ ## License
79
+
80
+ MIT License - see LICENSE file for details.
@@ -0,0 +1,49 @@
1
+ [project]
2
+ name = "imspy-simulation"
3
+ version = "0.4.0"
4
+ description = "TimsTOF data simulation tools for proteomics."
5
+ authors = [
6
+ { name = "theGreatHerrLebert", email = "davidteschner@googlemail.com" }
7
+ ]
8
+ readme = "README.md"
9
+ license = "MIT"
10
+ requires-python = ">=3.11,<3.14"
11
+
12
+ dependencies = [
13
+ "imspy-core>=0.4.0",
14
+ "imspy-predictors[koina]>=0.4.0", # Include Koina support for intensity prediction
15
+ "pandas>=2.0",
16
+ "numpy>=1.24",
17
+ "numba>=0.53",
18
+ "scipy>=1.7.1",
19
+ "toml>=0.10",
20
+ "tqdm>=4.66",
21
+ "zstd>=1.5",
22
+ "matplotlib>=3.5",
23
+ ]
24
+
25
+ [project.optional-dependencies]
26
+ search = ["imspy-search>=0.4.0"]
27
+ gui = [
28
+ "nicegui>=1.4.0",
29
+ "qdarkstyle>=3.0",
30
+ "markdown>=3.5",
31
+ ]
32
+
33
+ [project.scripts]
34
+ timsim = "imspy_simulation.timsim.simulator:main"
35
+ timsim-gui = "imspy_simulation.timsim.gui:main"
36
+
37
+ [build-system]
38
+ requires = ["poetry-core"]
39
+ build-backend = "poetry.core.masonry.api"
40
+
41
+ [tool.poetry.group.dev.dependencies]
42
+ pytest = "^8.0.0"
43
+ pytest-cov = "^4.1.0"
44
+
45
+ [tool.pytest.ini_options]
46
+ testpaths = ["tests"]
47
+ python_files = ["test_*.py"]
48
+ python_functions = ["test_*"]
49
+ addopts = "-v --tb=short"
@@ -0,0 +1,115 @@
1
+ """
2
+ imspy_simulation - TimsTOF data simulation tools for proteomics.
3
+
4
+ This package provides tools for simulating timsTOF mass spectrometry data,
5
+ including peptide ionization, quadrupole transmission, and frame building.
6
+
7
+ New API (recommended):
8
+ - builders.create_frame_builder: Factory for creating frame builders
9
+ - builders.DIAFrameBuilder: Unified DIA frame builder
10
+ - builders.DDAFrameBuilder: DDA frame builder
11
+ - data.SimulationDatabase: Database access for simulation data
12
+ - data.TransmissionHandle: Ion transmission calculations
13
+
14
+ Legacy API (deprecated):
15
+ - TimsTofSyntheticFrameBuilderDIA (use DIAFrameBuilder instead)
16
+ - TimsTofSyntheticFrameBuilderDDA (use DDAFrameBuilder instead)
17
+ - TimsTofLazyFrameBuilderDIA (use DIAFrameBuilder(lazy=True) instead)
18
+ - SyntheticExperimentDataHandle (use SimulationDatabase instead)
19
+ - TimsTofSyntheticsDataHandleRust (use TransmissionHandle instead)
20
+ """
21
+
22
+ __version__ = "0.4.0"
23
+
24
+ # New clean API
25
+ from imspy_simulation.core import FrameBuilder, AnnotatedFrameBuilder, PyO3Wrapper
26
+ from imspy_simulation.builders import (
27
+ create_frame_builder,
28
+ AcquisitionMode,
29
+ LoadingStrategy,
30
+ DIAFrameBuilder,
31
+ DDAFrameBuilder,
32
+ )
33
+ from imspy_simulation.data import SimulationDatabase, SimulationDatabaseDIA, TransmissionHandle
34
+
35
+ # Legacy imports for backward compatibility
36
+ from imspy_simulation.experiment import (
37
+ TimsTofSyntheticFrameBuilderDIA,
38
+ TimsTofSyntheticFrameBuilderDDA,
39
+ TimsTofLazyFrameBuilderDIA,
40
+ TimsTofSyntheticPrecursorFrameBuilder,
41
+ SyntheticExperimentDataHandle,
42
+ SyntheticExperimentDataHandleDIA,
43
+ )
44
+ from imspy_simulation.handle import TimsTofSyntheticsDataHandleRust
45
+
46
+ # Annotation classes
47
+ from imspy_simulation.annotation import (
48
+ SourceType,
49
+ SignalAttributes,
50
+ ContributionSource,
51
+ PeakAnnotation,
52
+ MzSpectrumAnnotated,
53
+ TimsFrameAnnotated,
54
+ TimsSpectrumAnnotated,
55
+ )
56
+
57
+ # Utility functions
58
+ from imspy_simulation.utility import (
59
+ flatten_prosit_array,
60
+ sequences_to_all_ions,
61
+ sequence_to_all_ions,
62
+ get_acquisition_builder_resource_path,
63
+ get_dilution_factors,
64
+ get_ms_ms_window_layout_resource_path,
65
+ read_acquisition_config,
66
+ get_native_dataset_path,
67
+ calculate_number_frames,
68
+ calculate_mobility_spacing,
69
+ iter_frame_batches,
70
+ )
71
+
72
+ __all__ = [
73
+ # Version
74
+ '__version__',
75
+ # New API
76
+ "FrameBuilder",
77
+ "AnnotatedFrameBuilder",
78
+ "PyO3Wrapper",
79
+ "create_frame_builder",
80
+ "AcquisitionMode",
81
+ "LoadingStrategy",
82
+ "DIAFrameBuilder",
83
+ "DDAFrameBuilder",
84
+ "SimulationDatabase",
85
+ "SimulationDatabaseDIA",
86
+ "TransmissionHandle",
87
+ # Legacy (for backward compatibility)
88
+ "TimsTofSyntheticFrameBuilderDIA",
89
+ "TimsTofSyntheticFrameBuilderDDA",
90
+ "TimsTofLazyFrameBuilderDIA",
91
+ "TimsTofSyntheticPrecursorFrameBuilder",
92
+ "SyntheticExperimentDataHandle",
93
+ "SyntheticExperimentDataHandleDIA",
94
+ "TimsTofSyntheticsDataHandleRust",
95
+ # Annotation
96
+ "SourceType",
97
+ "SignalAttributes",
98
+ "ContributionSource",
99
+ "PeakAnnotation",
100
+ "MzSpectrumAnnotated",
101
+ "TimsFrameAnnotated",
102
+ "TimsSpectrumAnnotated",
103
+ # Utility
104
+ "flatten_prosit_array",
105
+ "sequences_to_all_ions",
106
+ "sequence_to_all_ions",
107
+ "get_acquisition_builder_resource_path",
108
+ "get_dilution_factors",
109
+ "get_ms_ms_window_layout_resource_path",
110
+ "read_acquisition_config",
111
+ "get_native_dataset_path",
112
+ "calculate_number_frames",
113
+ "calculate_mobility_spacing",
114
+ "iter_frame_batches",
115
+ ]
@@ -0,0 +1,336 @@
1
+ from pathlib import Path
2
+ from typing import Dict
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+ from numpy.typing import NDArray
7
+ from abc import abstractmethod, ABC
8
+
9
+ from imspy_simulation.experiment import SyntheticExperimentDataHandle
10
+ from imspy_core.timstof import TimsDatasetDIA, TimsDatasetDDA
11
+ from imspy_core.timstof.data import AcquisitionMode, TimsDataset
12
+ from imspy_simulation.utility import calculate_number_frames, get_ms_ms_window_layout_resource_path
13
+ from imspy_simulation.tdf import TDFWriter
14
+
15
+
16
+ class TimsTofAcquisitionBuilder:
17
+ def __init__(
18
+ self,
19
+ path: str,
20
+ reference_ds: TimsDataset,
21
+ gradient_length: float,
22
+ rt_cycle_length: float,
23
+ exp_name: str = "RAW.d",
24
+ verbose: bool = False,
25
+ ):
26
+ """ Base class for building TimsTOF experiments
27
+ Parameters
28
+ ----------
29
+ path : str
30
+ Path to the experiment directory
31
+ gradient_length : float
32
+ Length of the gradient in seconds
33
+ rt_cycle_length : float
34
+ Length of the RT cycle in seconds
35
+ exp_name : str
36
+ Name of the experiment
37
+ verbose : bool
38
+ Print verbose output
39
+ """
40
+
41
+ self.path = path
42
+ self.gradient_length = gradient_length
43
+ self.rt_cycle_length = rt_cycle_length
44
+ self.num_frames = calculate_number_frames(gradient_length, rt_cycle_length)
45
+ self.verbose = verbose
46
+ # Create the TDFWriter, used to deal with bruker binary format writing and metadata for libtimsdata.so
47
+ self.tdf_writer = TDFWriter(
48
+ path=self.path,
49
+ helper_handle=reference_ds,
50
+ exp_name=exp_name,
51
+ verbose=verbose,
52
+ )
53
+ # Create the SyntheticExperimentDataHandle, which is used to deal with the sqlite database of synthetic data
54
+ self.synthetics_handle = SyntheticExperimentDataHandle(database_path=self.path)
55
+ self.frame_table = None
56
+ self.scan_table = None
57
+
58
+ def generate_frame_table(self, verbose: bool = True) -> pd.DataFrame:
59
+ if verbose:
60
+ print('Generating frame layout.')
61
+ frames = []
62
+ for i in range(self.num_frames):
63
+ frame_id = i + 1
64
+ time = frame_id * self.rt_cycle_length
65
+ frames.append({'frame_id': frame_id, 'time': time})
66
+
67
+ return pd.DataFrame(frames)
68
+
69
+ def generate_scan_table(self, verbose: bool = True) -> pd.DataFrame:
70
+ if verbose:
71
+ print('Generating scan layout.')
72
+
73
+ scans = np.arange(self.tdf_writer.helper_handle.num_scans)[::-1]
74
+ mobilities = self.tdf_writer.scan_to_inv_mobility(1, scans)
75
+
76
+ return pd.DataFrame({'scan': scans, 'mobility': mobilities})
77
+
78
+ def __repr__(self):
79
+ return (f"TimsTofAcquisitionBuilder(path={self.path}, gradient_length={np.round(self.gradient_length / 60)} "
80
+ f"min, mobility_range: {self.tdf_writer.helper_handle.im_lower}-{self.tdf_writer.helper_handle.im_upper}, "
81
+ f"num_frames: {self.num_frames}, num_scans: {self.tdf_writer.helper_handle.num_scans})")
82
+
83
+ @abstractmethod
84
+ def calculate_frame_types(self, *args) -> NDArray:
85
+ pass
86
+
87
+ @classmethod
88
+ def from_existing(cls, path: str, reference_ds: TimsDataset) -> "TimsTofAcquisitionBuilder":
89
+ """ Create an instance from existing data without calling __init__.
90
+ """
91
+ # Create a new instance without calling __init__
92
+ instance = cls.__new__(cls)
93
+ instance.synthetics_handle = SyntheticExperimentDataHandle(database_path=path)
94
+
95
+ # Manually set fields from data dictionary
96
+ instance.path = path
97
+ instance.frame_table = instance.synthetics_handle.get_table('frames')
98
+ instance.scan_table = instance.synthetics_handle.get_table('scans')
99
+ instance.gradient_length = np.round(instance.frame_table.time.max())
100
+ instance.rt_cycle_length = np.mean(np.diff(instance.frame_table.time))
101
+ instance.num_frames = instance.frame_table.shape[0]
102
+
103
+ # extract experiment name from the path
104
+ exp_name = Path(path).name
105
+
106
+ # Set up the TDFWriter and SyntheticExperimentDataHandle
107
+ instance.tdf_writer = TDFWriter(
108
+ path=instance.path,
109
+ helper_handle=reference_ds,
110
+ exp_name=exp_name,
111
+ )
112
+
113
+ return instance
114
+
115
+
116
+ class TimsTofAcquisitionBuilderDDA(TimsTofAcquisitionBuilder, ABC):
117
+ def __init__(self,
118
+ path: str,
119
+ reference_ds: TimsDatasetDDA,
120
+ verbose: bool = False,
121
+ gradient_length=60 * 60,
122
+ rt_cycle_length=0.109,
123
+ exp_name: str = "T001.d",
124
+ ):
125
+ super().__init__(path, reference_ds, gradient_length, rt_cycle_length, exp_name=exp_name, verbose=verbose)
126
+
127
+ self.scan_table = None
128
+ self.frame_table = None
129
+ self.pasef_meta = None
130
+ self.selected_precursors = None
131
+ self.acquisition_mode = AcquisitionMode('DDA')
132
+ self.verbose = verbose
133
+ self._setup(verbose=verbose)
134
+
135
+ def _setup(self, verbose: bool = True):
136
+ self.frame_table = self.generate_frame_table(verbose=verbose)
137
+ self.scan_table = self.generate_scan_table(verbose=verbose)
138
+ self.synthetics_handle.create_table(
139
+ table_name='frames',
140
+ table=self.frame_table
141
+ )
142
+ self.synthetics_handle.create_table(
143
+ table_name='scans',
144
+ table=self.scan_table
145
+ )
146
+
147
+ def calculate_frame_types(self, frame_types: NDArray):
148
+ assert len(frame_types) == self.frame_table.shape[0], "frame_types must have the same length as the frame table."
149
+ # assert set(frame_types).issubset({0, 8}), f"frame_types must be a list of 0s and 8s, got {set(frame_types)}."
150
+ self.frame_table['ms_type'] = frame_types
151
+ self.synthetics_handle.create_table(
152
+ table_name='frames',
153
+ table=self.frame_table
154
+ )
155
+
156
+ class TimsTofAcquisitionBuilderDIA(TimsTofAcquisitionBuilder, ABC):
157
+ def __init__(self,
158
+ path: str,
159
+ reference_ds: TimsDatasetDIA,
160
+ window_group_file: str,
161
+ acquisition_name: str = "dia",
162
+ exp_name: str = "RAW",
163
+ verbose: bool = True,
164
+ precursor_every: int = 17,
165
+ gradient_length=50 * 60,
166
+ rt_cycle_length=0.1054,
167
+ use_reference_ds_layout: bool = True,
168
+ round_collision_energy: bool = True,
169
+ collision_energy_decimals: int = 1
170
+ ):
171
+
172
+ super().__init__(path, reference_ds, gradient_length, rt_cycle_length,
173
+ exp_name=exp_name)
174
+ # TODO: check this, could be missing replacement of reference layout of windows
175
+ if use_reference_ds_layout:
176
+ rt_cycle_length = np.mean(np.diff(reference_ds.meta_data.Time))
177
+ if verbose:
178
+ print('Using reference dataset cycle length:', np.round(rt_cycle_length, 4))
179
+ self.rt_cycle_length = rt_cycle_length
180
+
181
+ self.acquisition_name = acquisition_name
182
+ self.scan_table = None
183
+ self.frame_table = None
184
+ self.frames_to_window_groups = None
185
+ self.dia_ms_ms_windows = pd.read_csv(window_group_file)
186
+ self.use_reference_ds_layout = use_reference_ds_layout
187
+ self.reference = reference_ds
188
+ self.round_collision_energy = round_collision_energy
189
+ self.collision_energy_decimals = collision_energy_decimals
190
+
191
+ # TODO: check if the number of scans in the window group file matches the number of scans in the experiment
192
+
193
+ self.acquisition_mode = AcquisitionMode('DIA')
194
+ self.verbose = verbose
195
+ self.precursor_every = precursor_every
196
+
197
+ self._setup(verbose=verbose)
198
+
199
+ def calculate_frame_types(self, verbose: bool = True) -> NDArray:
200
+ if verbose:
201
+ print(f'Calculating frame types, precursor frame will be taken every {self.precursor_every} rt cycles.')
202
+ return np.array([0 if (x - 1) % self.precursor_every == 0 else 9 for x in self.frame_table.frame_id])
203
+
204
+ def generate_frame_to_window_group_table(self, verbose: bool = True) -> pd.DataFrame:
205
+ if verbose:
206
+ print(f'generating frame to window group table, precursors every {self.precursor_every} frames.')
207
+
208
+ table_list = []
209
+ for index, row in self.frame_table.iterrows():
210
+ frame_id, ms_type = row.frame_id, row.ms_type
211
+ wg = index % self.precursor_every
212
+ if ms_type > 0:
213
+ table_list.append({'frame': int(frame_id), 'window_group': wg})
214
+
215
+ return pd.DataFrame(table_list)
216
+
217
+ def _setup(self, verbose: bool = True):
218
+ self.frame_table = self.generate_frame_table(verbose=verbose)
219
+ self.scan_table = self.generate_scan_table(verbose=verbose)
220
+
221
+ if self.use_reference_ds_layout:
222
+ self.precursor_every = int(np.diff(self.reference.precursor_frames)[0])
223
+ self.dia_ms_ms_windows = self.reference.dia_ms_ms_windows.rename(
224
+ columns={
225
+ 'WindowGroup': 'window_group',
226
+ 'ScanNumBegin': 'scan_start',
227
+ 'ScanNumEnd': 'scan_end',
228
+ 'IsolationMz': 'isolation_mz',
229
+ 'IsolationWidth': 'isolation_width',
230
+ 'CollisionEnergy': 'collision_energy',
231
+ }
232
+ )
233
+
234
+ self.frame_table['ms_type'] = self.calculate_frame_types(verbose=verbose)
235
+ self.frames_to_window_groups = self.generate_frame_to_window_group_table(verbose=verbose)
236
+
237
+ if self.round_collision_energy:
238
+ self.dia_ms_ms_windows['collision_energy'] = np.round(self.dia_ms_ms_windows['collision_energy'].values,
239
+ decimals=self.collision_energy_decimals)
240
+
241
+ self.synthetics_handle.create_table(
242
+ table_name='frames',
243
+ table=self.frame_table
244
+ )
245
+ self.synthetics_handle.create_table(
246
+ table_name='scans',
247
+ table=self.scan_table
248
+ )
249
+ self.synthetics_handle.create_table(
250
+ table_name='dia_ms_ms_info',
251
+ table=self.frames_to_window_groups
252
+ )
253
+ self.synthetics_handle.create_table(
254
+ table_name='dia_ms_ms_windows',
255
+ table=self.dia_ms_ms_windows
256
+ )
257
+
258
+ @staticmethod
259
+ def from_config(
260
+ path: str,
261
+ reference_ds: TimsDatasetDIA,
262
+ exp_name: str,
263
+ config: Dict[str, any],
264
+ verbose: bool = True,
265
+ use_reference_layout: bool = True,
266
+ round_collision_energy: bool = True,
267
+ collision_energy_decimals: int = 1
268
+ ) -> 'TimsTofAcquisitionBuilderDIA':
269
+
270
+ acquisition_name = config['name'].lower().replace('pasef', '')
271
+ window_group_file = get_ms_ms_window_layout_resource_path(acquisition_name)
272
+
273
+ return TimsTofAcquisitionBuilderDIA(
274
+ path=str(Path(path) / exp_name),
275
+ reference_ds=reference_ds,
276
+ window_group_file=str(window_group_file),
277
+ exp_name=exp_name + ".d",
278
+ verbose=verbose,
279
+ acquisition_name=acquisition_name,
280
+ precursor_every=config['precursor_every'],
281
+ gradient_length=config['gradient_length'],
282
+ rt_cycle_length=config['rt_cycle_length'],
283
+ use_reference_ds_layout=use_reference_layout,
284
+ round_collision_energy=round_collision_energy,
285
+ collision_energy_decimals=collision_energy_decimals
286
+ )
287
+
288
+ @classmethod
289
+ def from_existing(cls,
290
+ path: str,
291
+ reference_ds: TimsDatasetDIA,
292
+ use_reference_ds_layout: bool = True,
293
+ verbose: bool = True) -> "TimsTofAcquisitionBuilderDIA":
294
+ """ Create an instance from existing data for DIA without calling __init__."""
295
+
296
+ # Create an instance without calling __init__
297
+ instance = cls.__new__(cls)
298
+
299
+ # Initialize shared attributes as done in the parent’s from_existing
300
+ instance.synthetics_handle = SyntheticExperimentDataHandle(database_path=path)
301
+ instance.path = path
302
+ instance.frame_table = instance.synthetics_handle.get_table('frames')
303
+ instance.scan_table = instance.synthetics_handle.get_table('scans')
304
+ instance.gradient_length = np.round(instance.frame_table.time.max())
305
+ instance.rt_cycle_length = np.mean(np.diff(instance.frame_table.time))
306
+ instance.num_frames = instance.frame_table.shape[0]
307
+ exp_name = Path(path).name
308
+ instance.tdf_writer = TDFWriter(
309
+ path=instance.path,
310
+ helper_handle=reference_ds,
311
+ exp_name=exp_name,
312
+ )
313
+
314
+ # Ensure use_reference_ds_layout is supported
315
+ assert use_reference_ds_layout, "Only use_reference_ds_layout=True is supported for existing DIA acquisitions"
316
+
317
+ # Set DIA-specific fields
318
+ instance.reference = reference_ds
319
+ instance.verbose = verbose
320
+ instance.window_group_file = None
321
+ instance.precursor_every = int(np.diff(instance.reference.precursor_frames)[0])
322
+ instance.round_collision_energy = True
323
+ instance.collision_energy_decimals = 1
324
+ instance.use_reference_ds_layout = use_reference_ds_layout
325
+
326
+ # Load additional tables for DIA-specific data
327
+ instance.frames_to_window_groups = instance.synthetics_handle.get_table('dia_ms_ms_info')
328
+ instance.dia_ms_ms_windows = instance.synthetics_handle.get_table('dia_ms_ms_windows')
329
+
330
+ return instance
331
+
332
+ def __repr__(self):
333
+ return (f"TimsTofAcquisitionBuilderDIA(name={self.acquisition_name}, path={self.path}, "
334
+ f"gradient_length={np.round(self.gradient_length / 60)} min, mobility_range: "
335
+ f"{self.tdf_writer.helper_handle.im_lower}-{self.tdf_writer.helper_handle.im_upper}, "
336
+ f"num_frames: {self.num_frames}, num_scans: {self.tdf_writer.helper_handle.num_scans})")