@datagrok/sequence-translator 1.0.16 → 1.0.17
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/detectors.js +0 -28
- package/dist/package-test.js +3830 -3738
- package/dist/package.js +3826 -3734
- package/package.json +3 -1
- package/setup-unlink-clean.sh +21 -0
- package/src/autostart/calculations.ts +2 -2
- package/src/autostart/registration.ts +102 -37
- package/src/{axolabs/define-pattern.ts → axolabs-tab/axolabs-tab.ts} +2 -2
- package/src/axolabs-tab/define-pattern.ts +874 -0
- package/src/{axolabs → axolabs-tab}/draw-svg.ts +1 -1
- package/src/{axolabs → axolabs-tab}/helpers.ts +2 -2
- package/src/{autostart → hardcode-to-be-eliminated}/ICDs.ts +0 -0
- package/src/{autostart → hardcode-to-be-eliminated}/IDPs.ts +0 -0
- package/src/{structures-works → hardcode-to-be-eliminated}/const.ts +0 -0
- package/src/{axolabs → hardcode-to-be-eliminated}/constants.ts +0 -0
- package/src/{structures-works → hardcode-to-be-eliminated}/converters.ts +1 -1
- package/src/{structures-works → hardcode-to-be-eliminated}/map.ts +2 -2
- package/src/{autostart → hardcode-to-be-eliminated}/salts.ts +0 -0
- package/src/{autostart → hardcode-to-be-eliminated}/sources.ts +0 -0
- package/src/{autostart → hardcode-to-be-eliminated}/users.ts +0 -0
- package/src/{main/main-view.ts → main-tab/main-tab.ts} +27 -79
- package/src/package.ts +40 -23
- package/src/sdf-tab/sdf-tab.ts +163 -0
- package/src/{structures-works → sdf-tab}/sequence-codes-tools.ts +8 -5
- package/src/tests/smiles-tests.ts +2 -2
- package/src/utils/const.ts +0 -0
- package/src/{helpers.ts → utils/helpers.ts} +3 -3
- package/src/utils/sdf-add-columns.ts +3 -3
- package/src/utils/sdf-save-table.ts +4 -4
- package/src/utils/structures-works/draw-molecule.ts +84 -0
- package/src/{structures-works → utils/structures-works}/from-monomers.ts +15 -16
- package/src/{structures-works → utils/structures-works}/mol-transformations.ts +34 -52
- package/{test-SequenceTranslator-6288c2fbe346-cce4ac1d.html → test-SequenceTranslator-6288c2fbe346-695b7b55.html} +10 -10
- package/src/structures-works/save-sense-antisense.ts +0 -91
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
4
|
+
import * as DG from 'datagrok-api/dg';
|
|
5
|
+
import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
|
|
6
|
+
|
|
7
|
+
import $ from 'cash-dom';
|
|
8
|
+
|
|
9
|
+
import {extractAtomDataV3000} from './mol-transformations';
|
|
10
|
+
|
|
11
|
+
/** Draw molecule on the canvas and append it to the specified div, with the
|
|
12
|
+
* option of zoom-in */
|
|
13
|
+
export async function drawMolecule(
|
|
14
|
+
moleculeImgDiv: HTMLDivElement,
|
|
15
|
+
canvasWidth: number, canvasHeight: number,
|
|
16
|
+
molfile: string
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
// clear the div's content if any
|
|
19
|
+
async function drawMolfileOnCanvas(canvas: HTMLCanvasElement): Promise<void> {
|
|
20
|
+
await grok.functions.call('Chem:canvasMol', {
|
|
21
|
+
x: 0, y: 0, w: canvas.width, h: canvas.height, canvas: canvas,
|
|
22
|
+
molString: molfile, scaffoldMolString: '',
|
|
23
|
+
options: {normalizeDepiction: false, straightenDepiction: false}
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
async function drawZoomedInMolecule(): Promise<void> {
|
|
28
|
+
try {
|
|
29
|
+
const dialogDivStyle = {
|
|
30
|
+
overflowX: 'scroll',
|
|
31
|
+
};
|
|
32
|
+
const dialogDiv = ui.div([], {style: dialogDivStyle});
|
|
33
|
+
|
|
34
|
+
// dialogDiv size required, but now available before dialog show()
|
|
35
|
+
const atomCoordinates = extractAtomDataV3000(molfile);
|
|
36
|
+
// const cw: number = $(window).width() * 0.80; // dialogDiv.clientWidth
|
|
37
|
+
const clientHeight: number = $(window).height() * 0.70; // dialogDiv.clientHeight
|
|
38
|
+
const molWidth: number = Math.max(...atomCoordinates.x) - Math.min(...atomCoordinates.x);
|
|
39
|
+
const molHeight: number = Math.max(...atomCoordinates.y) - Math.min(...atomCoordinates.y);
|
|
40
|
+
|
|
41
|
+
// const wR: number = cw / molWidth;
|
|
42
|
+
const hR: number = clientHeight / molHeight;
|
|
43
|
+
const r: number = hR; // Math.max(wR, hR);
|
|
44
|
+
const dialogCanvasWidth = r * molWidth;
|
|
45
|
+
const dialogCanvasHeight = r * molHeight;
|
|
46
|
+
|
|
47
|
+
const dialogCanvas = ui.canvas(
|
|
48
|
+
dialogCanvasWidth * window.devicePixelRatio, dialogCanvasHeight * window.devicePixelRatio
|
|
49
|
+
);
|
|
50
|
+
dialogCanvas.style.width = `${dialogCanvasWidth}px`;
|
|
51
|
+
dialogCanvas.style.height = `${dialogCanvasHeight}px`;
|
|
52
|
+
await drawMolfileOnCanvas(dialogCanvas);
|
|
53
|
+
|
|
54
|
+
dialogDiv.appendChild(dialogCanvas);
|
|
55
|
+
ui.dialog('Molecule')
|
|
56
|
+
.add(dialogDiv)
|
|
57
|
+
.showModal(true);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
const errStr = errorToConsole(err);
|
|
60
|
+
console.error(errStr);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// clear div's content if any
|
|
65
|
+
moleculeImgDiv.innerHTML = '';
|
|
66
|
+
|
|
67
|
+
if (molfile !== '') {
|
|
68
|
+
const canvas = ui.canvas(canvasWidth * window.devicePixelRatio, canvasHeight * window.devicePixelRatio);
|
|
69
|
+
|
|
70
|
+
// Draw zoomed-out molecule
|
|
71
|
+
canvas.style.width = `${canvasWidth}px`;
|
|
72
|
+
canvas.style.height = `${canvasHeight}px`;
|
|
73
|
+
canvas.style.borderStyle = 'solid';
|
|
74
|
+
canvas.style.borderColor = 'blue';
|
|
75
|
+
drawMolfileOnCanvas(canvas);
|
|
76
|
+
|
|
77
|
+
// Dialog with zoomed-in molecule
|
|
78
|
+
$(canvas).on('click', drawZoomedInMolecule);
|
|
79
|
+
$(canvas).on('mouseover', () => $(canvas).css('cursor', 'grab')); // for some reason 'zoom-in' value wouldn't work
|
|
80
|
+
$(canvas).on('mouseout', () => $(canvas).css('cursor', 'default'));
|
|
81
|
+
|
|
82
|
+
moleculeImgDiv.append(canvas);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// import {map, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIONS, DELIMITER} from './map';
|
|
2
|
-
import {map, SYNTHESIZERS, TECHNOLOGIES, DELIMITER} from '
|
|
3
|
-
import {isValidSequence} from '
|
|
2
|
+
import {map, SYNTHESIZERS, TECHNOLOGIES, DELIMITER} from '../../hardcode-to-be-eliminated/map';
|
|
3
|
+
import {isValidSequence} from '../../sdf-tab/sequence-codes-tools';
|
|
4
4
|
import {sortByStringLengthInDescendingOrder} from '../helpers';
|
|
5
|
-
import {getMonomerWorks} from '
|
|
5
|
+
import {getMonomerWorks} from '../../package';
|
|
6
6
|
import {getNucleotidesMol} from './mol-transformations';
|
|
7
7
|
|
|
8
|
-
import {standardPhosphateLinkSmiles, MODIFICATIONS} from '
|
|
9
|
-
import {getMonomerLib} from '
|
|
8
|
+
import {standardPhosphateLinkSmiles, MODIFICATIONS} from '../../hardcode-to-be-eliminated/const';
|
|
9
|
+
import {getMonomerLib} from '../../package';
|
|
10
10
|
// todo: remove
|
|
11
11
|
// const NAME = 'name';
|
|
12
12
|
const CODES = 'codes';
|
|
@@ -15,7 +15,7 @@ const MOL = 'molfile';
|
|
|
15
15
|
|
|
16
16
|
export function sequenceToMolV3000(
|
|
17
17
|
sequence: string, inverted: boolean = false, oclRender: boolean = false,
|
|
18
|
-
format: string
|
|
18
|
+
format: string
|
|
19
19
|
): string {
|
|
20
20
|
const monomerNameFromCode = getCodeToNameMap(sequence, format);
|
|
21
21
|
let codes = sortByStringLengthInDescendingOrder(Object.keys(monomerNameFromCode));
|
|
@@ -38,25 +38,24 @@ export function sequenceToMolV3000(
|
|
|
38
38
|
includesStandardLinkAlready.includes(codesList[i]) ||
|
|
39
39
|
(i < codesList.length - 1 && links.includes(codesList[i + 1]))
|
|
40
40
|
) {
|
|
41
|
-
|
|
42
|
-
if(aa !== undefined)
|
|
41
|
+
const aa = monomerNameFromCode[codesList[i]];
|
|
42
|
+
if (aa !== undefined)
|
|
43
|
+
monomers.push(aa);
|
|
44
|
+
else
|
|
45
|
+
monomers.push(codesList[i]);
|
|
46
|
+
} else {
|
|
47
|
+
const aa = monomerNameFromCode[codesList[i]];
|
|
48
|
+
if (aa !== undefined)
|
|
43
49
|
monomers.push(aa);
|
|
44
50
|
else
|
|
45
51
|
monomers.push(codesList[i]);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
let aa = monomerNameFromCode[codesList[i]];
|
|
49
|
-
if(aa !== undefined)
|
|
50
|
-
monomers.push(aa);
|
|
51
|
-
else
|
|
52
|
-
monomers.push(codesList[i]);
|
|
53
52
|
monomers.push('p linkage');
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
const lib = getMonomerLib();
|
|
58
57
|
const mols: string [] = [];
|
|
59
|
-
for(let i = 0; i < monomers.length; i++) {
|
|
58
|
+
for (let i = 0; i < monomers.length; i++) {
|
|
60
59
|
const mnmr = lib?.getMonomer('RNA', monomers[i]);
|
|
61
60
|
mols.push(mnmr?.molfile!);
|
|
62
61
|
}
|
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
export function getNucleotidesMol(codes: string[]) {
|
|
2
2
|
const molBlocks: string[] = [];
|
|
3
3
|
|
|
4
|
-
// for (let i = 0; i < smilesCodes.length - 1; i++) {
|
|
5
|
-
// smilesCodes[i] == 'OP(=O)(O)O' ? molBlocks.push(PHOSHATE) :
|
|
6
|
-
// smilesCodes[i] == 'OP(=O)(S)O' ? molBlocks.push(THIOPHOSHATE) :
|
|
7
|
-
// smilesCodes[i] == 'O[C@@H]1C[C@@H]O[C@H]1CO' ? molBlocks.push(rotateNucleotidesV3000(INVABASIC)) :
|
|
8
|
-
// smilesCodes[i] == 'OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)' ? molBlocks.push(GALNAC) :
|
|
9
|
-
// smilesCodes[i] == 'C(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)NC(=O)CCCC(=O)NCC(O)CO' ? molBlocks.push(GALNACPRIME) :
|
|
10
|
-
// molBlocks.push(rotateNucleotidesV3000(smilesCodes[i]));
|
|
11
|
-
// }
|
|
12
|
-
|
|
13
4
|
for (let i = 0; i < codes.length - 1; i++) {
|
|
14
5
|
if (codes[i].includes('MODIFICATION')) {
|
|
15
|
-
if (i
|
|
6
|
+
if (i === 0)
|
|
16
7
|
molBlocks.push(reflect(codes[i]));
|
|
17
8
|
else
|
|
18
9
|
molBlocks.push(codes[i]);
|
|
19
|
-
}
|
|
20
|
-
else
|
|
10
|
+
} else {
|
|
21
11
|
molBlocks.push(rotateNucleotidesV3000(codes[i]));
|
|
12
|
+
}
|
|
22
13
|
}
|
|
23
14
|
|
|
24
15
|
return linkV3000(molBlocks);
|
|
25
16
|
}
|
|
26
17
|
|
|
27
|
-
export function linkStrandsV3000(
|
|
18
|
+
export function linkStrandsV3000(
|
|
19
|
+
strands: { senseStrands: string[], antiStrands: string[] }, useChirality: boolean = true
|
|
20
|
+
): string {
|
|
28
21
|
let macroMolBlock = '\nDatagrok macromolecule handler\n\n';
|
|
29
22
|
macroMolBlock += ' 0 0 0 0 0 0 999 V3000\n';
|
|
30
23
|
macroMolBlock += 'M V30 BEGIN CTAB\n';
|
|
@@ -40,22 +33,19 @@ export function linkStrandsV3000(strands: { senseStrands: string[], antiStrands:
|
|
|
40
33
|
// molBlocks[1] = invertNucleotidesV3000(molBlocks[1]);
|
|
41
34
|
|
|
42
35
|
if (strands.antiStrands.length > 0) {
|
|
43
|
-
for (let i = 0; i < strands.antiStrands.length; i++)
|
|
36
|
+
for (let i = 0; i < strands.antiStrands.length; i++)
|
|
44
37
|
strands.antiStrands[i] = invertNucleotidesV3000(strands.antiStrands[i]);
|
|
45
|
-
}
|
|
46
38
|
}
|
|
47
39
|
|
|
48
40
|
let inverted = false;
|
|
49
|
-
|
|
41
|
+
const molBlocks = strands.senseStrands.concat(strands.antiStrands);
|
|
50
42
|
|
|
51
43
|
for (let i = 0; i < molBlocks.length; i++) {
|
|
52
|
-
|
|
53
|
-
if (i >= strands.senseStrands.length && inverted == false) {
|
|
44
|
+
if (i >= strands.senseStrands.length && inverted === false) {
|
|
54
45
|
inverted = true;
|
|
55
46
|
xShift = 0;
|
|
56
47
|
}
|
|
57
48
|
|
|
58
|
-
|
|
59
49
|
molBlocks[i] = molBlocks[i].replaceAll('(-\nM V30 ', '(')
|
|
60
50
|
.replaceAll('-\nM V30 ', '').replaceAll(' )', ')');
|
|
61
51
|
const numbers = extractAtomsBondsNumbersV3000(molBlocks[i]);
|
|
@@ -63,7 +53,7 @@ export function linkStrandsV3000(strands: { senseStrands: string[], antiStrands:
|
|
|
63
53
|
|
|
64
54
|
if (inverted) {
|
|
65
55
|
const xShiftRight = Math.min(...coordinates.x) - xShift;
|
|
66
|
-
const yShift = !inverted ? Math.min(...coordinates.y) - 1 : Math.max(...coordinates.y) +
|
|
56
|
+
const yShift = !inverted ? Math.min(...coordinates.y) - 1 : Math.max(...coordinates.y) + 15;
|
|
67
57
|
for (let j = 0; j < coordinates.x.length; j++)
|
|
68
58
|
coordinates.x[j] -= xShiftRight;
|
|
69
59
|
for (let j = 0; j < coordinates.y.length; j++)
|
|
@@ -76,7 +66,7 @@ export function linkStrandsV3000(strands: { senseStrands: string[], antiStrands:
|
|
|
76
66
|
let indexEnd = indexAtoms;
|
|
77
67
|
|
|
78
68
|
for (let j = 0; j < numbers.natom; j++) {
|
|
79
|
-
// if (coordinates.atomIndex[j]
|
|
69
|
+
// if (coordinates.atomIndex[j] !== 1 || i === 0 || twoChains) {
|
|
80
70
|
//rewrite atom number
|
|
81
71
|
index = molBlocks[i].indexOf('V30', index) + 4;
|
|
82
72
|
indexEnd = molBlocks[i].indexOf(' ', index);
|
|
@@ -138,7 +128,7 @@ export function linkStrandsV3000(strands: { senseStrands: string[], antiStrands:
|
|
|
138
128
|
|
|
139
129
|
let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections
|
|
140
130
|
|
|
141
|
-
while (indexCollection
|
|
131
|
+
while (indexCollection !== -1) {
|
|
142
132
|
indexCollection += 28;
|
|
143
133
|
const collectionEnd = molBlocks[i].indexOf(')', indexCollection);
|
|
144
134
|
const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);
|
|
@@ -157,25 +147,16 @@ export function linkStrandsV3000(strands: { senseStrands: string[], antiStrands:
|
|
|
157
147
|
const entries = 4;
|
|
158
148
|
const collNumber = Math.ceil(collection.length / entries);
|
|
159
149
|
|
|
160
|
-
//if (oclRender) {
|
|
161
|
-
// collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length;
|
|
162
|
-
|
|
163
|
-
// for (let j = 0; j < collection.length; j++)
|
|
164
|
-
// collectionBlock += ' ' + collection[j];
|
|
165
|
-
|
|
166
|
-
// collectionBlock += ')\n';
|
|
167
|
-
//} else {
|
|
168
150
|
collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\n';
|
|
169
151
|
for (let i = 0; i < collNumber; i++) {
|
|
170
152
|
collectionBlock += 'M V30 ';
|
|
171
|
-
const entriesCurrent = i + 1
|
|
153
|
+
const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;
|
|
172
154
|
for (let j = 0; j < entriesCurrent; j++) {
|
|
173
|
-
collectionBlock += (j + 1
|
|
174
|
-
(i
|
|
155
|
+
collectionBlock += (j + 1 === entriesCurrent) ?
|
|
156
|
+
(i === collNumber - 1 ? collection[entries * i + j] + ')\n' : collection[entries * i + j] + ' -\n') :
|
|
175
157
|
collection[entries * i + j] + ' ';
|
|
176
158
|
}
|
|
177
159
|
}
|
|
178
|
-
//}
|
|
179
160
|
|
|
180
161
|
//generate file
|
|
181
162
|
true ? natom : natom++;
|
|
@@ -190,8 +171,9 @@ export function linkStrandsV3000(strands: { senseStrands: string[], antiStrands:
|
|
|
190
171
|
macroMolBlock += 'M V30 BEGIN COLLECTION\n';
|
|
191
172
|
macroMolBlock += collectionBlock;
|
|
192
173
|
macroMolBlock += 'M V30 END COLLECTION\n';
|
|
193
|
-
} else
|
|
174
|
+
} else {
|
|
194
175
|
macroMolBlock = macroMolBlock.replace(/ CFG=\d/g, ' ');
|
|
176
|
+
}
|
|
195
177
|
|
|
196
178
|
macroMolBlock += 'M V30 END CTAB\n';
|
|
197
179
|
macroMolBlock += 'M END';
|
|
@@ -199,7 +181,7 @@ export function linkStrandsV3000(strands: { senseStrands: string[], antiStrands:
|
|
|
199
181
|
return macroMolBlock;
|
|
200
182
|
}
|
|
201
183
|
|
|
202
|
-
export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
184
|
+
export function linkV3000(molBlocks: string[], useChirality: boolean = true): string {
|
|
203
185
|
let macroMolBlock = '\nDatagrok macromolecule handler\n\n';
|
|
204
186
|
macroMolBlock += ' 0 0 0 0 0 0 999 V3000\n';
|
|
205
187
|
macroMolBlock += 'M V30 BEGIN CTAB\n';
|
|
@@ -212,7 +194,7 @@ export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
|
212
194
|
let xShift = 0;
|
|
213
195
|
|
|
214
196
|
for (let i = 0; i < molBlocks.length; i++) {
|
|
215
|
-
const isBoundary = molBlocks[i].includes('MODIFICATION') && i
|
|
197
|
+
const isBoundary = molBlocks[i].includes('MODIFICATION') && i === 0;
|
|
216
198
|
let specLength = 0;
|
|
217
199
|
if (isBoundary) {
|
|
218
200
|
const coordinates = extractAtomDataV3000(molBlocks[i]);
|
|
@@ -231,16 +213,16 @@ export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
|
231
213
|
let indexEnd = indexAtoms;
|
|
232
214
|
|
|
233
215
|
for (let j = 0; j < numbers.natom; j++) {
|
|
234
|
-
if (coordinates.atomIndex[j]
|
|
216
|
+
if (coordinates.atomIndex[j] !== 1 || i === 0) {
|
|
235
217
|
//rewrite atom number
|
|
236
218
|
index = molBlocks[i].indexOf('V30', index) + 4;
|
|
237
219
|
indexEnd = molBlocks[i].indexOf(' ', index);
|
|
238
220
|
let atomNumber = 0;
|
|
239
221
|
if (isBoundary) {
|
|
240
222
|
atomNumber = parseInt(molBlocks[i].substring(index, indexEnd))
|
|
241
|
-
if (atomNumber
|
|
223
|
+
if (atomNumber === 1)
|
|
242
224
|
atomNumber = specLength;
|
|
243
|
-
else if (atomNumber
|
|
225
|
+
else if (atomNumber === specLength)
|
|
244
226
|
atomNumber = 1;
|
|
245
227
|
atomNumber += natom;
|
|
246
228
|
} else {
|
|
@@ -294,9 +276,9 @@ export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
|
294
276
|
let atomNumber = 0;
|
|
295
277
|
if (isBoundary) {
|
|
296
278
|
atomNumber = parseInt(molBlocks[i].substring(index, indexEnd))
|
|
297
|
-
if (atomNumber
|
|
279
|
+
if (atomNumber === 1)
|
|
298
280
|
atomNumber = specLength;
|
|
299
|
-
else if (atomNumber
|
|
281
|
+
else if (atomNumber === specLength)
|
|
300
282
|
atomNumber = 1;
|
|
301
283
|
atomNumber += natom;
|
|
302
284
|
} else {
|
|
@@ -309,9 +291,9 @@ export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
|
309
291
|
atomNumber = 0;
|
|
310
292
|
if (isBoundary) {
|
|
311
293
|
atomNumber = parseInt(molBlocks[i].substring(index, indexEnd))
|
|
312
|
-
if (atomNumber
|
|
294
|
+
if (atomNumber === 1)
|
|
313
295
|
atomNumber = specLength;
|
|
314
|
-
else if (atomNumber
|
|
296
|
+
else if (atomNumber === specLength)
|
|
315
297
|
atomNumber = 1;
|
|
316
298
|
atomNumber += natom;
|
|
317
299
|
} else {
|
|
@@ -327,7 +309,7 @@ export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
|
327
309
|
|
|
328
310
|
let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections
|
|
329
311
|
|
|
330
|
-
while (indexCollection
|
|
312
|
+
while (indexCollection !== -1) {
|
|
331
313
|
indexCollection += 28;
|
|
332
314
|
const collectionEnd = molBlocks[i].indexOf(')', indexCollection);
|
|
333
315
|
const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);
|
|
@@ -360,10 +342,10 @@ export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
|
360
342
|
collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\n';
|
|
361
343
|
for (let i = 0; i < collNumber; i++) {
|
|
362
344
|
collectionBlock += 'M V30 ';
|
|
363
|
-
const entriesCurrent = i + 1
|
|
345
|
+
const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;
|
|
364
346
|
for (let j = 0; j < entriesCurrent; j++) {
|
|
365
|
-
collectionBlock += (j + 1
|
|
366
|
-
(i
|
|
347
|
+
collectionBlock += (j + 1 === entriesCurrent) ?
|
|
348
|
+
(i === collNumber - 1 ? collection[entries * i + j] + ')\n' : collection[entries * i + j] + ' -\n') :
|
|
367
349
|
collection[entries * i + j] + ' ';
|
|
368
350
|
}
|
|
369
351
|
}
|
|
@@ -391,7 +373,7 @@ export function linkV3000(molBlocks: string[], useChirality: boolean = true) {
|
|
|
391
373
|
return macroMolBlock;
|
|
392
374
|
}
|
|
393
375
|
|
|
394
|
-
function rotateNucleotidesV3000(molecule: string) {
|
|
376
|
+
function rotateNucleotidesV3000(molecule: string): string {
|
|
395
377
|
// @ts-ignore
|
|
396
378
|
let molBlock = molecule.includes('M END') ? molecule : OCL.Molecule.fromSmiles(molecule).toMolfileV3();
|
|
397
379
|
const coordinates = extractAtomDataV3000(molBlock);
|
|
@@ -414,9 +396,9 @@ function rotateNucleotidesV3000(molecule: string) {
|
|
|
414
396
|
}
|
|
415
397
|
|
|
416
398
|
let angle = 0;
|
|
417
|
-
if (coordinates.x[indexFivePrime]
|
|
399
|
+
if (coordinates.x[indexFivePrime] === 0)
|
|
418
400
|
angle = coordinates.y[indexFivePrime] > coordinates.y[indexThreePrime] ? Math.PI / 2 : 3 * Math.PI / 2;
|
|
419
|
-
else if (coordinates.y[indexFivePrime]
|
|
401
|
+
else if (coordinates.y[indexFivePrime] === 0)
|
|
420
402
|
angle = coordinates.x[indexFivePrime] > coordinates.x[indexThreePrime] ? Math.PI : 0;
|
|
421
403
|
else {
|
|
422
404
|
const derivative = coordinates.y[indexFivePrime] / coordinates.x[indexFivePrime];
|
|
@@ -460,7 +442,7 @@ function rotateNucleotidesV3000(molecule: string) {
|
|
|
460
442
|
return molBlock;
|
|
461
443
|
}
|
|
462
444
|
|
|
463
|
-
function reflect(molecule: string) {
|
|
445
|
+
function reflect(molecule: string): string {
|
|
464
446
|
// @ts-ignore
|
|
465
447
|
let molBlock = molecule.includes('M END') ? molecule : OCL.Molecule.fromSmiles(molecule).toMolfileV3();
|
|
466
448
|
const coordinates = extractAtomDataV3000(molBlock);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<html><head><meta charset="utf-8"/><title>SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=6288c2fbe346. Commit
|
|
1
|
+
<html><head><meta charset="utf-8"/><title>SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=6288c2fbe346. Commit 695b7b55.</title><style type="text/css">html,
|
|
2
2
|
body {
|
|
3
3
|
font-family: Arial, Helvetica, sans-serif;
|
|
4
4
|
font-size: 1rem;
|
|
@@ -229,25 +229,25 @@ header {
|
|
|
229
229
|
font-size: 1rem;
|
|
230
230
|
padding: 0 0.5rem;
|
|
231
231
|
}
|
|
232
|
-
</style></head><body><div id="jesthtml-content"><header><h1 id="title">SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=6288c2fbe346. Commit
|
|
232
|
+
</style></head><body><div id="jesthtml-content"><header><h1 id="title">SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=6288c2fbe346. Commit 695b7b55.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-12-19 15:46:37</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts</div><div class="suite-time warn">15.201s</div></div><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">passed</div><div class="test-duration">4.324s</div></div></div></div><div class="suite-consolelog"><div class="suite-consolelog-header">Console Log</div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at Object.<anonymous> (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/test-node.ts:62:11)
|
|
233
233
|
at Generator.next (<anonymous>)
|
|
234
234
|
at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/test-node.ts:28:58)
|
|
235
235
|
at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message">Using web root: http://localhost:8080</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:40:11
|
|
236
236
|
at Generator.next (<anonymous>)
|
|
237
|
-
at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:
|
|
237
|
+
at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:34:71
|
|
238
238
|
at new Promise (<anonymous>)
|
|
239
|
-
at Object.<anonymous>.__awaiter (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:
|
|
239
|
+
at Object.<anonymous>.__awaiter (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:30:12)
|
|
240
240
|
at Object.<anonymous> (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:38:23)
|
|
241
241
|
at Promise.then.completed (/home/runner/work/public/public/packages/SequenceTranslator/node_modules/jest-circus/build/utils.js:391:28)
|
|
242
242
|
at new Promise (<anonymous>)</pre><pre class="suite-consolelog-item-message">Testing SequenceTranslator package</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:72:11
|
|
243
243
|
at Generator.next (<anonymous>)
|
|
244
|
-
at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:
|
|
244
|
+
at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:31:58)
|
|
245
245
|
at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message">Test result : Success : 2 : SequenceTranslator.sequence-translator.usCfCfUfGfAf : OK
|
|
246
|
-
Test result : Success :
|
|
247
|
-
Test result : Success :
|
|
246
|
+
Test result : Success : 1 : SequenceTranslator.sequence-translator.usAfsusgsgsg : OK
|
|
247
|
+
Test result : Success : 1 : SequenceTranslator.sequence-translator.UfUfUfsCfsuacg : OK
|
|
248
248
|
Test result : Success : 0 : SequenceTranslator.sequence-translator.susususauasu : OK
|
|
249
|
-
Test result : Success :
|
|
250
|
-
Test result : Success :
|
|
249
|
+
Test result : Success : 1 : SequenceTranslator.sequence-translator.CfGfCfsGfsCf : OK
|
|
250
|
+
Test result : Success : 0 : SequenceTranslator.sequence-translator.acacacsacsac : OK
|
|
251
251
|
Test result : Success : 0 : SequenceTranslator.sequence-translator.cccgggusug : OK
|
|
252
252
|
Test result : Success : 0 : SequenceTranslator.sequence-translator.UfAfCfGfGfCfAfUf : OK
|
|
253
253
|
Test result : Success : 1 : SequenceTranslator.sequence-translator.(invabasic)cuCfuUfsc : OK
|
|
@@ -255,5 +255,5 @@ Test result : Success : 1 : SequenceTranslator.sequence-translator.(invabasic)us
|
|
|
255
255
|
Test result : Success : 1 : SequenceTranslator.sequence-translator.(invabasic)asacgGfuGfCfAfacucuauuca : OK
|
|
256
256
|
</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:74:11
|
|
257
257
|
at Generator.next (<anonymous>)
|
|
258
|
-
at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:
|
|
258
|
+
at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:31:58)
|
|
259
259
|
at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message"/></div></div></div></div></body></html>
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import * as grok from 'datagrok-api/grok';
|
|
2
|
-
import * as ui from 'datagrok-api/ui';
|
|
3
|
-
import * as DG from 'datagrok-api/dg';
|
|
4
|
-
|
|
5
|
-
import {download} from '../helpers';
|
|
6
|
-
import {sequenceToMolV3000} from '../structures-works/from-monomers';
|
|
7
|
-
import {linkStrandsV3000} from '../structures-works/mol-transformations';
|
|
8
|
-
import {getFormat} from '../structures-works/sequence-codes-tools';
|
|
9
|
-
|
|
10
|
-
export function saveSdf(as: string, ss: string,
|
|
11
|
-
oneEntity: boolean, useChirality: boolean,
|
|
12
|
-
invertSS: boolean, invertAS: boolean,
|
|
13
|
-
as2: string | null = null, invertAS2: boolean | null) {
|
|
14
|
-
const formatAs = getFormat(as);
|
|
15
|
-
const formatSs = getFormat(ss);
|
|
16
|
-
let formatAs2: string | null = null;
|
|
17
|
-
let molAS2: string | null = null;
|
|
18
|
-
|
|
19
|
-
const molSS = sequenceToMolV3000(ss, invertSS, false, formatSs!);
|
|
20
|
-
const molAS = sequenceToMolV3000(as, invertAS, false, formatAs!);
|
|
21
|
-
|
|
22
|
-
if (as2 != null && as2 != '') {
|
|
23
|
-
formatAs2 = getFormat(as2!);
|
|
24
|
-
molAS2 = sequenceToMolV3000(as2, invertAS2!, false, formatAs2!);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let result: string;
|
|
28
|
-
if (oneEntity) {
|
|
29
|
-
const antiStrands = molAS2 == null ? [molAS] : [molAS, molAS2];
|
|
30
|
-
result = linkStrandsV3000({senseStrands: [molSS], antiStrands: antiStrands}, useChirality) + '\n$$$$\n';
|
|
31
|
-
|
|
32
|
-
} else {
|
|
33
|
-
result =
|
|
34
|
-
molSS + '\n' +
|
|
35
|
-
`> <Sequence>\nSense Strand\n$$$$\n` +
|
|
36
|
-
molAS + '\n' +
|
|
37
|
-
`> <Sequence>\nAnti Sense\n$$$$\n`;
|
|
38
|
-
|
|
39
|
-
if (molAS2)
|
|
40
|
-
result += molAS2+ '\n' +
|
|
41
|
-
`> <Sequence>\nAnti Sense 2\n$$$$\n`;
|
|
42
|
-
}
|
|
43
|
-
download(ss.replace(/\s/g, '') + '.sdf', encodeURIComponent(result));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function saveSenseAntiSense() {
|
|
47
|
-
const moleculeSvgDiv = ui.block([]);
|
|
48
|
-
const ssInput = ui.textInput('Sense Strand', '');
|
|
49
|
-
const asInput = ui.textInput('Anti Sense', '');
|
|
50
|
-
const asInput2 = ui.textInput('Anti Sense 2', '');
|
|
51
|
-
const straight = "5 prime -> 3 prime";
|
|
52
|
-
const inverse = "3 prime -> 5 prime";
|
|
53
|
-
let ssInverse = false;
|
|
54
|
-
let asInverse = false;
|
|
55
|
-
let as2Inverse = false;
|
|
56
|
-
|
|
57
|
-
const changeSense = ui.choiceInput('SS direction', straight, [straight, inverse]);
|
|
58
|
-
changeSense.onChanged(() => {ssInverse = changeSense.value == inverse;});
|
|
59
|
-
const changeAntiSense = ui.choiceInput('AS direction', straight, [straight, inverse]);
|
|
60
|
-
changeAntiSense.onChanged(() => {asInverse = changeAntiSense.value == inverse;});
|
|
61
|
-
const changeAntiSense2 = ui.choiceInput('AS 2 direction', straight, [straight, inverse]);
|
|
62
|
-
changeAntiSense2.onChanged(() => {asInverse = changeAntiSense.value == inverse;});
|
|
63
|
-
|
|
64
|
-
const saveOption = ui.switchInput('Save as one entity', true);
|
|
65
|
-
const chirality = ui.switchInput('Use chiral', true);
|
|
66
|
-
const saveBtn = ui.button('Save SDF', () =>
|
|
67
|
-
saveSdf(asInput.value, ssInput.value, saveOption.value, chirality.value, ssInverse, asInverse, asInput2.value, as2Inverse));
|
|
68
|
-
|
|
69
|
-
const saveSection = ui.panel([
|
|
70
|
-
ui.div([
|
|
71
|
-
ui.div([
|
|
72
|
-
ui.divH([ui.h1('Inputs')]),
|
|
73
|
-
ui.divV([
|
|
74
|
-
ssInput,
|
|
75
|
-
asInput,
|
|
76
|
-
asInput2,
|
|
77
|
-
ui.div([changeSense], {style: {width: '40'}}),
|
|
78
|
-
changeSense,
|
|
79
|
-
changeAntiSense,
|
|
80
|
-
changeAntiSense2,
|
|
81
|
-
saveOption,
|
|
82
|
-
chirality,
|
|
83
|
-
ui.buttonsInput([saveBtn]),
|
|
84
|
-
], 'ui-form'),
|
|
85
|
-
], 'ui-form'),
|
|
86
|
-
], 'ui-form'),
|
|
87
|
-
moleculeSvgDiv,
|
|
88
|
-
]);
|
|
89
|
-
|
|
90
|
-
return saveSection;
|
|
91
|
-
}
|