@gmod/hic 1.0.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/LICENSE +25 -0
- package/README.md +91 -0
- package/dist/binWindow.d.ts +24 -0
- package/dist/binWindow.js +32 -0
- package/dist/binWindow.js.map +1 -0
- package/dist/binary.d.ts +15 -0
- package/dist/binary.js +67 -0
- package/dist/binary.js.map +1 -0
- package/dist/bufferedFile.d.ts +13 -0
- package/dist/bufferedFile.js +78 -0
- package/dist/bufferedFile.js.map +1 -0
- package/dist/contactRecords.d.ts +25 -0
- package/dist/contactRecords.js +3 -0
- package/dist/contactRecords.js.map +1 -0
- package/dist/hicFile.d.ts +94 -0
- package/dist/hicFile.js +769 -0
- package/dist/hicFile.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lru.d.ts +29 -0
- package/dist/lru.js +55 -0
- package/dist/lru.js.map +1 -0
- package/dist/matrix.d.ts +9 -0
- package/dist/matrix.js +41 -0
- package/dist/matrix.js.map +1 -0
- package/dist/matrixZoomData.d.ts +14 -0
- package/dist/matrixZoomData.js +96 -0
- package/dist/matrixZoomData.js.map +1 -0
- package/dist/normalizationVector.d.ts +10 -0
- package/dist/normalizationVector.js +51 -0
- package/dist/normalizationVector.js.map +1 -0
- package/dist/package.json +1 -0
- package/dist/reader.d.ts +3 -0
- package/dist/reader.js +12 -0
- package/dist/reader.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/esm/binWindow.d.ts +24 -0
- package/esm/binWindow.js +29 -0
- package/esm/binWindow.js.map +1 -0
- package/esm/binary.d.ts +15 -0
- package/esm/binary.js +64 -0
- package/esm/binary.js.map +1 -0
- package/esm/bufferedFile.d.ts +13 -0
- package/esm/bufferedFile.js +75 -0
- package/esm/bufferedFile.js.map +1 -0
- package/esm/contactRecords.d.ts +25 -0
- package/esm/contactRecords.js +2 -0
- package/esm/contactRecords.js.map +1 -0
- package/esm/hicFile.d.ts +94 -0
- package/esm/hicFile.js +762 -0
- package/esm/hicFile.js.map +1 -0
- package/esm/index.d.ts +5 -0
- package/esm/index.js +3 -0
- package/esm/index.js.map +1 -0
- package/esm/lru.d.ts +29 -0
- package/esm/lru.js +52 -0
- package/esm/lru.js.map +1 -0
- package/esm/matrix.d.ts +9 -0
- package/esm/matrix.js +35 -0
- package/esm/matrix.js.map +1 -0
- package/esm/matrixZoomData.d.ts +14 -0
- package/esm/matrixZoomData.js +93 -0
- package/esm/matrixZoomData.js.map +1 -0
- package/esm/normalizationVector.d.ts +10 -0
- package/esm/normalizationVector.js +45 -0
- package/esm/normalizationVector.js.map +1 -0
- package/esm/reader.d.ts +3 -0
- package/esm/reader.js +9 -0
- package/esm/reader.js.map +1 -0
- package/esm/types.d.ts +35 -0
- package/esm/types.js +2 -0
- package/esm/types.js.map +1 -0
- package/package.json +73 -0
- package/src/binWindow.ts +30 -0
- package/src/binary.ts +72 -0
- package/src/bufferedFile.ts +74 -0
- package/src/contactRecords.ts +25 -0
- package/src/hicFile.ts +943 -0
- package/src/index.ts +12 -0
- package/src/lru.ts +77 -0
- package/src/matrix.ts +43 -0
- package/src/matrixZoomData.ts +133 -0
- package/src/normalizationVector.ts +58 -0
- package/src/reader.ts +11 -0
- package/src/types.ts +40 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Reader } from './types.ts'
|
|
2
|
+
|
|
3
|
+
function concatBuffers(buffer1: ArrayBuffer, buffer2: ArrayBuffer) {
|
|
4
|
+
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)
|
|
5
|
+
tmp.set(new Uint8Array(buffer1), 0)
|
|
6
|
+
tmp.set(new Uint8Array(buffer2), buffer1.byteLength)
|
|
7
|
+
return tmp.buffer
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default class BufferedFile {
|
|
11
|
+
private file: Reader
|
|
12
|
+
private size: number
|
|
13
|
+
private bufferStart = 0
|
|
14
|
+
private bufferLength = 0
|
|
15
|
+
private buffer: ArrayBuffer | undefined
|
|
16
|
+
|
|
17
|
+
constructor(args: { file: Reader; size?: number }) {
|
|
18
|
+
this.file = args.file
|
|
19
|
+
this.size = args.size ?? 64000
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async read(position: number, length: number): Promise<ArrayBuffer> {
|
|
23
|
+
const start = position
|
|
24
|
+
const end = position + length
|
|
25
|
+
const bufferStart = this.bufferStart
|
|
26
|
+
const bufferEnd = this.bufferStart + this.bufferLength
|
|
27
|
+
const buf = this.buffer
|
|
28
|
+
|
|
29
|
+
let result: ArrayBuffer
|
|
30
|
+
if (length > this.size) {
|
|
31
|
+
// Request larger than max buffer size, pass through to underlying file
|
|
32
|
+
this.buffer = undefined
|
|
33
|
+
this.bufferStart = 0
|
|
34
|
+
this.bufferLength = 0
|
|
35
|
+
result = await this.file.read(position, length)
|
|
36
|
+
} else if (buf && start >= bufferStart && end <= bufferEnd) {
|
|
37
|
+
// Request within buffer bounds
|
|
38
|
+
const sliceStart = start - bufferStart
|
|
39
|
+
result = buf.slice(sliceStart, sliceStart + length)
|
|
40
|
+
} else if (buf && start < bufferStart && end > bufferStart) {
|
|
41
|
+
// Overlap left (unexpected in straw); we don't adjust the buffer
|
|
42
|
+
const l1 = bufferStart - start
|
|
43
|
+
const a1 = await this.file.read(position, l1)
|
|
44
|
+
const l2 = length - l1
|
|
45
|
+
if (l2 > 0) {
|
|
46
|
+
result = concatBuffers(a1, buf.slice(0, l2))
|
|
47
|
+
} else {
|
|
48
|
+
result = a1
|
|
49
|
+
}
|
|
50
|
+
} else if (buf && start < bufferEnd && end > bufferEnd) {
|
|
51
|
+
// Overlap right
|
|
52
|
+
const l1 = bufferEnd - start
|
|
53
|
+
const a1 = buf.slice(this.bufferLength - l1, this.bufferLength)
|
|
54
|
+
const l2 = length - l1
|
|
55
|
+
if (l2 > 0) {
|
|
56
|
+
const next = await this.file.read(bufferEnd, this.size)
|
|
57
|
+
this.buffer = next
|
|
58
|
+
this.bufferStart = bufferEnd
|
|
59
|
+
this.bufferLength = next.byteLength
|
|
60
|
+
result = concatBuffers(a1, next.slice(0, l2))
|
|
61
|
+
} else {
|
|
62
|
+
result = a1
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
// No overlap with buffer
|
|
66
|
+
const next = await this.file.read(position, this.size)
|
|
67
|
+
this.buffer = next
|
|
68
|
+
this.bufferStart = position
|
|
69
|
+
this.bufferLength = next.byteLength
|
|
70
|
+
result = next.slice(0, length)
|
|
71
|
+
}
|
|
72
|
+
return result
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A run of contact records, held struct-of-arrays.
|
|
3
|
+
*
|
|
4
|
+
* hic-straw models a contact as an object, and the whole read path inherits
|
|
5
|
+
* that shape: a block holds `ContactRecord[]` and the window filter rebuilds
|
|
6
|
+
* the array. A renderer then has to unpack that into typed arrays anyway, so a
|
|
7
|
+
* contact was allocated several times over on its way to a vertex buffer — and
|
|
8
|
+
* a matrix is routinely millions of contacts.
|
|
9
|
+
*
|
|
10
|
+
* The per-contact allocation is the obvious cost, but the block cache is the
|
|
11
|
+
* expensive one: cached blocks are long-lived, so as objects they left millions
|
|
12
|
+
* of live pointers for every GC to trace for the rest of the session. Twelve
|
|
13
|
+
* bytes a contact here against ~50 for an object, and nothing for the collector
|
|
14
|
+
* to walk.
|
|
15
|
+
*
|
|
16
|
+
* The three arrays are always exactly the same length — `bin1.length` is the
|
|
17
|
+
* record count. Counts are float32 because that is what the file stores
|
|
18
|
+
* (`getFloat`/`getShort`) and what a GPU renderer takes, so carrying them as
|
|
19
|
+
* doubles only ever widened a value on its way back down to float32.
|
|
20
|
+
*/
|
|
21
|
+
export interface ContactRecords {
|
|
22
|
+
bin1: Int32Array
|
|
23
|
+
bin2: Int32Array
|
|
24
|
+
counts: Float32Array
|
|
25
|
+
}
|