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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syncoder
3
- Version: 0.0.3a1
3
+ Version: 0.0.4a1
4
4
  Summary: A codec for DNA data storage
5
5
  Project-URL: Homepage, https://example.com/TBD
6
6
  Project-URL: Issues, https://example.com/TBD/issues
@@ -3,4 +3,4 @@ from .codec import _default_b32_alphabet, _default_b32_alphabet_alt
3
3
  default_b32_alphabet = _default_b32_alphabet
4
4
  default_b32_alphabet_alt = _default_b32_alphabet_alt
5
5
 
6
- __version__ = "0.0.3a1"
6
+ __version__ = "0.0.4a1"
@@ -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.5 or later
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 shorted (0 padded) to inner_n symbols.
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