syncoder 0.0.3a1__tar.gz → 0.0.4a1__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.
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/PKG-INFO +1 -1
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/src/syncoder/__init__.py +1 -1
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/src/syncoder/codec.py +59 -2
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/tests/test_codec_pytest.py +15 -1
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/.gitignore +0 -0
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/.vscode/.gitignore +0 -0
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/LICENSE +0 -0
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/README.md +0 -0
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/environments/conda_environment.yml +0 -0
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/environments/conda_environment_dev.yml +0 -0
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/environments/conda_environment_test.yml +0 -0
- {syncoder-0.0.3a1 → syncoder-0.0.4a1}/pyproject.toml +0 -0
|
@@ -3,7 +3,7 @@ import struct
|
|
|
3
3
|
import itertools
|
|
4
4
|
import logging
|
|
5
5
|
import typing
|
|
6
|
-
from typing import Optional,Union, Callable, Tuple #requires python 3.
|
|
6
|
+
from typing import Optional,Union, Callable, Tuple, Literal, cast #requires python 3.8 or later
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
@@ -160,7 +160,7 @@ class BaseNBlockCodec:
|
|
|
160
160
|
# sizes in bytes:
|
|
161
161
|
# |<---- self.data_chunk_size ----->|<- . ->|
|
|
162
162
|
# ^ = self.index_bits <-- in bits not bytes.
|
|
163
|
-
# note: actual k remains alphabet_size-1, but the code is
|
|
163
|
+
# note: actual k remains alphabet_size-1, but the code is shortened (0 padded) to inner_n symbols.
|
|
164
164
|
k = inner_n - (inner_d - 1)
|
|
165
165
|
self.inner_k = k
|
|
166
166
|
q = self.inner_coder.field.order
|
|
@@ -356,6 +356,63 @@ class BaseNBlockCodec:
|
|
|
356
356
|
logging.warning("Outer code errors found on strand {}, byte {}.".format(*e))
|
|
357
357
|
|
|
358
358
|
return data_decoded, erasures, errors, chunk_errors
|
|
359
|
+
|
|
360
|
+
def extract_index_dna(self, dna: str|bytes, words:list[str], alternate_words:list[str], error_check: bool = False, padding: Literal["left","right"]="right") -> int:
|
|
361
|
+
"""
|
|
362
|
+
Extracts the index from the given DNA strand.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
dna (str|bytes): The input DNA strand from which to extract the index.
|
|
366
|
+
error_check (bool, optional): If True, the inner_codec will be used to
|
|
367
|
+
attempt to check for errors. Defaults to False.
|
|
368
|
+
padding Literal["left","right"], optional): Assume any missing bases are left or right of index. Defaults to "right".
|
|
369
|
+
Note padded sequences are unlikely to error correct properly.
|
|
370
|
+
words (list[str]): The primary set of base words used, in order, for encoding.
|
|
371
|
+
alternate_words (list[str]): The alternate (aka synonymous) set of words used, in order, for encoding.
|
|
372
|
+
|
|
373
|
+
Returns:
|
|
374
|
+
int: The index. or -1 if error_check==True and unrecoverable error found.
|
|
375
|
+
"""
|
|
376
|
+
word_len:int = len(words[0])
|
|
377
|
+
if isinstance(dna,bytes):
|
|
378
|
+
dna= dna.decode()
|
|
379
|
+
dna_s:str = cast(str,dna)
|
|
380
|
+
|
|
381
|
+
if padding == "right":
|
|
382
|
+
_p = self.inner_k*word_len - len(dna_s)
|
|
383
|
+
if _p>0: #if i have less than a full codeword of bases
|
|
384
|
+
dna_s = dna_s + "A"*_p
|
|
385
|
+
elif padding == "left":
|
|
386
|
+
_p = self.inner_k*word_len - len(dna_s)
|
|
387
|
+
if _p>0: #if i have less than a full codeword of bases
|
|
388
|
+
dna_s = "A"*_p + dna_s
|
|
389
|
+
|
|
390
|
+
data = dna_to_bN([dna_s],words,alternate_words)[0]
|
|
391
|
+
|
|
392
|
+
return self.extract_index(data,error_check)
|
|
393
|
+
|
|
394
|
+
def extract_index(self, data: list[int], error_check: bool = False) -> int:
|
|
395
|
+
"""
|
|
396
|
+
Extracts the index from the given DNA strand.
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
data list[int]: The input data from which to extract the index.
|
|
400
|
+
If a list[int] is given, it is assumed be be inner code symbols.
|
|
401
|
+
error_check (bool, optional): If True, the inner_codec will be used to
|
|
402
|
+
attempt to check for errors. Defaults to False.
|
|
403
|
+
|
|
404
|
+
Returns:
|
|
405
|
+
int: The index. or -1 if error_check==True and unrecoverable error found.
|
|
406
|
+
"""
|
|
407
|
+
if error_check == False:
|
|
408
|
+
data = data[0:self.inner_k] #extract message
|
|
409
|
+
else:
|
|
410
|
+
data, n_corrected = self.inner_coder.decode(data,errors=True)[0].tolist()
|
|
411
|
+
if n_corrected < 0:
|
|
412
|
+
return -1
|
|
413
|
+
chunk_int = _baseN_to_int(data, self.inner_coder.field.order)
|
|
414
|
+
chunk_index = (chunk_int >> (self.data_chunk_size * 8))
|
|
415
|
+
return chunk_index
|
|
359
416
|
|
|
360
417
|
|
|
361
418
|
#convert base N into DNA.
|
|
@@ -123,4 +123,18 @@ def test_nonzero_index():
|
|
|
123
123
|
test_data = np.random.randint(0,255,data_size,dtype=np.uint8).tobytes()
|
|
124
124
|
enc_d = coder.encode(test_data,index_start=2500)
|
|
125
125
|
ded_d = coder.decode(enc_d,index_start=2500)
|
|
126
|
-
assert ded_d[0] == test_data
|
|
126
|
+
assert ded_d[0] == test_data
|
|
127
|
+
|
|
128
|
+
dna = codec.b32_to_DNA_optimize(enc_d,codec._default_b32_alphabet,codec._default_b32_alphabet_alt) #type: ignore
|
|
129
|
+
|
|
130
|
+
index = coder.extract_index_dna(dna[0][0],
|
|
131
|
+
words = syncoder._default_b32_alphabet,
|
|
132
|
+
alternate_words= syncoder._default_b32_alphabet_alt,
|
|
133
|
+
error_check=False)
|
|
134
|
+
assert index == 2500
|
|
135
|
+
offset = 5
|
|
136
|
+
index = coder.extract_index_dna(dna[offset][0],
|
|
137
|
+
words = syncoder._default_b32_alphabet,
|
|
138
|
+
alternate_words= syncoder._default_b32_alphabet_alt,
|
|
139
|
+
error_check=False)
|
|
140
|
+
assert index == 2500+offset
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|