@fishka/seqio 0.3.0 → 0.4.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 +9 -4
- package/dist/abif/index.d.mts +212 -55
- package/dist/abif/index.d.ts +212 -55
- package/dist/abif/index.js +1 -1
- package/dist/abif/index.js.map +1 -1
- package/dist/abif/index.mjs +1 -1
- package/dist/abif/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Sequencing I/O — parsers and writers for bioinformatics file formats.
|
|
|
4
4
|
|
|
5
5
|
Currently supports:
|
|
6
6
|
|
|
7
|
-
- **ABIF** (`.ab1` / `.abi`) — chromatogram traces produced by ABI Sanger / fragment analysis instruments.
|
|
7
|
+
- **ABIF** (`.ab1` / `.abi`) — chromatogram traces produced by ABI Sanger / fragment analysis instruments. Meaning-lossless round-trip (every entry preserved), browser- and Node-compatible.
|
|
8
8
|
- **FASTA / FASTQ / .qual** — text writers (Phred+33), pure and format-agnostic.
|
|
9
9
|
|
|
10
10
|
Planned: SCF; FASTA/FASTQ reading.
|
|
@@ -25,10 +25,12 @@ import { parseAbif } from '@fishka/seqio/abif';
|
|
|
25
25
|
|
|
26
26
|
const result = parseAbif(uint8ArrayOrArrayBuffer, 'sample.ab1');
|
|
27
27
|
|
|
28
|
-
result.baseCalls?.sequence; // "ACGT..."
|
|
28
|
+
result.baseCalls?.sequence; // "ACGT..." (preferred/called version, upper-cased)
|
|
29
29
|
result.baseCalls?.confidences; // [40, 38, 41, ...]
|
|
30
30
|
result.baseCalls?.positions; // [13, 25, 38, ...] sample-point peaks
|
|
31
|
-
result.
|
|
31
|
+
result.baseCallVariants; // every PBAS version present: [{ version, role: 'called'|'edited', ... }]
|
|
32
|
+
result.chromatogram.data9To12.A; // A-channel int16 trace of the DATA9..12 block
|
|
33
|
+
result.chromatogram.data1To4.A; // A-channel int16 trace of the DATA1..4 block
|
|
32
34
|
result.metadata.sampleName; // SMPL tag
|
|
33
35
|
result.metadata.samplingRate; // SPAC tag (falls back to PLOC-derived spacing)
|
|
34
36
|
```
|
|
@@ -68,7 +70,10 @@ if (hasUsableQuality(qualities)) {
|
|
|
68
70
|
## Features
|
|
69
71
|
|
|
70
72
|
- Browser- and Node-compatible (Uint8Array + DataView, no Node Buffer dependency).
|
|
71
|
-
-
|
|
73
|
+
- Meaning-lossless round-trip: every directory entry preserved as a raw payload, so
|
|
74
|
+
`readAbif(writeAbif(f))` reproduces the same entries. The output is not byte-for-byte
|
|
75
|
+
identical to the input (payloads are repacked, `dataSize` normalized, MacBinary/padding
|
|
76
|
+
dropped); a byte-exact layout-preserving writer is a possible future opt-in.
|
|
72
77
|
- MacBinary preamble support.
|
|
73
78
|
- BioPython-compatible declared-vs-computed dataSize clamp.
|
|
74
79
|
- PLOC read/written as unsigned int16 (preserves traces > 32k scans).
|
package/dist/abif/index.d.mts
CHANGED
|
@@ -7,10 +7,35 @@
|
|
|
7
7
|
interface AbifFile {
|
|
8
8
|
/** ABIF version, e.g. 101 for v1.01. */
|
|
9
9
|
version: number;
|
|
10
|
+
/** The root directory (tdir) header, exactly as read — including any directory padding it declares. */
|
|
11
|
+
tdir: AbifDirectory;
|
|
10
12
|
/** Directory entries in the original on-disk order. */
|
|
11
13
|
entries: AbifEntry[];
|
|
12
14
|
/** MacBinary preamble offset (128 if present, 0 otherwise). Preserved for diagnostics. */
|
|
13
15
|
macBinaryOffset: number;
|
|
16
|
+
/**
|
|
17
|
+
* The 128-byte MacBinary preamble, verbatim — present only when {@link macBinaryOffset} is 128.
|
|
18
|
+
* Exposed so a raw reader can reproduce the wrapper, not just note that it existed.
|
|
19
|
+
*/
|
|
20
|
+
macBinaryHeader?: Uint8Array;
|
|
21
|
+
/**
|
|
22
|
+
* Reserved header bytes [34..127] (94 bytes), verbatim. Usually zeros; exposed so a raw reader
|
|
23
|
+
* keeps the entire 128-byte header, not just magic/version/tdir.
|
|
24
|
+
*/
|
|
25
|
+
headerReserved: Uint8Array;
|
|
26
|
+
/**
|
|
27
|
+
* Physical byte ranges not covered by the header, directory, or any entry payload — orphaned
|
|
28
|
+
* blocks left by editing tools, trailing padding, etc. Empty for a tightly-packed file. Exposed
|
|
29
|
+
* so a raw reader accounts for every byte; the chromatogram never depends on these.
|
|
30
|
+
*/
|
|
31
|
+
unreferencedRanges: AbifByteRange[];
|
|
32
|
+
}
|
|
33
|
+
/** A contiguous run of file bytes at an absolute offset — used for {@link AbifFile.unreferencedRanges}. */
|
|
34
|
+
interface AbifByteRange {
|
|
35
|
+
/** Absolute offset from the start of the file (includes any MacBinary preamble). */
|
|
36
|
+
offset: number;
|
|
37
|
+
/** The bytes in this range, verbatim. `bytes.length` is the range length. */
|
|
38
|
+
bytes: Uint8Array;
|
|
14
39
|
}
|
|
15
40
|
interface AbifEntry {
|
|
16
41
|
/** 4-character tag name, e.g. "DATA", "PBAS". */
|
|
@@ -23,12 +48,72 @@ interface AbifEntry {
|
|
|
23
48
|
elementType: number;
|
|
24
49
|
/** Bytes per element. */
|
|
25
50
|
elementSize: number;
|
|
26
|
-
/** Number of elements. */
|
|
51
|
+
/** Number of elements (reconciled: clamped to what the payload holds). */
|
|
27
52
|
elementCount: number;
|
|
28
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Raw payload bytes. Length === the on-disk `dataSize` (the authoritative field), which for
|
|
55
|
+
* user/opaque types may differ from `elementCount * elementSize`.
|
|
56
|
+
*/
|
|
29
57
|
payload: Uint8Array;
|
|
30
58
|
/** Opaque dataHandle field, usually 0. Preserved for round-trip. */
|
|
31
59
|
dataHandle: number;
|
|
60
|
+
/**
|
|
61
|
+
* The directory fields exactly as they were on disk — present only when this entry was read from a
|
|
62
|
+
* file (absent for entries synthesized by setters/writeAbif). Lets consumers inspect the real record
|
|
63
|
+
* without our reconciliation.
|
|
64
|
+
*/
|
|
65
|
+
raw?: AbifEntryRaw;
|
|
66
|
+
}
|
|
67
|
+
/** A directory entry's on-disk fields, verbatim, before any reconciliation applied by {@link readAbif}. */
|
|
68
|
+
interface AbifEntryRaw {
|
|
69
|
+
/** `elementCount` (numElements) as written on disk. */
|
|
70
|
+
elementCount: number;
|
|
71
|
+
/** `dataSize` field as written on disk, in bytes. */
|
|
72
|
+
dataSize: number;
|
|
73
|
+
/** External payload offset relative to the ABIF start, or -1 when the payload is inline. */
|
|
74
|
+
dataOffset: number;
|
|
75
|
+
/** Whether the payload was stored inline (declared dataSize ≤ 4). */
|
|
76
|
+
inline: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* The 4 raw bytes of the dataOffset/data slot, verbatim. For an external entry these are the
|
|
79
|
+
* big-endian offset; for an inline entry they are the value bytes plus any padding/stale bytes
|
|
80
|
+
* beyond `dataSize` — exposed so a raw reader loses no structure.
|
|
81
|
+
*/
|
|
82
|
+
dataOffsetBytes: Uint8Array;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The root directory (`tdir`) header — the header's own directory entry, describing the directory
|
|
86
|
+
* block. Its fields are exposed like any other raw entry so a raw reader never loses them, even when
|
|
87
|
+
* `rawEntryCount` desyncs from `dataSize`.
|
|
88
|
+
*/
|
|
89
|
+
interface AbifDirectory {
|
|
90
|
+
/** Effective number of entries actually read — equals `entries.length`. */
|
|
91
|
+
entryCount: number;
|
|
92
|
+
/** tdir `numElements` verbatim, before reconciliation; the authoritative on-disk entry count. */
|
|
93
|
+
rawEntryCount: number;
|
|
94
|
+
/** tdir `elementType` (1023). */
|
|
95
|
+
elementType: number;
|
|
96
|
+
/** tdir `tagNumber` (usually 1). */
|
|
97
|
+
tagNumber: number;
|
|
98
|
+
/** Bytes per directory entry (always 28). */
|
|
99
|
+
entrySize: number;
|
|
100
|
+
/**
|
|
101
|
+
* Directory block size in bytes, from the tdir `dataSize` field. May exceed `entryCount * 28`
|
|
102
|
+
* when the file carries directory padding / extra bytes.
|
|
103
|
+
*/
|
|
104
|
+
dataSize: number;
|
|
105
|
+
/** File offset (relative to the ABIF start) where the directory block begins. */
|
|
106
|
+
dataOffset: number;
|
|
107
|
+
/** The 4 raw bytes of the tdir's dataOffset field, verbatim. */
|
|
108
|
+
dataOffsetBytes: Uint8Array;
|
|
109
|
+
/** tdir `dataHandle` field, usually 0. */
|
|
110
|
+
dataHandle: number;
|
|
111
|
+
/**
|
|
112
|
+
* The raw directory-padding bytes: everything from the end of the last entry to the end of the
|
|
113
|
+
* directory block (`dataSize - entryCount*28`). Usually zeros; exposed so a raw reader keeps the
|
|
114
|
+
* whole directory structure, not just the entries.
|
|
115
|
+
*/
|
|
116
|
+
paddingBytes: Uint8Array;
|
|
32
117
|
}
|
|
33
118
|
interface ChannelSignals {
|
|
34
119
|
A: number[];
|
|
@@ -36,6 +121,8 @@ interface ChannelSignals {
|
|
|
36
121
|
G: number[];
|
|
37
122
|
T: number[];
|
|
38
123
|
}
|
|
124
|
+
/** Spec-defined role of a DATA<n> tag — see {@link dataChannelRole}. */
|
|
125
|
+
type AbifDataChannelRole = 'trace' | 'telemetry' | 'other';
|
|
39
126
|
/** Per-base chromatogram view. */
|
|
40
127
|
interface Chromatogram {
|
|
41
128
|
/** Per-base peak position in sample points (from PLOC). */
|
|
@@ -47,7 +134,39 @@ interface Chromatogram {
|
|
|
47
134
|
/** Average peak spacing (samples per base), from SPAC. */
|
|
48
135
|
samplingRate?: number;
|
|
49
136
|
}
|
|
50
|
-
/**
|
|
137
|
+
/**
|
|
138
|
+
* One basecall version exactly as the file stores it. ABIF numbers the
|
|
139
|
+
* PBAS/PCON/PLOC tags by version, and the spec fixes what each number means:
|
|
140
|
+
*
|
|
141
|
+
* - version 2 (`role: 'called'`) — the sequence as produced by the basecaller.
|
|
142
|
+
* - version 1 (`role: 'edited'`) — the sequence after user hand-editing.
|
|
143
|
+
* - any other version (`role: 'unknown'`) — the spec only defines 1 and 2, so
|
|
144
|
+
* a vendor/future PBAS3+ is surfaced without a claimed role.
|
|
145
|
+
*
|
|
146
|
+
* A file may carry either or both, and the two can differ in content and even in
|
|
147
|
+
* length (edits insert/delete bases). {@link parseAbif} exposes every version it
|
|
148
|
+
* finds via {@link ParsedAbif.baseCallVariants} — picking which one to show or
|
|
149
|
+
* export is the consumer's call, not the parser's.
|
|
150
|
+
*/
|
|
151
|
+
type AbifBaseCallRole = 'called' | 'edited' | 'unknown';
|
|
152
|
+
interface AbifBaseCallVariant {
|
|
153
|
+
/** Tag number of the PBAS/PCON/PLOC this variant came from (1, 2, or a vendor number). */
|
|
154
|
+
version: number;
|
|
155
|
+
/** Spec-defined role by tag number: 2 = basecaller-called, 1 = user-edited, else unknown. */
|
|
156
|
+
role: AbifBaseCallRole;
|
|
157
|
+
/** Bases from PBAS<version> as stored — case preserved, trailing NULs stripped, not normalized. */
|
|
158
|
+
sequence: string;
|
|
159
|
+
/** Per-base Q-scores from PCON<version>; `[]` when that version has no PCON. */
|
|
160
|
+
confidences: number[];
|
|
161
|
+
/** Per-base peak positions (sample indices) from PLOC<version>; `[]` when absent. */
|
|
162
|
+
positions: number[];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Convenience pointer to the preferred basecall version — the called one (PBAS2)
|
|
166
|
+
* when present, else whatever single version the file has. This is a spec-role
|
|
167
|
+
* choice (called over edited), not a quality judgement; see
|
|
168
|
+
* {@link ParsedAbif.baseCallVariants} for every version the file actually carries.
|
|
169
|
+
*/
|
|
51
170
|
interface AbifBaseCalls {
|
|
52
171
|
/** Called bases (uppercase). */
|
|
53
172
|
sequence: string;
|
|
@@ -68,34 +187,37 @@ interface AbifMetadata {
|
|
|
68
187
|
runDate?: string;
|
|
69
188
|
runTime?: string;
|
|
70
189
|
samplingRate?: number;
|
|
190
|
+
/**
|
|
191
|
+
* Value of the RevC1 flag: whether the file declares its sequence already
|
|
192
|
+
* reverse-complemented. undefined when the tag is absent. Reported as-is — the
|
|
193
|
+
* consumer decides what to do with it.
|
|
194
|
+
*/
|
|
195
|
+
reverseComplemented?: boolean;
|
|
71
196
|
comments: string[];
|
|
72
197
|
}
|
|
73
198
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* The
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* Use {@link hasProcessedTraces} (data9To12 present) to detect whether
|
|
88
|
-
* DATA1..4 has already been processed and bypass your own baseline/color
|
|
89
|
-
* steps accordingly.
|
|
199
|
+
* All DATA channels plus FWO_-aware A/C/G/T views of the two dye-trace blocks.
|
|
200
|
+
*
|
|
201
|
+
* The block views are named after their on-disk tag ranges — nothing more. Which
|
|
202
|
+
* block is "raw" and which is "analyzed / processed" is an instrument-and-tool
|
|
203
|
+
* convention that the ABIF file does NOT state, so this parser refuses to label
|
|
204
|
+
* it. The consumer that needs to tell them apart has the primitives to decide:
|
|
205
|
+
* the per-block sample counts (channel lengths) and the basecall peak positions
|
|
206
|
+
* ({@link AbifBaseCalls.positions}); e.g. positions that overflow one block's
|
|
207
|
+
* length can only belong to the other.
|
|
208
|
+
*
|
|
209
|
+
* Per the ABIF spec, DATA5..8 are instrument telemetry (voltage / current / power
|
|
210
|
+
* / temperature), NOT dye traces — see {@link dataChannelRole}. They live in
|
|
211
|
+
* {@link dataChannels} but are excluded from the A/C/G/T views.
|
|
90
212
|
*/
|
|
91
213
|
interface AbifChromatogramBundle {
|
|
92
214
|
/** FWO_ value (e.g. "GATC"). */
|
|
93
215
|
baseOrder: string;
|
|
94
|
-
/** All DATA tags by tagNumber → trace. */
|
|
216
|
+
/** All DATA tags by tagNumber → trace (dye traces AND telemetry). */
|
|
95
217
|
dataChannels: Record<number, number[]>;
|
|
96
|
-
/** DATA1..4 mapped to A/C/G/T by FWO_.
|
|
218
|
+
/** DATA1..4 mapped to A/C/G/T by FWO_. */
|
|
97
219
|
data1To4: ChannelSignals;
|
|
98
|
-
/** DATA9..12 mapped to A/C/G/T by FWO_
|
|
220
|
+
/** DATA9..12 mapped to A/C/G/T by FWO_; empty when the file has no 9..12 block. */
|
|
99
221
|
data9To12: ChannelSignals;
|
|
100
222
|
}
|
|
101
223
|
/** Rich result from {@link parseAbif} — everything the typical viewer needs. */
|
|
@@ -107,7 +229,10 @@ interface ParsedAbif {
|
|
|
107
229
|
dirEntryCount: number;
|
|
108
230
|
metadata: AbifMetadata;
|
|
109
231
|
chromatogram: AbifChromatogramBundle;
|
|
232
|
+
/** Preferred basecall version (called over edited); convenience over {@link baseCallVariants}. */
|
|
110
233
|
baseCalls?: AbifBaseCalls;
|
|
234
|
+
/** Every basecall version the file carries (called and/or edited), in version order. */
|
|
235
|
+
baseCallVariants: AbifBaseCallVariant[];
|
|
111
236
|
/** All directory entries with their decoded payloads (best-effort by type). */
|
|
112
237
|
entries: AbifDirEntry[];
|
|
113
238
|
}
|
|
@@ -119,9 +244,15 @@ interface AbifDirEntry {
|
|
|
119
244
|
elementType: number;
|
|
120
245
|
elementTypeName: string;
|
|
121
246
|
elementSize: number;
|
|
247
|
+
/** Reconciled element count (clamped to the declared dataSize when it was smaller). */
|
|
122
248
|
elementCount: number;
|
|
249
|
+
/** `numElements` exactly as written on disk, before reconciliation. */
|
|
250
|
+
rawElementCount: number;
|
|
251
|
+
/** `dataSize` as written on disk, in bytes (not recomputed). */
|
|
123
252
|
dataSize: number;
|
|
253
|
+
/** External payload offset relative to the ABIF start, or -1 when the payload is inline. */
|
|
124
254
|
dataOffset: number;
|
|
255
|
+
/** Whether the payload was stored inline (declared dataSize ≤ 4). */
|
|
125
256
|
inline: boolean;
|
|
126
257
|
decoded: AbifDecodedValue;
|
|
127
258
|
preview: string;
|
|
@@ -184,12 +315,14 @@ declare function tagNameFromInt32(n: number): string;
|
|
|
184
315
|
* 8 2 elementType (int16)
|
|
185
316
|
* 10 2 elementSize (int16)
|
|
186
317
|
* 12 4 elementCount (int32)
|
|
187
|
-
* 16 4 dataSize (int32; total payload bytes
|
|
318
|
+
* 16 4 dataSize (int32; total payload bytes — authoritative; for
|
|
319
|
+
* well-formed entries equals count*size, but user/
|
|
320
|
+
* opaque types may differ, so we read by dataSize)
|
|
188
321
|
* 20 4 dataOffset (int32) OR inline data if dataSize <= 4
|
|
189
322
|
* 24 4 dataHandle (int32; usually 0)
|
|
190
323
|
*
|
|
191
|
-
* Inline rule (per ABIF spec): when
|
|
192
|
-
* stored directly in the dataOffset field (left-aligned, padded to 4 bytes).
|
|
324
|
+
* Inline rule (per ABIF spec): when the declared dataSize <= 4 the payload bytes
|
|
325
|
+
* are stored directly in the dataOffset field (left-aligned, padded to 4 bytes).
|
|
193
326
|
*
|
|
194
327
|
* MacBinary preamble: some ABIF files (older Mac-origin) start with a 128-byte
|
|
195
328
|
* MacBinary header before the actual ABIF magic. We detect and skip it.
|
|
@@ -198,7 +331,13 @@ declare function tagNameFromInt32(n: number): string;
|
|
|
198
331
|
declare const HEADER_SIZE = 128;
|
|
199
332
|
declare const ENTRY_SIZE = 28;
|
|
200
333
|
/**
|
|
201
|
-
* Parse an ABIF file from raw bytes.
|
|
334
|
+
* Parse an ABIF file from raw bytes into its verbatim directory structure.
|
|
335
|
+
*
|
|
336
|
+
* This is the RAW source of truth: it reads the tdir header and every entry as
|
|
337
|
+
* stored — real dataSize, dataOffset, numElements (see `entry.raw`), the 4 inline
|
|
338
|
+
* bytes, and the tdir/directory metadata — and interprets nothing. For a
|
|
339
|
+
* high-level, opinionated view (typed channels, basecalls, metadata) layer
|
|
340
|
+
* {@link parseAbif} on top.
|
|
202
341
|
*
|
|
203
342
|
* Accepts Uint8Array (works in Node and the browser). Node's Buffer extends
|
|
204
343
|
* Uint8Array, so `readAbif(buffer)` and `readAbif(new Uint8Array(arrayBuffer))`
|
|
@@ -212,14 +351,13 @@ declare function readAbif(bytes: Uint8Array): AbifFile;
|
|
|
212
351
|
* Serialize an AbifFile back to a Uint8Array.
|
|
213
352
|
*
|
|
214
353
|
* Layout produced: header (128 B) + directory (N*28 B) + payload block.
|
|
215
|
-
* External payloads are packed tightly in entry order.
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* The output is not bit-identical to the input if the original had a different
|
|
219
|
-
* physical layout (e.g. payloads before directory), but the *meaning*
|
|
220
|
-
* round-trips: readAbif(writeAbif(f)) reproduces the same entries structurally.
|
|
354
|
+
* External payloads are packed tightly in entry order. Payloads <= 4 bytes are
|
|
355
|
+
* stored inline inside their directory entry.
|
|
221
356
|
*
|
|
222
|
-
*
|
|
357
|
+
* Meaning-lossless, not byte-exact: the payload bytes, tag fields and dataSize
|
|
358
|
+
* (= payload length) round-trip, but physical layout does not — payloads are
|
|
359
|
+
* repacked, directory/header padding and any MacBinary preamble are dropped. A
|
|
360
|
+
* byte-exact layout-preserving mode is a possible future opt-in.
|
|
223
361
|
*/
|
|
224
362
|
declare function writeAbif(file: AbifFile): Uint8Array;
|
|
225
363
|
/** Find an entry by name+number, or undefined. */
|
|
@@ -254,33 +392,46 @@ declare function getDataChannel(file: AbifFile, n: number): Int16Array | undefin
|
|
|
254
392
|
*/
|
|
255
393
|
declare function getFwo(file: AbifFile): string;
|
|
256
394
|
/**
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
* Older instruments produce only DATA1..4 (which IS the raw signal).
|
|
261
|
-
*
|
|
262
|
-
* Callers that re-process traces (basecallers) should detect this and bypass
|
|
263
|
-
* their own baseline-subtraction / color-matrix steps when DATA1..4 is
|
|
264
|
-
* already cleaned.
|
|
395
|
+
* Whether an FWO_ string is a genuine dye order: a permutation of A/C/G/T with all
|
|
396
|
+
* four bases distinct. `"GATC"` passes; `"AAAA"` (regex-valid but degenerate) does
|
|
397
|
+
* not — mapping four channels through it would collapse them onto one base.
|
|
265
398
|
*/
|
|
266
|
-
declare function
|
|
399
|
+
declare function isFwoPermutation(fwo: string): boolean;
|
|
267
400
|
/**
|
|
268
|
-
*
|
|
269
|
-
*
|
|
401
|
+
* Fact: the file carries a second dye-trace block, DATA9..12 (all four tags), in
|
|
402
|
+
* addition to DATA1..4. Reports presence only — it does NOT say which block is
|
|
403
|
+
* raw and which is analyzed/processed; that convention isn't stored in the file.
|
|
404
|
+
*/
|
|
405
|
+
declare function hasData9To12Block(file: AbifFile): boolean;
|
|
406
|
+
/**
|
|
407
|
+
* Spec-defined role of a DATA<n> tag, limited to the numbers the ABIF spec names:
|
|
270
408
|
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
409
|
+
* - `'trace'` — dye-signal channels: DATA1..4 (raw dyes 1-4), DATA9..12
|
|
410
|
+
* (analyzed dyes 1-4), and the two optional 5th-dye blocks
|
|
411
|
+
* DATA105 (raw dye 5) and DATA205 (analyzed dye 5).
|
|
412
|
+
* - `'telemetry'` — DATA5..8: instrument run telemetry (voltage, current,
|
|
413
|
+
* power, temperature), one value per scan — NOT dye signal.
|
|
414
|
+
* - `'other'` — any other DATA number. The spec does not enumerate higher
|
|
415
|
+
* extra-dye tags (106/206/…), so we don't claim a role for them.
|
|
274
416
|
*
|
|
275
|
-
*
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
417
|
+
* A fact from the ABIF specification, not an inference about content.
|
|
418
|
+
*/
|
|
419
|
+
declare function dataChannelRole(n: number): AbifDataChannelRole;
|
|
420
|
+
/**
|
|
421
|
+
* Whether the file declares its sequence already reverse-complemented, from the
|
|
422
|
+
* RevC1 flag (int16, non-zero = true). undefined when RevC1 is absent. Reported
|
|
423
|
+
* as-is; the consumer decides how to act on it.
|
|
424
|
+
*/
|
|
425
|
+
declare function getReverseComplemented(file: AbifFile): boolean | undefined;
|
|
426
|
+
/**
|
|
427
|
+
* Map from base letter ("A"|"C"|"G"|"T") to the DATA1..4 tag number that holds
|
|
428
|
+
* its channel, using the dye order declared by FWO_. If FWO_="GATC" then
|
|
429
|
+
* G→1, A→2, T→3, C→4.
|
|
279
430
|
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
431
|
+
* This follows the file's own FWO_ declaration for the DATA1..4 block; it makes
|
|
432
|
+
* no claim about whether that block is raw or processed.
|
|
282
433
|
*/
|
|
283
|
-
declare function
|
|
434
|
+
declare function getChannelMap(file: AbifFile): Record<'A' | 'C' | 'G' | 'T', number>;
|
|
284
435
|
/** Get PBAS sequence (prefer PBAS2 over PBAS1). undefined if neither present. */
|
|
285
436
|
declare function getSequence(file: AbifFile): string | undefined;
|
|
286
437
|
/**
|
|
@@ -374,6 +525,12 @@ declare function ensureRawDataChannels(file: AbifFile): void;
|
|
|
374
525
|
* Parse an ABIF file into a high-level view: metadata, channels, basecalls,
|
|
375
526
|
* and decoded directory entries.
|
|
376
527
|
*
|
|
528
|
+
* This is the INTERPRETING layer — it makes convenience choices (FWO_ → "GATC"
|
|
529
|
+
* fallback, derived samplingRate, preferred/upper-cased PBAS2 baseCalls). It is
|
|
530
|
+
* not the raw structural truth: for that use {@link readAbif}, which reads the
|
|
531
|
+
* directory verbatim (raw dataSize/offset/counts, tdir, inline bytes) and makes
|
|
532
|
+
* no interpretation. `parseAbif` builds on top of it.
|
|
533
|
+
*
|
|
377
534
|
* Accepts ArrayBuffer or Uint8Array (Buffer in Node works too — it extends
|
|
378
535
|
* Uint8Array). The `fileName` argument is informational only; it's preserved
|
|
379
536
|
* in the result.
|
|
@@ -384,4 +541,4 @@ declare function hasSignals(s: ChannelSignals): boolean;
|
|
|
384
541
|
/** Length of the longest channel in a ChannelSignals bundle. */
|
|
385
542
|
declare function channelMaxLength(s: ChannelSignals): number;
|
|
386
543
|
|
|
387
|
-
export { type AbifBaseCalls, type AbifChromatogramBundle, type AbifDecodedValue, type AbifDirEntry, type AbifEntry, type AbifFile, type AbifMetadata, type ChannelSignals, type Chromatogram, ENTRY_SIZE, HEADER_SIZE, type ParsedAbif, averagePeakSpacing, channelMaxLength, ensureRawDataChannels, findEntries, findEntry, getConfidences, getDataChannel, getFwo, getPositions,
|
|
544
|
+
export { type AbifBaseCallRole, type AbifBaseCallVariant, type AbifBaseCalls, type AbifByteRange, type AbifChromatogramBundle, type AbifDataChannelRole, type AbifDecodedValue, type AbifDirEntry, type AbifDirectory, type AbifEntry, type AbifEntryRaw, type AbifFile, type AbifMetadata, type ChannelSignals, type Chromatogram, ENTRY_SIZE, HEADER_SIZE, type ParsedAbif, averagePeakSpacing, channelMaxLength, dataChannelRole, ensureRawDataChannels, findEntries, findEntry, getChannelMap, getConfidences, getDataChannel, getFwo, getPositions, getReverseComplemented, getSamplingRate, getSequence, hasData9To12Block, hasSignals, isFwoPermutation, parseAbif, readAbif, setAveragePeakSpacing, setConfidences, setPositions, setSequence, tagNameFromInt32, upsertEntry, writeAbif };
|