poreflow 0.2.4__tar.gz → 0.3.3__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 (145) hide show
  1. poreflow-0.3.3/CMakeLists.txt +31 -0
  2. {poreflow-0.2.4 → poreflow-0.3.3}/PKG-INFO +4 -1
  3. {poreflow-0.2.4 → poreflow-0.3.3}/README.md +3 -0
  4. {poreflow-0.2.4 → poreflow-0.3.3}/pyproject.toml +4 -4
  5. {poreflow-0.2.4 → poreflow-0.3.3}/src/fast5_research/util.py +6 -6
  6. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/__init__.py +11 -12
  7. poreflow-0.3.3/src/poreflow/_version.py +34 -0
  8. poreflow-0.3.3/src/poreflow/events/__init__.py +20 -0
  9. poreflow-0.2.4/src/poreflow/preprocessing/eventdetection.py → poreflow-0.3.3/src/poreflow/events/detection.py +15 -15
  10. poreflow-0.2.4/src/poreflow/feature_selection/eventfiltering.py → poreflow-0.3.3/src/poreflow/events/selection.py +48 -4
  11. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/io/ont.py +56 -29
  12. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/parallel.py +4 -4
  13. poreflow-0.3.3/src/poreflow/steps/__init__.py +21 -0
  14. poreflow-0.2.4/src/poreflow/classification/predictdna.py → poreflow-0.3.3/src/poreflow/steps/predict.py +6 -4
  15. {poreflow-0.2.4/src/poreflow/classification → poreflow-0.3.3/src/poreflow/steps}/sequence.py +1 -1
  16. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/structures/base.py +2 -1
  17. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/structures/event.py +1 -1
  18. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/structures/events.py +5 -101
  19. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/structures/raw.py +2 -2
  20. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/utils.py +12 -0
  21. poreflow-0.2.4/.pytest_cache/README.md +0 -8
  22. poreflow-0.2.4/.venv/lib/python3.11/site-packages/README.md +0 -124
  23. poreflow-0.2.4/.venv/lib/python3.11/site-packages/debugpy/_vendored/pydevd/pydevd_plugins/extensions/README.md +0 -30
  24. poreflow-0.2.4/.venv/lib/python3.11/site-packages/examples/advanced-component-usage/README.md +0 -36
  25. poreflow-0.2.4/.venv/lib/python3.11/site-packages/examples/gallery/README.md +0 -5
  26. poreflow-0.2.4/.venv/lib/python3.11/site-packages/examples/templates/README.md +0 -4
  27. poreflow-0.2.4/.venv/lib/python3.11/site-packages/examples/templates/multi-page-apps/README.md +0 -37
  28. poreflow-0.2.4/.venv/lib/python3.11/site-packages/flask/sansio/README.md +0 -6
  29. poreflow-0.2.4/.venv/lib/python3.11/site-packages/jupyter_server/i18n/README.md +0 -140
  30. poreflow-0.2.4/.venv/lib/python3.11/site-packages/jupyterlab/tests/mock_packages/test-hyphens/pyproject.toml +0 -67
  31. poreflow-0.2.4/.venv/lib/python3.11/site-packages/jupyterlab/tests/mock_packages/test-hyphens-underscore/pyproject.toml +0 -67
  32. poreflow-0.2.4/.venv/lib/python3.11/site-packages/jupyterlab/tests/mock_packages/test_no_hyphens/pyproject.toml +0 -67
  33. poreflow-0.2.4/.venv/lib/python3.11/site-packages/nbconvert/templates/README.md +0 -8
  34. poreflow-0.2.4/.venv/lib/python3.11/site-packages/nbconvert/templates/skeleton/README.md +0 -12
  35. poreflow-0.2.4/.venv/lib/python3.11/site-packages/pandas/pyproject.toml +0 -835
  36. poreflow-0.2.4/.venv/lib/python3.11/site-packages/pyproject.toml +0 -120
  37. poreflow-0.2.4/.venv/lib/python3.11/site-packages/sklearn/externals/array_api_compat/README.md +0 -1
  38. poreflow-0.2.4/.venv/lib/python3.11/site-packages/sklearn/externals/array_api_extra/README.md +0 -1
  39. poreflow-0.2.4/.venv/lib/python3.11/site-packages/zmq/backend/cffi/README.md +0 -1
  40. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/README.md +0 -124
  41. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/examples/advanced-component-usage/README.md +0 -36
  42. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/examples/gallery/README.md +0 -5
  43. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/examples/templates/README.md +0 -4
  44. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/examples/templates/multi-page-apps/README.md +0 -37
  45. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/flask/sansio/README.md +0 -6
  46. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/pandas/pyproject.toml +0 -835
  47. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/poreflow-0.2.3.dist-info/licenses/LICENSE.MD +0 -21
  48. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/pyproject.toml +0 -120
  49. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/sklearn/externals/array_api_compat/README.md +0 -1
  50. poreflow-0.2.4/.venv2/lib/python3.11/site-packages/sklearn/externals/array_api_extra/README.md +0 -1
  51. poreflow-0.2.4/CMakeLists.txt +0 -37
  52. poreflow-0.2.4/LICENSE.MD +0 -21
  53. poreflow-0.2.4/src/.DS_Store +0 -0
  54. poreflow-0.2.4/src/fast5_research/__pycache__/__init__.cpython-311.pyc +0 -0
  55. poreflow-0.2.4/src/fast5_research/__pycache__/fast5.cpython-311.pyc +0 -0
  56. poreflow-0.2.4/src/fast5_research/__pycache__/fast5_bulk.cpython-311.pyc +0 -0
  57. poreflow-0.2.4/src/fast5_research/__pycache__/util.cpython-311.pyc +0 -0
  58. poreflow-0.2.4/src/poreflow/.DS_Store +0 -0
  59. poreflow-0.2.4/src/poreflow/README.md +0 -268
  60. poreflow-0.2.4/src/poreflow/__pycache__/__init__.cpython-311.pyc +0 -0
  61. poreflow-0.2.4/src/poreflow/__pycache__/cli.cpython-311.pyc +0 -0
  62. poreflow-0.2.4/src/poreflow/__pycache__/constants.cpython-311.pyc +0 -0
  63. poreflow-0.2.4/src/poreflow/__pycache__/parallel.cpython-311.pyc +0 -0
  64. poreflow-0.2.4/src/poreflow/__pycache__/plots.cpython-311.pyc +0 -0
  65. poreflow-0.2.4/src/poreflow/__pycache__/utils.cpython-311.pyc +0 -0
  66. poreflow-0.2.4/src/poreflow/__pycache__/widgets.cpython-311.pyc +0 -0
  67. poreflow-0.2.4/src/poreflow/classification/.DS_Store +0 -0
  68. poreflow-0.2.4/src/poreflow/classification/__pycache__/__init__.cpython-311.pyc +0 -0
  69. poreflow-0.2.4/src/poreflow/classification/__pycache__/event_filtering.cpython-311.pyc +0 -0
  70. poreflow-0.2.4/src/poreflow/classification/__pycache__/predictdna.cpython-311.pyc +0 -0
  71. poreflow-0.2.4/src/poreflow/classification/__pycache__/sequence.cpython-311.pyc +0 -0
  72. poreflow-0.2.4/src/poreflow/classification/calculateSequenceVV.m +0 -357
  73. poreflow-0.2.4/src/poreflow/classification/event_filtering.py +0 -42
  74. poreflow-0.2.4/src/poreflow/classification/logdet.m +0 -20
  75. poreflow-0.2.4/src/poreflow/classification/smatrixACpar.m +0 -40
  76. poreflow-0.2.4/src/poreflow/dashboards/__pycache__/__init__.cpython-311.pyc +0 -0
  77. poreflow-0.2.4/src/poreflow/dashboards/__pycache__/app.cpython-311.pyc +0 -0
  78. poreflow-0.2.4/src/poreflow/dashboards/__pycache__/components.cpython-311.pyc +0 -0
  79. poreflow-0.2.4/src/poreflow/dashboards/__pycache__/file_manager.cpython-311.pyc +0 -0
  80. poreflow-0.2.4/src/poreflow/dashboards/__pycache__/labeler.cpython-311.pyc +0 -0
  81. poreflow-0.2.4/src/poreflow/dashboards/__pycache__/utils.cpython-311.pyc +0 -0
  82. poreflow-0.2.4/src/poreflow/dashboards/pages/__pycache__/channels.cpython-311.pyc +0 -0
  83. poreflow-0.2.4/src/poreflow/dashboards/pages/__pycache__/file_manager.cpython-311.pyc +0 -0
  84. poreflow-0.2.4/src/poreflow/dashboards/pages/__pycache__/labeler.cpython-311.pyc +0 -0
  85. poreflow-0.2.4/src/poreflow/feature_extraction/__init__.py +0 -0
  86. poreflow-0.2.4/src/poreflow/feature_extraction/__pycache__/__init__.cpython-311.pyc +0 -0
  87. poreflow-0.2.4/src/poreflow/feature_extraction/__pycache__/changepoint.cpython-311.pyc +0 -0
  88. poreflow-0.2.4/src/poreflow/feature_extraction/__pycache__/cpic.cpython-311.pyc +0 -0
  89. poreflow-0.2.4/src/poreflow/feature_extraction/__pycache__/metrics.cpython-311.pyc +0 -0
  90. poreflow-0.2.4/src/poreflow/feature_selection/__init__.py +0 -0
  91. poreflow-0.2.4/src/poreflow/feature_selection/__pycache__/__init__.cpython-311.pyc +0 -0
  92. poreflow-0.2.4/src/poreflow/feature_selection/__pycache__/eventfiltering.cpython-311.pyc +0 -0
  93. poreflow-0.2.4/src/poreflow/io/.DS_Store +0 -0
  94. poreflow-0.2.4/src/poreflow/io/__pycache__/__init__.cpython-311.pyc +0 -0
  95. poreflow-0.2.4/src/poreflow/io/__pycache__/devices.cpython-311.pyc +0 -0
  96. poreflow-0.2.4/src/poreflow/io/__pycache__/labview.cpython-311.pyc +0 -0
  97. poreflow-0.2.4/src/poreflow/io/__pycache__/ont.cpython-311.pyc +0 -0
  98. poreflow-0.2.4/src/poreflow/preprocessing/__init__.py +0 -0
  99. poreflow-0.2.4/src/poreflow/preprocessing/__pycache__/__init__.cpython-311.pyc +0 -0
  100. poreflow-0.2.4/src/poreflow/preprocessing/__pycache__/eventdetection.cpython-311.pyc +0 -0
  101. poreflow-0.2.4/src/poreflow/preprocessing/__pycache__/openstate.cpython-311.pyc +0 -0
  102. poreflow-0.2.4/src/poreflow/preprocessing/__pycache__/voltagestate.cpython-311.pyc +0 -0
  103. poreflow-0.2.4/src/poreflow/structures/__init__.py +0 -0
  104. poreflow-0.2.4/src/poreflow/structures/__pycache__/__init__.cpython-311.pyc +0 -0
  105. poreflow-0.2.4/src/poreflow/structures/__pycache__/base.cpython-311.pyc +0 -0
  106. poreflow-0.2.4/src/poreflow/structures/__pycache__/event.cpython-311.pyc +0 -0
  107. poreflow-0.2.4/src/poreflow/structures/__pycache__/events.cpython-311.pyc +0 -0
  108. poreflow-0.2.4/src/poreflow/structures/__pycache__/raw.cpython-311.pyc +0 -0
  109. poreflow-0.2.4/src/poreflow/structures/__pycache__/steps.cpython-311.pyc +0 -0
  110. poreflow-0.2.4/src/poreflow/widgets.py +0 -221
  111. {poreflow-0.2.4/.venv/lib/python3.11/site-packages/poreflow-0.2.3.dist-info/licenses → poreflow-0.3.3}/LICENSE.MD +0 -0
  112. {poreflow-0.2.4 → poreflow-0.3.3}/src/fast5_research/LICENSE.md +0 -0
  113. {poreflow-0.2.4 → poreflow-0.3.3}/src/fast5_research/__init__.py +0 -0
  114. {poreflow-0.2.4 → poreflow-0.3.3}/src/fast5_research/extract.py +0 -0
  115. {poreflow-0.2.4 → poreflow-0.3.3}/src/fast5_research/fast5.py +0 -0
  116. {poreflow-0.2.4 → poreflow-0.3.3}/src/fast5_research/fast5_bulk.py +0 -0
  117. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/COPYING +0 -0
  118. {poreflow-0.2.4/.venv2/lib/python3.11/site-packages → poreflow-0.3.3/src}/poreflow/README.md +0 -0
  119. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/cli.py +0 -0
  120. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/constants.py +0 -0
  121. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dashboards/__init__.py +0 -0
  122. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dashboards/app.py +0 -0
  123. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dashboards/components.py +0 -0
  124. {poreflow-0.2.4/src/poreflow/classification → poreflow-0.3.3/src/poreflow/dashboards/pages}/__init__.py +0 -0
  125. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dashboards/pages/channels.py +0 -0
  126. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dashboards/pages/file_manager.py +0 -0
  127. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dashboards/pages/labeler.py +0 -0
  128. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dashboards/utils.py +0 -0
  129. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/dataset.py +0 -0
  130. /poreflow-0.2.4/src/poreflow/preprocessing/openstate.py → /poreflow-0.3.3/src/poreflow/events/open_state.py +0 -0
  131. /poreflow-0.2.4/src/poreflow/preprocessing/voltagestate.py → /poreflow-0.3.3/src/poreflow/events/voltage_state.py +0 -0
  132. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/io/__init__.py +0 -0
  133. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/io/devices.py +0 -0
  134. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/io/labview.py +0 -0
  135. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/plots.py +0 -0
  136. {poreflow-0.2.4/src/poreflow/feature_extraction → poreflow-0.3.3/src/poreflow/steps}/_changepoint.cpp +0 -0
  137. {poreflow-0.2.4/src/poreflow/classification → poreflow-0.3.3/src/poreflow/steps}/assets/DNA_6mer_prediction_model_cv.csv +0 -0
  138. {poreflow-0.2.4/src/poreflow/feature_extraction → poreflow-0.3.3/src/poreflow/steps}/assets/equal_spacing_dna.npz +0 -0
  139. {poreflow-0.2.4/src/poreflow/classification → poreflow-0.3.3/src/poreflow/steps}/assets/pore_model_6mer_constant_voltage.csv +0 -0
  140. {poreflow-0.2.4/src/poreflow/feature_extraction → poreflow-0.3.3/src/poreflow/steps}/assets/principal_components_for_level_finding.npy +0 -0
  141. {poreflow-0.2.4/src/poreflow/feature_extraction → poreflow-0.3.3/src/poreflow/steps}/changepoint.py +0 -0
  142. {poreflow-0.2.4/src/poreflow/feature_extraction → poreflow-0.3.3/src/poreflow/steps}/cpic.py +0 -0
  143. {poreflow-0.2.4/src/poreflow/feature_extraction → poreflow-0.3.3/src/poreflow/steps}/metrics.py +0 -0
  144. {poreflow-0.2.4/src/poreflow/dashboards/pages → poreflow-0.3.3/src/poreflow/structures}/__init__.py +0 -0
  145. {poreflow-0.2.4 → poreflow-0.3.3}/src/poreflow/structures/steps.py +0 -0
