@fishka/seqio 0.3.0 → 0.5.0

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.
package/README.md CHANGED
@@ -1,13 +1,16 @@
1
1
  # @fishka/seqio
2
2
 
3
- Sequencing I/Oparsers and writers for bioinformatics file formats.
3
+ Part of [fishka.bio](https://fishka.bio) free browser-based bioinformatics tools.
4
4
 
5
- Currently supports:
5
+ Browser- and Node-compatible sequencing file I/O.
6
6
 
7
- - **ABIF** (`.ab1` / `.abi`) — chromatogram traces produced by ABI Sanger / fragment analysis instruments. Lossless round-trip, browser- and Node-compatible.
8
- - **FASTA / FASTQ / .qual** — text writers (Phred+33), pure and format-agnostic.
7
+ Current API:
9
8
 
10
- Planned: SCF; FASTA/FASTQ reading.
9
+ - **ABIF** (`.ab1` / `.abi`) parser, typed chromatogram view, raw reader/writer,
10
+ and mutation helpers.
11
+ - **FASTA / FASTQ / .qual** text writers with Phred+33 quality encoding.
12
+
13
+ Planned: SCF and FASTA/FASTQ readers.
11
14
 
12
15
  ## Install
13
16
 
@@ -15,66 +18,79 @@ Planned: SCF; FASTA/FASTQ reading.
15
18
  npm install @fishka/seqio
16
19
  ```
17
20
 
18
- ## Use
21
+ ## ABIF
19
22
 
20
- ### Quick parse (typed view + metadata)
23
+ Use `parseAbif()` when you want a ready-to-render chromatogram, base calls, and
24
+ metadata from an `.ab1` file.
21
25
 
22
26
  ```ts
23
27
  import { parseAbif } from '@fishka/seqio/abif';
24
- // or: import { parseAbif } from '@fishka/seqio';
25
28
 
26
29
  const result = parseAbif(uint8ArrayOrArrayBuffer, 'sample.ab1');
27
30
 
28
- result.baseCalls?.sequence; // "ACGT..."
29
- result.baseCalls?.confidences; // [40, 38, 41, ...]
30
- result.baseCalls?.positions; // [13, 25, 38, ...] sample-point peaks
31
- result.chromatogram.basecalled.A; // raw int16 trace for the A channel
32
- result.metadata.sampleName; // SMPL tag
33
- result.metadata.samplingRate; // SPAC tag (falls back to PLOC-derived spacing)
31
+ result.baseCalls?.sequence; // preferred called sequence, upper-cased
32
+ result.baseCalls?.confidences; // PCON quality scores
33
+ result.baseCalls?.positions; // PLOC peak positions
34
+ result.baseCallVariants; // all PBAS/PCON/PLOC versions found
35
+ result.chromatogram.data9To12.A; // A trace mapped through FWO_
36
+ result.metadata.sampleName;
34
37
  ```
35
38
 
36
- ### Low-level (entry-by-entry, round-trip)
39
+ Use `readAbif()` / `writeAbif()` when you need entry-level access or want to
40
+ preserve unknown vendor tags during a round trip.
37
41
 
38
42
  ```ts
39
43
  import { readAbif, writeAbif, findEntry, upsertEntry } from '@fishka/seqio/abif';
40
- import { setSequence, setConfidences, setPositions, setAveragePeakSpacing } from '@fishka/seqio/abif';
44
+ import { setAveragePeakSpacing, setConfidences, setPositions, setSequence } from '@fishka/seqio/abif';
41
45
 
42
46
  const file = readAbif(bytes);
47
+
48
+ findEntry(file, 'SMPL', 1);
49
+ const commentPayload = new TextEncoder().encode('basecalled');
50
+ upsertEntry(file, 'CMNT', 1, commentPayload, {
51
+ elementType: 2,
52
+ elementSize: 1,
53
+ elementCount: commentPayload.byteLength,
54
+ });
55
+
43
56
  setSequence(file, 'ACGT...');
44
- setConfidences(file, [40, 38, 41, ...]);
45
- setPositions(file, [13, 25, 38, ...]);
57
+ setConfidences(file, [40, 38, 41]);
58
+ setPositions(file, [13, 25, 38]);
46
59
  setAveragePeakSpacing(file, 12.5, 'my-basecaller');
60
+
47
61
  const out = writeAbif(file);
48
62
  ```
49
63
 
50
- ### Text export (FASTA / FASTQ / .qual)
64
+ ## FASTA / FASTQ / .qual
51
65
 
52
66
  ```ts
53
67
  import { formatFasta, formatFastq, formatQual, hasUsableQuality } from '@fishka/seqio';
54
68
 
55
69
  const record = { id: 'sample.ab1', sequence, qualities };
56
70
 
57
- formatFasta(record); // ">sample.ab1\nACGT...\n" (wrapped at 60)
71
+ formatFasta(record); // wrapped at 60 residues by default
58
72
  formatFasta(record, { lineWidth: 0 }); // single sequence line
59
73
 
60
- // Phred+33; scores clamped to [0, 93]. Only emit quality when it exists —
61
- // missing/all-255 PCON should stay FASTA-only rather than invent perfect Q.
62
74
  if (hasUsableQuality(qualities)) {
63
- formatFastq(record); // "@sample.ab1\nACGT...\n+\n..."
64
- formatQual(record); // ">sample.ab1\n40 38 41 ...\n"
75
+ formatFastq(record); // Phred+33, scores clamped to [0, 93]
76
+ formatQual(record);
65
77
  }
66
78
  ```
67
79
 
68
- ## Features
80
+ ## API
81
+
82
+ - `parseAbif(input, fileName?)`
83
+ - `readAbif(bytes)`, `writeAbif(file)`, `findEntry()`, `findEntries()`,
84
+ `upsertEntry()`
85
+ - `getSequence()`, `getConfidences()`, `getPositions()`, `getDataChannel()`,
86
+ `getChannelMap()`, `getSamplingRate()`
87
+ - `setSequence()`, `setConfidences()`, `setPositions()`,
88
+ `setAveragePeakSpacing()`, `ensureRawDataChannels()`
89
+ - `formatFasta()`, `formatFastq()`, `formatQual()`, `hasUsableQuality()`
69
90
 
70
- - Browser- and Node-compatible (Uint8Array + DataView, no Node Buffer dependency).
71
- - Lossless round-trip: every directory entry preserved as raw payload.
72
- - MacBinary preamble support.
73
- - BioPython-compatible declared-vs-computed dataSize clamp.
74
- - PLOC read/written as unsigned int16 (preserves traces > 32k scans).
75
- - SPAC accepts both float32 (spec) and long (legacy) element types.
76
- - PCON/PLOC version fallback when PBAS2 ships without matching PCON2/PLOC2.
77
- - `ensureRawDataChannels()` helper for older DATA1..8-only files.
91
+ The library uses `Uint8Array` and `DataView`, with no Node `Buffer` dependency.
92
+ ABIF writing is meaning-lossless rather than byte-for-byte layout preserving:
93
+ unknown entries are kept, but payloads may be repacked and padding normalized.
78
94
 
79
95
  ## License
80
96