@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 CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "fullName": "Utils",
7
- "version": "0.0.5",
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": "^3.9.7",
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(length: number, defaultValue = false) {
68
- this._length = length;
69
- this._data = BitArray._createBuffer(length);
70
-
71
- if (defaultValue) {
72
- for (let i = 0; i < this._data.length; i++) {
73
- this._data[i] = -1;
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
- //import {AlignedSequenceEncoder} from './sequence-encoder';
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
- /* protected encoder: AlignedSequenceEncoder;
84
- protected distanceMatrix: Matrix;*/
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
- /* protected _encodedDistance(a: number[], b: number[]): number {
100
- return this.distanceMatrix[a[a.length-1]][b[b.length-1]];
101
- }
96
+ assert('distanceFn' in options);
102
97
 
103
- protected _decodedDistance(a: number[], b: number[]): number {
104
- return this.encoder.decode(a);
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
- protected encode(): number[][] {
108
- let vectors: number[][] = [];
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
- let encoded = this.encoder.encode(this.data[i]);
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
- const embedding = this.reducer.fit(this.data);
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
- private methods: string[];
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
- this.methods = ['UMAP', 'TSNE', 'SPE', 'PSPE'];
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 == 'TSNE') {
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 this.methods;
275
+ static get availableMethods() {
276
+ return DimensionalityReducer.methods;
271
277
  }
272
278
  }
@@ -41,12 +41,12 @@ export class AlignedSequenceEncoder {
41
41
  /**
42
42
  * Truncate NH2 and -COOH terminals of the given sequence.
43
43
  *
44
- * @protected
44
+ * @static
45
45
  * @param {string} seq The sequence provided.
46
46
  * @return {string} Truncated sequence.
47
47
  * @memberof AlignedSequenceEncoder
48
48
  */
49
- protected _truncateSequence(seq: string): string {
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
- * @protected
70
+ * @static
71
71
  * @param {string} seq The sequence to process.
72
72
  * @return {string} Processed sequence.
73
73
  * @memberof AlignedSequenceEncoder
74
74
  */
75
- protected _dropDefises(seq: string): string {
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
- public clean(sequence: string): string {
87
- return this._dropDefises(this._truncateSequence(sequence));
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 = this.clean(sequence);
99
+ const seq = AlignedSequenceEncoder.clean(sequence);
99
100
  const nItems = seq.length;
100
101
  let values = new Array(nItems).fill(0);
101
102
 
@@ -12,7 +12,7 @@ import {assert} from './operations';
12
12
  */
13
13
  export class Measurer {
14
14
  protected method: string;
15
- protected receipt: {[name: string]: DistanceMetric} = {
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(this.availableMeasures.includes(method), 'The ${method} was not found.')
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 this.receipt[this.method];
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 this.receipt) {
48
+ for (let key in Measurer.receipt) {
49
49
  keys.push(key);
50
50
  }
51
51
  return keys;