@@ -0,0 +1,31 @@
1
+ cmake_minimum_required(VERSION 3.15)
2
+ project(poreflow_changepoint)
3
+
4
+ set(CMAKE_CXX_STANDARD 20)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+
7
+ # Find Python and its associated components, natively including NumPy
8
+ find_package(Python 3.11 COMPONENTS Interpreter Development.Module NumPy REQUIRED)
9
+
10
+ # Use FetchContent to get Eigen
11
+ include(FetchContent)
12
+
13
+ FetchContent_Declare(
14
+ Eigen3
15
+ GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
16
+ GIT_TAG 5.0.1
17
+ GIT_SHALLOW TRUE
18
+ )
19
+ FetchContent_MakeAvailable(Eigen3)
20
+
21
+ # Define the extension module
22
+ python_add_library(_changepoint MODULE src/poreflow/steps/_changepoint.cpp)
23
+
24
+ # Include directories, utilizing the variable populated by FindPython
25
+ target_include_directories(_changepoint PRIVATE
26
+ ${Python_NumPy_INCLUDE_DIRS}
27
+ ${Eigen3_SOURCE_DIR}
28
+ )
29
+
30
+ # Install location
31
+ install(TARGETS _changepoint DESTINATION poreflow/steps)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: poreflow
3
- Version: 0.2.4
3
+ Version: 0.3.3
4
4
  Summary: Python module for processing nanopore sequencing
