dnakit 0.1.0.dev0__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.
Files changed (210) hide show
  1. dnakit/__init__.py +108 -0
  2. dnakit/_version.py +5 -0
  3. dnakit/alignment/__init__.py +6 -0
  4. dnakit/alignment/pairwise.py +512 -0
  5. dnakit/alignment/results.py +188 -0
  6. dnakit/backends/__init__.py +80 -0
  7. dnakit/backends/external.py +517 -0
  8. dnakit/backends/registry.py +207 -0
  9. dnakit/batch.py +452 -0
  10. dnakit/cache/__init__.py +5 -0
  11. dnakit/cache/store.py +424 -0
  12. dnakit/chunking.py +920 -0
  13. dnakit/cli/__init__.py +5 -0
  14. dnakit/cli/__main__.py +6 -0
  15. dnakit/cli/app.py +814 -0
  16. dnakit/cli/workflow.py +94 -0
  17. dnakit/config/__init__.py +5 -0
  18. dnakit/config/loader.py +381 -0
  19. dnakit/core/__init__.py +80 -0
  20. dnakit/core/_json.py +206 -0
  21. dnakit/core/backend_info.py +70 -0
  22. dnakit/core/collection.py +163 -0
  23. dnakit/core/coordinates.py +295 -0
  24. dnakit/core/enums.py +95 -0
  25. dnakit/core/facade.py +719 -0
  26. dnakit/core/feature.py +90 -0
  27. dnakit/core/gap.py +82 -0
  28. dnakit/core/issues.py +62 -0
  29. dnakit/core/provenance.py +305 -0
  30. dnakit/core/record.py +161 -0
  31. dnakit/core/results.py +134 -0
  32. dnakit/core/sequence.py +327 -0
  33. dnakit/datasets/__init__.py +100 -0
  34. dnakit/datasets/_advanced_shared.py +198 -0
  35. dnakit/datasets/_metadata.py +33 -0
  36. dnakit/datasets/advanced_deduplicate.py +183 -0
  37. dnakit/datasets/advanced_split.py +302 -0
  38. dnakit/datasets/clustering.py +286 -0
  39. dnakit/datasets/config.py +531 -0
  40. dnakit/datasets/deduplicate.py +303 -0
  41. dnakit/datasets/evaluation.py +244 -0
  42. dnakit/datasets/filter.py +135 -0
  43. dnakit/datasets/neural_clustering.py +221 -0
  44. dnakit/datasets/results.py +520 -0
  45. dnakit/datasets/split.py +450 -0
  46. dnakit/descriptors/__init__.py +102 -0
  47. dnakit/descriptors/_dinucleotide.py +345 -0
  48. dnakit/descriptors/_shared.py +180 -0
  49. dnakit/descriptors/all.py +917 -0
  50. dnakit/descriptors/basic.py +193 -0
  51. dnakit/descriptors/codon.py +195 -0
  52. dnakit/descriptors/complexity.py +201 -0
  53. dnakit/descriptors/entropy.py +101 -0
  54. dnakit/descriptors/homopolymer.py +105 -0
  55. dnakit/descriptors/kmer.py +88 -0
  56. dnakit/descriptors/results.py +286 -0
  57. dnakit/descriptors/schema.py +414 -0
  58. dnakit/descriptors/window.py +203 -0
  59. dnakit/download/__init__.py +54 -0
  60. dnakit/download/catalogs.py +166 -0
  61. dnakit/download/ena.py +131 -0
  62. dnakit/download/encode.py +103 -0
  63. dnakit/download/files.py +469 -0
  64. dnakit/download/indexes.py +233 -0
  65. dnakit/download/metadata.py +164 -0
  66. dnakit/download/models.py +227 -0
  67. dnakit/download/ncbi.py +333 -0
  68. dnakit/download/sequence.py +133 -0
  69. dnakit/download/ucsc.py +99 -0
  70. dnakit/evaluation/__init__.py +81 -0
  71. dnakit/evaluation/_shared.py +288 -0
  72. dnakit/evaluation/collection.py +270 -0
  73. dnakit/evaluation/config.py +591 -0
  74. dnakit/evaluation/distribution.py +287 -0
  75. dnakit/evaluation/frechet.py +223 -0
  76. dnakit/evaluation/generative.py +381 -0
  77. dnakit/evaluation/reference.py +409 -0
  78. dnakit/evaluation/results.py +137 -0
  79. dnakit/evaluation/scorecard.py +211 -0
  80. dnakit/evaluation/sequence.py +403 -0
  81. dnakit/evaluation/synthesis.py +249 -0
  82. dnakit/exceptions.py +189 -0
  83. dnakit/fingerprints/__init__.py +109 -0
  84. dnakit/fingerprints/_shared.py +116 -0
  85. dnakit/fingerprints/advanced.py +829 -0
  86. dnakit/fingerprints/bit.py +229 -0
  87. dnakit/fingerprints/encoding.py +351 -0
  88. dnakit/fingerprints/kmer.py +170 -0
  89. dnakit/fingerprints/results.py +531 -0
  90. dnakit/fingerprints/sketch.py +246 -0
  91. dnakit/io/__init__.py +112 -0
  92. dnakit/io/_advanced_common.py +105 -0
  93. dnakit/io/_formats.py +994 -0
  94. dnakit/io/annotations.py +1179 -0
  95. dnakit/io/api.py +759 -0
  96. dnakit/io/config.py +315 -0
  97. dnakit/io/genbank.py +523 -0
  98. dnakit/io/indexed.py +1146 -0
  99. dnakit/io/metadata.py +452 -0
  100. dnakit/io/parquet.py +56 -0
  101. dnakit/io/results.py +131 -0
  102. dnakit/io/source.py +138 -0
  103. dnakit/io/tables.py +1237 -0
  104. dnakit/molbio/__init__.py +101 -0
  105. dnakit/molbio/_shared.py +266 -0
  106. dnakit/molbio/assembly.py +279 -0
  107. dnakit/molbio/crispr.py +181 -0
  108. dnakit/molbio/optimization.py +897 -0
  109. dnakit/molbio/primer3_design.py +667 -0
  110. dnakit/molbio/primers.py +899 -0
  111. dnakit/molbio/restriction.py +573 -0
  112. dnakit/molbio/results.py +583 -0
  113. dnakit/ops/__init__.py +588 -0
  114. dnakit/ops/_common.py +201 -0
  115. dnakit/ops/circular.py +193 -0
  116. dnakit/ops/concat.py +204 -0
  117. dnakit/ops/direction.py +27 -0
  118. dnakit/ops/edit.py +443 -0
  119. dnakit/ops/evolution.py +991 -0
  120. dnakit/ops/mutation.py +151 -0
  121. dnakit/ops/records.py +1012 -0
  122. dnakit/ops/translation.py +257 -0
  123. dnakit/patterns/__init__.py +81 -0
  124. dnakit/patterns/_shared.py +282 -0
  125. dnakit/patterns/coding.py +360 -0
  126. dnakit/patterns/crispr.py +337 -0
  127. dnakit/patterns/motif.py +721 -0
  128. dnakit/patterns/regions.py +341 -0
  129. dnakit/patterns/repeats.py +480 -0
  130. dnakit/patterns/restriction.py +281 -0
  131. dnakit/patterns/results.py +411 -0
  132. dnakit/py.typed +1 -0
  133. dnakit/references/__init__.py +27 -0
  134. dnakit/references/models.py +155 -0
  135. dnakit/references/ncbi.py +785 -0
  136. dnakit/representations/__init__.py +29 -0
  137. dnakit/representations/backends.py +928 -0
  138. dnakit/representations/checkpoints.py +356 -0
  139. dnakit/representations/extraction.py +220 -0
  140. dnakit/representations/models.py +395 -0
  141. dnakit/representations/results.py +79 -0
  142. dnakit/search/__init__.py +132 -0
  143. dnakit/search/_http.py +271 -0
  144. dnakit/search/_shared.py +108 -0
  145. dnakit/search/blast.py +516 -0
  146. dnakit/search/ena.py +245 -0
  147. dnakit/search/encode.py +102 -0
  148. dnakit/search/ensembl.py +874 -0
  149. dnakit/search/models.py +159 -0
  150. dnakit/search/ncbi.py +756 -0
  151. dnakit/search/ucsc.py +388 -0
  152. dnakit/secondary_structure/__init__.py +38 -0
  153. dnakit/secondary_structure/dotbracket.py +410 -0
  154. dnakit/secondary_structure/nupack.py +589 -0
  155. dnakit/secondary_structure/results.py +142 -0
  156. dnakit/similarity/__init__.py +125 -0
  157. dnakit/similarity/_shared.py +152 -0
  158. dnakit/similarity/approximate.py +258 -0
  159. dnakit/similarity/compare.py +162 -0
  160. dnakit/similarity/dashing.py +936 -0
  161. dnakit/similarity/distance.py +279 -0
  162. dnakit/similarity/index.py +365 -0
  163. dnakit/similarity/matrix.py +254 -0
  164. dnakit/similarity/results.py +676 -0
  165. dnakit/similarity/search.py +286 -0
  166. dnakit/similarity/sketch.py +96 -0
  167. dnakit/similarity/vector.py +662 -0
  168. dnakit/standardize/__init__.py +77 -0
  169. dnakit/standardize/_shared.py +100 -0
  170. dnakit/standardize/config.py +411 -0
  171. dnakit/standardize/gaps.py +1060 -0
  172. dnakit/standardize/normalize.py +565 -0
  173. dnakit/standardize/results.py +247 -0
  174. dnakit/standardize/validate.py +487 -0
  175. dnakit/structure3d/__init__.py +47 -0
  176. dnakit/structure3d/_shared.py +47 -0
  177. dnakit/structure3d/geometry.py +773 -0
  178. dnakit/structure3d/pdb.py +253 -0
  179. dnakit/structure3d/results.py +233 -0
  180. dnakit/structure3d/threedna.py +174 -0
  181. dnakit/thermodynamics/__init__.py +112 -0
  182. dnakit/thermodynamics/_shared.py +92 -0
  183. dnakit/thermodynamics/backends.py +653 -0
  184. dnakit/thermodynamics/calculations.py +837 -0
  185. dnakit/thermodynamics/config.py +175 -0
  186. dnakit/thermodynamics/equilibrium.py +340 -0
  187. dnakit/thermodynamics/optics.py +385 -0
  188. dnakit/thermodynamics/parameters.py +79 -0
  189. dnakit/thermodynamics/results.py +445 -0
  190. dnakit/visualization/__init__.py +43 -0
  191. dnakit/visualization/_svg.py +185 -0
  192. dnakit/visualization/advanced.py +314 -0
  193. dnakit/visualization/config.py +255 -0
  194. dnakit/visualization/export.py +349 -0
  195. dnakit/visualization/matrix.py +279 -0
  196. dnakit/visualization/report.py +431 -0
  197. dnakit/visualization/results.py +236 -0
  198. dnakit/visualization/sequence.py +459 -0
  199. dnakit/workflows/__init__.py +45 -0
  200. dnakit/workflows/manifest.py +365 -0
  201. dnakit/workflows/runner.py +1548 -0
  202. dnakit/workflows/schema.py +898 -0
  203. dnakit-0.1.0.dev0.dist-info/METADATA +126 -0
  204. dnakit-0.1.0.dev0.dist-info/RECORD +210 -0
  205. dnakit-0.1.0.dev0.dist-info/WHEEL +5 -0
  206. dnakit-0.1.0.dev0.dist-info/entry_points.txt +2 -0
  207. dnakit-0.1.0.dev0.dist-info/licenses/DISCLAIMER.md +26 -0
  208. dnakit-0.1.0.dev0.dist-info/licenses/LICENSE +21 -0
  209. dnakit-0.1.0.dev0.dist-info/licenses/THIRD_PARTY_NOTICES.md +73 -0
  210. dnakit-0.1.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,162 @@
