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,170 @@
1
+ """Fixed-schema exact k-mer fingerprints."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from itertools import product
6
+
7
+ from dnakit.core._json import FrozenDict
8
+ from dnakit.descriptors import canonical_kmer, kmer_statistics
9
+ from dnakit.exceptions import ConfigurationError
10
+ from dnakit.fingerprints._shared import (
11
+ FingerprintAmbiguityPolicy,
12
+ FingerprintRepresentation,
13
+ KmerFingerprintMode,
14
+ SequenceInput,
15
+ coerce_enum,
16
+ sequence_and_id,
17
+ validate_bool,
18
+ validate_positive_int,
19
+ )
20
+ from dnakit.fingerprints.results import FingerprintResult, FingerprintValues, Numeric
21
+
22
+ DEFAULT_MAX_DIMENSION = 1_000_000
23
+
24
+
25
+ def _coerce_mode(value: KmerFingerprintMode | str) -> KmerFingerprintMode:
26
+ if value == "presence":
27
+ return KmerFingerprintMode.BINARY
28
+ return coerce_enum(value, KmerFingerprintMode, "k-mer fingerprint mode")
29
+
30
+
31
+ def _schema_dimension(k: int, canonical: bool, max_dimension: int) -> int:
32
+ raw_limit = max_dimension * 2 if canonical else max_dimension
33
+ raw_dimension = 1
34
+ for _ in range(k):
35
+ raw_dimension *= 4
36
+ if raw_dimension > raw_limit:
37
+ return max_dimension + 1
38
+ if not canonical:
39
+ return raw_dimension
40
+ fixed_reverse_complements = 0 if k % 2 else 4 ** (k // 2)
41
+ return (raw_dimension + fixed_reverse_complements) // 2
42
+
43
+
44
+ def _feature_names(k: int, canonical: bool) -> tuple[str, ...]:
45
+ words = ("".join(symbols) for symbols in product("ACGT", repeat=k))
46
+ if not canonical:
47
+ return tuple(words)
48
+ return tuple(sorted({canonical_kmer(word) for word in words}))
49
+
50
+
51
+ def _count_for(counts: FrozenDict, feature: str) -> int:
52
+ value = counts.get(feature, 0)
53
+ if isinstance(value, bool) or not isinstance(value, int):
54
+ raise ConfigurationError(
55
+ "The descriptor k-mer count result contained a non-integer value.",
56
+ code="INVALID_INTERNAL_KMER_COUNT",
57
+ context={"feature": feature, "value": value},
58
+ )
59
+ return value
60
+
61
+
62
+ def kmer(
63
+ value: SequenceInput,
64
+ *,
65
+ k: int,
66
+ canonical: bool = False,
67
+ mode: KmerFingerprintMode | str = KmerFingerprintMode.COUNT,
68
+ representation: FingerprintRepresentation | str = FingerprintRepresentation.DENSE,
69
+ ambiguity_policy: FingerprintAmbiguityPolicy | str = FingerprintAmbiguityPolicy.ERROR,
70
+ overlapping: bool = True,
71
+ cross_gaps: bool = False,
72
+ max_dimension: int = DEFAULT_MAX_DIMENSION,
73
+ ) -> FingerprintResult:
74
+ """Build a deterministic fixed-schema exact k-mer fingerprint.
75
+
76
+ The feature order is lexicographic over all A/C/G/T words. Canonical mode
77
+ collapses each word with its reverse complement and sorts the unique
78
+ representatives. ``presence`` is accepted as an alias for ``binary``.
79
+ """
80
+
81
+ validate_positive_int(k, "k")
82
+ validate_positive_int(max_dimension, "max_dimension")
83
+ validate_bool(canonical, "canonical")
84
+ validate_bool(overlapping, "overlapping")
85
+ validate_bool(cross_gaps, "cross_gaps")
86
+ resolved_mode = _coerce_mode(mode)
87
+ resolved_representation = coerce_enum(
88
+ representation,
89
+ FingerprintRepresentation,
90
+ "fingerprint representation",
91
+ )
92
+ resolved_ambiguity = coerce_enum(
93
+ ambiguity_policy,
94
+ FingerprintAmbiguityPolicy,
95
+ "fingerprint ambiguity policy",
96
+ )
97
+ dimension = _schema_dimension(k, canonical, max_dimension)
98
+ if dimension > max_dimension:
99
+ raise ConfigurationError(
100
+ "The requested exact k-mer schema exceeds max_dimension.",
101
+ code="FINGERPRINT_DIMENSION_LIMIT",
102
+ context={
103
+ "k": k,
104
+ "canonical": canonical,
105
+ "dimension_lower_bound": dimension,
106
+ "max_dimension": max_dimension,
107
+ },
108
+ hint="Reduce k, use canonical=True, or explicitly raise max_dimension.",
109
+ )
110
+
111
+ sequence, sequence_id = sequence_and_id(value)
112
+ features = _feature_names(k, canonical)
113
+ statistics = kmer_statistics(
114
+ sequence,
115
+ k,
116
+ overlapping=overlapping,
117
+ canonical=canonical,
118
+ ambiguity_policy=resolved_ambiguity.value,
119
+ cross_gaps=cross_gaps,
120
+ )
121
+ counts = statistics.counts
122
+ count_values = tuple(_count_for(counts, feature) for feature in features)
123
+ if resolved_mode is KmerFingerprintMode.COUNT:
124
+ ordered_values: tuple[Numeric, ...] = count_values
125
+ elif resolved_mode is KmerFingerprintMode.BINARY:
126
+ ordered_values = tuple(int(count != 0) for count in count_values)
127
+ else:
128
+ denominator = statistics.denominator
129
+ ordered_values = tuple(
130
+ count / denominator if denominator else 0.0 for count in count_values
131
+ )
132
+
133
+ materialized: FingerprintValues
134
+ if resolved_representation is FingerprintRepresentation.DENSE:
135
+ materialized = ordered_values
136
+ else:
137
+ materialized = FrozenDict(
138
+ {
139
+ feature: numeric
140
+ for feature, numeric in zip(features, ordered_values, strict=True)
141
+ if numeric != 0
142
+ }
143
+ )
144
+ return FingerprintResult(
145
+ name="kmer",
146
+ method="exact_fixed_schema_kmer",
147
+ schema_version="dnakit.kmer.acgt.v1",
148
+ sequence_id=sequence_id,
149
+ symbol_length=sequence.symbol_length,
150
+ gap_count=statistics.gap_count,
151
+ unknown_gap_count=statistics.unknown_gap_count,
152
+ k=k,
153
+ canonical=canonical,
154
+ mode=resolved_mode,
155
+ representation=resolved_representation,
156
+ ambiguity_policy=resolved_ambiguity,
157
+ overlapping=overlapping,
158
+ cross_gaps=cross_gaps,
159
+ feature_names=features,
160
+ values=materialized,
161
+ observation_count=statistics.denominator,
162
+ ignored_ambiguity_count=statistics.ignored_ambiguity_count,
163
+ max_dimension=max_dimension,
164
+ )
165
+
166
+
167
+ kmer_fingerprint = kmer
168
+
169
+
170
+ __all__ = ["DEFAULT_MAX_DIMENSION", "kmer", "kmer_fingerprint"]