5
5
  Keywords: nanopore,peptide,bioinformatics
6
6
  Author-Email: Xiuqi Chen <X.Chen-13@tudelft.nl>, Thijn Hoekstra <thijnhoekstra@gmail.com>
@@ -49,6 +49,9 @@ Description-Content-Type: text/markdown
49
49
  # PoreFlow
50
50
  > *Nanopore data analysis tools*
51
51
 
52
+ [![pipeline status](https://gitlab.tudelft.nl/xiuqichen/poreFlow/badges/main/pipeline.svg)](https://gitlab.tudelft.nl/xiuqichen/poreFlow/-/commits/main)
53
+ [![Latest Release](https://gitlab.tudelft.nl/xiuqichen/poreFlow/-/badges/release.svg)](https://gitlab.tudelft.nl/xiuqichen/poreFlow/-/releases)
54
+
52
55
  PoreFlow is a fast, simple, and flexible set of tools for analysing raw nanopore sequencing data,
53
56
  intended for use for research in the Cees Dekker lab (and beyond?).
54
57
 
@@ -1,6 +1,9 @@
1
1
  # PoreFlow
2
2
  > *Nanopore data analysis tools*
3
3
 
4
+ [![pipeline status](https://gitlab.tudelft.nl/xiuqichen/poreFlow/badges/main/pipeline.svg)](https://gitlab.tudelft.nl/xiuqichen/poreFlow/-/commits/main)
5
+ [![Latest Release](https://gitlab.tudelft.nl/xiuqichen/poreFlow/-/badges/release.svg)](https://gitlab.tudelft.nl/xiuqichen/poreFlow/-/releases)
6
+
4
7
  PoreFlow is a fast, simple, and flexible set of tools for analysing raw nanopore sequencing data,
5
8
  intended for use for research in the Cees Dekker lab (and beyond?).
6
9
 
@@ -47,13 +47,13 @@ Repository = "https://gitlab.tudelft.nl/xiuqichen/poreFlow.git"
47
47
  Issues = "https://gitlab.tudelft.nl/xiuqichen/poreFlow/-/issues"
48
48
 
49
49
  [tool.scikit-build]
50
+ metadata.version.provider = "scikit_build_core.metadata.setuptools_scm"
50
51
  wheel.packages = ["src/poreflow", "src/fast5_research"]
51
- sdist.include = ["src/*", "LICENSE.MD", "pyproject.toml", "CMakeLists.txt", "README.md"]
52
+ sdist.include = ["src/*", "src/poreflow/_version.py", "LICENSE.MD", "pyproject.toml", "CMakeLists.txt", "README.md"]
52
53
  sdist.exclude = ["*"]
53
54
 
54
- [tool.scikit-build.metadata.version]
55
- provider = "scikit_build_core.metadata.regex"
56
- input = "src/poreflow/__init__.py"
55
+ [tool.setuptools_scm] # Section required
56
+ write_to = "src/poreflow/_version.py"
57
57
 
58
58
  [dependency-groups]
59
59
  dev = [
@@ -7,16 +7,16 @@ import sys
7
7
  import numpy as np
8
8
  import numpy.lib.recfunctions as nprf
9
9
 
10
+
10
11
  def descale(
11
- x: np.ndarray,
12
- meta: dict,
13
- dtype: np.dtype = np.int16,
12
+ x: np.ndarray,
13
+ meta: dict,
14
+ dtype: np.dtype = np.int16,
14
15
  ) -> np.ndarray[np.int16]:
15
16
  """Scale float data down to int data"""
16
17
  return (x * meta["digitisation"] / meta["range"] - meta["offset"]).astype(dtype)
17
18
 
18
19
 
19
-
20
20
  def qstring_to_phred(quality):
21
21
  """Compute standard phred scores from a quality string."""
22
22
  qscores = [ord(q) - 33 for q in quality]
@@ -545,7 +545,7 @@ def med_mad(data, factor=None, axis=None, keepdims=False):
545
545
  :param data: A :class:`ndarray` object
546
546
  :param factor: Factor to scale MAD by. Default (None) is to be consistent
547
547
  with the standard deviation of a normal distribution
548
- (i.e. mad( N(0,\sigma^2) ) = \sigma).
548
+ (i.e. mad( N(0,\\sigma^2) ) = \\sigma).
549
549
  :param axis: For multidimensional arrays, which axis to calculate over
550
550
  :param keepdims: If True, axis is kept as dimension of length 1
551
551
 
@@ -573,7 +573,7 @@ def mad(data, factor=None, axis=None, keepdims=False):
573
573
  :param data: A :class:`ndarray` object
574
574
  :param factor: Factor to scale MAD by. Default (None) is to be consistent
575
575
  with the standard deviation of a normal distribution
576
- (i.e. mad( N(0,\sigma^2) ) = \sigma).
576
+ (i.e. mad( N(0,\\sigma^2) ) = \\sigma).
577
577
  :param axis: For multidimensional arrays, which axis to calculate the median over.
578
578
  :param keepdims: If True, axis is kept as dimension of length 1
579
579
 
@@ -15,18 +15,20 @@ from poreflow.io.devices import ONT, UTUBE
15
15
  from poreflow import constants
16
16
  from poreflow.constants import *
17
17
 
18
+ from poreflow import _version
19
+
20
+ __version__ = _version.__version__
21
+
18
22
  submodules = [
19
- "classification",
20
- "fast_5_research",
21
- "feature_extraction",
22
- "io",
23
- "preprocessing",
23
+ "dashboards"
24
24
  "events",
25
- "base",
26
- "utils",
27
- "widgets",
28
- "plots",
25
+ "io",
26
+ "steps",
27
+ "structures",
28
+ "dataset",
29
29
  "parallel",
30
+ "plots",
31
+ "utils",
30
32
  ]
31
33
 
32
34
  __all__ = (
@@ -44,9 +46,6 @@ __all__ = (
44
46
  + constants.__all__
45
47
  )
46
48
 
47
- __version__ = "0.2.4"
48
-
49
-
50
49
  def __dir__():
51
50
  return __all__
52
51
 
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '0.3.3'
32
+ __version_tuple__ = version_tuple = (0, 3, 3)
33
+
34
+ __commit_id__ = commit_id = 'g5a625d68c'
@@ -0,0 +1,20 @@
1
+ import importlib as _importlib
2
+
3
+ submodules = [
4
+ "detection",
5
+ "open_state",
6
+ "voltage_state",
7
+ "selection",
8
+ ]
9
+
10
+ __all__ = submodules
11
+
12
+
13
+ def __getattr__(name):
14
+ if name in submodules:
15
+ return _importlib.import_module(f"poreflow.events.{name}")
16
+ else:
17
+ try:
18
+ return globals()[name]
19
+ except KeyError:
20
+ raise AttributeError(f"Module 'poreflow.events' has no attribute '{name}'")
@@ -8,7 +8,7 @@ import numpy as np
8
8
  import pandas as pd
9
9
 
10
10
  import poreflow as pf
11
- from poreflow.preprocessing import openstate, voltagestate
11
+ from poreflow.events import open_state, voltage_state
12
12
 
13
13
  DEFAULT_DEGREE = 1
14
14
 
@@ -18,29 +18,29 @@ class EventDetectionFailure(Exception):
18
18
 
19
19
 
20
20
  def find_events(
21
- raw: pd.DataFrame,
22
- open_state_range: tuple[float, float] = (200, 300),
23
- voltage_range: tuple[float, float] = (175, 185),
24
- closing_iterations: int | bool = 10,
25
- boundary_trim: int = 5,
26
- n_components: int = 3,
27
- degree: int = DEFAULT_DEGREE,
28
- min_frac_os: float = 0.01
21
+ raw: pd.DataFrame,
22
+ open_state_range: tuple[float, float] = (200, 300),
23
+ voltage_range: tuple[float, float] = (175, 185),
24
+ closing_iterations: int | bool = 10,
25
+ boundary_trim: int = 5,
26
+ n_components: int = 3,
27
+ degree: int = DEFAULT_DEGREE,
28
+ min_frac_os: float = 0.01,
29
29
  ) -> pf.EventsDataFrame | None:
30
- component = openstate.find_open_state(raw, open_state_range, n_components)
30
+ component = open_state.find_open_state(raw, open_state_range, n_components)
31
31
 
32
32
  # "Bad state" still only open state
33
- bad_state = openstate.get_open_state_mask(raw, component)
33
+ bad_state = open_state.get_open_state_mask(raw, component)
34
34
 
35
35
  if bad_state.sum() / len(raw) < min_frac_os:
36
36
  return None
37
37
 
38
- poly = openstate.get_open_state_fit(raw, bad_state, degree)
38
+ poly = open_state.get_open_state_fit(raw, bad_state, degree)
39
39
  raw.ios = poly
40
40
 
41
41
  # Boolean AND: want to include all samples either in bad voltage or
42
42
  # in an open state
43
- bad_state = bad_state | voltagestate.get_voltage_state_mask(raw, voltage_range)
43
+ bad_state = bad_state | voltage_state.get_voltage_state_mask(raw, voltage_range)
44
44
  bad_state = bad_state.to_numpy(dtype=bool)
45
45
 
46
46
  # Do binary closing to clean up mask
@@ -62,7 +62,7 @@ def find_events(
62
62
  df.trim_events(size=boundary_trim, recalculate_times=False)
63
63
  df.clip_events(lower=0, upper=len(raw)) # Times are recalculated here
64
64
 
65
- add_local_openstate(df, poly)
65
+ add_local_open_state(df, poly)
66
66
 
67
67
  df[pf.CHANNEL_COL] = raw.channel
68
68
  df[pf.QUALITY_COL] = 0.0
@@ -90,7 +90,7 @@ def get_event_indices(bad_state: np.ndarray[np.bool]):
90
90
  return start_indices, end_indices
91
91
 
92
92
 
93
- def add_local_openstate(df: pd.DataFrame, poly: np.polynomial.Polynomial) -> None:
93
+ def add_local_open_state(df: pd.DataFrame, poly: np.polynomial.Polynomial) -> None:
94
94
  start_ios = poly(df[pf.START_TIME_COL])
95
95
  end_ios = poly(df[pf.END_TIME_COL])
96
96
 
@@ -4,6 +4,46 @@ import pandas as pd
4
4
 
5
5
  import poreflow as pf
6
6
 
7
+ from poreflow.steps import metrics
8
+
9
+
10
+ def get_step_finding_stats(f: pf.File) -> pf.EventsDataFrame:
11
+ if not f.has_events:
12
+ raise RuntimeError("File must have events. Please run event detection first.")
13
+
14
+ if not f.has_events:
15
+ raise RuntimeError("File must have steps. Please run step detection first.")
16
+
17
+ steps = f.get_steps()
18
+ events = f.get_events()
19
+
20
+ events["std_of_step_means"] = get_std_of_step_means(steps)
21
+ events["n_steps"] = get_n_steps(steps)
22
+
23
+ events[pf.STEP_RATE_COL] = events["n_steps"] / events[pf.DURATION_COL]
24
+
25
+ events["binned_entropy_of_means"] = get_binned_entropies(events, steps)
26
+
27
+ return events
28
+
29
+
30
+ def get_binned_entropies(
31
+ events: pf.EventsDataFrame, steps: pf.StepsDataFrame
32
+ ) -> pd.Series:
33
+ s = pd.Series(index=events.index, dtype=float)
34
+ for j, mean in steps.groupby(pf.EVENT_COL)[pf.MEAN_COL]:
35
+ s[j] = metrics.binned_entropy(mean)
36
+ return s
37
+
38
+
39
+ def get_n_steps(steps: pf.StepsDataFrame) -> pd.Series:
40
+ return steps[pf.EVENT_COL].value_counts()
41
+
42
+
43
+ def get_std_of_step_means(steps: pf.StepsDataFrame) -> pd.Series:
44
+ return steps.groupby(pf.EVENT_COL)[pf.MEAN_COL].std()
45
+
46
+
7
47
  def filter_from_config(events: pf.EventsDataFrame, conditions: dict) -> pd.DataFrame:
8
48
  """Filter using a dictionary of conditions
9
49
 
@@ -31,7 +71,9 @@ def filter_from_config(events: pf.EventsDataFrame, conditions: dict) -> pd.DataF
31
71
  """
32
72
  n_conditions = len(conditions)
33
73
 
34
- targets = pd.DataFrame(index=range(n_conditions), columns=["col", "comparison", "value"], dtype=object)
74
+ targets = pd.DataFrame(
75
+ index=range(n_conditions), columns=["col", "comparison", "value"], dtype=object
76
+ )
35
77
  for j, (condition, value) in enumerate(conditions.items()):
36
78
  results = re.findall(r"(min|max)_(\w+)", condition)
37
79
 
@@ -39,12 +81,14 @@ def filter_from_config(events: pf.EventsDataFrame, conditions: dict) -> pd.DataF
39
81
  raise KeyError(
40
82
  f'Condition "{condition}" could not be interpreted. '
41
83
  'Please format as "min_[col]" or "max_[col]" in dict/TOML, '
42
- 'where [col] is a column available in the event dataframe.'
84
+ "where [col] is a column available in the event dataframe."
43
85
  )
44
86
  prefix, col = results[0]
45
87
 
46
88
  if col not in events.columns:
47
- raise KeyError(f'Column {col} specified in condition "{condition}" not present in EventsDataFrame')
89
+ raise KeyError(
90
+ f'Column {col} specified in condition "{condition}" not present in EventsDataFrame'
91
+ )
48
92
 
49
93
  if prefix == "min":
50
94
  comparison = ">"
@@ -69,4 +113,4 @@ def filter_from_config(events: pf.EventsDataFrame, conditions: dict) -> pd.DataF
69
113
  truth_table.iloc[:, tup.Index] = events[tup.col] > tup.value
70
114
 
71
115
  truth_table["all"] = truth_table.all(axis=1)
72
- return truth_table
116
+ return truth_table
@@ -24,7 +24,8 @@ import scipy.signal
24
24
  from fast5_research.fast5_bulk import BulkFast5
25
25
 
26
26
  import poreflow as pf
27
- import poreflow.feature_extraction.changepoint
27
+ from poreflow.events import detection
28
+ from poreflow.steps import changepoint
28
29
  from poreflow.parallel import mapper
29
30
 
30
31
  META_DURATION_ATTR_NAME = "duration_samples"
@@ -108,6 +109,8 @@ class File(BulkFast5):
108
109
  g_meta.attrs["poreflow_version"] = pf.__version__
109
110
  g_meta.attrs["python_version"] = platform.python_version()
110
111
 
112
+ self._name = None
113
+
111
114
  @property
112
115
  def poreflow_group(self):
113
116
  return self[pf.POREFLOW_GROUP]
@@ -116,6 +119,18 @@ class File(BulkFast5):
116
119
  def has_poreflow_data(self):
117
120
  return pf.POREFLOW_GROUP in self
118
121
 
122
+ @property
123
+ def name(self) -> str:
124
+ """Pretty name, defaults to filename."""
125
+ return (
126
+ self._name if self._name is not None else pathlib.Path(self.filename).stem
127
+ )
128
+
129
+ @name.setter
130
+ def name(self, value: str):
131
+ """Set a pretty name"""
132
+ self._name = value
133
+
119
134
  @property
120
135
  def device(self):
121
136
  if self.tracking_meta["device_id"] == pf.UTUBE:
@@ -123,14 +138,30 @@ class File(BulkFast5):
123
138
  else:
124
139
  return pf.ONT
125
140
 
141
+ @property
142
+ def n_events(self) -> int:
143
+ return len(self.poreflow_group[pf.EVENTS_DATASET])
144
+
145
+ @property
146
+ def n_steps(self) -> int:
147
+ return len(self.poreflow_group[pf.STEPS_DATASET])
148
+
126
149
  def get_channels(self):
127
- """Tries getting channels even when in write mode."""
150
+ """Tries getting channels even when in write mode.
151
+
152
+ Returns:
153
+ list: List of channel numbers in file. Starts from 0.
154
+
155
+ Note:
156
+ ONT stores channels in Fast5 files starting from 1. Channels
157
+ in poreFlow are indexed from 0. So 0 --> Channel 1, etc.
158
+ """
128
159
  data = self[self.__intermediate_data__]
129
- return sorted([int(name.strip("Channel_")) for name in data.keys()])
160
+ return sorted([int(name.strip("Channel_")) - 1 for name in data.keys()])
130
161
 
131
162
  def _get_channel_data(
132
163
  self,
133
- channel: int = 1,
164
+ channel: int = 0,
134
165
  times: typing.Optional[typing.Tuple[float, float]] = None,
135
166
  index: typing.Optional[typing.Tuple[int, int]] = None,
136
167
  downsample: typing.Optional[float] = None,
@@ -164,7 +195,8 @@ class File(BulkFast5):
164
195
  elif index:
165
196
  raw_indices = index
166
197
 
167
- out = [super().get_raw(channel, times, raw_indices)]
198
+ # ONT stores channels starting from 1
199
+ out = [super().get_raw(channel + 1, times, raw_indices)]
168
200
 
169
201
  if read_voltage:
170
202
  out.append(super().get_voltage(times, raw_indices))
@@ -192,7 +224,7 @@ class File(BulkFast5):
192
224
 
193
225
  def get_data(
194
226
  self,
195
- channel: int = 1,
227
+ channel: int = 0,
196
228
  times: typing.Optional[typing.Tuple[float, float]] = None,
197
229
  index: typing.Optional[typing.Tuple[int, int]] = None,
198
230
  downsample: typing.Optional[float] = None,
@@ -224,12 +256,12 @@ class File(BulkFast5):
224
256
  {pf.CURRENT_FIELD_NAME: current_data},
225
257
  sfreq=sfreq,
226
258
  channel=channel,
227
- name=self.filename,
259
+ name=self.name,
228
260
  )
229
261
 
230
262
  def get_raw(
231
263
  self,
232
- channel: int = 1,
264
+ channel: int = 0,
233
265
  times: tuple[float, float] = None,
234
266
  index: tuple[int, int] = None,
235
267
  downsample: float = None,
@@ -258,13 +290,11 @@ class File(BulkFast5):
258
290
  channel, times, index, downsample
259
291
  )
260
292
 
261
- filename = pathlib.Path(self.filename).stem
262
-
263
293
  return pf.RawDataFrame(
264
294
  {pf.CURRENT_FIELD_NAME: current_data, pf.VOLTAGE_FIELD_NAME: voltage_data},
265
295
  sfreq=sfreq,
266
296
  channel=channel,
267
- name=f"Channel {channel} of {filename}",
297
+ name=f"Channel {channel} of {self.name}",
268
298
  ios=self.get_ios(channel),
269
299
  )
270
300
 
@@ -291,7 +321,7 @@ class File(BulkFast5):
291
321
  start * sfreq / self.sfreq
292
322
  ), # Scale start_idx if downsample was used
293
323
  ios=row[pf.IOS_COL],
294
- name=f"Event {item} in channel {channel} of {self.filename}",
324
+ name=f"Event {item} in channel {channel} of {self.name}",
295
325
  quality=row[pf.QUALITY_COL],
296
326
  label=row[pf.LABEL_COL],
297
327
  )
@@ -452,7 +482,7 @@ class File(BulkFast5):
452
482
  data=rec,
453
483
  )
454
484
 
455
- def set_ios(self, p: np.polynomial.Polynomial, channel: int = 1):
485
+ def set_ios(self, p: np.polynomial.Polynomial, channel: int = 0):
456
486
 
457
487
  if pf.IOS_FIT_DATASET not in self.poreflow_group:
458
488
  self._create_ios_fit_dataset(p.degree())
@@ -476,7 +506,7 @@ class File(BulkFast5):
476
506
 
477
507
  return _remove_index(df)
478
508
 
479
- def get_ios(self, channel: int = 1) -> np.polynomial.Polynomial | None:
509
+ def get_ios(self, channel: int = 0) -> np.polynomial.Polynomial | None:
480
510
 
481
511
  if not self.has_poreflow_data or (
482
512
  pf.IOS_FIT_DATASET not in self.poreflow_group
@@ -528,13 +558,7 @@ class File(BulkFast5):
528
558
 
529
559
  return results
530
560
 
531
- def find_events(
532
- self,
533
- processes=None,
534
- verbose=0,
535
- channels: list = None,
536
- **kwargs
537
- ):
561
+ def find_events(self, processes=None, verbose=0, channels: list = None, **kwargs):
538
562
  """
539
563
  Find events in the file using parallel processing.
540
564
 
@@ -548,25 +572,24 @@ class File(BulkFast5):
548
572
  Closes file, does processing, and then opens it again by calling
549
573
  __init__.
550
574
  """
551
- from poreflow.preprocessing import eventdetection
552
575
 
553
576
  if self.mode != "r+":
554
577
  raise IOError("Must set mode to read and write (r+)")
555
578
 
556
579
  self.set_events(None)
557
- degree = kwargs.get("degree", eventdetection.DEFAULT_DEGREE)
580
+ degree = kwargs.get("degree", detection.DEFAULT_DEGREE)
558
581
  self._create_ios_fit_dataset(degree)
559
582
 
560
583
  if channels is None:
561
584
  channels = self.get_channels()
562
585
 
563
586
  results = self.map(
564
- eventdetection.event_detection_worker,
587
+ detection.event_detection_worker,
565
588
  channels,
566
589
  processes=processes,
567
590
  verbose=verbose,
568
591
  callback=functools.partial(
569
- eventdetection.save_events_to_file,
592
+ detection.save_events_to_file,
570
593
  fname=self.filename,
571
594
  verbose=verbose,
572
595
  ),
@@ -574,7 +597,11 @@ class File(BulkFast5):
574
597
  )
575
598
 
576
599
  if verbose > 0:
577
- eventdetection.summarize_events(results)
600
+ detection.summarize_events(results)
601
+
602
+ def iter_events(self, **kwargs):
603
+ for j in range(self.n_events):
604
+ yield self.get_event(j, **kwargs)
578
605
 
579
606
  def find_steps(self, processes=None, verbose=0, events: list = None, **kwargs):
580
607
 
@@ -587,19 +614,19 @@ class File(BulkFast5):
587
614
  events = range(len(self.get_events()))
588
615
 
589
616
  results = self.map(
590
- poreflow.feature_extraction.changepoint.step_finding_worker,
617
+ changepoint.step_finding_worker,
591
618
  events,
592
619
  processes=processes,
593
620
  verbose=verbose,
594
621
  callback=functools.partial(
595
- poreflow.feature_extraction.changepoint.save_steps_to_file,
622
+ changepoint.save_steps_to_file,
596
623
  fname=self.filename,
597
624
  ),
598
625
  **kwargs,
599
626
  )
600
627
 
601
628
  if verbose > 0:
602
- poreflow.feature_extraction.changepoint.summarize_steps(results)
629
+ changepoint.summarize_steps(results)
603
630
 
604
631
  def filter_events(self, mask: pd.Series) -> None:
605
632
  """Remove events using a mask
@@ -3,16 +3,16 @@ import multiprocessing
3
3
  import os
4
4
  import threading
5
5
  import time
6
- from multiprocessing import Manager, Pool
6
+
7
7
  from multiprocessing.pool import Pool
8
+ from multiprocessing import Manager
9
+
8
10
 
9
11
  import numpy as np
10
12
  import psutil
11
13
 
12
14
  from tqdm.auto import tqdm
13
15
 
14
- import poreflow as pf
15
-
16
16
 
17
17
  def imap_worker_wrapper(args):
18
18
  """Generic wrapper to unpack arguments for any function in imap"""
@@ -91,7 +91,7 @@ class MemoryMonitor:
91
91
  if proc.is_alive():
92
92
  try:
93
93
  memory += psutil.Process(proc.pid).memory_info().rss / 1024 / 1024
94
- except:
94
+ except Exception:
95
95
  pass
96
96
 
97
97
  self.pbar.set_description(
@@ -0,0 +1,21 @@
1
+ import importlib as _importlib
2
+
3
+ submodules = [
4
+ "changepoint",
5
+ "cpic",
6
+ "metrics",
7
+ "predict",
8
+ "sequence",
9
+ ]
10
+
11
+ __all__ = submodules
12
+
13
+
14
+ def __getattr__(name):
15
+ if name in submodules:
16
+ return _importlib.import_module(f"poreflow.steps.{name}")
17
+ else:
18
+ try:
19
+ return globals()[name]
20
+ except KeyError:
21
+ raise AttributeError(f"Module 'poreflow.steps' has no attribute '{name}'")
@@ -4,13 +4,14 @@ from collections import deque
4
4
  from importlib import resources as impresources
5
5
  from itertools import islice
6
6
 
7
- import poreflow as pf
8
- from poreflow.classification import assets
9
-
10
7
  import numpy as np
11
8
  import pandas as pd
12
9
  import matplotlib.pyplot as plt
13
10
 
11
+ import poreflow as pf
12
+ from poreflow.steps import assets
13
+
14
+
14
15
  inp_file = impresources.files(assets) / "DNA_6mer_prediction_model_cv.csv"
15
16
 
16
17
  DNA_MODEL = pd.read_csv(inp_file)
@@ -39,7 +40,7 @@ def predict(sequence, model: pd.DataFrame = None, k_mer_size=6, nan_policy="omit
39
40
  half-steps. Returns a signal from 3-prime end to 5-prime end.
40
41
 
41
42
  Args:
42
- sequence (str): Sequence in 5-prime to 3-prime format.
43
+ sequence (str): Sequence in 5-prime to 3-prime format. Sequence may have lower case letters.
43
44
  model: Dataframe of DNA model
44
45
  k_mer_size: k-mer size. Defaults to 6.
45
46
  nan_policy: Whether to return NaN for the steps in the sequence that do not have a k-mer (at the beginning and
@@ -49,6 +50,7 @@ def predict(sequence, model: pd.DataFrame = None, k_mer_size=6, nan_policy="omit
49
50
  model = DNA_MODEL
50
51
 
51
52
  sequence = sequence[::-1] # Reverse the string (3'->5')
53
+ sequence = sequence.upper()
52
54
  constriction_kmer_offset = -4
53
55
 
54
56
  sub_6mer = list(sliding_window(sequence, k_mer_size))