1
+ """Unified scalar comparison dispatch for sequence and fingerprint inputs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TypeAlias, cast
6
+
7
+ from dnakit.core import DNA, DNARecord, DNASequence
8
+ from dnakit.core._json import FrozenDict
9
+ from dnakit.exceptions import ConfigurationError
10
+ from dnakit.similarity._shared import SequenceInput, sequence_and_id, validate_bool
11
+ from dnakit.similarity.distance import edit_distance, hamming_distance
12
+ from dnakit.similarity.results import DistanceResult, SimilarityResult
13
+ from dnakit.similarity.vector import (
14
+ KmerMetric,
15
+ KmerMode,
16
+ KmerVectorInput,
17
+ VectorInput,
18
+ VectorMetric,
19
+ WeightInput,
20
+ ZeroVectorPolicy,
21
+ fingerprint_similarity,
22
+ kmer_similarity,
23
+ kmer_vector_similarity,
24
+ )
25
+
26
+ ComparisonInput: TypeAlias = SequenceInput | VectorInput
27
+ ComparisonResult: TypeAlias = SimilarityResult | DistanceResult
28
+
29
+
30
+ def _as_sequence(value: ComparisonInput, *, role: str) -> SequenceInput:
31
+ if not isinstance(value, (DNA, DNASequence, DNARecord)):
32
+ raise ConfigurationError(
33
+ f"{role} must be DNASequence or DNARecord for this method.",
34
+ code="INVALID_COMPARISON_INPUT",
35
+ context={"role": role, "input_type": type(value).__name__},
36
+ )
37
+ return value
38
+
39
+
40
+ def exact_similarity(
41
+ left: SequenceInput,
42
+ right: SequenceInput,
43
+ *,
44
+ reverse_complement: bool = False,
45
+ ) -> SimilarityResult:
46
+ """Return 1 for literal full-sequence equality, otherwise 0."""
47
+
48
+ validate_bool(reverse_complement, "reverse_complement")
49
+ left_sequence, left_id = sequence_and_id(left, role="left")
50
+ right_sequence, right_id = sequence_and_id(right, role="right")
51
+ forward_equal = left_sequence.symbols == right_sequence.symbols
52
+ reverse_equal = (
53
+ reverse_complement and left_sequence.reverse_complement().symbols == right_sequence.symbols
54
+ )
55
+ return SimilarityResult(
56
+ name="exact_similarity",
57
+ method="literal_full_sequence_equality",
58
+ value=float(forward_equal or reverse_equal),
59
+ value_kind="similarity",
60
+ left_id=left_id,
61
+ right_id=right_id,
62
+ left_dimension=left_sequence.symbol_length,
63
+ right_dimension=right_sequence.symbol_length,
64
+ parameters=FrozenDict({"reverse_complement": reverse_complement}),
65
+ components=FrozenDict(
66
+ {"forward_equal": forward_equal, "reverse_complement_equal": reverse_equal}
67
+ ),
68
+ zero_vector_policy=None,
69
+ iupac_matching="literal",
70
+ )
71
+
72
+
73
+ def compare(
74
+ left: ComparisonInput,
75
+ right: ComparisonInput,
76
+ *,
77
+ method: str,
78
+ k: int | None = None,
79
+ mode: KmerMode = "set",
80
+ canonical: bool = False,
81
+ overlapping: bool = True,
82
+ reverse_complement: bool = False,
83
+ weights: WeightInput | None = None,
84
+ zero_vector_policy: ZeroVectorPolicy = "identity",
85
+ return_path: bool = False,
86
+ ) -> ComparisonResult:
87
+ """Dispatch one explicit native comparison method.
88
+
89
+ Supported names are ``exact``, ``hamming``, ``edit``,
90
+ ``kmer_jaccard``, ``kmer_containment``, ``kmer_cosine``, and the
91
+ fingerprint/vector methods ``tanimoto``, ``jaccard``, ``cosine``,
92
+ ``euclidean``, and ``manhattan``.
93
+ """
94
+
95
+ if not isinstance(method, str) or not method:
96
+ raise ConfigurationError("Comparison method must be a non-empty string.")
97
+ if method == "exact":
98
+ return exact_similarity(
99
+ _as_sequence(left, role="left"),
100
+ _as_sequence(right, role="right"),
101
+ reverse_complement=reverse_complement,
102
+ )
103
+ if method == "hamming":
104
+ return hamming_distance(
105
+ _as_sequence(left, role="left"),
106
+ _as_sequence(right, role="right"),
107
+ )
108
+ if method == "edit":
109
+ return edit_distance(
110
+ _as_sequence(left, role="left"),
111
+ _as_sequence(right, role="right"),
112
+ return_path=return_path,
113
+ )
114
+ if method in ("kmer_jaccard", "kmer_containment", "kmer_cosine"):
115
+ metric = cast(KmerMetric, method.removeprefix("kmer_"))
116
+ left_is_sequence = isinstance(left, (DNA, DNASequence, DNARecord))
117
+ right_is_sequence = isinstance(right, (DNA, DNASequence, DNARecord))
118
+ if left_is_sequence != right_is_sequence:
119
+ raise ConfigurationError(
120
+ "k-mer comparison cannot mix a DNA sequence with a k-mer vector.",
121
+ code="MIXED_COMPARISON_INPUTS",
122
+ )
123
+ if left_is_sequence and k is None:
124
+ raise ConfigurationError(
125
+ "A positive k is required for k-mer comparison.",
126
+ code="MISSING_KMER_SIZE",
127
+ )
128
+ if left_is_sequence:
129
+ assert k is not None
130
+ return kmer_similarity(
131
+ _as_sequence(left, role="left"),
132
+ _as_sequence(right, role="right"),
133
+ k=k,
134
+ metric=metric,
135
+ mode=mode,
136
+ canonical=canonical,
137
+ overlapping=overlapping,
138
+ zero_vector_policy=zero_vector_policy,
139
+ )
140
+ return kmer_vector_similarity(
141
+ cast(KmerVectorInput, left),
142
+ cast(KmerVectorInput, right),
143
+ metric=metric,
144
+ mode=mode,
145
+ zero_vector_policy=zero_vector_policy,
146
+ )
147
+ if method in ("tanimoto", "jaccard", "cosine", "euclidean", "manhattan"):
148
+ return fingerprint_similarity(
149
+ cast(VectorInput, left),
150
+ cast(VectorInput, right),
151
+ metric=cast(VectorMetric, method),
152
+ weights=weights,
153
+ zero_vector_policy=zero_vector_policy,
154
+ )
155
+ raise ConfigurationError(
156
+ "Unknown comparison method.",
157
+ code="INVALID_COMPARISON_METHOD",
158
+ context={"method": method},
159
+ )
160
+
161
+
162
+ __all__ = ["compare", "exact_similarity"]