@datagrok/sequence-translator 1.3.13 → 1.3.15

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/dist/package-test.js +1 -1
  3. package/dist/package-test.js.map +1 -1
  4. package/dist/package.js +1 -1
  5. package/dist/package.js.map +1 -1
  6. package/files/polytool-rules/rules_example.json +34 -34
  7. package/files/samples/cyclized.csv +6 -0
  8. package/package.json +9 -10
  9. package/src/apps/common/view/components/colored-input/colored-text-input.ts +2 -2
  10. package/src/apps/pattern/view/components/bulk-convert/column-input.ts +2 -2
  11. package/src/apps/pattern/view/components/bulk-convert/table-input.ts +8 -6
  12. package/src/apps/pattern/view/components/edit-block-controls.ts +5 -5
  13. package/src/apps/pattern/view/components/load-block-controls.ts +7 -3
  14. package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +1 -1
  15. package/src/apps/pattern/view/components/strand-editor/header-controls.ts +2 -2
  16. package/src/apps/pattern/view/components/strand-editor/strand-controls.ts +2 -2
  17. package/src/apps/pattern/view/components/terminal-modification-editor.ts +1 -1
  18. package/src/apps/structure/view/ui.ts +5 -5
  19. package/src/apps/translator/view/ui.ts +27 -18
  20. package/src/package-test.ts +1 -0
  21. package/src/package.ts +34 -12
  22. package/src/polytool/pt-conversion.ts +2 -33
  23. package/src/polytool/pt-convert-editor.ts +116 -0
  24. package/src/polytool/pt-dialog.ts +177 -97
  25. package/src/polytool/pt-enumeration-helm-dialog.ts +338 -282
  26. package/src/polytool/pt-enumeration-helm.ts +6 -2
  27. package/src/polytool/pt-placeholders-input.ts +1 -2
  28. package/src/polytool/utils.ts +0 -7
  29. package/src/tests/polytool-convert-tests.ts +99 -0
  30. package/src/tests/polytool-enumerate-tests.ts +21 -5
  31. package/src/utils/context-menu.ts +7 -10
  32. package/src/polytool/cyclized.ts +0 -56
@@ -1,34 +1,34 @@
1
- [
2
- {
3
- "type": "link",
4
- "code": "1",
5
- "monomericSubstitution": {
6
- "firstMonomer": "C",
7
- "secondMonomer": "C",
8
- "firstLinkingGroup":"3",
9
- "secondLinkingGroup":"3",
10
- "firstSubstitution": "C",
11
- "secondSubstitution": "C"
12
- }
13
- },
14
- {
15
- "type": "link",
16
- "code": "2",
17
- "monomericSubstitution": {
18
- "firstMonomer": "NH2",
19
- "secondMonomer": "L",
20
- "firstLinkingGroup":"2",
21
- "secondLinkingGroup":"3",
22
- "firstSubstitution": "NH2",
23
- "secondSubstitution": "L"
24
- }
25
- },
26
- {
27
- "type": "fragmentDuplication",
28
- "code": "#3"
29
- },
30
- {
31
- "type": "differentFragments",
32
- "code": "$4"
33
- }
34
- ]
1
+ [
2
+ {
3
+ "type": "link",
4
+ "code": "1",
5
+ "monomericSubstitution": {
6
+ "firstMonomer": "C",
7
+ "secondMonomer": "C",
8
+ "firstLinkingGroup": "3",
9
+ "secondLinkingGroup": "3",
10
+ "firstSubstitution": "C",
11
+ "secondSubstitution": "C"
12
+ }
13
+ },
14
+ {
15
+ "type": "link",
16
+ "code": "2",
17
+ "monomericSubstitution": {
18
+ "firstMonomer": "NH2",
19
+ "secondMonomer": "D",
20
+ "firstLinkingGroup": "2",
21
+ "secondLinkingGroup": "3",
22
+ "firstSubstitution": "NH2",
23
+ "secondSubstitution": "D"
24
+ }
25
+ },
26
+ {
27
+ "type": "fragmentDuplication",
28
+ "code": "#3"
29
+ },
30
+ {
31
+ "type": "differentFragments",
32
+ "code": "$4"
33
+ }
34
+ ]
@@ -0,0 +1,6 @@
1
+ n,seqs
2
+ 1,R-F-C(1)-T-G-H-F-Y-P-C(1)-meI
3
+ 2,C(1)-T-G-H-F-Y-P-C(1)-meI
4
+ 3,R-F-C(1)-T-G-H-F-Y-P-C(1)
5
+ 4,C(1)-T-G-H-F-H-P-C(1)
6
+ 5,R-F-D(2)-T-G-H-F-Y-P-NH2(2)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/sequence-translator",
3
3
  "friendlyName": "Sequence Translator",
