@datagrok-libraries/utils 0.0.5 → 0.0.6
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/package.json +4 -3
- package/src/bit-array.ts +29 -18
- package/src/reduce-dimensionality.ts +40 -34
- package/src/sequence-encoder.ts +8 -7
- package/src/string-measure.ts +5 -5
- package/src/bit-array.js +0 -656
- package/src/operations.js +0 -144
- package/src/reduce-dimensionality.js +0 -233
- package/src/sequence-encoder.js +0 -116
- package/src/spe.js +0 -151
- package/src/string-measure.js +0 -46
- package/src/string-utils.js +0 -9
- package/src/table-validation.js +0 -47
- package/src/test-utils.js +0 -80
- package/src/type_declarations.js +0 -37
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"fullName": "Utils",
|
|
7
|
-
"version": "0.0.
|
|
7
|
+
"version": "0.0.6",
|
|
8
8
|
"description": "Common utilities",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@keckelt/tsne": "^1.0.2",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"dts-bundle": "^0.7.3",
|
|
14
14
|
"fastest-levenshtein": "^1.0.12",
|
|
15
15
|
"jaro-winkler-typescript": "^1.0.1",
|
|
16
|
-
"typescript": "^
|
|
16
|
+
"typescript": "^4.2.3",
|
|
17
17
|
"umap-js": "^1.3.3",
|
|
18
|
-
"js-yaml": "^4.1.0"
|
|
18
|
+
"js-yaml": "^4.1.0",
|
|
19
|
+
"node-fetch": "^2.6.0"
|
|
19
20
|
},
|
|
20
21
|
"scripts": {
|
|
21
22
|
"link": "npm link",
|
package/src/bit-array.ts
CHANGED
|
@@ -53,28 +53,39 @@ export default class BitArray {
|
|
|
53
53
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
|
54
54
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]);
|
|
55
55
|
|
|
56
|
-
_data: Uint32Array;
|
|
57
|
-
_length = 0;
|
|
58
|
-
_version = 0;
|
|
59
|
-
_updateLevel = 0;
|
|
60
|
-
_selectedCount = 0;
|
|
61
|
-
_selectedCountVersion = -1;
|
|
62
|
-
_selectedIndexesVersion = -1;
|
|
63
|
-
_versionedName = '';
|
|
64
|
-
_versionedNameVersion = -1;
|
|
56
|
+
private _data: Uint32Array;
|
|
57
|
+
private _length = 0;
|
|
58
|
+
private _version = 0;
|
|
59
|
+
private _updateLevel = 0;
|
|
60
|
+
private _selectedCount = 0;
|
|
61
|
+
private _selectedCountVersion = -1;
|
|
62
|
+
private _selectedIndexesVersion = -1;
|
|
63
|
+
private _versionedName = '';
|
|
64
|
+
private _versionedNameVersion = -1;
|
|
65
65
|
SHRINK_THRESHOLD = 0x100;
|
|
66
66
|
|
|
67
|
-
constructor(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
constructor(data: Uint32Array, length: number)
|
|
68
|
+
constructor(length: number, defaultValue?: boolean)
|
|
69
|
+
constructor(arg: number | Uint32Array, defaultValue: boolean | number = false) {
|
|
70
|
+
if (typeof arg === 'number') {
|
|
71
|
+
const length = arg;
|
|
72
|
+
let buff = BitArray._createBuffer(length);
|
|
73
|
+
if (defaultValue)
|
|
74
|
+
for (let i = 0; i < buff.length; i++)
|
|
75
|
+
buff[i] = -1;
|
|
76
|
+
this._data = buff;
|
|
77
|
+
this._length = length;
|
|
78
|
+
} else if (arg instanceof Uint32Array) {
|
|
79
|
+
this._data = arg as Uint32Array;
|
|
80
|
+
this._length = defaultValue as number;
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error("Invalid constructor");
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
85
|
|
|
86
|
+
|
|
87
|
+
getRawData() { return this._data; }
|
|
88
|
+
|
|
78
89
|
assureGoez(num: number, argName: String): void {
|
|
79
90
|
if (num < 0) throw new Error(`${argName} should be greater than zero`);
|
|
80
91
|
}
|
|
@@ -181,7 +192,7 @@ export default class BitArray {
|
|
|
181
192
|
return temp;
|
|
182
193
|
}
|
|
183
194
|
|
|
184
|
-
static _createBuffer(length: number): Uint32Array {
|
|
195
|
+
private static _createBuffer(length: number): Uint32Array {
|
|
185
196
|
return new Uint32Array(Math.floor((length + 0x1f) / 0x20));
|
|
186
197
|
}
|
|
187
198
|
|
|
@@ -5,7 +5,8 @@ import {Options, DistanceMetric, Coordinates, Vector, Vectors, Matrix} from './t
|
|
|
5
5
|
import {calcDistanceMatrix, transposeMatrix} from './operations';
|
|
6
6
|
import {SPEBase, PSPEBase} from './spe';
|
|
7
7
|
import {Measurer} from './string-measure';
|
|
8
|
-
|
|
8
|
+
import {AlignedSequenceEncoder} from './sequence-encoder';
|
|
9
|
+
import {assert} from './operations';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Abstract dimensionality reducer.
|
|
@@ -80,8 +81,9 @@ class TSNEReducer extends Reducer {
|
|
|
80
81
|
*/
|
|
81
82
|
class UMAPReducer extends Reducer {
|
|
82
83
|
protected reducer: umj.UMAP;
|
|
83
|
-
|
|
84
|
-
protected
|
|
84
|
+
protected encoder: AlignedSequenceEncoder;
|
|
85
|
+
protected distanceFn: Function;
|
|
86
|
+
protected vectors: number[][];
|
|
85
87
|
|
|
86
88
|
/**
|
|
87
89
|
* Creates an instance of UMAPReducer.
|
|
@@ -90,46 +92,54 @@ class UMAPReducer extends Reducer {
|
|
|
90
92
|
*/
|
|
91
93
|
constructor(options: Options) {
|
|
92
94
|
super(options);
|
|
93
|
-
this.reducer = new umj.UMAP(options);
|
|
94
|
-
/* this.encoder = new AlignedSequenceEncoder();
|
|
95
|
-
this.distanceMatrix = calcDistanceMatrix(this.data, options.distanceFn);
|
|
96
|
-
this.distanceFn = options.distanceFn;*/
|
|
97
|
-
}
|
|
98
95
|
|
|
99
|
-
|
|
100
|
-
return this.distanceMatrix[a[a.length-1]][b[b.length-1]];
|
|
101
|
-
}
|
|
96
|
+
assert('distanceFn' in options);
|
|
102
97
|
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
this.encoder = new AlignedSequenceEncoder();
|
|
99
|
+
this.distanceFn = options.distanceFn;
|
|
100
|
+
this.vectors = [];
|
|
101
|
+
options.distanceFn = this._encodedDistance.bind(this);
|
|
102
|
+
this.reducer = new umj.UMAP(options);
|
|
105
103
|
}
|
|
106
104
|
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Custom distance wrapper to have numeric inputs instead of string ones.
|
|
107
|
+
*
|
|
108
|
+
* @protected
|
|
109
|
+
* @param {number[]} a The first item.
|
|
110
|
+
* @param {number[]} b The first item.
|
|
111
|
+
* @return {number} Distance metric.
|
|
112
|
+
* @memberof UMAPReducer
|
|
113
|
+
*/
|
|
114
|
+
protected _encodedDistance(a: number[], b: number[]): number {
|
|
115
|
+
return this.distanceFn(this.data[a[0]], this.data[b[0]]);
|
|
116
|
+
}
|
|
109
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Encodes the input data as a vector of indices.
|
|
120
|
+
*
|
|
121
|
+
* @protected
|
|
122
|
+
* @memberof UMAPReducer
|
|
123
|
+
*/
|
|
124
|
+
protected _encode() {
|
|
110
125
|
for (let i = 0; i < this.data.length; ++i) {
|
|
111
|
-
|
|
112
|
-
vectors.push(encoded);
|
|
126
|
+
this.vectors.push([i]);
|
|
113
127
|
}
|
|
114
|
-
return vectors;
|
|
115
128
|
}
|
|
116
129
|
|
|
117
|
-
protected _calcDistance() {
|
|
118
|
-
const nItems = this.data.length;
|
|
119
|
-
const vectors = this.encode();
|
|
120
|
-
|
|
121
|
-
}*/
|
|
122
|
-
|
|
123
130
|
/**
|
|
124
131
|
* Embeds the data given into the two-dimensional space using UMAP method.
|
|
125
132
|
* @return {Coordinates} Cartesian coordinate of this embedding.
|
|
126
133
|
*/
|
|
127
134
|
public transform(): Coordinates {
|
|
128
|
-
|
|
135
|
+
this._encode();
|
|
136
|
+
|
|
137
|
+
const embedding = this.reducer.fit(this.vectors);
|
|
129
138
|
|
|
130
139
|
function arrayCast2Coordinates(data: number[][]): Coordinates {
|
|
131
140
|
return new Array(data.length).fill(0).map((_, i) => (Vector.from(data[i])));
|
|
132
141
|
}
|
|
142
|
+
|
|
133
143
|
return arrayCast2Coordinates(embedding);
|
|
134
144
|
}
|
|
135
145
|
}
|
|
@@ -198,7 +208,7 @@ class PSPEReducer extends Reducer {
|
|
|
198
208
|
*/
|
|
199
209
|
export class DimensionalityReducer {
|
|
200
210
|
private reducer: Reducer | undefined;
|
|
201
|
-
|
|
211
|
+
public static methods: string[] = ['UMAP', 't-SNE', 'SPE', 'pSPE'];
|
|
202
212
|
private measurer: Measurer;
|
|
203
213
|
|
|
204
214
|
/**
|
|
@@ -210,11 +220,7 @@ export class DimensionalityReducer {
|
|
|
210
220
|
* @memberof DimensionalityReducer
|
|
211
221
|
*/
|
|
212
222
|
constructor(data: any[], method: string, metric: string, options?: Options) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (!this.availableMethods.includes(method)) {
|
|
216
|
-
throw new Error('The method "'+method+'" is not supported');
|
|
217
|
-
}
|
|
223
|
+
assert(DimensionalityReducer.availableMethods.includes(method), `The method '${method}' is not supported`);
|
|
218
224
|
|
|
219
225
|
this.measurer = new Measurer(metric);
|
|
220
226
|
const measure = this.measurer.getMeasure()
|
|
@@ -226,7 +232,7 @@ export class DimensionalityReducer {
|
|
|
226
232
|
...{nEpochs: options?.cycles},
|
|
227
233
|
...options
|
|
228
234
|
});
|
|
229
|
-
} else if (method == '
|
|
235
|
+
} else if (method == 't-SNE') {
|
|
230
236
|
this.reducer = new TSNEReducer({
|
|
231
237
|
...{data: data},
|
|
232
238
|
...{distance: measure},
|
|
@@ -266,7 +272,7 @@ export class DimensionalityReducer {
|
|
|
266
272
|
* @readonly
|
|
267
273
|
* @memberof DimensionalityReducer
|
|
268
274
|
*/
|
|
269
|
-
get availableMethods() {
|
|
270
|
-
return
|
|
275
|
+
static get availableMethods() {
|
|
276
|
+
return DimensionalityReducer.methods;
|
|
271
277
|
}
|
|
272
278
|
}
|
package/src/sequence-encoder.ts
CHANGED
|
@@ -41,12 +41,12 @@ export class AlignedSequenceEncoder {
|
|
|
41
41
|
/**
|
|
42
42
|
* Truncate NH2 and -COOH terminals of the given sequence.
|
|
43
43
|
*
|
|
44
|
-
* @
|
|
44
|
+
* @static
|
|
45
45
|
* @param {string} seq The sequence provided.
|
|
46
46
|
* @return {string} Truncated sequence.
|
|
47
47
|
* @memberof AlignedSequenceEncoder
|
|
48
48
|
*/
|
|
49
|
-
|
|
49
|
+
static _truncateSequence(seq: string): string {
|
|
50
50
|
let start = 0;
|
|
51
51
|
let end = seq.length;
|
|
52
52
|
const termina = ['NH2', 'COOH'];
|
|
@@ -67,24 +67,25 @@ export class AlignedSequenceEncoder {
|
|
|
67
67
|
/**
|
|
68
68
|
* Cuts auxiliary defises before a residue.
|
|
69
69
|
*
|
|
70
|
-
* @
|
|
70
|
+
* @static
|
|
71
71
|
* @param {string} seq The sequence to process.
|
|
72
72
|
* @return {string} Processed sequence.
|
|
73
73
|
* @memberof AlignedSequenceEncoder
|
|
74
74
|
*/
|
|
75
|
-
|
|
75
|
+
static _dropDefises(seq: string): string {
|
|
76
76
|
return seq.replace(/(-)([^-]+)/g, '$2')
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Performs truncation and cutting auxiliary defises.
|
|
81
81
|
*
|
|
82
|
+
* @static
|
|
82
83
|
* @param {string} sequence The sequence work under process.
|
|
83
84
|
* @return {string} Result of cleaning.
|
|
84
85
|
* @memberof AlignedSequenceEncoder
|
|
85
86
|
*/
|
|
86
|
-
|
|
87
|
-
return
|
|
87
|
+
static clean(sequence: string): string {
|
|
88
|
+
return AlignedSequenceEncoder._dropDefises(AlignedSequenceEncoder._truncateSequence(sequence));
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
/**
|
|
@@ -95,7 +96,7 @@ export class AlignedSequenceEncoder {
|
|
|
95
96
|
* @memberof AlignedSequenceEncoder
|
|
96
97
|
*/
|
|
97
98
|
public encode(sequence: string): number[] {
|
|
98
|
-
const seq =
|
|
99
|
+
const seq = AlignedSequenceEncoder.clean(sequence);
|
|
99
100
|
const nItems = seq.length;
|
|
100
101
|
let values = new Array(nItems).fill(0);
|
|
101
102
|
|
package/src/string-measure.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {assert} from './operations';
|
|
|
12
12
|
*/
|
|
13
13
|
export class Measurer {
|
|
14
14
|
protected method: string;
|
|
15
|
-
|
|
15
|
+
public static receipt: {[name: string]: DistanceMetric} = {
|
|
16
16
|
'Levenshtein': fl.distance,
|
|
17
17
|
'Jaro-Winkler': jaroWinkler,
|
|
18
18
|
};
|
|
@@ -23,7 +23,7 @@ export class Measurer {
|
|
|
23
23
|
* @memberof Measurer
|
|
24
24
|
*/
|
|
25
25
|
constructor(method: string) {
|
|
26
|
-
assert(
|
|
26
|
+
assert(Measurer.availableMeasures.includes(method), 'The ${method} was not found.')
|
|
27
27
|
this.method = method;
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -32,7 +32,7 @@ export class Measurer {
|
|
|
32
32
|
* @return {DistanceMetric} Callback of the measure chosen.
|
|
33
33
|
*/
|
|
34
34
|
public getMeasure(): DistanceMetric {
|
|
35
|
-
return
|
|
35
|
+
return Measurer.receipt[this.method];
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -42,10 +42,10 @@ export class Measurer {
|
|
|
42
42
|
* @type {string[]}
|
|
43
43
|
* @memberof Measurer
|
|
44
44
|
*/
|
|
45
|
-
public get availableMeasures() : string[] {
|
|
45
|
+
public static get availableMeasures() : string[] {
|
|
46
46
|
let keys = [];
|
|
47
47
|
|
|
48
|
-
for (let key in
|
|
48
|
+
for (let key in Measurer.receipt) {
|
|
49
49
|
keys.push(key);
|
|
50
50
|
}
|
|
51
51
|
return keys;
|