@datagrok/sequence-translator 1.0.6 → 1.0.7

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.0.6",
4
+ "version": "1.0.7",
5
5
  "author": {
6
6
  "name": "Vadym Kovadlo",
7
7
  "email": "vkovadlo@datagrok.ai"
@@ -42,19 +42,20 @@ it('TEST', async () => {
42
42
  let r = await page.evaluate((targetPackage):Promise<object> => {
43
43
  return new Promise<object>((resolve, reject) => {
44
44
  (<any>window).grok.functions.eval(targetPackage + ':test()').then((df: any) => {
45
- let cStatus = df.columns.byName('success');
46
- let cMessage = df.columns.byName('result');
47
- let cCat = df.columns.byName('category');
48
- let cName = df.columns.byName('name');
45
+ const cStatus = df.columns.byName('success');
46
+ const cMessage = df.columns.byName('result');
47
+ const cCat = df.columns.byName('category');
48
+ const cName = df.columns.byName('name');
49
+ const cTime = df.columns.byName('ms');
49
50
  let failed = false;
50
51
  let passReport = '';
51
52
  let failReport = '';
52
53
  for (let i = 0; i < df.rowCount; i++) {
53
54
  if (cStatus.get(i)) {
54
- passReport += `Test result : Success : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
55
+ passReport += `Test result : Success : ${cTime.get(i)} : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
55
56
  } else {
56
57
  failed = true;
57
- failReport += `Test result : Failed : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
58
+ failReport += `Test result : Failed : ${cTime.get(i)} : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
58
59
  }
59
60
  }
60
61
  resolve({failReport, passReport, failed});
@@ -75,7 +75,7 @@ export async function getBrowserPage(puppeteer: any): Promise<{browser: any, pag
75
75
  }, token);
76
76
  await page.goto(url);
77
77
  try {
78
- await page.waitForSelector('.grok-preloader', { timeout: 1800000 });
78
+ // await page.waitForSelector('.grok-preloader', { timeout: 1800000 });
79
79
  await page.waitForFunction(() => document.querySelector('.grok-preloader') == null, {timeout: 3600000});
80
80
  } catch (error) {
81
81
  throw error;
@@ -4,7 +4,7 @@ import * as DG from 'datagrok-api/dg';
4
4
  import {siRnaAxolabsToGcrs, gcrsToNucleotides, asoGapmersBioSpringToGcrs, gcrsToMermade12,
5
5
  } from '../structures-works/converters';
6
6
  import {map, COL_NAMES, MODIFICATIONS} from '../structures-works/map';
7
- import {getFormat, isValidSequence} from '../structures-works/sequence-codes-tools';
7
+ import {isValidSequence} from '../structures-works/sequence-codes-tools';
8
8
  import {sequenceToMolV3000} from '../structures-works/from-monomers';
9
9
 
10
10
  import {SALTS_CSV} from '../salts';
@@ -48,13 +48,13 @@ async function saveTableAsSdFile(table: DG.DataFrame) {
48
48
  for (let i = 0; i < table.rowCount; i++) {
49
49
  const format = 'Janssen GCRS Codes'; //getFormat(structureColumn.get(i))!;
50
50
  result += (typeColumn.get(i) == 'SS') ?
51
- sequenceToMolV3000(structureColumn.get(i), false, true, format) + '\n' + `> <Sequence>\nSense Strand\n\n` :
52
- sequenceToMolV3000(structureColumn.get(i), true, true, format) + '\n' + `> <Sequence>\nAnti Sense\n\n`;
51
+ sequenceToMolV3000(structureColumn.get(i), false, true, format) + '\n' + `> <Sequence>\nSense Strand\n\n` :
52
+ sequenceToMolV3000(structureColumn.get(i), true, true, format) + '\n' + `> <Sequence>\nAnti Sense\n\n`;
53
53
  for (const col of table.columns) {
54
54
  if (col.name != COL_NAMES.SEQUENCE)
55
- result += `> <${col.name}>\n${col.get(i)}\n\n`;
55
+ result += `> <${col.name}>\n${col.get(i)}\n\n`;
56
56
  }
57
- result += '$$$$\n\n';
57
+ result += '$$$$\n';
58
58
  }
59
59
  const element = document.createElement('a');
60
60
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result));
@@ -125,6 +125,11 @@ export function oligoSdFile(table: DG.DataFrame) {
125
125
  const saltCol = t.getCol(COL_NAMES.SALT);
126
126
  const equivalentsCol = t.getCol(COL_NAMES.EQUIVALENTS);
127
127
 
128
+ for (let i = t.rowCount - 1; i > -1; i--) {
129
+ if (sequenceCol.get(i) == '')
130
+ t.rows.removeAt(i, 1, false);
131
+ }
132
+
128
133
  t.columns.addNewString(COL_NAMES.COMPOUND_NAME).init((i: number) => sequenceCol.get(i));
129
134
 
130
135
  t.columns.addNewString(COL_NAMES.COMPOUND_COMMENTS).init((i: number) => (i > 0 && i % 2 == 0) ?
@@ -151,9 +156,12 @@ export function oligoSdFile(table: DG.DataFrame) {
151
156
 
152
157
  t.columns.addNewFloat(COL_NAMES.SALT_MASS).init((i: number) => {
153
158
  const saltRowIndex = saltNamesList.indexOf(saltCol.get(i));
154
- return (saltRowIndex == -1) ?
155
- DG.FLOAT_NULL :
156
- molWeightCol.get(saltRowIndex) * equivalentsCol.get(i);
159
+ return (saltRowIndex == -1) ? DG.FLOAT_NULL : molWeightCol.get(saltRowIndex) * equivalentsCol.get(i);
160
+ });
161
+
162
+ t.columns.addNewFloat(COL_NAMES.SALT_MOL_WEIGHT).init((i: number) => {
163
+ const saltRowIndex = saltNamesList.indexOf(saltCol.get(i));
164
+ return (saltRowIndex == -1) ? DG.FLOAT_NULL : molWeightCol.get(saltRowIndex);
157
165
  });
158
166
 
159
167
  await t.columns.addNewCalculated(COL_NAMES.BATCH_MW,
@@ -361,6 +361,11 @@ export function defineAxolabsPattern() {
361
361
  })
362
362
  .show();
363
363
  }
364
+ if (col.get(0) != ssLength.value) {
365
+ const d = ui.dialog('Length was updated by value to from imported file');
366
+ d.add(ui.divText('Latest modifications may not take effect during translation'))
367
+ .onOK(() => grok.shell.info('Lengths changed')).show();
368
+ }
364
369
  return allLengthsAreTheSame;
365
370
  }
366
371
 
@@ -513,7 +518,9 @@ export function defineAxolabsPattern() {
513
518
  let asPtoLinkages = Array(defaultSequenceLength).fill(ui.boolInput('', defaultPto));
514
519
 
515
520
  const ssLength = ui.intInput('SS Length', defaultSequenceLength, () => updateUiForNewSequenceLength());
521
+ ssLength.setTooltip('Length of sense strand, including overhangs');
516
522
  const asLength = ui.intInput('AS Length', defaultSequenceLength, () => updateUiForNewSequenceLength());
523
+ asLength.setTooltip('Length of sense strand, including overhangs');
517
524
  const asLengthDiv = ui.div([asLength.root]);
518
525
 
519
526
  function validateSsColumn(colName: string): void {
@@ -605,7 +612,9 @@ export function defineAxolabsPattern() {
605
612
  });
606
613
 
607
614
  const firstSsPto = ui.boolInput('First SS PTO', fullyPto.value!, () => updateSvgScheme());
615
+ firstSsPto.setTooltip('ps linkage before first nucleotide of sense strand');
608
616
  const firstAsPto = ui.boolInput('First AS PTO', fullyPto.value!, () => updateSvgScheme());
617
+ firstAsPto.setTooltip('ps linkage before first nucleotide of antisense strand');
609
618
  firstAsPtoDiv.append(firstAsPto.root);
610
619
 
611
620
  const createAsStrand = ui.boolInput('Create AS Strand', true, (v: boolean) => {
@@ -617,6 +626,7 @@ export function defineAxolabsPattern() {
617
626
  firstAsPtoDiv.hidden = (!v);
618
627
  updateSvgScheme();
619
628
  });
629
+ createAsStrand.setTooltip('Create antisense strand sections on SVG and table to the right');
620
630
 
621
631
  const saveAs = ui.textInput('Save As', 'Pattern Name', () => updateSvgScheme());
622
632
  saveAs.setTooltip('Name Of New Pattern');
@@ -4,7 +4,6 @@ import * as DG from 'datagrok-api/dg';
4
4
  import {convertSequence, undefinedInputSequence, isValidSequence} from '../structures-works/sequence-codes-tools';
5
5
  import {map, MODIFICATIONS} from '../structures-works/map';
6
6
  import {sequenceToSmiles, sequenceToMolV3000} from '../structures-works/from-monomers';
7
-
8
7
  import $ from 'cash-dom';
9
8
 
10
9
  const defaultInput = 'fAmCmGmAmCpsmU';
@@ -12,7 +11,7 @@ const sequenceWasCopied = 'Copied';
12
11
  const tooltipSequence = 'Copy sequence';
13
12
 
14
13
  export function mainView() {
15
- function updateTableAndMolecule(sequence: string, inputFormat: string, isSet: boolean): void {
14
+ function updateTableAndMolecule(sequence: string, inputFormat: string): void {
16
15
  moleculeSvgDiv.innerHTML = '';
17
16
  outputTableDiv.innerHTML = '';
18
17
  const pi = DG.TaskBarProgressIndicator.create('Rendering table and molecule...');
@@ -20,9 +19,8 @@ export function mainView() {
20
19
  try {
21
20
  sequence = sequence.replace(/\s/g, '');
22
21
  const output = isValidSequence(sequence, null);
23
- if (isSet)
24
- output.synthesizer = [inputFormat];
25
- inputFormatChoiceInput.value = output.synthesizer![0];
22
+ output.synthesizer = [inputFormat];
23
+ // inputFormatChoiceInput.value = output.synthesizer![0];
26
24
  const outputSequenceObj = convertSequence(sequence, output);
27
25
  const tableRows = [];
28
26
 
@@ -101,14 +99,15 @@ export function mainView() {
101
99
  }
102
100
  }
103
101
 
104
- const inputFormatChoiceInput = ui.choiceInput(
105
- 'Input format: ', 'Janssen GCRS Codes', Object.keys(map), (format: string) => {
106
- updateTableAndMolecule(inputSequenceField.value.replace(/\s/g, ''), format, true);
107
- });
102
+ const inputFormatChoiceInput = ui.choiceInput('Input format: ', 'Janssen GCRS Codes', Object.keys(map));
103
+ inputFormatChoiceInput.onInput((format: string) => {
104
+ updateTableAndMolecule(inputSequenceField.value.replace(/\s/g, ''), format);
105
+ });
108
106
  const moleculeSvgDiv = ui.block([]);
109
107
  const outputTableDiv = ui.div([]);
110
- const inputSequenceField = ui.textInput('', defaultInput, (sequence: string) => updateTableAndMolecule(sequence,
111
- inputFormatChoiceInput.value!, false));
108
+ const inputSequenceField = ui.textInput('', defaultInput, (sequence: string) => {
109
+ updateTableAndMolecule(sequence, inputFormatChoiceInput.value!);
110
+ });
112
111
 
113
112
  const asoDf = DG.DataFrame.fromObjects([
114
113
  {'Name': '2\'MOE-5Me-rU', 'BioSpring': '5', 'Janssen GCRS': 'moeT'},
@@ -151,7 +150,7 @@ export function mainView() {
151
150
  DG.Column.fromStrings('Name', Object.keys(MODIFICATIONS)),
152
151
  ])!, {showRowHeader: false, showCellTooltip: false},
153
152
  );
154
- updateTableAndMolecule(defaultInput, inputFormatChoiceInput.value!, true);
153
+ updateTableAndMolecule(defaultInput, inputFormatChoiceInput.value!);
155
154
 
156
155
  const codesTablesDiv = ui.splitV([
157
156
  ui.box(ui.h2('ASO Gapmers'), {style: {maxHeight: '40px'}}),
@@ -1,6 +1,6 @@
1
1
  import {lcmsToGcrs} from './map';
2
2
  import * as DG from 'datagrok-api/dg';
3
-
3
+ import {delimiter} from './map';
4
4
  //name: gcrsToLcms
5
5
  //input: string nucleotides {semType: GCRS}
6
6
  //output: string result {semType: LCMS}
@@ -10,12 +10,21 @@ export function gcrsToLcms(sequence: string): string {
10
10
  const arr2 = df.getCol('LCMS').toList();
11
11
  const obj: {[i: string]: string} = {};
12
12
  arr1.forEach((element, index) => obj[element] = arr2[index]);
13
- for (let i = 0; i < arr1.length; i++) {
14
- arr1[i] = arr1[i].replace('(', '\\(');
15
- arr1[i] = arr1[i].replace(')', '\\)');
13
+ obj[delimiter] = delimiter;
14
+ // for (let i = 0; i < arr1.length; i++) {
15
+ // arr1[i] = arr1[i].replace('(', '\\(');
16
+ // arr1[i] = arr1[i].replace(')', '\\)');
17
+ // }
18
+ // const regExp = new RegExp('(' + arr1.join('|') + ')', 'g');
19
+ // let r1 = sequence.replace(regExp, function(code) {return obj[code];});
20
+ const codes = arr1.concat(delimiter).sort(function(a, b) {return b.length - a.length;});
21
+ let i = 0;
22
+ let r1 = '';
23
+ while (i < sequence.length) {
24
+ const matchedCode = codes.find((c) => c == sequence.slice(i, i + c.length));
25
+ r1 += obj[sequence.slice(i, i + matchedCode.length)];
26
+ i += matchedCode.length;
16
27
  }
17
- const regExp = new RegExp('(' + arr1.join('|') + ')', 'g');
18
- let r1 = sequence.replace(regExp, function(code) {return obj[code];});
19
28
  while (r1.indexOf('//') != -1)
20
29
  r1 = r1.replace('//', '/');
21
30
  return r1;
@@ -22,7 +22,8 @@ export function sequenceToMolV3000(sequence: string, inverted: boolean = false,
22
22
  if (dropdowns.includes(codesList[i])) {
23
23
  smilesCodes.push((i >= codesList.length / 2) ?
24
24
  MODIFICATIONS[codesList[i]].right : MODIFICATIONS[codesList[i]].left);
25
- smilesCodes.push(stadardPhosphateLinkSmiles);
25
+ if (!(i < codesList.length - 1 && links.includes(codesList[i + 1])))
26
+ smilesCodes.push(stadardPhosphateLinkSmiles);
26
27
  } else {
27
28
  if (links.includes(codesList[i]) ||
28
29
  includesStandardLinkAlready.includes(codesList[i]) ||
@@ -30,6 +30,7 @@ export const COL_NAMES = {
30
30
  EQUIVALENTS: 'Equivalents',
31
31
  PURITY: 'Purity',
32
32
  CPD_MW: 'Cpd MW',
33
+ SALT_MOL_WEIGHT: 'Salt MW',
33
34
  SALT_MASS: 'Salt mass',
34
35
  BATCH_MW: 'Batch MW',
35
36
  SOURCE: 'Source',
@@ -250,7 +250,7 @@ export function linkV3000(molBlocks: string[], twoChains: boolean = false, useCh
250
250
  macroMolBlock = macroMolBlock.replace(/ CFG=\d/g, ' ');
251
251
 
252
252
  macroMolBlock += 'M V30 END CTAB\n';
253
- macroMolBlock += 'M END\n';
253
+ macroMolBlock += 'M END';
254
254
 
255
255
  return macroMolBlock;
256
256
  }
@@ -10,13 +10,13 @@ export function saveSdf(as: string, ss: string, oneEntity: boolean, useChirality
10
10
  const molAS = sequenceToMolV3000(as, invertAS, false, formatAs!);
11
11
  let result: string;
12
12
  if (oneEntity)
13
- result = linkV3000([molSS, molAS], true, useChirality) + '\n\n$$$$\n';
13
+ result = linkV3000([molSS, molAS], true, useChirality) + '\n$$$$\n';
14
14
  else {
15
15
  result =
16
16
  molSS + '\n' +
17
- `> <Sequence>\nSense Strand\n\n$$$$\n` +
17
+ `> <Sequence>\nSense Strand\n$$$$\n` +
18
18
  molAS + '\n' +
19
- `> <Sequence>\nAnti Sense\n\n$$$$\n`;
19
+ `> <Sequence>\nAnti Sense\n$$$$\n`;
20
20
  }
21
21
 
22
22
  const element = document.createElement('a');
@@ -170,8 +170,8 @@ export function isValidSequence(sequence: string, format: string | null): {
170
170
  // })
171
171
  // .show();
172
172
  // } else if (possibleTechnologies.length == 0)
173
- if (possibleTechnologies.length == 0)
174
- return {indexOfFirstNotValidChar: 0, synthesizer: [possibleSynthesizers[3]], technology: null};
173
+ // if (possibleTechnologies.length == 0)
174
+ // return {indexOfFirstNotValidChar: 0, synthesizer: [possibleSynthesizers[3]], technology: null};
175
175
 
176
176
  outputIndex = 0;
177
177