4
- "version": "1.3.13",
4
+ "version": "1.3.15",
5
5
  "author": {
6
6
  "name": "Alexey Choposky",
7
7
  "email": "achopovsky@datagrok.ai"
@@ -22,13 +22,13 @@
22
22
  }
23
23
  ],
24
24
  "dependencies": {
25
- "@datagrok-libraries/bio": "^5.42.11",
25
+ "@datagrok-libraries/bio": "^5.42.14",
26
26
  "@datagrok-libraries/chem-meta": "^1.2.5",
27
- "@datagrok-libraries/tutorials": "^1.3.13",
28
- "@datagrok-libraries/utils": "^4.2.29",
27
+ "@datagrok-libraries/tutorials": "^1.4.0",
28
+ "@datagrok-libraries/utils": "^4.3.0",
29
29
  "@types/react": "^18.0.15",
30
30
  "cash-dom": "^8.1.0",
31
- "datagrok-api": "^1.20.0",
31
+ "datagrok-api": "^1.21.1",
32
32
  "lodash": "^4.17.21",
33
33
  "object-hash": "^3.0.0",
34
34
  "openchemlib": "6.0.1",
@@ -39,11 +39,11 @@
39
39
  "wu": "latest"
40
40
  },
41
41
  "devDependencies": {
42
- "@datagrok-libraries/helm-web-editor": "^1.1.10",
42
+ "@datagrok-libraries/helm-web-editor": "^1.1.11",
43
43
  "@datagrok-libraries/js-draw-lite": "^0.0.8",
44
- "@datagrok/bio": "^2.14.2",
45
- "@datagrok/helm": "^2.4.4",
46
- "@datagrok/chem": "^1.11.3",
44
+ "@datagrok/bio": "^2.15.0",
45
+ "@datagrok/helm": "^2.5.0",
46
+ "@datagrok/chem": "^1.12.0",
47
47
  "@types/jquery": "^3.5.14",
48
48
  "@types/js-yaml": "^4.0.5",
49
49
  "@types/lodash": "^4.14.202",
@@ -54,7 +54,6 @@
54
54
  "@typescript-eslint/eslint-plugin": "^7.2.0",
55
55
  "@typescript-eslint/parser": "^7.2.0",
56
56
  "css-loader": "^6.7.3",
57
- "datagrok-tools": "latest",
58
57
  "eslint": "^8.57.0",
59
58
  "eslint-config-google": "latest",
60
59
  "style-loader": "^3.3.1",
@@ -22,7 +22,7 @@ export class ColoredTextInput {
22
22
  $(this.root).addClass('colored-text-input');
23
23
  if (resizeable) {
24
24
  // make input field automatically resizeable
25
- this.textInputBase.onChanged(
25
+ this.textInputBase.onChanged.subscribe(
26
26
  () => {
27
27
  // necessary for the field to be squeezable, not only expandable
28
28
  $(this.textArea).css('height', 0);
@@ -34,7 +34,7 @@ export class ColoredTextInput {
34
34
  this.root.appendChild(this.highlights);
35
35
  this.colorize();
36
36
 
37
- this.textInputBase.onChanged(() => this.colorize());
37
+ this.textInputBase.onChanged.subscribe(() => this.colorize());
38
38
  }
39
39
 
40
40
  private highlights: HTMLDivElement;
@@ -54,7 +54,7 @@ export class ColumnInputManager {
54
54
  [];
55
55
  const strandColumnInput = Object.fromEntries(STRANDS.map((strand) => {
56
56
  const input = ui.input.choice(`${STRAND_LABEL[strand]} column`, {value: columns[0], items: columns,
57
- onValueChanged: (input) => this.eventBus.selectStrandColumn(strand, input.value)}
57
+ onValueChanged: (value) => this.eventBus.selectStrandColumn(strand, value)}
58
58
  );
59
59
  this.eventBus.selectStrandColumn(strand, columns[0]);
60
60
  return [strand, input.root];
@@ -65,7 +65,7 @@ export class ColumnInputManager {
65
65
  private createIdColumnInput(): HTMLElement {
66
66
  const columns = this.selectedTable ? this.selectedTable.columns.names() : [];
67
67
  const idColumnInput = ui.input.choice('ID column', {value: columns[0], items: columns,
68
- onValueChanged: (input) => this.eventBus.selectIdColumn(input.value)}
68
+ onValueChanged: (value) => this.eventBus.selectIdColumn(value)}
69
69
  );
70
70
  this.eventBus.selectIdColumn(columns[0]);
71
71
  return idColumnInput.root;
@@ -28,7 +28,7 @@ export class TableInputManager {
28
28
  }
29
29
 
30
30
  private getTableFromEventData(eventData: any): DG.DataFrame {
31
- if (! eventData && eventData.args && eventData.args.dataFrame instanceof DG.DataFrame)
31
+ if (!eventData && eventData.args && eventData.args.dataFrame instanceof DG.DataFrame)
32
32
  throw new Error(`EventData does not contain a dataframe`, eventData);
33
33
 
34
34
  return eventData.args.dataFrame as DG.DataFrame;
@@ -63,13 +63,15 @@ export class TableInputManager {
63
63
  private createTableInput(): DG.InputBase<DG.DataFrame | null> {
64
64
  const currentlySelectedTable = this.eventBus.getTableSelection();
65
65
 
66
- const tableInput = ui.input.table('Tables', {value: currentlySelectedTable!, items: this.availableTables,
67
- onValueChanged: (input) => {
66
+ const tableInput = ui.input.table('Tables', {
67
+ value: currentlySelectedTable!, items: this.availableTables,
68
+ onValueChanged: (value) => {
68
69
  // WARNING: non-null check necessary to prevent resetting columns to
69
70
  // null upon handling onTableAdded
70
- if (input.value !== null)
71
- this.eventBus.selectTable(input.value);
72
- }});
71
+ if (value !== null)
72
+ this.eventBus.selectTable(value);
73
+ }
74
+ });
73
75
  return tableInput;
74
76
  }
75
77
 
@@ -79,7 +79,7 @@ export class PatternEditControlsManager {
79
79
  {value: this.eventBus.isAntisenseStrandActive()}
80
80
  );
81
81
 
82
- toggleAntisenseStrand.onInput(
82
+ toggleAntisenseStrand.onInput.subscribe(
83
83
  () => this.eventBus.toggleAntisenseStrand(toggleAntisenseStrand.value)
84
84
  );
85
85
 
@@ -97,7 +97,7 @@ export class PatternEditControlsManager {
97
97
  const sequenceLength = this.eventBus.getNucleotideSequences()[strand].length;
98
98
 
99
99
  const input = ui.input.int(`${STRAND_LABEL[strand]} length`, {value: sequenceLength});
100
- input.onInput(() => updateStrandLengthInputs(strand, input));
100
+ input.onInput.subscribe(() => updateStrandLengthInputs(strand, input));
101
101
 
102
102
  this.eventBus.nucleotideSequencesChanged$.subscribe(() => {
103
103
  input.value = this.eventBus.getNucleotideSequences()[strand].length;
@@ -141,7 +141,7 @@ export class PatternEditControlsManager {
141
141
 
142
142
  const sequenceBaseInput = ui.input.choice('Sequence basis', {value: defaultNucleotideBase, items: availableNucleoBases});
143
143
 
144
- sequenceBaseInput.onInput(() => this.eventBus.replaceSequenceBase(sequenceBaseInput.value!));
144
+ sequenceBaseInput.onInput.subscribe(() => this.eventBus.replaceSequenceBase(sequenceBaseInput.value!));
145
145
 
146
146
  this.eventBus.nucleotideSequencesChanged$.subscribe(() => {
147
147
  sequenceBaseInput.value = this.eventBus.getSequenceBase();
@@ -156,7 +156,7 @@ export class PatternEditControlsManager {
156
156
 
157
157
  $(patternCommentInput.root).addClass('st-pattern-text-input');
158
158
 
159
- patternCommentInput.onInput(
159
+ patternCommentInput.onInput.subscribe(
160
160
  () => this.eventBus.updateComment(patternCommentInput.value!)
161
161
  );
162
162
 
@@ -172,7 +172,7 @@ export class PatternEditControlsManager {
172
172
 
173
173
  $(patternNameInput.root).addClass('st-pattern-text-input');
174
174
 
175
- patternNameInput.onInput(
175
+ patternNameInput.onInput.subscribe(
176
176
  () => this.eventBus.updatePatternName(patternNameInput.value)
177
177
  );
178
178
  this.eventBus.patternLoaded$.subscribe(() => {
@@ -96,7 +96,7 @@ export class PatternLoadControlsManager {
96
96
  const authorChoiceInput = ui.input.choice(
97
97
  'Author', {value: this.eventBus.getSelectedAuthor(), items: possibleValues});
98
98
 
99
- authorChoiceInput.onInput(() => {
99
+ authorChoiceInput.onInput.subscribe(() => {
100
100
  this.authorSelectedByUser = true;
101
101
  if (authorChoiceInput.value === null)
102
102
  throw new Error('author choice must be non-null');
@@ -142,7 +142,7 @@ export class PatternLoadControlsManager {
142
142
  });
143
143
 
144
144
  this.subscriptions.add(
145
- choiceInput.onInput(
145
+ choiceInput.onInput.subscribe(
146
146
  () => {
147
147
  const patternHash = this.dataManager.getPatternHash(choiceInput.value!, this.isCurrentUserSelected());
148
148
  this.eventBus.requestPatternLoad(patternHash);
@@ -164,7 +164,11 @@ export class PatternLoadControlsManager {
164
164
 
165
165
  private getPatternName(patternList: string[]): string {
166
166
  return patternList.find(
167
- (patternName) => patternName === this.eventBus.getPatternName()
167
+ (longPatternName) => {
168
+ // The pattern name can be followed by the author name in parenths
169
+ const shortPatternName = longPatternName.split(' (')[0];
170
+ return shortPatternName === this.eventBus.getPatternName();
171
+ }
168
172
  ) ?? patternList[0];
169
173
  }
170
174
 
@@ -46,7 +46,7 @@ export class NumericLabelVisibilityControls {
46
46
  const initialValue = this.eventBus.getModificationsWithNumericLabels().includes(nucleotide);
47
47
  const input = ui.input.bool(nucleotide, {
48
48
  value: initialValue,
49
- onValueChanged: (input) => this.handleNumericLabelToggle(nucleotide, input.value)
49
+ onValueChanged: (value) => this.handleNumericLabelToggle(nucleotide, value)
50
50
  });
51
51
  $(input.root).css('padding-right', '20px');
52
52
 
@@ -45,7 +45,7 @@ export class HeaderControls {
45
45
  const initialValue = this.areAllPtoLinkagesSet(flags);
46
46
  const allPtoActivationInput = ui.input.bool('All PTO', {value: initialValue});
47
47
 
48
- allPtoActivationInput.onInput(() => {
48
+ allPtoActivationInput.onInput.subscribe(() => {
49
49
  const value = allPtoActivationInput.value!;
50
50
  this.eventBus.setAllPTOLinkages(value);
51
51
  });
@@ -81,7 +81,7 @@ export class HeaderControls {
81
81
  const initialValue = this.isFirstPtoActive(strand);
82
82
  const firstPtoInput = ui.input.bool(`First ${strand} PTO`, {value: initialValue});
83
83
 
84
- firstPtoInput.onInput(() => {
84
+ firstPtoInput.onInput.subscribe(() => {
85
85
  const value = firstPtoInput.value!;
86
86
  this.eventBus.setPhosphorothioateLinkageFlag(strand, 0, value);
87
87
  });
@@ -79,7 +79,7 @@ export class StrandControls {
79
79
  const nucleotides = this.eventBus.getNucleotideSequences()[strand];
80
80
  const choiceInputs = nucleotides.map((nucleotide, index) => {
81
81
  const input = ui.input.choice<string>('', {value: nucleotide, items: nucleotideBaseChoices});
82
- input.onInput(() => {
82
+ input.onInput.subscribe(() => {
83
83
  const newValue = input.value!;
84
84
  this.eventBus.setNucleotide(strand, index, newValue);
85
85
  });
@@ -93,7 +93,7 @@ export class StrandControls {
93
93
  const ptoLinkageFlags = this.eventBus.getPhosphorothioateLinkageFlags()[strand].slice(1);
94
94
  const ptoLinkageInputs = ptoLinkageFlags.map((flag, index) => {
95
95
  const input = ui.input.bool('', {value: flag});
96
- input.onInput(() => {
96
+ input.onInput.subscribe(() => {
97
97
  const newValue = input.value!;
98
98
  this.eventBus.setPhosphorothioateLinkageFlag(strand, index + 1, newValue);
99
99
  });
@@ -109,7 +109,7 @@ class StrandTerminalModificationControls {
109
109
  const input = ui.input.textArea(terminus, {value: initialValue});
110
110
  this.applyStylingToInput(input);
111
111
 
112
- input.onInput(() => {
112
+ input.onInput.subscribe(() => {
113
113
  const newValue = input.value;
114
114
  if (newValue === null)
115
115
  return;
@@ -110,12 +110,12 @@ class StructureAppLayout {
110
110
  );
111
111
 
112
112
  STRANDS.forEach((strand, idx) => {
113
- directionChoiceInput[strand].onChanged(() => {
114
- let value = directionChoiceInput[strand].value === DIRECTION.INVERSE;
113
+ directionChoiceInput[strand].onChanged.subscribe((value) => {
114
+ let inputValue = value === DIRECTION.INVERSE;
115
115
  // warning: the next line is necessary
116
116
  // until the legacy notion of direction used in the molfile generation gets fixed
117
- if (idx > 0) value = !value;
118
- this.directionInversion[strand] = value;
117
+ if (idx > 0) inputValue = !inputValue;
118
+ this.directionInversion[strand] = inputValue;
119
119
  this.onInput.next();
120
120
  });
121
121
  });
@@ -142,7 +142,7 @@ class StructureAppLayout {
142
142
 
143
143
  const sequenseInputs = ui.form([], 'st-structure-inputs');
144
144
  const clearButtons = ui.divV([], 'st-structure-clear-buttons');
145
- const directionInputs = ui.form([], 'st-direction-inputs');
145
+ const directionInputs = ui.form([], 'st-direction-inputs');
146
146
 
147
147
  for (const strand of STRANDS) {
148
148
  sequenseInputs.append(this.inputBase[strand].root);
@@ -47,11 +47,14 @@ class TranslatorAppLayout {
47
47
  this.moleculeImgDiv.style.marginTop = '12px';
48
48
 
49
49
  this.outputTableDiv = ui.div([]);
50
- this.formatChoiceInput = ui.input.choice('', {value: DEFAULT_FORMATS.HELM, items: this.inputFormats, onValueChanged: async () => {
51
- this.format = this.formatChoiceInput.value;
52
- this.updateTable();
53
- await this.updateMolImg();
54
- }});
50
+ this.formatChoiceInput = ui.input.choice('', {
51
+ value: DEFAULT_FORMATS.HELM, items: this.inputFormats,
52
+ onValueChanged: async (value, input) => {
53
+ this.format = value;
54
+ this.updateTable();
55
+ await this.updateMolImg();
56
+ }
57
+ });
55
58
  this.sequenceInputBase = ui.input.textArea('', {value: DEFAULT_AXOLABS_INPUT, onValueChanged: () => { this.onInput.next(); }});
56
59
 
57
60
  this.init();
@@ -99,13 +102,15 @@ class TranslatorAppLayout {
99
102
 
100
103
  const tableControlsManager = new TableControlsManager(this.eventBus);
101
104
  const tableControls = tableControlsManager.createUIComponents();
102
- const inputFormats = ui.input.choice('Input format', {value: DEFAULT_FORMATS.AXOLABS,
103
- items: this.inputFormats, onValueChanged: (input) => this.eventBus.selectInputFormat(input.value)}
104
- );
105
+ const inputFormats = ui.input.choice('Input format', {
106
+ value: DEFAULT_FORMATS.AXOLABS,
107
+ items: this.inputFormats, onValueChanged: (value) => this.eventBus.selectInputFormat(value)
108
+ });
105
109
 
106
- const outputFormats = ui.input.choice('Output format', {value: NUCLEOTIDES_FORMAT,
107
- items: getSupportedTargetFormats(this.th), onValueChanged: (input) => this.eventBus.selectOutputFormat(input.value)}
108
- );
110
+ const outputFormats = ui.input.choice('Output format', {
111
+ value: NUCLEOTIDES_FORMAT,
112
+ items: getSupportedTargetFormats(this.th), onValueChanged: (value) => this.eventBus.selectOutputFormat(value)
113
+ });
109
114
  const convertBulkButton = this.createConvertBulkButton();
110
115
 
111
116
  const tableControlsContainer = ui.div([
@@ -374,13 +379,15 @@ class TableInputManager {
374
379
  private createTableInput(): DG.InputBase<DG.DataFrame | null> {
375
380
  const currentlySelectedTable = this.eventBus.getSelectedTable();
376
381
 
377
- const tableInput = ui.input.table('Table', {value: currentlySelectedTable!, items: this.availableTables,
378
- onValueChanged: (input) => {
382
+ const tableInput = ui.input.table('Table', {
383
+ value: currentlySelectedTable!, items: this.availableTables,
384
+ onValueChanged: (value) => {
379
385
  // WARNING: non-null check necessary to prevent resetting columns to
380
386
  // null upon handling onTableAdded
381
- if (input.value !== null)
382
- this.eventBus.selectTable(input.value);
383
- }});
387
+ if (value !== null)
388
+ this.eventBus.selectTable(value);
389
+ }
390
+ });
384
391
  return tableInput;
385
392
  }
386
393
 
@@ -449,8 +456,10 @@ class ColumnInputsManager {
449
456
  const selectedColumnName = matchingColumnName ? matchingColumnName : columnNames[0];
450
457
  this.selectColumnIfTableNotNull(selectedTable, selectedColumnName, columnLabel);
451
458
 
452
- const input = ui.input.choice(`${columnLabel}`, {value: selectedColumnName, items: columnNames,
453
- onValueChanged: (input) => this.selectColumnIfTableNotNull(selectedTable, input.value, columnLabel)}
459
+ const input = ui.input.choice(`${columnLabel}`, {
460
+ value: selectedColumnName, items: columnNames,
461
+ onValueChanged: (value) => this.selectColumnIfTableNotNull(selectedTable, value, columnLabel)
462
+ }
454
463
  );
455
464
 
456
465
  return input;
@@ -8,6 +8,7 @@ import './tests/formats-to-helm';
8
8
  import './tests/helm-to-nucleotides';
9
9
  import './tests/formats-support';
10
10
  import './tests/files-tests';
11
+ import './tests/polytool-convert-tests';
11
12
  import './tests/polytool-enumerate-tests';
12
13
 
13
14
  import {OligoToolkitTestPackage} from './tests/utils';
package/src/package.ts CHANGED
@@ -14,16 +14,19 @@ import {SequenceToMolfileConverter} from './apps/structure/model/sequence-to-mol
14
14
  import {FormatConverter} from './apps/translator/model/format-converter';
15
15
  import {demoOligoPatternUI, demoOligoStructureUI, demoOligoTranslatorUI} from './demo/demo-st-ui';
16
16
  import {getExternalAppViewFactories} from './plugins/mermade';
17
+ import {defaultErrorHandler} from './utils/err-info';
17
18
 
18
19
  //polytool specific
19
- import {getPolyToolConversionDialog, polyToolEnumerateChemUI} from './polytool/pt-dialog';
20
+ import {polyToolConvert, polyToolConvertUI} from './polytool/pt-dialog';
21
+ import {polyToolEnumerateChemUI} from './polytool/pt-dialog';
20
22
  import {polyToolEnumerateHelmUI} from './polytool/pt-enumeration-helm-dialog';
21
23
  import {_setPeptideColumn} from './polytool/utils';
22
24
  import {PolyToolCsvLibHandler} from './polytool/csv-to-json-monomer-lib-converter';
23
25
  import {ITranslationHelper} from './types';
24
26
  import {addContextMenuUI} from './utils/context-menu';
27
+ import {PolyToolConvertFuncEditor} from './polytool/pt-convert-editor';
25
28
 
26
- export const _package: OligoToolkitPackage = new OligoToolkitPackage(/*{debug: true}/**/);
29
+ export const _package: OligoToolkitPackage = new OligoToolkitPackage({debug: true}/**/);
27
30
 
28
31
  //name: Oligo Toolkit
29
32
  //meta.icon: img/icons/toolkit.png
@@ -155,27 +158,46 @@ async function getSpecifiedAppView(appName: string): Promise<DG.ViewBase> {
155
158
  //top-menu: Bio | PolyTool | Convert...
156
159
  //name: polyToolConvert
157
160
  //description: Perform cyclization of polymers
158
- export async function polyToolConvert(): Promise<void> {
159
- let dialog: DG.Dialog;
160
- try {
161
- dialog = await getPolyToolConversionDialog();
162
- dialog.show();
163
- } catch (err: any) {
164
- grok.shell.warning('To run PolyTool Conversion, open a dataframe with macromolecules');
165
- }
161
+ export async function polyToolConvertTopMenu(): Promise<void> {
162
+ await polyToolConvertUI();
166
163
  }
167
164
 
165
+ //name: getPolyToolConvertEditor
166
+ //tags: editor
167
+ //input: funccall call
168
+ //output: column resCol
169
+ export async function getPolyToolConvertEditor(call: DG.FuncCall): Promise<DG.Column<string> | null> {
170
+ const funcEditor = await PolyToolConvertFuncEditor.create(call);
171
+ return await funcEditor.showDialog();
172
+ }
173
+
174
+ //name: polyToolConvert2
175
+ //input: dataframe table
176
+ //input: column seqCol { caption: Sequence }
177
+ //input: bool generateHelm = true
178
+ //input: bool chiralityEngine = true
179
+ //input: object rules
180
+ //output: column resCol
181
+ //editor: SequenceTranslator:getPolyToolConvertEditor
182
+ export async function polyToolConvert2(table: DG.DataFrame,
183
+ seqCol: DG.Column, generateHelm: boolean, chiralityEngine: boolean, rules: string[]
184
+ ): Promise<DG.Column<string>> {
185
+ const ptConvertRes = await polyToolConvert(seqCol, generateHelm, chiralityEngine, rules);
186
+ return ptConvertRes[0];
187
+ }
188
+
189
+
168
190
  //top-menu: Bio | PolyTool | Enumerate HELM...
169
191
  //name: polyToolEnumerateHelm
170
192
  //description: Perform cyclization of polymers
171
- export async function polyToolEnumerateHelm(): Promise<void> {
193
+ export async function polyToolEnumerateHelmTopMenu(): Promise<void> {
172
194
  await polyToolEnumerateHelmUI(grok.shell.tv?.dataFrame.currentCell);
173
195
  }
174
196
 
175
197
  //top-menu: Bio | PolyTool | Enumerate Chem...
176
198
  //name: polyToolEnumerateChem
177
199
  //description: Perform cyclization of polymers
178
- export async function polyToolEnumerateChem(): Promise<void> {
200
+ export async function polyToolEnumerateChemTopMenu(): Promise<void> {
179
201
  polyToolEnumerateChemUI();
180
202
  }
181
203
 
@@ -265,7 +265,8 @@ export class Chain {
265
265
  }
266
266
  }
267
267
 
268
- function getHelms(sequences: string[], rules: Rules): string[] {
268
+ /** The main PolyTool convert engine. Returns list of Helms. Covered with tests. */
269
+ export function doPolyToolConvert(sequences: string[], rules: Rules): string[] {
269
270
  const helms = new Array<string>(sequences.length);
270
271
  for (let i = 0; i < sequences.length; i++) {
271
272
  if (sequences[i] === undefined)
@@ -278,35 +279,3 @@ function getHelms(sequences: string[], rules: Rules): string[] {
278
279
 
279
280
  return helms;
280
281
  }
281
-
282
- export async function addTransformedColumn(
283
- sequencesCol: DG.Column<string>, addHelm: boolean, ruleFiles: string[], chiralityEngine?: boolean
284
- ): Promise<void> {
285
- const df = sequencesCol.dataFrame;
286
-
287
- const rules = await getRules(ruleFiles);
288
- const targetList = getHelms(sequencesCol.toList(), rules);
289
- const helmColName = df.columns.getUnusedName('transformed(' + sequencesCol.name + ')');
290
- const targetHelmCol = DG.Column.fromList('string', helmColName, targetList);
291
-
292
- addCommonTags(targetHelmCol);
293
- targetHelmCol.meta.units = NOTATION.HELM;
294
-
295
- if (addHelm) {
296
- targetHelmCol.setTag('cell.renderer', 'helm');
297
- df.columns.add(targetHelmCol);
298
- }
299
-
300
- // toAtomicLevel
301
- const molCol = await grok.functions.call('Bio:getMolFromHelm', {
302
- 'df': df,
303
- 'helmCol': targetHelmCol,
304
- 'chiralityEngine': chiralityEngine
305
- });
306
-
307
- molCol.name = df.columns.getUnusedName('molfile(' + sequencesCol.name + ')');
308
- molCol.semType = DG.SEMTYPE.MOLECULE;
309
-
310
- df.columns.add(molCol, true);
311
- await grok.data.detectSemanticTypes(df);
312
- }