@datagrok/sequence-translator 1.2.6 → 1.2.9
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/.eslintrc.json +5 -5
- package/CHANGELOG.md +12 -0
- package/dist/package-test.js +2 -1
- package/dist/package-test.js.LICENSE.txt +8 -0
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +2 -1
- package/dist/package.js.LICENSE.txt +8 -0
- package/dist/package.js.map +1 -1
- package/files/pattern-app-data.json +80 -0
- package/package.json +21 -14
- package/src/{model → apps/common/model}/const.ts +1 -1
- package/src/{model/data-loading-utils → apps/common/model/data-loader}/const.ts +7 -2
- package/src/apps/common/model/data-loader/json-loader.ts +48 -0
- package/src/{model/data-loading-utils → apps/common/model/data-loader}/types.ts +13 -6
- package/src/{model → apps/common/model}/monomer-lib/lib-wrapper.ts +9 -12
- package/src/apps/common/model/oligo-toolkit-package.ts +30 -0
- package/src/{model → apps/common/model}/parsing-validation/format-detector.ts +5 -5
- package/src/{model → apps/common/model}/parsing-validation/format-handler.ts +18 -19
- package/src/{model → apps/common/model}/parsing-validation/sequence-validator.ts +1 -1
- package/src/apps/common/view/app-ui-base.ts +28 -0
- package/src/apps/common/view/combined-app-ui.ts +66 -0
- package/src/{view/utils → apps/common/view/components}/colored-input/colored-text-input.ts +1 -1
- package/src/{view/utils → apps/common/view/components}/draw-molecule.ts +1 -1
- package/src/{view/utils → apps/common/view/components}/molecule-img.ts +3 -3
- package/src/{view/const/ui.ts → apps/common/view/const.ts} +4 -4
- package/src/apps/common/view/isolated-app-ui.ts +43 -0
- package/src/{view/monomer-lib-viewer/viewer.ts → apps/common/view/monomer-lib-viewer.ts} +2 -2
- package/src/apps/common/view/utils.ts +29 -0
- package/src/apps/pattern/model/const.ts +121 -0
- package/src/apps/pattern/model/data-manager.ts +297 -0
- package/src/apps/pattern/model/event-bus.ts +470 -0
- package/src/apps/pattern/model/router.ts +46 -0
- package/src/apps/pattern/model/subscription-manager.ts +21 -0
- package/src/apps/pattern/model/translator.ts +68 -0
- package/src/apps/pattern/model/types.ts +52 -0
- package/src/apps/pattern/model/utils.ts +110 -0
- package/src/apps/pattern/view/components/bulk-convert/column-input.ts +69 -0
- package/src/apps/pattern/view/components/bulk-convert/table-controls.ts +37 -0
- package/src/apps/pattern/view/components/bulk-convert/table-input.ts +95 -0
- package/src/apps/pattern/view/components/edit-block-controls.ts +196 -0
- package/src/apps/pattern/view/components/left-section.ts +44 -0
- package/src/apps/pattern/view/components/load-block-controls.ts +198 -0
- package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +69 -0
- package/src/apps/pattern/view/components/right-section.ts +148 -0
- package/src/apps/pattern/view/components/strand-editor/dialog.ts +79 -0
- package/src/apps/pattern/view/components/strand-editor/header-controls.ts +105 -0
- package/src/apps/pattern/view/components/strand-editor/strand-controls.ts +159 -0
- package/src/apps/pattern/view/components/terminal-modification-editor.ts +127 -0
- package/src/apps/pattern/view/components/translation-examples-block.ts +139 -0
- package/src/{view/style/pattern-app.css → apps/pattern/view/style.css} +4 -0
- package/src/apps/pattern/view/svg-utils/const.ts +63 -0
- package/src/apps/pattern/view/svg-utils/dimensions-calculator.ts +498 -0
- package/src/apps/pattern/view/svg-utils/svg-display-manager.ts +45 -0
- package/src/apps/pattern/view/svg-utils/svg-element-factory.ts +82 -0
- package/src/apps/pattern/view/svg-utils/svg-renderer.ts +396 -0
- package/src/apps/pattern/view/svg-utils/utils.ts +37 -0
- package/src/apps/pattern/view/types.ts +14 -0
- package/src/apps/pattern/view/ui.ts +61 -0
- package/src/{model/structure-app → apps/structure/model}/mol-transformations.ts +3 -3
- package/src/{model/structure-app → apps/structure/model}/monomer-code-parser.ts +9 -10
- package/src/{model/structure-app → apps/structure/model}/oligo-structure.ts +4 -4
- package/src/{model/structure-app → apps/structure/model}/sequence-to-molfile.ts +2 -2
- package/src/{view/apps/oligo-structure.ts → apps/structure/view/ui.ts} +31 -17
- package/src/{model/translator-app → apps/translator/model}/conversion-utils.ts +25 -7
- package/src/{model/translator-app → apps/translator/model}/format-converter.ts +7 -12
- package/src/{view/const/oligo-translator.ts → apps/translator/view/const.ts} +2 -0
- package/src/apps/translator/view/ui.ts +547 -0
- package/src/demo/demo-st-ui.ts +12 -32
- package/src/package.ts +76 -56
- package/src/plugins/mermade.ts +9 -9
- package/src/polytool/const.ts +40 -0
- package/src/polytool/csv-to-json-monomer-lib-converter.ts +40 -0
- package/src/polytool/cyclized.ts +56 -0
- package/src/polytool/monomer-lib-handler.ts +115 -0
- package/src/polytool/transformation.ts +326 -0
- package/src/polytool/ui.ts +59 -0
- package/src/polytool/utils.ts +20 -0
- package/src/tests/const.ts +5 -5
- package/src/tests/formats-support.ts +6 -6
- package/src/tests/formats-to-helm.ts +5 -5
- package/src/tests/helm-to-nucleotides.ts +5 -5
- package/tsconfig.json +4 -10
- package/webpack.config.js +3 -0
- package/files/axolabs-style.json +0 -97
- package/src/model/data-loading-utils/json-loader.ts +0 -38
- package/src/model/pattern-app/const.ts +0 -33
- package/src/model/pattern-app/draw-svg.ts +0 -193
- package/src/model/pattern-app/helpers.ts +0 -96
- package/src/model/pattern-app/oligo-pattern.ts +0 -111
- package/src/view/app-ui.ts +0 -193
- package/src/view/apps/oligo-pattern.ts +0 -759
- package/src/view/apps/oligo-translator.ts +0 -184
- /package/src/{model → apps/common/model}/helpers.ts +0 -0
- /package/src/{model → apps/common/model}/monomer-lib/const.ts +0 -0
- /package/src/{view/utils → apps/common/view/components}/app-info-dialog.ts +0 -0
- /package/src/{view/utils → apps/common/view/components}/colored-input/input-painters.ts +0 -0
- /package/src/{view/style/colored-text-input.css → apps/common/view/components/colored-input/style.css} +0 -0
- /package/src/{view/utils → apps/common/view/components}/router.ts +0 -0
- /package/src/{model/structure-app → apps/structure/model}/const.ts +0 -0
- /package/src/{view/style/structure-app.css → apps/structure/view/style.css} +0 -0
- /package/src/{model/translator-app → apps/translator/model}/const.ts +0 -0
- /package/src/{view/style/translator-app.css → apps/translator/view/style.css} +0 -0
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
3
|
import * as grok from 'datagrok-api/grok';
|
|
3
4
|
import * as ui from 'datagrok-api/ui';
|
|
4
|
-
import * as DG from 'datagrok-api/dg';
|
|
5
5
|
|
|
6
|
-
import * as rxjs from 'rxjs';
|
|
7
|
-
import '../style/structure-app.css';
|
|
8
6
|
import $ from 'cash-dom';
|
|
7
|
+
import * as rxjs from 'rxjs';
|
|
8
|
+
import './style.css';
|
|
9
9
|
|
|
10
10
|
import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
12
|
+
import {ColoredTextInput} from '../../common/view/components/colored-input/colored-text-input';
|
|
13
|
+
import {highlightInvalidSubsequence} from '../../common/view/components/colored-input/input-painters';
|
|
14
|
+
import {MoleculeImage} from '../../common/view/components/molecule-img';
|
|
15
|
+
import {APP_NAME} from '../../common/view/const';
|
|
16
|
+
import {IsolatedAppUIBase} from '../../common/view/isolated-app-ui';
|
|
17
|
+
import {getLinkedMolfile, saveSdf, StrandData} from '../model/oligo-structure';
|
|
17
18
|
|
|
18
19
|
const enum DIRECTION {
|
|
19
20
|
STRAIGHT = '5′ → 3′',
|
|
@@ -21,7 +22,7 @@ const enum DIRECTION {
|
|
|
21
22
|
};
|
|
22
23
|
const STRANDS = ['ss', 'as', 'as2'] as const;
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
class StructureAppLayout {
|
|
25
26
|
constructor() {
|
|
26
27
|
this.onInput = new rxjs.Subject<string>();
|
|
27
28
|
this.onInvalidInput = new rxjs.Subject<string>();
|
|
@@ -98,7 +99,7 @@ export class StructureLayoutHandler {
|
|
|
98
99
|
const selected = (idx === 0) ? DIRECTION.STRAIGHT : DIRECTION.INVERSE;
|
|
99
100
|
return [key, ui.choiceInput(
|
|
100
101
|
`${key.toUpperCase()} direction`, selected, [DIRECTION.STRAIGHT, DIRECTION.INVERSE]
|
|
101
|
-
)]
|
|
102
|
+
)];
|
|
102
103
|
}
|
|
103
104
|
)
|
|
104
105
|
);
|
|
@@ -106,8 +107,9 @@ export class StructureLayoutHandler {
|
|
|
106
107
|
STRANDS.forEach((strand, idx) => {
|
|
107
108
|
directionChoiceInput[strand].onChanged(() => {
|
|
108
109
|
let value = directionChoiceInput[strand].value === DIRECTION.INVERSE;
|
|
109
|
-
// warning: the next line is necessary
|
|
110
|
-
|
|
110
|
+
// warning: the next line is necessary
|
|
111
|
+
// until the legacy notion of direction used in the molfile generation gets fixed
|
|
112
|
+
if (idx > 0) value = !value;
|
|
111
113
|
this.directionInversion[strand] = value;
|
|
112
114
|
this.onInput.next();
|
|
113
115
|
});
|
|
@@ -126,7 +128,7 @@ export class StructureLayoutHandler {
|
|
|
126
128
|
const clearBlock = Object.fromEntries(
|
|
127
129
|
STRANDS.map(
|
|
128
130
|
(key) => {
|
|
129
|
-
const clearIcon = ui.icons.delete(() => { coloredInput[key].inputBase.value = '' });
|
|
131
|
+
const clearIcon = ui.icons.delete(() => { coloredInput[key].inputBase.value = ''; });
|
|
130
132
|
const clearButton = ui.button(clearIcon, () => {});
|
|
131
133
|
ui.tooltip.bind(clearButton, `Clear ${key.toUpperCase()}`);
|
|
132
134
|
return [key, clearIcon];
|
|
@@ -163,12 +165,12 @@ export class StructureLayoutHandler {
|
|
|
163
165
|
|
|
164
166
|
private getStrandData() {
|
|
165
167
|
return Object.fromEntries(
|
|
166
|
-
STRANDS.map((strand
|
|
167
|
-
|
|
168
|
+
STRANDS.map((strand) => {
|
|
169
|
+
const invert = this.directionInversion[strand];
|
|
168
170
|
return [strand, {
|
|
169
171
|
strand: this.inputBase[strand].value.replace(/\s*/g, ''),
|
|
170
172
|
invert: invert
|
|
171
|
-
}]
|
|
173
|
+
}];
|
|
172
174
|
})
|
|
173
175
|
);
|
|
174
176
|
}
|
|
@@ -192,7 +194,7 @@ export class StructureLayoutHandler {
|
|
|
192
194
|
const errStr = errorToConsole(err);
|
|
193
195
|
console.error(errStr);
|
|
194
196
|
}
|
|
195
|
-
// todo:
|
|
197
|
+
// todo: compute relative numbers
|
|
196
198
|
const canvasWidth = 650;
|
|
197
199
|
const canvasHeight = 150;
|
|
198
200
|
const molImgObj = new MoleculeImage(molfile);
|
|
@@ -201,3 +203,15 @@ export class StructureLayoutHandler {
|
|
|
201
203
|
$(this.moleculeImgDiv).find('canvas').css('float', 'inherit');
|
|
202
204
|
}
|
|
203
205
|
}
|
|
206
|
+
|
|
207
|
+
export class OligoStructureUI extends IsolatedAppUIBase {
|
|
208
|
+
constructor() {
|
|
209
|
+
super(APP_NAME.STRUCTURE);
|
|
210
|
+
this.layout = new StructureAppLayout();
|
|
211
|
+
}
|
|
212
|
+
private readonly layout: StructureAppLayout;
|
|
213
|
+
|
|
214
|
+
protected getContent(): Promise<HTMLDivElement> {
|
|
215
|
+
return this.layout.getHtmlDivElement();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {DEFAULT_FORMATS, NUCLEOTIDES} from '
|
|
1
|
+
import {DEFAULT_FORMATS, NUCLEOTIDES} from '../../common/model/const';
|
|
2
|
+
import {NUCLEOTIDES_FORMAT} from '../view/const';
|
|
2
3
|
import {UNKNOWN_SYMBOL} from './const';
|
|
3
4
|
import {FormatConverter} from './format-converter';
|
|
4
|
-
import {
|
|
5
|
-
import {MonomerLibWrapper} from '
|
|
5
|
+
import {CODES_TO_HELM_DICT} from '../../common/model/data-loader/json-loader';
|
|
6
|
+
import {MonomerLibWrapper} from '../../common/model/monomer-lib/lib-wrapper';
|
|
6
7
|
|
|
7
8
|
export function getTranslatedSequences(sequence: string, indexOfFirstInvalidChar: number, sourceFormat: string): {[key: string]: string} {
|
|
8
|
-
const supportedFormats = Object.keys(
|
|
9
|
+
const supportedFormats = Object.keys(CODES_TO_HELM_DICT).concat([DEFAULT_FORMATS.HELM]) as string[];
|
|
9
10
|
|
|
10
11
|
if (!sequence || (indexOfFirstInvalidChar !== -1 && sourceFormat !== DEFAULT_FORMATS.HELM))
|
|
11
12
|
return {};
|
|
12
13
|
|
|
13
14
|
if (!supportedFormats.includes(sourceFormat))
|
|
14
|
-
throw new Error(`${sourceFormat} format is not supported by SequenceTranslator`)
|
|
15
|
+
throw new Error(`${sourceFormat} format is not supported by SequenceTranslator`);
|
|
15
16
|
|
|
16
17
|
const outputFormats = supportedFormats.filter((el) => el != sourceFormat)
|
|
17
18
|
.sort((a, b) => a.localeCompare(b));
|
|
@@ -25,8 +26,8 @@ export function getTranslatedSequences(sequence: string, indexOfFirstInvalidChar
|
|
|
25
26
|
translation = null;
|
|
26
27
|
}
|
|
27
28
|
return [format, translation];
|
|
28
|
-
}).filter(([
|
|
29
|
-
)
|
|
29
|
+
}).filter(([_, translation]) => translation)
|
|
30
|
+
);
|
|
30
31
|
const helm = (sourceFormat === DEFAULT_FORMATS.HELM) ? sequence : result[DEFAULT_FORMATS.HELM];
|
|
31
32
|
const nucleotides = getNucleotidesSequence(helm, MonomerLibWrapper.getInstance());
|
|
32
33
|
if (nucleotides)
|
|
@@ -47,3 +48,20 @@ export function getNucleotidesSequence(helmString: string, monomerLib: MonomerLi
|
|
|
47
48
|
}).map((el) => el ? el : UNKNOWN_SYMBOL).join('');
|
|
48
49
|
return nucleotides;
|
|
49
50
|
}
|
|
51
|
+
|
|
52
|
+
// todo: remove after refactoring as a workaround
|
|
53
|
+
export function convert(sequence: string, sourceFormat: string, targetFormat: string): string | null {
|
|
54
|
+
const converter = new FormatConverter(sequence, sourceFormat);
|
|
55
|
+
if (targetFormat === NUCLEOTIDES_FORMAT) {
|
|
56
|
+
const helm = converter.convertTo(DEFAULT_FORMATS.HELM);
|
|
57
|
+
const nucleotides = getNucleotidesSequence(helm, MonomerLibWrapper.getInstance());
|
|
58
|
+
return nucleotides;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return converter.convertTo(targetFormat);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getSupportedTargetFormats(): string[] {
|
|
65
|
+
const supportedTargetFormats = Object.keys(CODES_TO_HELM_DICT).concat([DEFAULT_FORMATS.HELM, NUCLEOTIDES_FORMAT]).sort() as string[];
|
|
66
|
+
return supportedTargetFormats;
|
|
67
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
|
-
import {DEFAULT_FORMATS} from '
|
|
2
|
+
import {DEFAULT_FORMATS} from '../../common/model/const';
|
|
3
3
|
import {PHOSPHATE_SYMBOL, UNKNOWN_SYMBOL} from './const';
|
|
4
|
-
import {FormatHandler, getRegExpPattern} from '
|
|
4
|
+
import {FormatHandler, getRegExpPattern} from '../../common/model/parsing-validation/format-handler';
|
|
5
5
|
|
|
6
6
|
const HELM_WRAPPER = {
|
|
7
7
|
LEFT: 'RNA1{',
|
|
@@ -16,21 +16,16 @@ export class FormatConverter {
|
|
|
16
16
|
convertTo(targetFormat: string): string {
|
|
17
17
|
const formats = this.formats.getFormatNames();
|
|
18
18
|
|
|
19
|
-
if (this.sourceFormat === DEFAULT_FORMATS.HELM && formats.includes(targetFormat))
|
|
20
|
-
return this.helmToFormat(this.sequence, targetFormat);
|
|
21
|
-
else if (formats.includes(this.sourceFormat) && targetFormat === DEFAULT_FORMATS.HELM)
|
|
22
|
-
return this.formatToHelm(this.sequence, this.sourceFormat);
|
|
23
|
-
else if ([this.sourceFormat, targetFormat].every((el) => formats.includes(el))) {
|
|
19
|
+
if (this.sourceFormat === DEFAULT_FORMATS.HELM && formats.includes(targetFormat)) { return this.helmToFormat(this.sequence, targetFormat); } else if (formats.includes(this.sourceFormat) && targetFormat === DEFAULT_FORMATS.HELM) { return this.formatToHelm(this.sequence, this.sourceFormat); } else if ([this.sourceFormat, targetFormat].every((el) => formats.includes(el))) {
|
|
24
20
|
const helm = this.formatToHelm(this.sequence, this.sourceFormat);
|
|
25
21
|
return this.helmToFormat(helm, targetFormat);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
throw new Error (`ST: unsupported translation direction ${this.sourceFormat} -> ${targetFormat}`);
|
|
22
|
+
} else {
|
|
23
|
+
throw new Error(`ST: unsupported translation direction ${this.sourceFormat} -> ${targetFormat}`);
|
|
29
24
|
}
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
private helmToFormat(helmSequence: string, targetFormat: string): string {
|
|
33
|
-
const wrapperRegExp = new RegExp(getRegExpPattern(Object.values(HELM_WRAPPER)), 'g')
|
|
28
|
+
const wrapperRegExp = new RegExp(getRegExpPattern(Object.values(HELM_WRAPPER)), 'g');
|
|
34
29
|
let result = helmSequence.replace(wrapperRegExp, '');
|
|
35
30
|
|
|
36
31
|
const dict = this.formats.getHelmToFormatDict(targetFormat);
|
|
@@ -54,7 +49,7 @@ export class FormatConverter {
|
|
|
54
49
|
const phosphateRegExp = this.formats.getPhosphateHelmCodesRegExp(sourceFormat);
|
|
55
50
|
|
|
56
51
|
let helm = sequence.replace(formatRegExp, (match) => {
|
|
57
|
-
const result = formatCodes.includes(match) ?
|
|
52
|
+
const result = formatCodes.includes(match) ? dict[match] + '.' : '?';
|
|
58
53
|
return result;
|
|
59
54
|
});
|
|
60
55
|
helm = helm.replace(/\?+/g, `${UNKNOWN_SYMBOL}.`);
|