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
dnakit/ops/__init__.py ADDED
@@ -0,0 +1,588 @@
1
+ """Public immutable operations with unified sequence/record method names."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Iterable, Mapping
6
+ from typing import TypeAlias, overload
7
+
8
+ from dnakit.core import DNA, DNARecord, DNASequence
9
+ from dnakit.ops.circular import (
10
+ CircularOperationResult,
11
+ )
12
+ from dnakit.ops.circular import (
13
+ canonical_origin as _canonical_origin_sequence,
14
+ )
15
+ from dnakit.ops.circular import (
16
+ rotate as _rotate_sequence,
17
+ )
18
+ from dnakit.ops.concat import concat, concat_overlap
19
+ from dnakit.ops.direction import (
20
+ complement,
21
+ reverse,
22
+ )
23
+ from dnakit.ops.direction import (
24
+ reverse_complement as _reverse_complement_sequence,
25
+ )
26
+ from dnakit.ops.edit import (
27
+ Edit,
28
+ EditResult,
29
+ circular_subsequence,
30
+ subsequence,
31
+ )
32
+ from dnakit.ops.edit import (
33
+ delete as _delete_sequence,
34
+ )
35
+ from dnakit.ops.edit import (
36
+ insert as _insert_sequence,
37
+ )
38
+ from dnakit.ops.edit import (
39
+ mask as _mask_sequence,
40
+ )
41
+ from dnakit.ops.edit import (
42
+ substitute as _substitute_sequence,
43
+ )
44
+ from dnakit.ops.edit import (
45
+ trim as _trim_sequence,
46
+ )
47
+ from dnakit.ops.evolution import (
48
+ DEFAULT_EVOLUTION_AUGMENTATIONS,
49
+ CrossoverResult,
50
+ EvolutionAugmentation,
51
+ EvolutionGenerationResult,
52
+ EvolutionStep,
53
+ IndelOperation,
54
+ KmerShuffleResult,
55
+ RearrangementOperation,
56
+ RearrangementResult,
57
+ crossover,
58
+ evolution_generate,
59
+ indel_generate,
60
+ kmer_shuffle,
61
+ rearrange_generate,
62
+ )
63
+ from dnakit.ops.mutation import MutationResult, mutate
64
+ from dnakit.ops.records import (
65
+ FeatureChange,
66
+ FeatureChangeAction,
67
+ FeatureOverlapPolicy,
68
+ LetterAnnotationAction,
69
+ LetterAnnotationPolicy,
70
+ RecordOperationResult,
71
+ canonical_origin_record,
72
+ delete_record,
73
+ insert_record,
74
+ mask_record,
75
+ reverse_complement_record,
76
+ rotate_record,
77
+ substitute_record,
78
+ trim_record,
79
+ )
80
+ from dnakit.ops.translation import transcribe, translate
81
+
82
+ OperationInput: TypeAlias = DNA | DNARecord | DNASequence
83
+ FragmentInput: TypeAlias = DNA | DNARecord | DNASequence | str
84
+ OperationResult: TypeAlias = DNA | EditResult | CircularOperationResult | RecordOperationResult
85
+
86
+
87
+ def _record_input(value: OperationInput) -> DNARecord | None:
88
+ if isinstance(value, DNA):
89
+ return value.record
90
+ if isinstance(value, DNARecord):
91
+ return value
92
+ return None
93
+
94
+
95
+ def _fragment_input(value: FragmentInput) -> DNASequence | str:
96
+ if isinstance(value, DNA):
97
+ return value.sequence
98
+ if isinstance(value, DNARecord):
99
+ return value.sequence
100
+ return value
101
+
102
+
103
+ def _sequence_input(value: OperationInput) -> DNASequence:
104
+ if isinstance(value, DNASequence):
105
+ return value
106
+ raise TypeError("value must be DNA, DNARecord, or DNASequence.")
107
+
108
+
109
+ def _public_record_result(
110
+ value: OperationInput, result: RecordOperationResult
111
+ ) -> DNA | RecordOperationResult:
112
+ if not isinstance(value, DNA):
113
+ return result
114
+ return DNA(
115
+ result.record,
116
+ name=value.name,
117
+ source=value.source,
118
+ version=value.version,
119
+ collection_metadata=value.collection_metadata,
120
+ )
121
+
122
+
123
+ @overload
124
+ def insert(
125
+ value: DNA,
126
+ position: int,
127
+ fragment: FragmentInput,
128
+ *,
129
+ feature_policy: FeatureOverlapPolicy = "preserve",
130
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
131
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
132
+ ) -> DNA: ...
133
+
134
+
135
+ @overload
136
+ def insert(
137
+ value: DNARecord,
138
+ position: int,
139
+ fragment: FragmentInput,
140
+ *,
141
+ feature_policy: FeatureOverlapPolicy = "preserve",
142
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
143
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
144
+ ) -> RecordOperationResult: ...
145
+
146
+
147
+ @overload
148
+ def insert(
149
+ value: DNASequence,
150
+ position: int,
151
+ fragment: FragmentInput,
152
+ *,
153
+ feature_policy: FeatureOverlapPolicy = "preserve",
154
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
155
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
156
+ ) -> EditResult: ...
157
+
158
+
159
+ def insert(
160
+ value: OperationInput,
161
+ position: int,
162
+ fragment: FragmentInput,
163
+ *,
164
+ feature_policy: FeatureOverlapPolicy = "preserve",
165
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
166
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
167
+ ) -> DNA | EditResult | RecordOperationResult:
168
+ """Insert into a sequence or annotated record using one public name."""
169
+
170
+ record = _record_input(value)
171
+ resolved_fragment = _fragment_input(fragment)
172
+ if record is not None:
173
+ result = insert_record(
174
+ record,
175
+ position,
176
+ resolved_fragment,
177
+ feature_policy=feature_policy,
178
+ replacement_annotations=replacement_annotations,
179
+ letter_annotation_policy=letter_annotation_policy,
180
+ )
181
+ return _public_record_result(value, result)
182
+ return _insert_sequence(_sequence_input(value), position, resolved_fragment)
183
+
184
+
185
+ @overload
186
+ def delete(
187
+ value: DNA,
188
+ start: int,
189
+ end: int,
190
+ *,
191
+ feature_policy: FeatureOverlapPolicy = "preserve",
192
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
193
+ ) -> DNA: ...
194
+
195
+
196
+ @overload
197
+ def delete(
198
+ value: DNARecord,
199
+ start: int,
200
+ end: int,
201
+ *,
202
+ feature_policy: FeatureOverlapPolicy = "preserve",
203
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
204
+ ) -> RecordOperationResult: ...
205
+
206
+
207
+ @overload
208
+ def delete(
209
+ value: DNASequence,
210
+ start: int,
211
+ end: int,
212
+ *,
213
+ feature_policy: FeatureOverlapPolicy = "preserve",
214
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
215
+ ) -> EditResult: ...
216
+
217
+
218
+ def delete(
219
+ value: OperationInput,
220
+ start: int,
221
+ end: int,
222
+ *,
223
+ feature_policy: FeatureOverlapPolicy = "preserve",
224
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
225
+ ) -> DNA | EditResult | RecordOperationResult:
226
+ """Delete from a sequence or annotated record using one public name."""
227
+
228
+ record = _record_input(value)
229
+ if record is not None:
230
+ result = delete_record(
231
+ record,
232
+ start,
233
+ end,
234
+ feature_policy=feature_policy,
235
+ letter_annotation_policy=letter_annotation_policy,
236
+ )
237
+ return _public_record_result(value, result)
238
+ return _delete_sequence(_sequence_input(value), start, end)
239
+
240
+
241
+ @overload
242
+ def substitute(
243
+ value: DNA,
244
+ start: int,
245
+ end: int,
246
+ fragment: FragmentInput,
247
+ *,
248
+ feature_policy: FeatureOverlapPolicy = "preserve",
249
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
250
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
251
+ ) -> DNA: ...
252
+
253
+
254
+ @overload
255
+ def substitute(
256
+ value: DNARecord,
257
+ start: int,
258
+ end: int,
259
+ fragment: FragmentInput,
260
+ *,
261
+ feature_policy: FeatureOverlapPolicy = "preserve",
262
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
263
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
264
+ ) -> RecordOperationResult: ...
265
+
266
+
267
+ @overload
268
+ def substitute(
269
+ value: DNASequence,
270
+ start: int,
271
+ end: int,
272
+ fragment: FragmentInput,
273
+ *,
274
+ feature_policy: FeatureOverlapPolicy = "preserve",
275
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
276
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
277
+ ) -> EditResult: ...
278
+
279
+
280
+ def substitute(
281
+ value: OperationInput,
282
+ start: int,
283
+ end: int,
284
+ fragment: FragmentInput,
285
+ *,
286
+ feature_policy: FeatureOverlapPolicy = "preserve",
287
+ replacement_annotations: Mapping[str, Iterable[int | float]] | None = None,
288
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
289
+ ) -> DNA | EditResult | RecordOperationResult:
290
+ """Substitute sequence or record content using one public name."""
291
+
292
+ record = _record_input(value)
293
+ resolved_fragment = _fragment_input(fragment)
294
+ if record is not None:
295
+ result = substitute_record(
296
+ record,
297
+ start,
298
+ end,
299
+ resolved_fragment,
300
+ feature_policy=feature_policy,
301
+ replacement_annotations=replacement_annotations,
302
+ letter_annotation_policy=letter_annotation_policy,
303
+ )
304
+ return _public_record_result(value, result)
305
+ return _substitute_sequence(_sequence_input(value), start, end, resolved_fragment)
306
+
307
+
308
+ @overload
309
+ def mask(
310
+ value: DNA,
311
+ intervals: Iterable[tuple[int, int]],
312
+ *,
313
+ symbol: str = "N",
314
+ feature_policy: FeatureOverlapPolicy = "preserve",
315
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
316
+ ) -> DNA: ...
317
+
318
+
319
+ @overload
320
+ def mask(
321
+ value: DNARecord,
322
+ intervals: Iterable[tuple[int, int]],
323
+ *,
324
+ symbol: str = "N",
325
+ feature_policy: FeatureOverlapPolicy = "preserve",
326
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
327
+ ) -> RecordOperationResult: ...
328
+
329
+
330
+ @overload
331
+ def mask(
332
+ value: DNASequence,
333
+ intervals: Iterable[tuple[int, int]],
334
+ *,
335
+ symbol: str = "N",
336
+ feature_policy: FeatureOverlapPolicy = "preserve",
337
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
338
+ ) -> EditResult: ...
339
+
340
+
341
+ def mask(
342
+ value: OperationInput,
343
+ intervals: Iterable[tuple[int, int]],
344
+ *,
345
+ symbol: str = "N",
346
+ feature_policy: FeatureOverlapPolicy = "preserve",
347
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
348
+ ) -> DNA | EditResult | RecordOperationResult:
349
+ """Mask a sequence or annotated record using one public name."""
350
+
351
+ record = _record_input(value)
352
+ if record is not None:
353
+ result = mask_record(
354
+ record,
355
+ intervals,
356
+ symbol=symbol,
357
+ feature_policy=feature_policy,
358
+ letter_annotation_policy=letter_annotation_policy,
359
+ )
360
+ return _public_record_result(value, result)
361
+ return _mask_sequence(_sequence_input(value), intervals, symbol=symbol)
362
+
363
+
364
+ @overload
365
+ def trim(
366
+ value: DNA,
367
+ *,
368
+ left: int = 0,
369
+ right: int = 0,
370
+ feature_policy: FeatureOverlapPolicy = "preserve",
371
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
372
+ ) -> DNA: ...
373
+
374
+
375
+ @overload
376
+ def trim(
377
+ value: DNARecord,
378
+ *,
379
+ left: int = 0,
380
+ right: int = 0,
381
+ feature_policy: FeatureOverlapPolicy = "preserve",
382
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
383
+ ) -> RecordOperationResult: ...
384
+
385
+
386
+ @overload
387
+ def trim(
388
+ value: DNASequence,
389
+ *,
390
+ left: int = 0,
391
+ right: int = 0,
392
+ feature_policy: FeatureOverlapPolicy = "preserve",
393
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
394
+ ) -> EditResult: ...
395
+
396
+
397
+ def trim(
398
+ value: OperationInput,
399
+ *,
400
+ left: int = 0,
401
+ right: int = 0,
402
+ feature_policy: FeatureOverlapPolicy = "preserve",
403
+ letter_annotation_policy: LetterAnnotationPolicy = "error",
404
+ ) -> DNA | EditResult | RecordOperationResult:
405
+ """Trim a sequence or annotated record using one public name."""
406
+
407
+ record = _record_input(value)
408
+ if record is not None:
409
+ result = trim_record(
410
+ record,
411
+ left=left,
412
+ right=right,
413
+ feature_policy=feature_policy,
414
+ letter_annotation_policy=letter_annotation_policy,
415
+ )
416
+ return _public_record_result(value, result)
417
+ return _trim_sequence(_sequence_input(value), left=left, right=right)
418
+
419
+
420
+ @overload
421
+ def reverse_complement(
422
+ value: DNASequence,
423
+ *,
424
+ feature_policy: FeatureOverlapPolicy = "preserve",
425
+ ) -> DNASequence: ...
426
+
427
+
428
+ @overload
429
+ def reverse_complement(
430
+ value: DNA,
431
+ *,
432
+ feature_policy: FeatureOverlapPolicy = "preserve",
433
+ ) -> DNA: ...
434
+
435
+
436
+ @overload
437
+ def reverse_complement(
438
+ value: DNARecord,
439
+ *,
440
+ feature_policy: FeatureOverlapPolicy = "preserve",
441
+ ) -> RecordOperationResult: ...
442
+
443
+
444
+ def reverse_complement(
445
+ value: OperationInput,
446
+ *,
447
+ feature_policy: FeatureOverlapPolicy = "preserve",
448
+ ) -> DNA | DNASequence | RecordOperationResult:
449
+ """Reverse-complement sequence or record content using one public name."""
450
+
451
+ record = _record_input(value)
452
+ if record is not None:
453
+ result = reverse_complement_record(record, feature_policy=feature_policy)
454
+ return _public_record_result(value, result)
455
+ return _reverse_complement_sequence(_sequence_input(value))
456
+
457
+
458
+ @overload
459
+ def rotate(
460
+ value: DNASequence,
461
+ offset: int,
462
+ *,
463
+ feature_policy: FeatureOverlapPolicy = "split",
464
+ ) -> CircularOperationResult: ...
465
+
466
+
467
+ @overload
468
+ def rotate(
469
+ value: DNA,
470
+ offset: int,
471
+ *,
472
+ feature_policy: FeatureOverlapPolicy = "split",
473
+ ) -> DNA: ...
474
+
475
+
476
+ @overload
477
+ def rotate(
478
+ value: DNARecord,
479
+ offset: int,
480
+ *,
481
+ feature_policy: FeatureOverlapPolicy = "split",
482
+ ) -> RecordOperationResult: ...
483
+
484
+
485
+ def rotate(
486
+ value: OperationInput,
487
+ offset: int,
488
+ *,
489
+ feature_policy: FeatureOverlapPolicy = "split",
490
+ ) -> DNA | CircularOperationResult | RecordOperationResult:
491
+ """Rotate a circular sequence or record using one public name."""
492
+
493
+ record = _record_input(value)
494
+ if record is not None:
495
+ result = rotate_record(record, offset, feature_policy=feature_policy)
496
+ return _public_record_result(value, result)
497
+ return _rotate_sequence(_sequence_input(value), offset)
498
+
499
+
500
+ @overload
501
+ def canonical_origin(
502
+ value: DNASequence,
503
+ *,
504
+ feature_policy: FeatureOverlapPolicy = "split",
505
+ ) -> CircularOperationResult: ...
506
+
507
+
508
+ @overload
509
+ def canonical_origin(
510
+ value: DNA,
511
+ *,
512
+ feature_policy: FeatureOverlapPolicy = "split",
513
+ ) -> DNA: ...
514
+
515
+
516
+ @overload
517
+ def canonical_origin(
518
+ value: DNARecord,
519
+ *,
520
+ feature_policy: FeatureOverlapPolicy = "split",
521
+ ) -> RecordOperationResult: ...
522
+
523
+
524
+ def canonical_origin(
525
+ value: OperationInput,
526
+ *,
527
+ feature_policy: FeatureOverlapPolicy = "split",
528
+ ) -> DNA | CircularOperationResult | RecordOperationResult:
529
+ """Canonicalize a circular sequence or record using one public name."""
530
+
531
+ record = _record_input(value)
532
+ if record is not None:
533
+ result = canonical_origin_record(record, feature_policy=feature_policy)
534
+ return _public_record_result(value, result)
535
+ return _canonical_origin_sequence(_sequence_input(value))
536
+
537
+
538
+ __all__ = [
539
+ "DEFAULT_EVOLUTION_AUGMENTATIONS",
540
+ "CircularOperationResult",
541
+ "CrossoverResult",
542
+ "Edit",
543
+ "EditResult",
544
+ "EvolutionAugmentation",
545
+ "EvolutionGenerationResult",
546
+ "EvolutionStep",
547
+ "FeatureChange",
548
+ "FeatureChangeAction",
549
+ "FeatureOverlapPolicy",
550
+ "IndelOperation",
551
+ "KmerShuffleResult",
552
+ "LetterAnnotationAction",
553
+ "LetterAnnotationPolicy",
554
+ "MutationResult",
555
+ "RearrangementOperation",
556
+ "RearrangementResult",
557
+ "RecordOperationResult",
558
+ "canonical_origin",
559
+ "canonical_origin_record",
560
+ "circular_subsequence",
561
+ "complement",
562
+ "concat",
563
+ "concat_overlap",
564
+ "crossover",
565
+ "delete",
566
+ "delete_record",
567
+ "evolution_generate",
568
+ "indel_generate",
569
+ "insert",
570
+ "insert_record",
571
+ "kmer_shuffle",
572
+ "mask",
573
+ "mask_record",
574
+ "mutate",
575
+ "rearrange_generate",
576
+ "reverse",
577
+ "reverse_complement",
578
+ "reverse_complement_record",
579
+ "rotate",
580
+ "rotate_record",
581
+ "subsequence",
582
+ "substitute",
583
+ "substitute_record",
584
+ "transcribe",
585
+ "translate",
586
+ "trim",
587
+ "trim_record",
588
+ ]