@datagrok/sequence-translator 1.3.15 → 1.4.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/sequence-translator",
3
3
  "friendlyName": "Sequence Translator",
4
- "version": "1.3.15",
4
+ "version": "1.4.1",
5
5
  "author": {
6
6
  "name": "Alexey Choposky",
7
7
  "email": "achopovsky@datagrok.ai"
@@ -22,7 +22,7 @@
22
22
  }
23
23
  ],
24
24
  "dependencies": {
25
- "@datagrok-libraries/bio": "^5.42.14",
25
+ "@datagrok-libraries/bio": "^5.42.15",
26
26
  "@datagrok-libraries/chem-meta": "^1.2.5",
27
27
  "@datagrok-libraries/tutorials": "^1.4.0",
28
28
  "@datagrok-libraries/utils": "^4.3.0",
@@ -41,7 +41,7 @@
41
41
  "devDependencies": {
42
42
  "@datagrok-libraries/helm-web-editor": "^1.1.11",
43
43
  "@datagrok-libraries/js-draw-lite": "^0.0.8",
44
- "@datagrok/bio": "^2.15.0",
44
+ "@datagrok/bio": "^2.15.1",
45
45
  "@datagrok/helm": "^2.5.0",
46
46
  "@datagrok/chem": "^1.12.0",
47
47
  "@types/jquery": "^3.5.14",
@@ -19,7 +19,7 @@ export class ColoredTextInput {
19
19
  /** Resize, no scrolls */
20
20
  resizeable: boolean = true
21
21
  ) {
22
- $(this.root).addClass('colored-text-input');
22
+ $(this.root).addClass('st-colored-text-input');
23
23
  if (resizeable) {
24
24
  // make input field automatically resizeable
25
25
  this.textInputBase.onChanged.subscribe(
@@ -1,4 +1,4 @@
1
- .colored-text-input > textarea {
1
+ .st-colored-text-input > textarea {
2
2
  width: 100%;
3
3
  -webkit-text-fill-color: transparent;
4
4
  background-color: transparent;
@@ -8,7 +8,7 @@
8
8
  height: 22px; /* Fine tuned value to avoid "jumping" of the textarea upon autoresize */
9
9
  }
10
10
 
11
- .colored-text-input > div {
11
+ .st-colored-text-input > div {
12
12
  /* The values here are fine tuned to those of the ui.input textarea in order
13
13
  * to achieve precise overlap */
14
14
  overflow: auto;
@@ -25,5 +25,4 @@
25
25
  color: transparent;
26
26
  white-space: pre-wrap;
27
27
  word-wrap: break-word;
28
- padding-left: 35px;
29
28
  }
@@ -96,10 +96,10 @@ export class PatternAppRightSection {
96
96
  }
97
97
 
98
98
  const message = ui.divV([
99
- ui.divText(`Author: ${author}`),
100
99
  ui.divText(`Pattern Name: ${patternName}`),
101
- ui.divText(`Created: ${new Date(createDate).toLocaleString()}`),
102
- ui.divText(`Modified: ${new Date(modifyDate).toLocaleString()}`),
100
+ ui.divText(`Author: ${author}`),
101
+ ui.divText(`Created: ${getInfoTimestamp(new Date(createDate))}`),
102
+ ui.divText(`Modified: ${getInfoTimestamp(new Date(modifyDate))}`),
103
103
  ]);
104
104
  grok.shell.info(message);
105
105
  }
@@ -195,3 +195,6 @@ class OverwritePatternDialog {
195
195
  }
196
196
  }
197
197
 
198
+ function getInfoTimestamp(date: Date): string {
199
+ return date.toLocaleString().split(':').slice(0, -1).join(':');
200
+ }
@@ -33,7 +33,15 @@ class StructureAppLayout {
33
33
  this.onInvalidInput = new rxjs.Subject<string>();
34
34
  this.inputBase = Object.fromEntries(
35
35
  STRANDS.map(
36
- (key) => [key, ui.input.textArea(key.toUpperCase(), {value: '', onValueChanged: () => { this.onInput.next(); }})]
36
+ (key) => {
37
+ const input = ui.input.textArea(key.toUpperCase(), {value: '', onValueChanged: () => {
38
+ this.onInput.next();
39
+ // WARNING: this fine tuning is necessary to fix layout within ui.form
40
+ // js-api version ^1.21
41
+ $(input.root.getElementsByTagName('div')).css('padding-left', '38px');
42
+ }});
43
+ return [key, input];
44
+ }
37
45
  )
38
46
  );
39
47
  this.useChiralInput = ui.input.bool('Use chiral', {value: true});
@@ -165,11 +173,6 @@ class StructureAppLayout {
165
173
  }
166
174
 
167
175
  private getMolfile(ss: StrandData, as: StrandData, as2: StrandData): string {
168
- // if (ss.strand === '' && (as.strand !== '' || as2.strand !== '')) {
169
- // this.onInvalidInput.next();
170
- // return '';
171
- // }
172
-
173
176
  return getLinkedMolfile(ss, as, as2, this.useChiralInput.value!, this.th);
174
177
  }
175
178
 
@@ -24,10 +24,6 @@
24
24
  table-layout: fixed;
25
25
  }
26
26
 
27
- /* .st-translator-output-table table tbody tr td { */
28
- /* max-width: 20%; */
29
- /* } */
30
-
31
27
  .st-translator-output-table td {
32
28
  padding-top: 6px;
33
29
  padding-bottom: 6px;
@@ -10,8 +10,6 @@ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
10
10
 
11
11
  import {DEFAULT_FORMATS} from '../../common/model/const';
12
12
  import {download} from '../../common/model/helpers';
13
- import {FormatDetector} from '../../common/model/parsing-validation/format-detector';
14
- import {SequenceValidator} from '../../common/model/parsing-validation/sequence-validator';
15
13
  import {ColoredTextInput} from '../../common/view/components/colored-input/colored-text-input';
16
14
  import {highlightInvalidSubsequence} from '../../common/view/components/colored-input/input-painters';
17
15
  import {MoleculeImage} from '../../common/view/components/molecule-img';
@@ -20,11 +18,11 @@ import {IsolatedAppUIBase} from '../../common/view/isolated-app-ui';
20
18
  import {MonomerLibViewer} from '../../common/view/monomer-lib-viewer';
21
19
  import {SequenceToMolfileConverter} from '../../structure/model/sequence-to-molfile';
22
20
  import {convert, getSupportedTargetFormats, getTranslatedSequences} from '../model/conversion-utils';
23
- import {FormatConverter} from '../model/format-converter';
24
21
  import {ITranslationHelper} from '../../../types';
25
22
 
26
23
  import {NUCLEOTIDES_FORMAT, SEQUENCE_COPIED_MSG, SEQ_TOOLTIP_MSG} from './const';
27
24
  import './style.css';
25
+ import $ from 'cash-dom';
28
26
  import {_package} from '../../../package';
29
27
 
30
28
  const enum REQUIRED_COLUMN_LABEL {
@@ -55,7 +53,12 @@ class TranslatorAppLayout {
55
53
  await this.updateMolImg();
56
54
  }
57
55
  });
58
- this.sequenceInputBase = ui.input.textArea('', {value: DEFAULT_AXOLABS_INPUT, onValueChanged: () => { this.onInput.next(); }});
56
+
57
+ $(this.formatChoiceInput.root.getElementsByTagName('select')[0]).css('width', '20%');
58
+
59
+ this.sequenceInputBase = ui.input.textArea(
60
+ '', {value: DEFAULT_AXOLABS_INPUT, onValueChanged: () => { this.onInput.next(); }}
61
+ );
59
62
 
60
63
  this.init();
61
64
 
@@ -457,9 +460,9 @@ class ColumnInputsManager {
457
460
  this.selectColumnIfTableNotNull(selectedTable, selectedColumnName, columnLabel);
458
461
 
459
462
  const input = ui.input.choice(`${columnLabel}`, {
460
- value: selectedColumnName, items: columnNames,
461
- onValueChanged: (value) => this.selectColumnIfTableNotNull(selectedTable, value, columnLabel)
462
- }
463
+ value: selectedColumnName, items: columnNames,
464
+ onValueChanged: (value) => this.selectColumnIfTableNotNull(selectedTable, value, columnLabel)
465
+ }
463
466
  );
464
467
 
465
468
  return input;
@@ -24,7 +24,7 @@ export async function demoOligoStructureUI() {
24
24
  await tryCatch(async () => {
25
25
  async function setInputValue(idx: number, sequence: string): Promise<void> {
26
26
  await delay(500);
27
- const textInputs: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll('.colored-text-input > textarea');
27
+ const textInputs: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll('.st-colored-text-input > textarea');
28
28
  const textarea = textInputs[idx];
29
29
  textarea.value = sequence;
30
30
  const event = new Event('input');
@@ -269,9 +269,7 @@ export class Chain {
269
269
  export function doPolyToolConvert(sequences: string[], rules: Rules): string[] {
270
270
  const helms = new Array<string>(sequences.length);
271
271
  for (let i = 0; i < sequences.length; i++) {
272
- if (sequences[i] === undefined)
273
- helms[i] = '';
274
- else {
272
+ if (sequences[i] === undefined) { helms[i] = ''; } else {
275
273
  const chain = Chain.fromNotation(sequences[i], rules);
276
274
  helms[i] = chain.getHelm();
277
275
  }
@@ -74,14 +74,14 @@ export class PolyToolConvertFuncEditor {
74
74
 
75
75
  public async showDialog(): Promise<DG.Column<string>> {
76
76
  const formDiv = ui.div([
77
- this.inputs.table,
78
- this.inputs.seqCol,
79
- this.inputs.generateHelm,
80
- this.inputs.chiralityEngine,
81
- this.inputs.rules.header,
82
- this.inputs.rules.form,
83
- ],
84
- {style: {minWidth: '320px'}});
77
+ this.inputs.table,
78
+ this.inputs.seqCol,
79
+ this.inputs.generateHelm,
80
+ this.inputs.chiralityEngine,
81
+ this.inputs.rules.header,
82
+ this.inputs.rules.form,
83
+ ],
84
+ {style: {minWidth: '320px'}});
85
85
 
86
86
  return new Promise((resolve, reject) => {
87
87
  ui.dialog({title: PT_UI_DIALOG_CONVERSION})
@@ -3,7 +3,6 @@ import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
5
 
6
- import $ from 'cash-dom';
7
6
  import {Unsubscribable} from 'rxjs';
8
7
 
9
8
  import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
@@ -110,7 +109,6 @@ async function getPolyToolEnumerationChemDialog(cell?: DG.Cell): Promise<DG.Dial
110
109
  for (const sub of subs) sub.unsubscribe();
111
110
  };
112
111
  try {
113
-
114
112
  const [libList, helmHelper] = await Promise.all([
115
113
  getLibrariesList(), getHelmHelper()]);
116
114
 
@@ -209,7 +207,7 @@ export async function polyToolConvert(
209
207
 
210
208
  const resHelmColName = getUnusedName(table, `transformed(${seqCol.name})`);
211
209
  const resHelmCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, resHelmColName, resList.length)
212
- .init((rowIdx: number) => { return resList[rowIdx];});
210
+ .init((rowIdx: number) => { return resList[rowIdx]; });
213
211
  resHelmCol.semType = DG.SEMTYPE.MACROMOLECULE;
214
212
  resHelmCol.meta.units = NOTATION.HELM;
215
213
  resHelmCol.setTag(DG.TAGS.CELL_RENDERER, 'helm');
@@ -60,12 +60,11 @@ M END`;
60
60
 
61
61
  export async function getEnumerationChem(molString: string, screenLibrary: string):
62
62
  Promise<string[]> {
63
-
64
63
  const variableMonomers = await getAvailableMonomers(screenLibrary);
65
64
  const variableMols = await getAvailableMonomerMols(screenLibrary);
66
65
  const enumerations = new Array<string>(variableMonomers.length);
67
66
 
68
- const rdkitModule: RDModule = await grok.functions.call('Chem:getRdKitModule');
67
+ const rdkitModule: RDModule = await grok.functions.call('Chem:getRdKitModule');
69
68
  const molScaffold: RDMol = rdkitModule.get_mol(molString);
70
69
  const smiScaffold = molScaffold.get_smiles();
71
70
  molScaffold.delete();
@@ -73,7 +72,6 @@ export async function getEnumerationChem(molString: string, screenLibrary: strin
73
72
  const smilesSubsts = new Array<string>(variableMonomers.length);
74
73
 
75
74
  for (let i = 0; i < variableMonomers.length; i++) {
76
-
77
75
  const name = variableMonomers[i];
78
76
  const molBlock = variableMols[name];
79
77
  const molSubst: RDMol = rdkitModule.get_mol(molBlock);
@@ -87,18 +85,16 @@ export async function getEnumerationChem(molString: string, screenLibrary: strin
87
85
  //TODO: use RDKit linking function when exposed
88
86
  const smiResRaw = `${smiScaffold}.${smilesSubsts[i]}`.replaceAll('[1*]C', 'C([1*])').replaceAll('[1*]c', 'c([1*])').replaceAll('[1*]O', 'O([1*])').replaceAll('[1*]N', 'N([1*])');
89
87
  const smiRes = `${smiResRaw}`.replaceAll('([1*])', '9').replaceAll('[1*]', '9');
90
- molRes = rdkitModule.get_mol(smiRes, JSON.stringify({mappedDummiesAreRGroups: true}))
91
- let molV3 = molRes.get_v3Kmolblock();
88
+ molRes = rdkitModule.get_mol(smiRes, JSON.stringify({mappedDummiesAreRGroups: true}));
89
+ const molV3 = molRes.get_v3Kmolblock();
92
90
  enumerations[i] = molV3;
93
- }
94
- catch(err:any) {
91
+ } catch (err:any) {
95
92
  enumerations[i] = '';
96
- }
97
- finally {
93
+ } finally {
98
94
  molRes?.delete();
99
95
  }
100
96
  }
101
-
97
+
102
98
 
103
99
  return enumerations;
104
100
  }
@@ -82,9 +82,9 @@ export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
82
82
  if (isFirstShow) {
83
83
  const dialogInputList = dialog.inputs;
84
84
  const dialogRootCash = $(dialog.root);
85
- const contentMaxHeight = maxHeight
86
- - dialogRootCash.find('div.d4-dialog-header').get(0)!.offsetHeight
87
- - dialogRootCash.find('div.d4-dialog-footer').get(0)!.offsetHeight;
85
+ const contentMaxHeight = maxHeight -
86
+ dialogRootCash.find('div.d4-dialog-header').get(0)!.offsetHeight -
87
+ dialogRootCash.find('div.d4-dialog-footer').get(0)!.offsetHeight;
88
88
 
89
89
  // dialog.inputs2.macromolecule.root.style.backgroundColor = '#CCFFCC';
90
90
 
@@ -259,9 +259,9 @@ async function getPolyToolEnumerateDialog(
259
259
  let rowIdx = posList.indexOf(clickedAtomContIdxStr);
260
260
  if (rowIdx === -1) {
261
261
  rowIdx = posList.findIndex((v) => isNaN(v));
262
- if (rowIdx === -1) {
262
+ if (rowIdx === -1)
263
263
  rowIdx = phDf.rows.addNew([clickedAtomContIdxStr, '']).idx;
264
- }
264
+
265
265
  phDf.set('Position', rowIdx, clickedAtomContIdxStr);
266
266
  // const tgtCell = inputs.placeholders.grid.cell('Monomers', rowIdx);
267
267
  }
@@ -107,7 +107,7 @@ export function getPlaceholdersFromText(src: string): PolyToolPlaceholders {
107
107
  const lineM = /^\s*(?<pos>\d+)\s*:\s*(?<monomers>.+)$/.exec(line);
108
108
  if (lineM) {
109
109
  const pos: number = parseInt(lineM.groups!['pos']) - 1;
110
- const monomerList: string[] = lineM.groups!['monomers'].split(',').map(m => m.trim());
110
+ const monomerList: string[] = lineM.groups!['monomers'].split(',').map((m) => m.trim());
111
111
  if (!(pos in res)) res[pos] = [];
112
112
  res[pos].push(...monomerList);
113
113
  }
@@ -86,18 +86,18 @@ category('PolyTool: Enumerate', () => {
86
86
  }
87
87
  },
88
88
  tgt: [
89
- ["PEPTIDE1{[Ac(1)].D.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5K-[Tic]7Y"],
90
- ["PEPTIDE1{[Ac(1)].D.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5K-[Tic]7T"],
91
- ["PEPTIDE1{[Ac(1)].D.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5P-[Tic]7Y"],
92
- ["PEPTIDE1{[Ac(1)].D.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5P-[Tic]7T"],
93
- ["PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5[F4COO]-[Tic]7Y"],
94
- ["PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2D-P5[F4COO]-[Tic]7T"],
95
- ["PEPTIDE1{[Ac(1)].L.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5K-[Tic]7Y"],
96
- ["PEPTIDE1{[Ac(1)].L.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5K-[Tic]7T"],
97
- ["PEPTIDE1{[Ac(1)].L.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5P-[Tic]7Y"],
98
- ["PEPTIDE1{[Ac(1)].L.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5P-[Tic]7T"],
99
- ["PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5[F4COO]-[Tic]7Y"],
100
- ["PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0", "-F2L-P5[F4COO]-[Tic]7T"],
89
+ ['PEPTIDE1{[Ac(1)].D.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5K-[Tic]7Y'],
90
+ ['PEPTIDE1{[Ac(1)].D.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5K-[Tic]7T'],
91
+ ['PEPTIDE1{[Ac(1)].D.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5P-[Tic]7Y'],
92
+ ['PEPTIDE1{[Ac(1)].D.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5P-[Tic]7T'],
93
+ ['PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5[F4COO]-[Tic]7Y'],
94
+ ['PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5[F4COO]-[Tic]7T'],
95
+ ['PEPTIDE1{[Ac(1)].L.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5K-[Tic]7Y'],
96
+ ['PEPTIDE1{[Ac(1)].L.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5K-[Tic]7T'],
97
+ ['PEPTIDE1{[Ac(1)].L.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5P-[Tic]7Y'],
98
+ ['PEPTIDE1{[Ac(1)].L.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5P-[Tic]7T'],
99
+ ['PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5[F4COO]-[Tic]7Y'],
100
+ ['PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5[F4COO]-[Tic]7T'],
101
101
  ],
102
102
  }
103
103
  };