@gmod/bed 2.0.7 → 2.1.1
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/CHANGELOG.md +18 -0
- package/README.md +5 -0
- package/dist/as/autoSqlSchemas.d.ts +10 -10
- package/dist/as/autoSqlSchemas.js.map +1 -1
- package/dist/defaultTypes.d.ts +3 -2
- package/dist/defaultTypes.js +9 -2
- package/dist/defaultTypes.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/parser.d.ts +11 -10
- package/dist/parser.js +1 -7
- package/dist/parser.js.map +1 -1
- package/dist/util.d.ts +18 -1
- package/dist/util.js +1 -14
- package/dist/util.js.map +1 -1
- package/esm/as/autoSqlSchemas.d.ts +10 -10
- package/esm/as/autoSqlSchemas.js.map +1 -1
- package/esm/defaultTypes.d.ts +3 -2
- package/esm/defaultTypes.js +4 -3
- package/esm/defaultTypes.js.map +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.js.map +1 -1
- package/esm/parser.d.ts +11 -10
- package/esm/parser.js +2 -8
- package/esm/parser.js.map +1 -1
- package/esm/util.d.ts +18 -1
- package/esm/util.js +9 -14
- package/esm/util.js.map +1 -1
- package/package.json +13 -12
- package/src/as/README.md +7 -0
- package/src/as/autoSqlSchemas.ts +176 -0
- package/src/autoSql.js +1501 -0
- package/src/defaultTypes.ts +10 -0
- package/src/index.ts +3 -0
- package/src/parser.ts +99 -0
- package/src/util.ts +27 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { parse } from './autoSql'
|
|
2
|
+
import { AutoSqlPreSchema } from './util'
|
|
3
|
+
import * as types from './as/autoSqlSchemas'
|
|
4
|
+
|
|
5
|
+
export default Object.fromEntries(
|
|
6
|
+
Object.entries(types).map(([key, val]) => [
|
|
7
|
+
key,
|
|
8
|
+
parse(val.trim()) as AutoSqlPreSchema,
|
|
9
|
+
]),
|
|
10
|
+
)
|
package/src/index.ts
ADDED
package/src/parser.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import parser from './autoSql'
|
|
2
|
+
import types from './defaultTypes'
|
|
3
|
+
import { detectTypes, AutoSqlSchema, AutoSqlPreSchema } from './util'
|
|
4
|
+
|
|
5
|
+
const strandMap = { '.': 0, '-': -1, '+': 1 }
|
|
6
|
+
|
|
7
|
+
// heuristic that a BED file is BED12 like...the number in col 10 is blockCount-like
|
|
8
|
+
function isBed12Like(fields: string[]) {
|
|
9
|
+
return (
|
|
10
|
+
fields.length >= 12 &&
|
|
11
|
+
!Number.isNaN(parseInt(fields[9], 10)) &&
|
|
12
|
+
fields[10]?.split(',').filter(f => !!f).length === parseInt(fields[9], 10)
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
export default class BED {
|
|
16
|
+
public autoSql: AutoSqlSchema
|
|
17
|
+
|
|
18
|
+
private attemptDefaultBed?: boolean
|
|
19
|
+
|
|
20
|
+
constructor(args: { autoSql?: string; type?: string } = {}) {
|
|
21
|
+
if (args.autoSql) {
|
|
22
|
+
this.autoSql = detectTypes(parser.parse(args.autoSql) as AutoSqlPreSchema)
|
|
23
|
+
} else if (args.type) {
|
|
24
|
+
if (!types[args.type]) {
|
|
25
|
+
throw new Error('Type not found')
|
|
26
|
+
}
|
|
27
|
+
this.autoSql = detectTypes(types[args.type])
|
|
28
|
+
} else {
|
|
29
|
+
this.autoSql = detectTypes(types.defaultBedSchema)
|
|
30
|
+
this.attemptDefaultBed = true
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
* parses a line of text as a BED line with the loaded autoSql schema
|
|
36
|
+
*
|
|
37
|
+
* @param line - a BED line as tab delimited text or array
|
|
38
|
+
* @param opts - supply opts.uniqueId
|
|
39
|
+
* @return a object representing a feature
|
|
40
|
+
*/
|
|
41
|
+
parseLine(line: string | string[], opts: { uniqueId?: string } = {}) {
|
|
42
|
+
const { autoSql } = this
|
|
43
|
+
const { uniqueId } = opts
|
|
44
|
+
const fields = Array.isArray(line) ? line : line.split('\t')
|
|
45
|
+
|
|
46
|
+
let feature = {} as { [key: string]: any }
|
|
47
|
+
if (
|
|
48
|
+
!this.attemptDefaultBed ||
|
|
49
|
+
(this.attemptDefaultBed && isBed12Like(fields))
|
|
50
|
+
) {
|
|
51
|
+
for (let i = 0; i < autoSql.fields.length; i++) {
|
|
52
|
+
const autoField = autoSql.fields[i]
|
|
53
|
+
let columnVal: any = fields[i]
|
|
54
|
+
const { isNumeric, isArray, arrayIsNumeric, name } = autoField
|
|
55
|
+
if (columnVal === null || columnVal === undefined) {
|
|
56
|
+
break
|
|
57
|
+
}
|
|
58
|
+
if (columnVal !== '.') {
|
|
59
|
+
if (isNumeric) {
|
|
60
|
+
const num = Number(columnVal)
|
|
61
|
+
columnVal = Number.isNaN(num) ? columnVal : num
|
|
62
|
+
} else if (isArray) {
|
|
63
|
+
columnVal = columnVal.split(',')
|
|
64
|
+
if (columnVal[columnVal.length - 1] === '') {
|
|
65
|
+
columnVal.pop()
|
|
66
|
+
}
|
|
67
|
+
if (arrayIsNumeric) {
|
|
68
|
+
columnVal = columnVal.map((str: string) => Number(str))
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
feature[name] = columnVal
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
const fieldNames = ['chrom', 'chromStart', 'chromEnd', 'name']
|
|
77
|
+
feature = Object.fromEntries(
|
|
78
|
+
fields.map((f, i) => [fieldNames[i] || 'field' + i, f]),
|
|
79
|
+
)
|
|
80
|
+
feature.chromStart = +feature.chromStart
|
|
81
|
+
feature.chromEnd = +feature.chromEnd
|
|
82
|
+
if (!Number.isNaN(Number.parseFloat(feature.field4))) {
|
|
83
|
+
feature.score = +feature.field4
|
|
84
|
+
delete feature.field4
|
|
85
|
+
}
|
|
86
|
+
if (feature.field5 === '+' || feature.field5 === '-') {
|
|
87
|
+
feature.strand = feature.field5
|
|
88
|
+
delete feature.field5
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (uniqueId) {
|
|
92
|
+
feature.uniqueId = uniqueId
|
|
93
|
+
}
|
|
94
|
+
feature.strand = strandMap[feature.strand as keyof typeof strandMap] || 0
|
|
95
|
+
|
|
96
|
+
feature.chrom = decodeURIComponent(feature.chrom)
|
|
97
|
+
return feature
|
|
98
|
+
}
|
|
99
|
+
}
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface AutoSqlPreSchema {
|
|
2
|
+
fields: { size: number; type: string; name: string }[]
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* adds some type annotations to the autoSql schema
|
|
7
|
+
* for numeric fields ['uint', 'int', 'float', 'long'] "isNumeric" is added
|
|
8
|
+
* for array types "isArray" is added
|
|
9
|
+
* for numeric array types "isArray" and "arrayIsNumeric" is set
|
|
10
|
+
*
|
|
11
|
+
* @param autoSql - an autoSql schema from the peg parser
|
|
12
|
+
* @return autoSql with type annotations added
|
|
13
|
+
*/
|
|
14
|
+
export function detectTypes(autoSql: AutoSqlPreSchema) {
|
|
15
|
+
const numericTypes = ['uint', 'int', 'float', 'long']
|
|
16
|
+
return {
|
|
17
|
+
...autoSql,
|
|
18
|
+
fields: autoSql.fields.map(autoField => ({
|
|
19
|
+
...autoField,
|
|
20
|
+
isArray: autoField.size && autoField.type !== 'char',
|
|
21
|
+
arrayIsNumeric: autoField.size && numericTypes.includes(autoField.type),
|
|
22
|
+
isNumeric: !autoField.size && numericTypes.includes(autoField.type),
|
|
23
|
+
})),
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type AutoSqlSchema = ReturnType<typeof detectTypes>
|